aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2010-04-07 12:21:42 -0700
committerShih-wei Liao <sliao@google.com>2010-04-07 12:21:42 -0700
commite4454320b3cfffe926a487c33fbeb454366de2f8 (patch)
tree133c05da684edf4a3b2529bcacfa996298c455f6
parent20570085304f0a4ab4f112a01d77958bbd2827a1 (diff)
downloadexternal_llvm-e4454320b3cfffe926a487c33fbeb454366de2f8.zip
external_llvm-e4454320b3cfffe926a487c33fbeb454366de2f8.tar.gz
external_llvm-e4454320b3cfffe926a487c33fbeb454366de2f8.tar.bz2
libbcc
Change-Id: Ieaa3ebd5a38f370752495549f8870b534eeedfc5
-rw-r--r--Android.mk39
-rw-r--r--CMakeLists.txt1
-rw-r--r--CREDITS.TXT5
-rw-r--r--Makefile13
-rw-r--r--Makefile.config.in42
-rw-r--r--Makefile.rules127
-rw-r--r--README.txt3
-rw-r--r--Xcode/LLVM.xcodeproj/project.pbxproj3303
-rw-r--r--Xcode/README.txt1
-rw-r--r--autoconf/ExportMap.map3
-rw-r--r--autoconf/configure.ac110
-rw-r--r--autoconf/m4/huge_val.m42
-rw-r--r--bindings/ocaml/bitreader/bitreader_ocaml.c9
-rw-r--r--bindings/ocaml/bitreader/llvm_bitreader.ml5
-rw-r--r--bindings/ocaml/bitreader/llvm_bitreader.mli14
-rw-r--r--bindings/ocaml/bitwriter/bitwriter_ocaml.c15
-rw-r--r--bindings/ocaml/bitwriter/llvm_bitwriter.ml7
-rw-r--r--bindings/ocaml/bitwriter/llvm_bitwriter.mli12
-rw-r--r--bindings/ocaml/executionengine/executionengine_ocaml.c49
-rw-r--r--bindings/ocaml/executionengine/llvm_executionengine.ml20
-rw-r--r--bindings/ocaml/executionengine/llvm_executionengine.mli109
-rw-r--r--bindings/ocaml/llvm/llvm.ml137
-rw-r--r--bindings/ocaml/llvm/llvm.mli355
-rw-r--r--bindings/ocaml/llvm/llvm_ocaml.c298
-rw-r--r--bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml59
-rw-r--r--bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli91
-rw-r--r--bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c96
-rw-r--r--clear_tblgen_vars.mk2
-rwxr-xr-xconfigure176
-rw-r--r--device/include/llvm/Config/AsmParsers.def29
-rw-r--r--device/include/llvm/Config/AsmPrinters.def29
-rw-r--r--device/include/llvm/Config/Disassemblers.def27
-rw-r--r--device/include/llvm/Config/Targets.def28
-rw-r--r--device/include/llvm/Config/config.h586
-rw-r--r--docs/AliasAnalysis.html25
-rw-r--r--docs/BitCodeFormat.html2
-rw-r--r--docs/Bugpoint.html2
-rw-r--r--docs/CodeGenerator.html8
-rw-r--r--docs/CodingStandards.html6
-rw-r--r--docs/CommandGuide/FileCheck.pod2
-rw-r--r--docs/CommandGuide/Makefile6
-rw-r--r--docs/CommandGuide/bugpoint.pod6
-rw-r--r--docs/CommandGuide/index.html4
-rw-r--r--docs/CommandGuide/llc.pod4
-rw-r--r--docs/CommandGuide/lli.pod6
-rw-r--r--docs/CommandGuide/llvm-as.pod2
-rw-r--r--docs/CommandGuide/llvm-bcanalyzer.pod2
-rw-r--r--docs/CommandGuide/llvm-config.pod2
-rw-r--r--docs/CommandGuide/llvm-db.pod16
-rw-r--r--docs/CommandGuide/llvm-dis.pod2
-rw-r--r--docs/CommandGuide/llvm-extract.pod10
-rw-r--r--docs/CommandGuide/llvm-link.pod2
-rw-r--r--docs/CommandGuide/llvm-nm.pod2
-rw-r--r--docs/CommandGuide/llvm-prof.pod2
-rw-r--r--docs/CommandGuide/llvm-ranlib.pod4
-rw-r--r--docs/CommandGuide/llvmc.pod4
-rw-r--r--docs/CommandGuide/tblgen.pod2
-rw-r--r--docs/CommandLine.html72
-rw-r--r--docs/CompilerDriver.html8
-rw-r--r--docs/CompilerWriterInfo.html2
-rw-r--r--docs/DeveloperPolicy.html4
-rw-r--r--docs/ExceptionHandling.html2
-rw-r--r--docs/ExtendingLLVM.html2
-rw-r--r--docs/FAQ.html4
-rw-r--r--docs/GCCFEBuildInstrs.html2
-rw-r--r--docs/GarbageCollection.html2
-rw-r--r--docs/GetElementPtr.html407
-rw-r--r--docs/GettingStarted.html28
-rw-r--r--docs/GettingStartedVS.html2
-rw-r--r--docs/HowToReleaseLLVM.html2
-rw-r--r--docs/HowToSubmitABug.html2
-rw-r--r--docs/LangRef.html254
-rw-r--r--docs/Lexicon.html2
-rw-r--r--docs/LinkTimeOptimization.html2
-rw-r--r--docs/Makefile24
-rw-r--r--docs/MakefileGuide.html6
-rw-r--r--docs/Packaging.html118
-rw-r--r--docs/Passes.html77
-rw-r--r--docs/ProgrammersManual.html10
-rw-r--r--docs/Projects.html2
-rw-r--r--docs/ReleaseNotes.html16
-rw-r--r--docs/SourceLevelDebugging.html2
-rw-r--r--docs/SystemLibrary.html2
-rw-r--r--docs/TableGenFundamentals.html5
-rw-r--r--docs/TestingGuide.html27
-rw-r--r--docs/UsingLibraries.html2
-rw-r--r--docs/WritingAnLLVMBackend.html2
-rw-r--r--docs/WritingAnLLVMPass.html16
-rw-r--r--docs/index.html6
-rw-r--r--docs/tutorial/LangImpl1.html2
-rw-r--r--docs/tutorial/LangImpl2.html2
-rw-r--r--docs/tutorial/LangImpl3.html44
-rw-r--r--docs/tutorial/LangImpl4.html38
-rw-r--r--docs/tutorial/LangImpl5.html12
-rw-r--r--docs/tutorial/LangImpl6.html10
-rw-r--r--docs/tutorial/LangImpl7.html28
-rw-r--r--docs/tutorial/LangImpl8.html2
-rw-r--r--docs/tutorial/Makefile2
-rw-r--r--docs/tutorial/OCamlLangImpl1.html2
-rw-r--r--docs/tutorial/OCamlLangImpl2.html2
-rw-r--r--docs/tutorial/OCamlLangImpl3.html34
-rw-r--r--docs/tutorial/OCamlLangImpl4.html28
-rw-r--r--docs/tutorial/OCamlLangImpl5.html4
-rw-r--r--docs/tutorial/OCamlLangImpl6.html2
-rw-r--r--docs/tutorial/OCamlLangImpl7.html20
-rw-r--r--examples/Kaleidoscope/Chapter4/Makefile2
-rw-r--r--examples/Kaleidoscope/Chapter4/toy.cpp8
-rw-r--r--examples/Kaleidoscope/Chapter5/Makefile2
-rw-r--r--examples/Kaleidoscope/Chapter5/toy.cpp8
-rw-r--r--examples/Kaleidoscope/Chapter6/Makefile2
-rw-r--r--examples/Kaleidoscope/Chapter6/toy.cpp8
-rw-r--r--examples/Kaleidoscope/Chapter7/Makefile2
-rw-r--r--examples/Kaleidoscope/Chapter7/toy.cpp8
-rw-r--r--examples/Makefile7
-rw-r--r--host/include/llvm/Config/AsmParsers.def29
-rw-r--r--host/include/llvm/Config/AsmPrinters.def29
-rw-r--r--host/include/llvm/Config/Disassemblers.def29
-rw-r--r--host/include/llvm/Config/Targets.def28
-rw-r--r--host/include/llvm/Config/config.h583
-rw-r--r--include/llvm-c/BitReader.h22
-rw-r--r--include/llvm-c/BitWriter.h13
-rw-r--r--include/llvm-c/Core.h206
-rw-r--r--include/llvm-c/ExecutionEngine.h23
-rw-r--r--include/llvm/ADT/APFloat.h34
-rw-r--r--include/llvm/ADT/APInt.h28
-rw-r--r--include/llvm/ADT/DeltaAlgorithm.h2
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h2
-rw-r--r--include/llvm/ADT/ScopedHashTable.h69
-rw-r--r--include/llvm/ADT/SmallPtrSet.h2
-rw-r--r--include/llvm/ADT/StringRef.h16
-rw-r--r--include/llvm/ADT/Triple.h1
-rw-r--r--include/llvm/Analysis/DebugInfo.h11
-rw-r--r--include/llvm/Analysis/Dominators.h48
-rw-r--r--include/llvm/Analysis/IVUsers.h110
-rw-r--r--include/llvm/Analysis/LoopInfo.h2
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h7
-rw-r--r--include/llvm/Analysis/PHITransAddr.h18
-rw-r--r--include/llvm/Analysis/Passes.h7
-rw-r--r--include/llvm/Analysis/PostDominators.h4
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h23
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h11
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h4
-rw-r--r--include/llvm/Analysis/ValueTracking.h4
-rw-r--r--include/llvm/Assembly/AsmAnnotationWriter.h21
-rw-r--r--include/llvm/Attributes.h29
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h9
-rw-r--r--include/llvm/CodeGen/DAGISelHeader.h135
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/LiveInterval.h12
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h14
-rw-r--r--include/llvm/CodeGen/LiveVariables.h11
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h5
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h16
-rw-r--r--include/llvm/CodeGen/MachineInstr.h49
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h2
-rw-r--r--include/llvm/CodeGen/MachineMemOperand.h11
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineModuleInfoImpls.h35
-rw-r--r--include/llvm/CodeGen/MachineOperand.h11
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h8
-rw-r--r--include/llvm/CodeGen/ObjectCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/Passes.h10
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h51
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h196
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h36
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h207
-rw-r--r--include/llvm/CompilerDriver/Common.td8
-rw-r--r--include/llvm/CompilerDriver/Main.inc2
-rw-r--r--include/llvm/CompilerDriver/Tool.h9
-rw-r--r--include/llvm/Constants.h56
-rw-r--r--include/llvm/DerivedTypes.h62
-rw-r--r--include/llvm/GlobalValue.h82
-rw-r--r--include/llvm/InstrTypes.h54
-rw-r--r--include/llvm/Instructions.h20
-rw-r--r--include/llvm/LinkAllPasses.h1
-rw-r--r--include/llvm/MC/MCAssembler.h216
-rw-r--r--include/llvm/MC/MCCodeEmitter.h2
-rw-r--r--include/llvm/MC/MCContext.h10
-rw-r--r--include/llvm/MC/MCDirectives.h42
-rw-r--r--include/llvm/MC/MCExpr.h2
-rw-r--r--include/llvm/MC/MCFixup.h12
-rw-r--r--include/llvm/MC/MCInstPrinter.h6
-rw-r--r--include/llvm/MC/MCStreamer.h48
-rw-r--r--include/llvm/Metadata.h7
-rw-r--r--include/llvm/Pass.h12
-rw-r--r--include/llvm/Support/CommandLine.h16
-rw-r--r--include/llvm/Support/Compiler.h4
-rw-r--r--include/llvm/Support/Dwarf.h1
-rw-r--r--include/llvm/Support/FormattedStream.h4
-rw-r--r--include/llvm/Support/IRBuilder.h6
-rw-r--r--include/llvm/Support/Regex.h13
-rw-r--r--include/llvm/Support/SourceMgr.h2
-rw-r--r--include/llvm/Support/TargetFolder.h4
-rw-r--r--include/llvm/System/DataTypes.h111
-rw-r--r--include/llvm/System/Path.h2
-rw-r--r--include/llvm/Target/Mangler.h2
-rw-r--r--include/llvm/Target/Target.td7
-rw-r--r--include/llvm/Target/TargetAsmBackend.h35
-rw-r--r--include/llvm/Target/TargetAsmParser.h4
-rw-r--r--include/llvm/Target/TargetInstrInfo.h28
-rw-r--r--include/llvm/Target/TargetLowering.h11
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h182
-rw-r--r--include/llvm/Target/TargetMachine.h43
-rw-r--r--include/llvm/Target/TargetOpcodes.h4
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h11
-rw-r--r--include/llvm/Target/TargetRegistry.h205
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td3
-rw-r--r--include/llvm/Transforms/Scalar.h2
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h6
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h96
-rw-r--r--include/llvm/Type.h78
-rw-r--r--include/llvm/Value.h1
-rw-r--r--lib/Analysis/AliasAnalysisCounter.cpp2
-rw-r--r--lib/Analysis/AliasAnalysisEvaluator.cpp6
-rw-r--r--lib/Analysis/Android.mk69
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp4
-rw-r--r--lib/Analysis/CaptureTracking.cpp2
-rw-r--r--lib/Analysis/ConstantFolding.cpp57
-rw-r--r--lib/Analysis/DebugInfo.cpp9
-rw-r--r--lib/Analysis/IPA/Andersens.cpp2868
-rw-r--r--lib/Analysis/IPA/CMakeLists.txt1
-rw-r--r--lib/Analysis/IPA/GlobalsModRef.cpp4
-rw-r--r--lib/Analysis/IVUsers.cpp206
-rw-r--r--lib/Analysis/InlineCost.cpp4
-rw-r--r--lib/Analysis/InstructionSimplify.cpp33
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp15
-rw-r--r--lib/Analysis/PHITransAddr.cpp60
-rw-r--r--lib/Analysis/PointerTracking.cpp2
-rw-r--r--lib/Analysis/ProfileInfo.cpp8
-rw-r--r--lib/Analysis/ScalarEvolution.cpp241
-rw-r--r--lib/Analysis/ScalarEvolutionAliasAnalysis.cpp8
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp400
-rw-r--r--lib/Analysis/ValueTracking.cpp153
-rw-r--r--lib/AsmParser/Android.mk28
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp192
-rw-r--r--lib/AsmParser/LLParser.h5
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/Bitcode/Reader/Android.mk29
-rw-r--r--lib/Bitcode/Reader/BitReader.cpp63
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp34
-rw-r--r--lib/Bitcode/Writer/BitWriter.cpp14
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp61
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp5
-rw-r--r--lib/CodeGen/Android.mk99
-rw-r--r--lib/CodeGen/AsmPrinter/Android.mk31
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp43
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp1
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp17
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp232
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h5
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp77
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.h12
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp1
-rw-r--r--lib/CodeGen/BranchFolding.cpp6
-rw-r--r--lib/CodeGen/CMakeLists.txt3
-rw-r--r--lib/CodeGen/CalcSpillWeights.cpp5
-rw-r--r--lib/CodeGen/CodePlacementOpt.cpp17
-rw-r--r--lib/CodeGen/CriticalAntiDepBreaker.cpp4
-rw-r--r--lib/CodeGen/DeadMachineInstructionElim.cpp42
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp4
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp51
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp142
-rw-r--r--lib/CodeGen/LiveVariables.cpp43
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp30
-rw-r--r--lib/CodeGen/MachineCSE.cpp268
-rw-r--r--lib/CodeGen/MachineFunction.cpp3
-rw-r--r--lib/CodeGen/MachineInstr.cpp90
-rw-r--r--lib/CodeGen/MachineLICM.cpp45
-rw-r--r--lib/CodeGen/MachineModuleInfoImpls.cpp11
-rw-r--r--lib/CodeGen/MachineRegisterInfo.cpp13
-rw-r--r--lib/CodeGen/MachineSink.cpp16
-rw-r--r--lib/CodeGen/OptimizePHIs.cpp189
-rw-r--r--lib/CodeGen/PBQP/HeuristicSolver.h29
-rw-r--r--lib/CodeGen/PBQP/Heuristics/Briggs.h9
-rw-r--r--lib/CodeGen/PHIElimination.cpp41
-rw-r--r--lib/CodeGen/PHIElimination.h72
-rw-r--r--lib/CodeGen/Passes.cpp2
-rw-r--r--lib/CodeGen/PostRASchedulerList.cpp2
-rw-r--r--lib/CodeGen/ProcessImplicitDefs.cpp5
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp22
-rw-r--r--lib/CodeGen/PseudoSourceValue.cpp37
-rw-r--r--lib/CodeGen/RegAllocLinearScan.cpp4
-rw-r--r--lib/CodeGen/RegAllocLocal.cpp33
-rw-r--r--lib/CodeGen/RegAllocPBQP.cpp6
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/Android.mk48
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp178
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp28
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp51
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.h11
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp204
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp17
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp39
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp19
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp154
-rw-r--r--lib/CodeGen/SelectionDAG/SDDbgValue.h67
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp16
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp320
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp171
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp1361
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp72
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp68
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp67
-rw-r--r--lib/CodeGen/StackProtector.cpp2
-rw-r--r--lib/CodeGen/TailDuplication.cpp33
-rw-r--r--lib/CodeGen/TargetInstrInfoImpl.cpp36
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp902
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp20
-rw-r--r--lib/CodeGen/VirtRegMap.cpp6
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp33
-rw-r--r--lib/CompilerDriver/Action.cpp15
-rw-r--r--lib/CompilerDriver/CompilationGraph.cpp5
-rw-r--r--lib/CompilerDriver/Main.cpp7
-rw-r--r--lib/CompilerDriver/Tool.cpp21
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp12
-rw-r--r--lib/ExecutionEngine/ExecutionEngineBindings.cpp77
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp28
-rw-r--r--lib/ExecutionEngine/JIT/Android.mk32
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp75
-rw-r--r--lib/ExecutionEngine/JIT/JIT.h4
-rw-r--r--lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp6
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp444
-rw-r--r--lib/Linker/LinkModules.cpp2
-rw-r--r--lib/MC/Android.mk45
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/MCAsmStreamer.cpp21
-rw-r--r--lib/MC/MCAssembler.cpp386
-rw-r--r--lib/MC/MCCodeEmitter.cpp12
-rw-r--r--lib/MC/MCInstPrinter.cpp7
-rw-r--r--lib/MC/MCMachOStreamer.cpp49
-rw-r--r--lib/MC/MCNullStreamer.cpp3
-rw-r--r--lib/MC/MCParser/AsmParser.cpp38
-rw-r--r--lib/MC/MCSectionMachO.cpp1
-rw-r--r--lib/MC/TargetAsmBackend.cpp19
-rw-r--r--lib/Support/APFloat.cpp88
-rw-r--r--lib/Support/APInt.cpp10
-rw-r--r--lib/Support/Android.mk72
-rw-r--r--lib/Support/CommandLine.cpp14
-rw-r--r--lib/Support/FormattedStream.cpp5
-rw-r--r--lib/Support/GraphWriter.cpp2
-rw-r--r--lib/Support/MemoryBuffer.cpp3
-rw-r--r--lib/Support/Regex.cpp76
-rw-r--r--lib/Support/StringRef.cpp105
-rw-r--r--lib/Support/Triple.cpp9
-rw-r--r--lib/Support/raw_ostream.cpp19
-rw-r--r--lib/System/Android.mk46
-rw-r--r--lib/System/Unix/Host.inc1
-rw-r--r--lib/System/Unix/Program.inc2
-rw-r--r--lib/System/Unix/Signals.inc11
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp24
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h6
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp119
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.h1
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp101
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp7
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp188
-rw-r--r--lib/Target/ARM/ARMISelLowering.h6
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td86
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td1056
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td803
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td128
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td818
-rw-r--r--lib/Target/ARM/ARMInstrVFP.td97
-rw-r--r--lib/Target/ARM/ARMJITInfo.cpp24
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp18
-rw-r--r--lib/Target/ARM/ARMRelocations.h8
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp40
-rw-r--r--lib/Target/ARM/ARMSubtarget.h4
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.h4
-rw-r--r--lib/Target/ARM/Android.mk49
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp9
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp6
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.h1
-rw-r--r--lib/Target/ARM/README.txt2
-rw-r--r--lib/Target/ARM/TargetInfo/Android.mk24
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.cpp28
-rw-r--r--lib/Target/Alpha/AlphaCallingConv.td3
-rw-r--r--lib/Target/Alpha/AlphaISelDAGToDAG.cpp17
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp45
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.td6
-rw-r--r--lib/Target/Alpha/AlphaRegisterInfo.cpp7
-rw-r--r--lib/Target/Android.mk38
-rw-r--r--lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp10
-rw-r--r--lib/Target/Blackfin/BlackfinISelLowering.cpp7
-rw-r--r--lib/Target/CBackend/CBackend.cpp256
-rw-r--r--lib/Target/CBackend/CTargetMachine.h3
-rw-r--r--lib/Target/CellSPU/SPU64InstrInfo.td8
-rw-r--r--lib/Target/CellSPU/SPUISelDAGToDAG.cpp129
-rw-r--r--lib/Target/CellSPU/SPUISelLowering.cpp26
-rw-r--r--lib/Target/CellSPU/SPUMCAsmInfo.cpp3
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp41
-rw-r--r--lib/Target/CppBackend/CPPTargetMachine.h3
-rw-r--r--lib/Target/MBlaze/AsmPrinter/CMakeLists.txt9
-rw-r--r--lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp302
-rw-r--r--lib/Target/MBlaze/AsmPrinter/Makefile17
-rw-r--r--lib/Target/MBlaze/CMakeLists.txt27
-rw-r--r--lib/Target/MBlaze/MBlaze.h39
-rw-r--r--lib/Target/MBlaze/MBlaze.td85
-rw-r--r--lib/Target/MBlaze/MBlazeCallingConv.td26
-rw-r--r--lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp75
-rw-r--r--lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp339
-rw-r--r--lib/Target/MBlaze/MBlazeISelLowering.cpp975
-rw-r--r--lib/Target/MBlaze/MBlazeISelLowering.h149
-rw-r--r--lib/Target/MBlaze/MBlazeInstrFPU.td223
-rw-r--r--lib/Target/MBlaze/MBlazeInstrFSL.td153
-rw-r--r--lib/Target/MBlaze/MBlazeInstrFormats.td246
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.cpp222
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.h242
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.td672
-rw-r--r--lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp109
-rw-r--r--lib/Target/MBlaze/MBlazeIntrinsicInfo.h33
-rw-r--r--lib/Target/MBlaze/MBlazeIntrinsics.td137
-rw-r--r--lib/Target/MBlaze/MBlazeMCAsmInfo.cpp27
-rw-r--r--lib/Target/MBlaze/MBlazeMCAsmInfo.h30
-rw-r--r--lib/Target/MBlaze/MBlazeMachineFunction.h136
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.cpp421
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.h96
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.td186
-rw-r--r--lib/Target/MBlaze/MBlazeSchedule.td63
-rw-r--r--lib/Target/MBlaze/MBlazeSubtarget.cpp31
-rw-r--r--lib/Target/MBlaze/MBlazeSubtarget.h79
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.cpp66
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.h69
-rw-r--r--lib/Target/MBlaze/MBlazeTargetObjectFile.cpp88
-rw-r--r--lib/Target/MBlaze/MBlazeTargetObjectFile.h41
-rw-r--r--lib/Target/MBlaze/Makefile23
-rw-r--r--lib/Target/MBlaze/TargetInfo/CMakeLists.txt7
-rw-r--r--lib/Target/MBlaze/TargetInfo/MBlazeTargetInfo.cpp19
-rw-r--r--lib/Target/MBlaze/TargetInfo/Makefile15
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp18
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp23
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp23
-rw-r--r--lib/Target/MSP430/MSP430ISelDAGToDAG.cpp330
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp31
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td2
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp35
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp23
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td11
-rw-r--r--lib/Target/Mips/MipsTargetObjectFile.h2
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp27
-rw-r--r--lib/Target/PIC16/PIC16ABINames.h68
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.cpp2
-rw-r--r--lib/Target/PIC16/PIC16ISelDAGToDAG.cpp10
-rw-r--r--lib/Target/PIC16/PIC16ISelDAGToDAG.h4
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp32
-rw-r--r--lib/Target/PIC16/PIC16MemSelOpt.cpp105
-rw-r--r--lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp299
-rw-r--r--lib/Target/PIC16/PIC16Passes/PIC16Cloner.h83
-rw-r--r--lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp26
-rw-r--r--lib/Target/PIC16/PIC16Passes/PIC16Overlay.h23
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.cpp6
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.h3
-rw-r--r--lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp3
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp2
-rw-r--r--lib/Target/PowerPC/PPCCallingConv.td17
-rw-r--r--lib/Target/PowerPC/PPCHazardRecognizers.cpp2
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp12
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp124
-rw-r--r--lib/Target/PowerPC/PPCInstr64Bit.td11
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.cpp94
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td28
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp12
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.td12
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp29
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.h12
-rw-r--r--lib/Target/PowerPC/README.txt19
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp47
-rw-r--r--lib/Target/Sparc/README.txt1
-rw-r--r--lib/Target/Sparc/SparcISelDAGToDAG.cpp16
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp51
-rw-r--r--lib/Target/Sparc/SparcMachineFunctionInfo.h2
-rw-r--r--lib/Target/SystemZ/SystemZISelDAGToDAG.cpp59
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.cpp10
-rw-r--r--lib/Target/SystemZ/SystemZInstrFP.td2
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td2
-rw-r--r--lib/Target/SystemZ/SystemZMachineFunctionInfo.h3
-rw-r--r--lib/Target/TargetData.cpp2
-rw-r--r--lib/Target/TargetInstrInfo.cpp1
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp844
-rw-r--r--lib/Target/X86/Android.mk47
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp49
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp7
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h5
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp78
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.h3
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp4
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h2
-rw-r--r--lib/Target/X86/CMakeLists.txt1
-rw-r--r--lib/Target/X86/README-SSE.txt8
-rw-r--r--lib/Target/X86/README.txt71
-rw-r--r--lib/Target/X86/TargetInfo/Android.mk24
-rw-r--r--lib/Target/X86/X86.h19
-rw-r--r--lib/Target/X86/X86AsmBackend.cpp34
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.cpp97
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.h27
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp387
-rw-r--r--lib/Target/X86/X86FastISel.cpp77
-rw-r--r--lib/Target/X86/X86FixupKinds.h25
-rw-r--r--lib/Target/X86/X86FloatingPointRegKill.cpp2
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp403
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp512
-rw-r--r--lib/Target/X86/X86ISelLowering.h16
-rw-r--r--lib/Target/X86/X86Instr64bit.td79
-rw-r--r--lib/Target/X86/X86InstrFPStack.td2
-rw-r--r--lib/Target/X86/X86InstrFormats.td36
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp110
-rw-r--r--lib/Target/X86/X86InstrInfo.h54
-rw-r--r--lib/Target/X86/X86InstrInfo.td420
-rw-r--r--lib/Target/X86/X86InstrMMX.td17
-rw-r--r--lib/Target/X86/X86InstrSSE.td427
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp30
-rw-r--r--lib/Target/X86/X86MCAsmInfo.h5
-rw-r--r--lib/Target/X86/X86MCCodeEmitter.cpp350
-rw-r--r--lib/Target/X86/X86MachineFunctionInfo.h15
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp22
-rw-r--r--lib/Target/X86/X86RegisterInfo.h3
-rw-r--r--lib/Target/X86/X86RegisterInfo.td63
-rw-r--r--lib/Target/X86/X86Subtarget.h25
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp43
-rw-r--r--lib/Target/X86/X86TargetMachine.h12
-rw-r--r--lib/Target/X86/X86TargetObjectFile.cpp139
-rw-r--r--lib/Target/X86/X86TargetObjectFile.h42
-rw-r--r--lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp23
-rw-r--r--lib/Target/XCore/XCoreISelDAGToDAG.cpp17
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp81
-rw-r--r--lib/Target/XCore/XCoreISelLowering.h12
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.cpp13
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.td38
-rw-r--r--lib/Target/XCore/XCoreTargetObjectFile.h3
-rw-r--r--lib/Transforms/Hello/Hello.cpp1
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp6
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp41
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp4
-rw-r--r--lib/Transforms/IPO/DeadTypeElimination.cpp4
-rw-r--r--lib/Transforms/IPO/FunctionAttrs.cpp8
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp178
-rw-r--r--lib/Transforms/IPO/Inliner.cpp25
-rw-r--r--lib/Transforms/IPO/StripSymbols.cpp9
-rw-r--r--lib/Transforms/InstCombine/InstCombine.h24
-rw-r--r--lib/Transforms/InstCombine/InstCombineAddSub.cpp18
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp394
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp207
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp47
-rw-r--r--lib/Transforms/InstCombine/InstCombineCompares.cpp43
-rw-r--r--lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp30
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp20
-rw-r--r--lib/Transforms/InstCombine/InstCombinePHI.cpp6
-rw-r--r--lib/Transforms/InstCombine/InstCombineSelect.cpp32
-rw-r--r--lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp8
-rw-r--r--lib/Transforms/InstCombine/InstCombineVectorOps.cpp4
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp14
-rw-r--r--lib/Transforms/Instrumentation/ProfilingUtils.cpp2
-rw-r--r--lib/Transforms/Scalar/ABCD.cpp4
-rw-r--r--lib/Transforms/Scalar/Android.mk55
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp167
-rw-r--r--lib/Transforms/Scalar/DeadStoreElimination.cpp8
-rw-r--r--lib/Transforms/Scalar/GVN.cpp139
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp208
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp17
-rw-r--r--lib/Transforms/Scalar/LICM.cpp4
-rw-r--r--lib/Transforms/Scalar/LoopStrengthReduce.cpp5117
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp12
-rw-r--r--lib/Transforms/Scalar/MemCpyOptimizer.cpp2
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp34
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp58
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp39
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp969
-rw-r--r--lib/Transforms/Utils/AddrModeMatcher.cpp8
-rw-r--r--lib/Transforms/Utils/Android.mk49
-rw-r--r--lib/Transforms/Utils/BasicBlockUtils.cpp29
-rw-r--r--lib/Transforms/Utils/BreakCriticalEdges.cpp86
-rw-r--r--lib/Transforms/Utils/BuildLibCalls.cpp324
-rw-r--r--lib/Transforms/Utils/CMakeLists.txt1
-rw-r--r--lib/Transforms/Utils/Local.cpp15
-rw-r--r--lib/Transforms/Utils/LoopSimplify.cpp48
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp12
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp12
-rw-r--r--lib/VMCore/Android.mk61
-rw-r--r--lib/VMCore/AsmWriter.cpp66
-rw-r--r--lib/VMCore/Attributes.cpp9
-rw-r--r--lib/VMCore/ConstantFold.cpp154
-rw-r--r--lib/VMCore/Constants.cpp176
-rw-r--r--lib/VMCore/ConstantsContext.h15
-rw-r--r--lib/VMCore/Core.cpp227
-rw-r--r--lib/VMCore/Function.cpp12
-rw-r--r--lib/VMCore/Globals.cpp4
-rw-r--r--lib/VMCore/IRBuilder.cpp2
-rw-r--r--lib/VMCore/InlineAsm.cpp2
-rw-r--r--lib/VMCore/Instructions.cpp173
-rw-r--r--lib/VMCore/LLVMContextImpl.h35
-rw-r--r--lib/VMCore/Makefile4
-rw-r--r--lib/VMCore/Metadata.cpp7
-rw-r--r--lib/VMCore/Pass.cpp9
-rw-r--r--lib/VMCore/PassManager.cpp33
-rw-r--r--lib/VMCore/Type.cpp207
-rw-r--r--lib/VMCore/TypesContext.h26
-rw-r--r--lib/VMCore/Value.cpp12
-rw-r--r--lib/VMCore/ValueTypes.cpp7
-rw-r--r--lib/VMCore/Verifier.cpp145
-rw-r--r--llvm-device-build.mk52
-rw-r--r--llvm-gen-intrinsics.mk18
-rw-r--r--llvm-host-build.mk50
-rw-r--r--projects/CMakeLists.txt2
-rwxr-xr-xprojects/sample/configure1
-rw-r--r--runtime/Makefile4
-rw-r--r--runtime/libprofile/Makefile2
-rw-r--r--tblgen-rules.mk108
-rw-r--r--test/Analysis/Andersens/2007-11-19-InlineAsm.ll8
-rw-r--r--test/Analysis/Andersens/2008-03-19-External.ll12
-rw-r--r--test/Analysis/Andersens/2008-04-07-Memcpy.ll14
-rw-r--r--test/Analysis/Andersens/2008-12-27-BuiltinWrongType.ll19
-rw-r--r--test/Analysis/Andersens/basictest.ll28
-rw-r--r--test/Analysis/Andersens/dg.exp4
-rw-r--r--test/Analysis/Andersens/external.ll20
-rw-r--r--test/Analysis/Andersens/modreftest.ll15
-rw-r--r--test/Analysis/Andersens/modreftest2.ll14
-rw-r--r--test/Analysis/Andersens/trivialtest.ll3
-rw-r--r--test/Analysis/ScalarEvolution/trip-count10.ll76
-rw-r--r--test/Archive/GNU.abin4210 -> 0 bytes
-rw-r--r--test/Archive/IsNAN.obin2280 -> 0 bytes
-rw-r--r--test/Archive/MacOSX.abin4166 -> 0 bytes
-rw-r--r--test/Archive/SVR4.abin4214 -> 0 bytes
-rw-r--r--test/Archive/xpg4.abin4214 -> 0 bytes
-rw-r--r--test/Assembler/2010-01-06-UnionType.ll3
-rw-r--r--test/Bindings/Ocaml/bitreader.ml16
-rw-r--r--test/Bindings/Ocaml/bitwriter.ml34
-rw-r--r--test/Bindings/Ocaml/executionengine.ml9
-rw-r--r--test/Bindings/Ocaml/scalar_opts.ml28
-rw-r--r--test/Bindings/Ocaml/vmcore.ml730
-rw-r--r--test/CodeGen/ARM/2010-03-04-eabi-fp-spill.ll65
-rw-r--r--test/CodeGen/ARM/2010-03-04-stm-undef-addr.ll54
-rw-r--r--test/CodeGen/ARM/arm-negative-stride.ll26
-rw-r--r--test/CodeGen/ARM/armv4.ll13
-rw-r--r--test/CodeGen/ARM/call.ll14
-rw-r--r--test/CodeGen/ARM/lsr-code-insertion.ll4
-rw-r--r--test/CodeGen/ARM/neon_minmax.ll81
-rw-r--r--test/CodeGen/ARM/remat.ll6
-rw-r--r--test/CodeGen/Alpha/add.ll3
-rw-r--r--test/CodeGen/Blackfin/promote-logic.ll3
-rw-r--r--test/CodeGen/CellSPU/bss.ll5
-rw-r--r--test/CodeGen/Generic/2007-05-05-Personality.ll2
-rw-r--r--test/CodeGen/Generic/GC/argpromotion.ll2
-rw-r--r--test/CodeGen/Generic/debug-info.ll19
-rw-r--r--test/CodeGen/MBlaze/brind.ll73
-rw-r--r--test/CodeGen/MBlaze/callind.ll80
-rw-r--r--test/CodeGen/MBlaze/cc.ll315
-rw-r--r--test/CodeGen/MBlaze/dg.exp5
-rw-r--r--test/CodeGen/MBlaze/div.ll75
-rw-r--r--test/CodeGen/MBlaze/fpu.ll66
-rw-r--r--test/CodeGen/MBlaze/fsl.ll323
-rw-r--r--test/CodeGen/MBlaze/imm.ll70
-rw-r--r--test/CodeGen/MBlaze/jumptable.ll79
-rw-r--r--test/CodeGen/MBlaze/loop.ll47
-rw-r--r--test/CodeGen/MBlaze/mul.ll51
-rw-r--r--test/CodeGen/MBlaze/mul64.ll23
-rw-r--r--test/CodeGen/MBlaze/select.ll15
-rw-r--r--test/CodeGen/MBlaze/shift.ll117
-rw-r--r--test/CodeGen/MSP430/AddrMode-bis-rx.ll6
-rw-r--r--test/CodeGen/MSP430/AddrMode-bis-xr.ll6
-rw-r--r--test/CodeGen/MSP430/AddrMode-mov-rx.ll6
-rw-r--r--test/CodeGen/MSP430/AddrMode-mov-xr.ll6
-rw-r--r--test/CodeGen/MSP430/Inst16mm.ll17
-rw-r--r--test/CodeGen/MSP430/Inst8rr.ll2
-rw-r--r--test/CodeGen/MSP430/bit.ll2
-rw-r--r--test/CodeGen/MSP430/setcc.ll44
-rw-r--r--test/CodeGen/PIC16/C16-11.ll5
-rw-r--r--test/CodeGen/PIC16/C16-15.ll2
-rw-r--r--test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll4
-rw-r--r--test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll6
-rw-r--r--test/CodeGen/PowerPC/2010-02-12-saveCR.ll30
-rw-r--r--test/CodeGen/PowerPC/2010-02-26-FoldFloats.ll433
-rw-r--r--test/CodeGen/PowerPC/Frames-alloca.ll2
-rw-r--r--test/CodeGen/PowerPC/LargeAbsoluteAddr.ll6
-rw-r--r--test/CodeGen/PowerPC/addc.ll25
-rw-r--r--test/CodeGen/PowerPC/indirectbr.ll14
-rw-r--r--test/CodeGen/PowerPC/lsr-postinc-pos.ll32
-rw-r--r--test/CodeGen/PowerPC/mem_update.ll54
-rw-r--r--test/CodeGen/PowerPC/retaddr.ll2
-rw-r--r--test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll76
-rw-r--r--test/CodeGen/Thumb2/2010-02-24-BigStack.ll15
-rw-r--r--test/CodeGen/Thumb2/cross-rc-coalescing-2.ll2
-rw-r--r--test/CodeGen/Thumb2/ldr-str-imm12.ll2
-rw-r--r--test/CodeGen/Thumb2/lsr-deficiency.ll18
-rw-r--r--test/CodeGen/Thumb2/thumb2-ifcvt1.ll12
-rw-r--r--test/CodeGen/Thumb2/thumb2-spill-q.ll4
-rw-r--r--test/CodeGen/Thumb2/thumb2-uxtb.ll20
-rw-r--r--test/CodeGen/X86/2005-01-17-CycleInDAG.ll2
-rw-r--r--test/CodeGen/X86/2006-05-11-InstrSched.ll4
-rw-r--r--test/CodeGen/X86/2006-10-07-ScalarSSEMiscompile.ll2
-rw-r--r--test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll2
-rw-r--r--test/CodeGen/X86/2007-10-05-3AddrConvert.ll4
-rw-r--r--test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll2
-rw-r--r--test/CodeGen/X86/2008-02-22-ReMatBug.ll2
-rw-r--r--test/CodeGen/X86/2008-07-11-SpillerBug.ll4
-rw-r--r--test/CodeGen/X86/2008-08-05-SpillerBug.ll2
-rw-r--r--test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll133
-rw-r--r--test/CodeGen/X86/2009-07-16-LoadFoldingBug.ll102
-rw-r--r--test/CodeGen/X86/2009-09-07-CoalescerBug.ll3
-rw-r--r--test/CodeGen/X86/2010-02-11-NonTemporal.ll22
-rw-r--r--test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll260
-rw-r--r--test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll80
-rw-r--r--test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll55
-rw-r--r--test/CodeGen/X86/2010-02-23-DAGCombineBug.ll18
-rw-r--r--test/CodeGen/X86/2010-02-23-DIV8rDefinesAX.ll20
-rw-r--r--test/CodeGen/X86/2010-02-23-RematImplicitSubreg.ll49
-rw-r--r--test/CodeGen/X86/2010-02-23-SingleDefPhiJoin.ll146
-rw-r--r--test/CodeGen/X86/2010-03-04-Mul8Bug.ll25
-rw-r--r--test/CodeGen/X86/2010-03-05-ConstantFoldCFG.ll42
-rw-r--r--test/CodeGen/X86/2010-03-05-EFLAGS-Redef.ll49
-rw-r--r--test/CodeGen/X86/addr-label-difference.ll10
-rw-r--r--test/CodeGen/X86/and-or-fold.ll28
-rw-r--r--test/CodeGen/X86/bswap-inline-asm.ll67
-rw-r--r--test/CodeGen/X86/code_placement_eh.ll45
-rw-r--r--test/CodeGen/X86/crash.ll20
-rw-r--r--test/CodeGen/X86/critical-edge-split.ll2
-rw-r--r--test/CodeGen/X86/dllexport.ll12
-rw-r--r--test/CodeGen/X86/fastcall-correct-mangling.ll4
-rw-r--r--test/CodeGen/X86/full-lsr.ll9
-rw-r--r--test/CodeGen/X86/global-sections.ll3
-rw-r--r--test/CodeGen/X86/ins_subreg_coalesce-3.ll2
-rw-r--r--test/CodeGen/X86/iv-users-in-other-loops.ll8
-rw-r--r--test/CodeGen/X86/licm-symbol.ll39
-rw-r--r--test/CodeGen/X86/loop-strength-reduce-2.ll19
-rw-r--r--test/CodeGen/X86/loop-strength-reduce-3.ll13
-rw-r--r--test/CodeGen/X86/loop-strength-reduce.ll13
-rw-r--r--test/CodeGen/X86/loop-strength-reduce4.ll18
-rw-r--r--test/CodeGen/X86/loop-strength-reduce8.ll8
-rw-r--r--test/CodeGen/X86/lsr-overflow.ll26
-rw-r--r--test/CodeGen/X86/lsr-reuse-trunc.ll59
-rw-r--r--test/CodeGen/X86/lsr-reuse.ll442
-rw-r--r--test/CodeGen/X86/lsr-wrap.ll37
-rw-r--r--test/CodeGen/X86/masked-iv-safe.ll6
-rw-r--r--test/CodeGen/X86/omit-label.ll57
-rw-r--r--test/CodeGen/X86/pr1505b.ll4
-rw-r--r--test/CodeGen/X86/pr3495-2.ll6
-rw-r--r--test/CodeGen/X86/pr3495.ll3
-rw-r--r--test/CodeGen/X86/pre-split8.ll2
-rw-r--r--test/CodeGen/X86/pre-split9.ll2
-rw-r--r--test/CodeGen/X86/ptrtoint-constexpr.ll2
-rw-r--r--test/CodeGen/X86/scalar_widen_div.ll29
-rw-r--r--test/CodeGen/X86/sse-minmax.ll610
-rw-r--r--test/CodeGen/X86/sse3.ll7
-rw-r--r--test/CodeGen/X86/stack-align.ll19
-rw-r--r--test/CodeGen/X86/stack-color-with-reg.ll2
-rw-r--r--test/CodeGen/X86/stdcall.ll16
-rw-r--r--test/CodeGen/X86/store_op_load_fold.ll2
-rw-r--r--test/CodeGen/X86/store_op_load_fold2.ll24
-rw-r--r--test/CodeGen/X86/tailcall2.ll21
-rw-r--r--test/CodeGen/X86/trunc-to-bool.ll21
-rw-r--r--test/CodeGen/X86/twoaddr-coalesce.ll2
-rw-r--r--test/CodeGen/X86/use-add-flags.ll12
-rw-r--r--test/CodeGen/X86/vec_cast.ll18
-rw-r--r--test/CodeGen/X86/vec_insert.ll4
-rw-r--r--test/CodeGen/X86/vec_shuffle-36.ll17
-rw-r--r--test/CodeGen/X86/vec_ss_load_fold.ll37
-rw-r--r--test/CodeGen/X86/xor-icmp.ll31
-rw-r--r--test/CodeGen/XCore/2010-02-25-LSR-Crash.ll26
-rw-r--r--test/CodeGen/XCore/switch.ll24
-rw-r--r--test/CodeGen/XCore/switch_long.ll132
-rw-r--r--test/DebugInfo/2009-02-27-licm.ll83
-rw-r--r--test/DebugInfo/2009-03-03-cheapdse.ll80
-rw-r--r--test/DebugInfo/2009-03-05-gvn.ll125
-rw-r--r--test/DebugInfo/deaddebuglabel.ll62
-rw-r--r--test/DebugInfo/funccall.ll147
-rw-r--r--test/DebugInfo/globalGetElementPtr.ll264
-rw-r--r--test/DebugInfo/inheritance.ll151
-rw-r--r--test/ExecutionEngine/2010-01-15-UndefValue.ll4
-rw-r--r--test/Feature/alignment.ll4
-rw-r--r--test/Feature/unions.ll12
-rw-r--r--test/FrontendC++/2010-02-08-NamespaceVar.cpp16
-rw-r--r--test/FrontendC++/2010-02-17-DbgArtificialArg.cpp14
-rw-r--r--test/FrontendC/2003-12-14-ExternInlineSupport.c2
-rw-r--r--test/FrontendC/2007-02-16-WritableStrings.c2
-rw-r--r--test/FrontendC/2007-09-17-WeakRef.c2
-rw-r--r--test/FrontendC/2010-02-10-PointerName.c7
-rw-r--r--test/FrontendC/2010-02-15-DbgStaticVar.c13
-rw-r--r--test/FrontendC/2010-02-16-DbgVarScope.c30
-rw-r--r--test/FrontendC/2010-02-18-Dbg-VectorType.c9
-rw-r--r--test/FrontendC/2010-03-5-LexicalScope.c10
-rw-r--r--test/FrontendObjC/2010-02-11-fwritable-stringsBug.m17
-rw-r--r--test/FrontendObjC/2010-02-23-DbgInheritance.m9
-rw-r--r--test/LLVMC/AppendCmdHook.td8
-rw-r--r--test/LLVMC/EnvParentheses.td4
-rw-r--r--test/LLVMC/ExternOptions.td2
-rw-r--r--test/LLVMC/ForwardAs.td4
-rw-r--r--test/LLVMC/ForwardTransformedValue.td2
-rw-r--r--test/LLVMC/ForwardValue.td6
-rw-r--r--test/LLVMC/HookWithArguments.td4
-rw-r--r--test/LLVMC/HookWithInFile.td2
-rw-r--r--test/LLVMC/Init.td2
-rw-r--r--test/LLVMC/MultiValuedOption.td2
-rw-r--r--test/LLVMC/MultiplePluginPriorities.td4
-rw-r--r--test/LLVMC/NoActions.td2
-rw-r--r--test/LLVMC/OneOrMore.td2
-rw-r--r--test/LLVMC/OptionPreprocessor.td2
-rw-r--r--test/MC/AsmParser/X86/x86_32-bit_cat.s158
-rw-r--r--test/MC/AsmParser/X86/x86_32-encoding.s9866
-rw-r--r--test/MC/AsmParser/X86/x86_32-new-encoder.s41
-rw-r--r--test/MC/AsmParser/X86/x86_64-new-encoder.s26
-rw-r--r--test/MC/AsmParser/X86/x86_instructions.s14
-rw-r--r--test/MC/AsmParser/X86/x86_operands.s20
-rw-r--r--test/MC/AsmParser/conditional_asm.s2
-rw-r--r--test/MC/Disassembler/simple-tests.txt29
-rw-r--r--test/MC/MachO/Darwin/optimal_nop.s156
-rw-r--r--test/Makefile4
-rw-r--r--test/Makefile.tests6
-rw-r--r--test/Other/2008-03-19-PassManager.ll58
-rw-r--r--test/Other/constant-fold-gep.ll54
-rw-r--r--test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll16
-rw-r--r--test/Transforms/ConstantMerge/dont-merge.ll30
-rw-r--r--test/Transforms/DeadStoreElimination/crash.ll14
-rw-r--r--test/Transforms/GVN/2008-02-13-NewPHI.ll2
-rw-r--r--test/Transforms/GVN/2009-03-05-dbg.ll66
-rw-r--r--test/Transforms/GVN/crash.ll22
-rw-r--r--test/Transforms/GVN/pre-load.ll27
-rw-r--r--test/Transforms/GlobalOpt/2009-03-03-dbg.ll54
-rw-r--r--test/Transforms/GlobalOpt/2009-03-05-dbg.ll119
-rw-r--r--test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll18
-rw-r--r--test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll27
-rw-r--r--test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll98
-rw-r--r--test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll2
-rw-r--r--test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll2
-rw-r--r--test/Transforms/IndVarSimplify/2003-12-15-Crash.ll4
-rw-r--r--test/Transforms/IndVarSimplify/2005-11-18-Crash.ll2
-rw-r--r--test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll2
-rw-r--r--test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll4
-rw-r--r--test/Transforms/IndVarSimplify/addrec-gep.ll2
-rw-r--r--test/Transforms/IndVarSimplify/avoid-i0.ll4
-rw-r--r--test/Transforms/IndVarSimplify/max-pointer.ll4
-rw-r--r--test/Transforms/InstCombine/2006-12-08-ICmp-Combining.ll18
-rw-r--r--test/Transforms/InstCombine/2009-01-19-fmod-constant-float-specials.ll3
-rw-r--r--test/Transforms/InstCombine/2010-03-03-ExtElim.ll18
-rw-r--r--test/Transforms/InstCombine/JavaCompare.ll2
-rw-r--r--test/Transforms/InstCombine/and2.ll6
-rw-r--r--test/Transforms/InstCombine/bswap-fold.ll6
-rw-r--r--test/Transforms/InstCombine/constant-fold-ptr-casts.ll18
-rw-r--r--test/Transforms/InstCombine/crash.ll15
-rw-r--r--test/Transforms/InstCombine/fcmp-select.ll53
-rw-r--r--test/Transforms/InstCombine/fcmp-special.ll155
-rw-r--r--test/Transforms/InstCombine/icmp.ll12
-rw-r--r--test/Transforms/InstCombine/load-cmp.ll8
-rw-r--r--test/Transforms/InstCombine/memset_chk.ll18
-rw-r--r--test/Transforms/InstCombine/multi-use-or.ll2
-rw-r--r--test/Transforms/InstCombine/objsize.ll87
-rw-r--r--test/Transforms/InstCombine/or.ll20
-rw-r--r--test/Transforms/InstCombine/phi.ll40
-rw-r--r--test/Transforms/InstCombine/ptr-int-cast.ll18
-rw-r--r--test/Transforms/InstCombine/strcpy_chk.ll (renamed from test/Transforms/SimplifyLibCalls/strcpy_chk.ll)2
-rw-r--r--test/Transforms/InstCombine/vec_narrow.ll2
-rw-r--r--test/Transforms/InstCombine/vector-casts.ll16
-rw-r--r--test/Transforms/InstCombine/xor2.ll8
-rw-r--r--test/Transforms/JumpThreading/crash.ll11
-rw-r--r--test/Transforms/JumpThreading/or-undef.ll69
-rw-r--r--test/Transforms/LoopDeletion/simplify-then-delete.ll65
-rw-r--r--test/Transforms/LoopIndexSplit/SplitValue-2007-08-24-dbg.ll71
-rw-r--r--test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll5
-rw-r--r--test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll13
-rw-r--r--test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/count-to-zero.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/invariant_value_first.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/nonlinear-postinc.ll44
-rw-r--r--test/Transforms/LoopStrengthReduce/ops_after_indvar.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/remove_indvar.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll2
-rw-r--r--test/Transforms/Reassociate/crash.ll15
-rw-r--r--test/Transforms/SCCP/retvalue-undef.ll32
-rw-r--r--test/Transforms/ScalarRepl/2009-03-17-CleanUp.ll3961
-rw-r--r--test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll14
-rw-r--r--test/Unit/lit.cfg9
-rw-r--r--test/Unit/lit.site.cfg.in2
-rw-r--r--test/lib/llvm.exp15
-rw-r--r--test/lit.cfg8
-rw-r--r--test/site.exp.in2
-rw-r--r--tools/Makefile27
-rw-r--r--tools/bugpoint/CrashDebugger.cpp2
-rw-r--r--tools/bugpoint/ExtractFunction.cpp2
-rw-r--r--tools/llc/llc.cpp14
-rw-r--r--tools/llvm-config/CMakeLists.txt2
-rw-r--r--tools/llvm-config/Makefile4
-rw-r--r--tools/llvm-extract/llvm-extract.cpp52
-rw-r--r--tools/llvm-mc/llvm-mc.cpp4
-rw-r--r--tools/llvm-shlib/Makefile60
-rw-r--r--tools/llvmc/doc/LLVMC-Reference.rst26
-rw-r--r--tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td42
-rw-r--r--tools/llvmc/plugins/Base/Base.td.in146
-rw-r--r--tools/llvmc/plugins/Clang/Clang.td37
-rw-r--r--tools/opt/opt.cpp3
-rw-r--r--unittests/ADT/APFloatTest.cpp36
-rw-r--r--unittests/ADT/StringMapTest.cpp1
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp50
-rw-r--r--unittests/ExecutionEngine/JIT/MultiJITTest.cpp164
-rw-r--r--unittests/Makefile.unittest11
-rw-r--r--unittests/Support/AllocatorTest.cpp2
-rw-r--r--unittests/Support/RegexTest.cpp29
-rw-r--r--unittests/VMCore/DerivedTypesTest.cpp10
-rw-r--r--unittests/VMCore/MetadataTest.cpp29
-rw-r--r--unittests/VMCore/VerifierTest.cpp44
-rwxr-xr-xutils/GenLibDeps.pl2
-rw-r--r--utils/TableGen/Android.mk46
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp62
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp44
-rw-r--r--utils/TableGen/AsmWriterEmitter.h1
-rw-r--r--utils/TableGen/CMakeLists.txt4
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp346
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h47
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp3
-rw-r--r--utils/TableGen/CodeGenInstruction.h2
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp1967
-rw-r--r--utils/TableGen/DAGISelEmitter.h16
-rw-r--r--utils/TableGen/DAGISelMatcher.cpp402
-rw-r--r--utils/TableGen/DAGISelMatcher.h1112
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp779
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp882
-rw-r--r--utils/TableGen/DAGISelMatcherOpt.cpp509
-rw-r--r--utils/TableGen/InstrEnumEmitter.cpp2
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp444
-rw-r--r--utils/TableGen/Record.h4
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp107
-rw-r--r--utils/buildit/GNUmakefile4
-rwxr-xr-xutils/git/find-rev50
-rw-r--r--utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp2
-rw-r--r--utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp2
-rw-r--r--utils/lit/lit/TestFormats.py7
-rw-r--r--utils/lit/lit/TestRunner.py18
-rw-r--r--utils/lit/lit/TestingConfig.py9
-rw-r--r--utils/llvm.grm1
-rw-r--r--utils/vim/llvm.vim5
-rw-r--r--utils/vim/tablegen.vim2
-rw-r--r--utils/vim/vimrc31
935 files changed, 52952 insertions, 27903 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..9c065f6
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,39 @@
+LOCAL_PATH := $(call my-dir)
+LLVM_ROOT_PATH := $(LOCAL_PATH)
+include $(CLEAR_VARS)
+
+# Only use this on the device or emulator.
+ifeq ($(TARGET_SIMULATOR),true)
+$(error LLVM not suitable for the simulator! $(LOCAL_PATH))
+endif
+
+subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
+ lib/System \
+ lib/Support \
+ utils/TableGen \
+ lib/VMCore \
+ lib/Bitcode/Reader \
+ lib/Analysis \
+ lib/Transforms/Utils \
+ lib/Transforms/Scalar \
+ lib/CodeGen \
+ lib/CodeGen/SelectionDAG \
+ lib/CodeGen/AsmPrinter \
+ lib/Target \
+ lib/Target/ARM \
+ lib/Target/ARM/TargetInfo \
+ lib/Target/X86 \
+ lib/Target/X86/TargetInfo \
+ lib/ExecutionEngine/JIT \
+ lib/MC \
+ ))
+
+TBLGEN := $(HOST_OUT_EXECUTABLES)/tblgen$(HOST_EXECUTABLE_SUFFIX)
+
+CLEAR_TBLGEN_VARS := $(LOCAL_PATH)/clear_tblgen_vars.mk
+LLVM_HOST_BUILD_MK := $(LOCAL_PATH)/llvm-host-build.mk
+LLVM_DEVICE_BUILD_MK := $(LOCAL_PATH)/llvm-device-build.mk
+LLVM_GEN_INTRINSICS_MK := $(LOCAL_PATH)/llvm-gen-intrinsics.mk
+LLVM_TBLGEN_RULES_MK := $(LOCAL_PATH)/tblgen-rules.mk
+
+include $(subdirs)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 216e0f6..96e0608 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,6 +52,7 @@ set(LLVM_ALL_TARGETS
CellSPU
CppBackend
Mips
+ MBlaze
MSIL
MSP430
PIC16
diff --git a/CREDITS.TXT b/CREDITS.TXT
index f6467ab..e58b85f 100644
--- a/CREDITS.TXT
+++ b/CREDITS.TXT
@@ -335,3 +335,8 @@ D: Bunches of stuff
N: Bob Wilson
E: bob.wilson@acm.org
D: Advanced SIMD (NEON) support in the ARM backend
+
+N: Wesley Peck
+E: peckw@wesleypeck.com
+W: http://wesleypeck.com/
+D: MicroBlaze backend
diff --git a/Makefile b/Makefile
index 319bdcd..f5a9b33 100644
--- a/Makefile
+++ b/Makefile
@@ -30,8 +30,8 @@ ifeq ($(BUILD_DIRS_ONLY),1)
DIRS := lib/System lib/Support utils
OPTIONAL_DIRS :=
else
- DIRS := lib/System lib/Support utils lib/VMCore lib tools/llvm-config \
- tools runtime docs unittests
+ DIRS := lib/System lib/Support utils lib/VMCore lib tools/llvm-shlib \
+ tools/llvm-config tools runtime docs unittests
OPTIONAL_DIRS := projects bindings
endif
@@ -43,12 +43,9 @@ EXTRA_DIST := test unittests llvm.spec include win32 Xcode
include $(LEVEL)/Makefile.config
-# llvm-gcc4 doesn't need runtime libs. llvm-gcc4 is the only supported one.
-# FIXME: Remove runtime entirely once we have an understanding of where
-# libprofile etc should go.
-#ifeq ($(LLVMGCC_MAJVERS),4)
-# DIRS := $(filter-out runtime, $(DIRS))
-#endif
+ifneq ($(ENABLE_SHARED),1)
+ DIRS := $(filter-out tools/llvm-shlib, $(DIRS))
+endif
ifeq ($(MAKECMDGOALS),libs-only)
DIRS := $(filter-out tools runtime docs, $(DIRS))
diff --git a/Makefile.config.in b/Makefile.config.in
index 2cc69dc..1b61f09 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -76,14 +76,14 @@ endif
LLVMMAKE := $(LLVM_SRC_ROOT)/make
-PROJ_bindir := $(DESTDIR)$(PROJ_prefix)/bin
-PROJ_libdir := $(DESTDIR)$(PROJ_prefix)/lib
-PROJ_datadir := $(DESTDIR)$(PROJ_prefix)/share
-PROJ_docsdir := $(DESTDIR)$(PROJ_prefix)/docs/llvm
-PROJ_etcdir := $(DESTDIR)$(PROJ_prefix)/etc/llvm
-PROJ_includedir := $(DESTDIR)$(PROJ_prefix)/include
-PROJ_infodir := $(DESTDIR)$(PROJ_prefix)/info
-PROJ_mandir := $(DESTDIR)$(PROJ_prefix)/share/man
+PROJ_bindir := $(PROJ_prefix)/bin
+PROJ_libdir := $(PROJ_prefix)/lib
+PROJ_datadir := $(PROJ_prefix)/share
+PROJ_docsdir := $(PROJ_prefix)/docs/llvm
+PROJ_etcdir := $(PROJ_prefix)/etc/llvm
+PROJ_includedir := $(PROJ_prefix)/include
+PROJ_infodir := $(PROJ_prefix)/info
+PROJ_mandir := $(PROJ_prefix)/share/man
# Determine if we're on a unix type operating system
LLVM_ON_UNIX:=@LLVM_ON_UNIX@
@@ -183,25 +183,21 @@ TARGETS_TO_BUILD=@TARGETS_TO_BUILD@
# want to override the value set by configure.
LLVMGCCDIR := @LLVMGCCDIR@
-# Determine the target for which LLVM should generate code.
-ifeq (@LLVMGCC_MAJVERS@,3)
-LLVMGCCARCH := @target@/3.4-llvm
-else
-LLVMGCCARCH := @target@/@LLVMGCC_VERSION@
-endif
-
-# Determine the path where the library executables are
-LLVMGCCLIBEXEC := @LLVMGCCLIBEXEC@
-
# Full pathnames of LLVM C/C++ front-end 'cc1' and 'cc1plus' binaries:
LLVMGCC := @LLVMGCC@
LLVMGXX := @LLVMGXX@
LLVMCC1 := @LLVMCC1@
LLVMCC1PLUS := @LLVMCC1PLUS@
-LLVMGCC_VERSION := @LLVMGCC_VERSION@
-LLVMGCC_MAJVERS := @LLVMGCC_MAJVERS@
LLVMGCC_LANGS := @LLVMGCC_LANGS@
+# Information on Clang, if configured.
+CLANGPATH := @CLANGPATH@
+CLANGXXPATH := @CLANGXXPATH@
+ENABLE_BUILT_CLANG := @ENABLE_BUILT_CLANG@
+
+# The LLVM capable compiler to use.
+LLVMCC_OPTION := @LLVMCC_OPTION@
+
# Path to directory where object files should be stored during a build.
# Set OBJ_ROOT to "." if you do not want to use a separate place for
# object files.
@@ -266,6 +262,9 @@ ENABLE_THREADS := @ENABLE_THREADS@
# Do we want to build with position independent code?
ENABLE_PIC := @ENABLE_PIC@
+# Do we want to build a shared library and link the tools with it?
+ENABLE_SHARED := @ENABLE_SHARED@
+
# Use -fvisibility-inlines-hidden?
ENABLE_VISIBILITY_INLINES_HIDDEN := @ENABLE_VISIBILITY_INLINES_HIDDEN@
@@ -276,6 +275,9 @@ ENABLE_VISIBILITY_INLINES_HIDDEN := @ENABLE_VISIBILITY_INLINES_HIDDEN@
# Enable JIT for this platform
TARGET_HAS_JIT = @TARGET_HAS_JIT@
+# Environment variable to set to change the runtime shared library search path.
+SHLIBPATH_VAR = @SHLIBPATH_VAR@
+
# Shared library extension for host platform.
SHLIBEXT = @SHLIBEXT@
diff --git a/Makefile.rules b/Makefile.rules
index 761cc81..fcddd50 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -493,7 +493,27 @@ ExmplDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/examples
LLVMLibDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/lib
LLVMToolDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/bin
LLVMExmplDir:= $(LLVM_OBJ_ROOT)/$(BuildMode)/examples
-CFERuntimeLibDir := $(LLVMGCCDIR)/lib
+
+#--------------------------------------------------------------------
+# LLVM Capable Compiler
+#--------------------------------------------------------------------
+
+ifeq ($(LLVMCC_OPTION),llvm-gcc)
+ LLVMCC := $(LLVMGCC)
+ LLVMCXX := $(LLVMGXX)
+else
+ ifeq ($(LLVMCC_OPTION),clang)
+ ifneq ($(CLANGPATH),)
+ LLVMCC := $(CLANGPATH)
+ LLVMCXX := $(CLANGXXPATH)
+ else
+ ifeq ($(ENABLE_BUILT_CLANG),1)
+ LLVMCC := $(LLVMToolDir)/clang
+ LLVMCXX := $(LLVMToolDir)/clang++
+ endif
+ endif
+ endif
+endif
#--------------------------------------------------------------------
# Full Paths To Compiled Tools and Utilities
@@ -529,16 +549,6 @@ endif
ifndef LBUGPOINT
LBUGPOINT := $(LLVMToolDir)/bugpoint$(EXEEXT)
endif
-ifndef LUPGRADE
-LUPGRADE := $(LLVMToolDir)/llvm-upgrade$(EXEEXT)
-endif
-ifeq ($(LLVMGCC_MAJVERS),3)
-LLVMGCCWITHPATH := PATH="$(LLVMToolDir):$(PATH)" $(LLVMGCC)
-LLVMGXXWITHPATH := PATH="$(LLVMToolDir):$(PATH)" $(LLVMGXX)
-else
-LLVMGCCWITHPATH := $(LLVMGCC)
-LLVMGXXWITHPATH := $(LLVMGXX)
-endif
#--------------------------------------------------------------------
# Adjust to user's request
@@ -613,11 +623,12 @@ endif
ifneq ($(HOST_OS),Darwin)
ifneq ($(DARWIN_MAJVERS),4)
ifdef TOOLNAME
-ifdef EXAMPLE_TOOL
- LD.Flags += $(RPATH) -Wl,$(ExmplDir) $(RDYNAMIC)
-else
- LD.Flags += $(RPATH) -Wl,$(ToolDir) $(RDYNAMIC)
-endif
+ LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib'
+ ifdef EXAMPLE_TOOL
+ LD.Flags += $(RPATH) -Wl,$(ExmplDir) $(RDYNAMIC)
+ else
+ LD.Flags += $(RPATH) -Wl,$(ToolDir) $(RDYNAMIC)
+ endif
endif
endif
endif
@@ -710,14 +721,12 @@ else
$(TargetCommonOpts) $(CompileCommonOpts) $(LD.Flags) $(Strip)
endif
-BCCompile.C = $(LLVMGCCWITHPATH) $(CPP.Flags) $(C.Flags) $(CFLAGS) \
- $(CPPFLAGS) \
+BCCompile.C = $(LLVMCC) $(CPP.Flags) $(C.Flags) $(CFLAGS) $(CPPFLAGS) \
$(TargetCommonOpts) $(CompileCommonOpts)
Preprocess.C = $(CC) $(CPP.Flags) $(C.Flags) $(CPPFLAGS) \
$(TargetCommonOpts) $(CompileCommonOpts) -E
-BCCompile.CXX = $(LLVMGXXWITHPATH) $(CPP.Flags) $(CXX.Flags) $(CXXFLAGS) \
- $(CPPFLAGS) \
+BCCompile.CXX = $(LLVMCXX) $(CPP.Flags) $(CXX.Flags) $(CXXFLAGS) $(CPPFLAGS) \
$(TargetCommonOpts) $(CompileCommonOpts)
ProgInstall = $(INSTALL) $(Install.StripFlag) -m 0755
@@ -772,7 +781,7 @@ ObjectsBC := $(BaseNameSources:%=$(ObjDir)/%.bc)
# in the file so they get built before dependencies
#---------------------------------------------------------
-$(PROJ_bindir) $(PROJ_libdir) $(PROJ_includedir) $(PROJ_etcdir)::
+$(DESTDIR)$(PROJ_bindir) $(DESTDIR)$(PROJ_libdir) $(DESTDIR)$(PROJ_includedir) $(DESTDIR)$(PROJ_etcdir)::
$(Verb) $(MKDIR) $@
# To create other directories, as needed, and timestamp their creation
@@ -895,22 +904,22 @@ install-local::
uninstall-local::
$(Echo) UnInstall circumvented with NO_INSTALL
else
-install-local:: $(PROJ_etcdir) $(CONFIG_FILES)
- $(Echo) Installing Configuration Files To $(PROJ_etcdir)
+install-local:: $(DESTDIR)$(PROJ_etcdir) $(CONFIG_FILES)
+ $(Echo) Installing Configuration Files To $(DESTDIR)$(PROJ_etcdir)
$(Verb)for file in $(CONFIG_FILES); do \
if test -f $(PROJ_OBJ_DIR)/$${file} ; then \
- $(DataInstall) $(PROJ_OBJ_DIR)/$${file} $(PROJ_etcdir) ; \
+ $(DataInstall) $(PROJ_OBJ_DIR)/$${file} $(DESTDIR)$(PROJ_etcdir) ; \
elif test -f $(PROJ_SRC_DIR)/$${file} ; then \
- $(DataInstall) $(PROJ_SRC_DIR)/$${file} $(PROJ_etcdir) ; \
+ $(DataInstall) $(PROJ_SRC_DIR)/$${file} $(DESTDIR)$(PROJ_etcdir) ; \
else \
$(ECHO) Error: cannot find config file $${file}. ; \
fi \
done
uninstall-local::
- $(Echo) Uninstalling Configuration Files From $(PROJ_etcdir)
+ $(Echo) Uninstalling Configuration Files From $(DESTDIR)$(PROJ_etcdir)
$(Verb)for file in $(CONFIG_FILES); do \
- $(RM) -f $(PROJ_etcdir)/$${file} ; \
+ $(RM) -f $(DESTDIR)$(PROJ_etcdir)/$${file} ; \
done
endif
@@ -952,11 +961,16 @@ $(LLVM_CONFIG):
$(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT): $(LLVM_CONFIG)
+ifeq ($(ENABLE_SHARED), 1)
+LLVMLibsOptions += -lLLVM-$(LLVMVersion)
+LLVMLibsPaths += $(LibDir)/libLLVM-$(LLVMVersion)$(SHLIBEXT)
+else
LLVMLibsOptions += $(shell $(LLVM_CONFIG) --libs $(LINK_COMPONENTS))
LLVMLibsPaths += $(LLVM_CONFIG) \
$(shell $(LLVM_CONFIG) --libfiles $(LINK_COMPONENTS))
endif
endif
+endif
###############################################################################
# Library Build Rules: Four ways to build a library
@@ -971,12 +985,12 @@ endif
#---------------------------------------------------------
ifdef MODULE_NAME
-ifeq ($(strip $(LLVMGCC)),)
-$(warning Modules require llvm-gcc but no llvm-gcc is available ****)
+ifeq ($(strip $(LLVMCC)),)
+$(warning Modules require LLVM capable compiler but none is available ****)
else
Module := $(LibDir)/$(MODULE_NAME).bc
-LinkModule := $(LLVMLD) -L$(CFERuntimeLibDir) -r
+LinkModule := $(LLVMLD) -r
ifdef EXPORTED_SYMBOL_FILE
@@ -997,7 +1011,7 @@ endif
ifdef BYTECODE_DESTINATION
ModuleDestDir := $(BYTECODE_DESTINATION)
else
-ModuleDestDir := $(PROJ_libdir)
+ModuleDestDir := $(DESTDIR)$(PROJ_libdir)
endif
ifdef NO_INSTALL
@@ -1076,17 +1090,17 @@ install-local::
uninstall-local::
$(Echo) Uninstall circumvented with NO_INSTALL
else
-DestSharedLib = $(PROJ_libdir)/lib$(LIBRARYNAME)$(SHLIBEXT)
+DestSharedLib = $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME)$(SHLIBEXT)
install-local:: $(DestSharedLib)
-$(DestSharedLib): $(LibName.SO) $(PROJ_libdir)
+$(DestSharedLib): $(LibName.SO) $(DESTDIR)$(PROJ_libdir)
$(Echo) Installing $(BuildMode) Shared Library $(DestSharedLib)
$(Verb) $(INSTALL) $(LibName.SO) $(DestSharedLib)
uninstall-local::
$(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib)
- -$(Verb) $(RM) -f $(PROJ_libdir)/lib$(LIBRARYNAME).*
+ -$(Verb) $(RM) -f $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME).*
endif
endif
@@ -1097,15 +1111,14 @@ endif
# targets for building them.
#---------------------------------------------------------
ifdef BYTECODE_LIBRARY
-ifeq ($(strip $(LLVMGCC)),)
-$(warning Bytecode libraries require llvm-gcc which could not be found ****)
+ifeq ($(strip $(LLVMCC)),)
+$(warning Bytecode libraries require LLVM capable compiler but none is available ****)
else
all-local:: $(LibName.BCA)
ifdef EXPORTED_SYMBOL_FILE
-BCLinkLib = $(LLVMLD) -L$(CFERuntimeLibDir) \
- -internalize-public-api-file=$(EXPORTED_SYMBOL_FILE)
+BCLinkLib = $(LLVMLD) -internalize-public-api-file=$(EXPORTED_SYMBOL_FILE)
$(LibName.BCA): $(ObjectsBC) $(LibDir)/.dir $(LLVMLD) \
$(LLVMToolDir)/llvm-ar
@@ -1131,7 +1144,7 @@ endif
ifdef BYTECODE_DESTINATION
BytecodeDestDir := $(BYTECODE_DESTINATION)
else
-BytecodeDestDir := $(PROJ_libdir)
+BytecodeDestDir := $(DESTDIR)$(PROJ_libdir)
endif
DestBytecodeLib = $(BytecodeDestDir)/lib$(LIBRARYNAME).bca
@@ -1162,11 +1175,13 @@ endif
# If neither BUILD_ARCHIVE or LOADABLE_MODULE are specified, default to
# building an archive.
#---------------------------------------------------------
+ifndef NO_BUILD_ARCHIVE
ifndef BUILD_ARCHIVE
ifndef LOADABLE_MODULE
BUILD_ARCHIVE = 1
endif
endif
+endif
#---------------------------------------------------------
# Archive Library Targets:
@@ -1194,13 +1209,13 @@ install-local::
uninstall-local::
$(Echo) Uninstall circumvented with NO_INSTALL
else
-DestArchiveLib := $(PROJ_libdir)/lib$(LIBRARYNAME).a
+DestArchiveLib := $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME).a
install-local:: $(DestArchiveLib)
-$(DestArchiveLib): $(LibName.A) $(PROJ_libdir)
+$(DestArchiveLib): $(LibName.A) $(DESTDIR)$(PROJ_libdir)
$(Echo) Installing $(BuildMode) Archive Library $(DestArchiveLib)
- $(Verb) $(MKDIR) $(PROJ_libdir)
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_libdir)
$(Verb) $(INSTALL) $(LibName.A) $(DestArchiveLib)
uninstall-local::
@@ -1300,11 +1315,11 @@ install-local::
uninstall-local::
$(Echo) Uninstall circumvented with NO_INSTALL
else
-DestTool = $(PROJ_bindir)/$(TOOLEXENAME)
+DestTool = $(DESTDIR)$(PROJ_bindir)/$(TOOLEXENAME)
install-local:: $(DestTool)
-$(DestTool): $(ToolBuildPath) $(PROJ_bindir)
+$(DestTool): $(ToolBuildPath) $(DESTDIR)$(PROJ_bindir)
$(Echo) Installing $(BuildMode) $(DestTool)
$(Verb) $(ProgInstall) $(ToolBuildPath) $(DestTool)
@@ -1382,19 +1397,19 @@ BC_DEPEND_OPTIONS = -MMD -MP -MF "$(ObjDir)/$*.bc.d.tmp" \
BC_DEPEND_MOVEFILE = then $(MV) -f "$(ObjDir)/$*.bc.d.tmp" "$(ObjDir)/$*.bc.d"; \
else $(RM) "$(ObjDir)/$*.bc.d.tmp"; exit 1; fi
-$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
+$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
$(Echo) "Compiling $*.cpp for $(BuildMode) build (bytecode)"
$(Verb) if $(BCCompile.CXX) $(BC_DEPEND_OPTIONS) \
$< -o $(ObjDir)/$*.ll -S -emit-llvm ; \
$(BC_DEPEND_MOVEFILE)
-$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
+$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
$(Echo) "Compiling $*.cc for $(BuildMode) build (bytecode)"
$(Verb) if $(BCCompile.CXX) $(BC_DEPEND_OPTIONS) \
$< -o $(ObjDir)/$*.ll -S -emit-llvm ; \
$(BC_DEPEND_MOVEFILE)
-$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGCC)
+$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
$(Echo) "Compiling $*.c for $(BuildMode) build (bytecode)"
$(Verb) if $(BCCompile.C) $(BC_DEPEND_OPTIONS) \
$< -o $(ObjDir)/$*.ll -S -emit-llvm ; \
@@ -1415,15 +1430,15 @@ $(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES)
$(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG)
$(Compile.C) $< -o $@
-$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
+$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
$(Echo) "Compiling $*.cpp for $(BuildMode) build (bytecode)"
$(BCCompile.CXX) $< -o $@ -S -emit-llvm
-$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
+$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
$(Echo) "Compiling $*.cc for $(BuildMode) build (bytecode)"
$(BCCompile.CXX) $< -o $@ -S -emit-llvm
-$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGCC)
+$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
$(Echo) "Compiling $*.c for $(BuildMode) build (bytecode)"
$(BCCompile.C) $< -o $@ -S -emit-llvm
@@ -1949,25 +1964,25 @@ uninstall-local::
else
install-local::
$(Echo) Installing include files
- $(Verb) $(MKDIR) $(PROJ_includedir)
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
$(Verb) if test -d "$(PROJ_SRC_ROOT)/include" ; then \
cd $(PROJ_SRC_ROOT)/include && \
for hdr in `find . -type f '!' '(' -name '*~' \
-o -name '.#*' -o -name '*.in' ')' -print | grep -v CVS | \
grep -v .svn` ; do \
- instdir=`dirname "$(PROJ_includedir)/$$hdr"` ; \
+ instdir=`dirname "$(DESTDIR)$(PROJ_includedir)/$$hdr"` ; \
if test \! -d "$$instdir" ; then \
$(EchoCmd) Making install directory $$instdir ; \
$(MKDIR) $$instdir ;\
fi ; \
- $(DataInstall) $$hdr $(PROJ_includedir)/$$hdr ; \
+ $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
done ; \
fi
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
$(Verb) if test -d "$(PROJ_OBJ_ROOT)/include" ; then \
cd $(PROJ_OBJ_ROOT)/include && \
for hdr in `find . -type f -print | grep -v CVS` ; do \
- $(DataInstall) $$hdr $(PROJ_includedir)/$$hdr ; \
+ $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
done ; \
fi
endif
@@ -1979,10 +1994,10 @@ uninstall-local::
$(RM) -f `find . -path '*/Internal' -prune -o '(' -type f \
'!' '(' -name '*~' -o -name '.#*' \
-o -name '*.in' ')' -print ')' | \
- grep -v CVS | sed 's#^#$(PROJ_includedir)/#'` ; \
+ grep -v CVS | sed 's#^#$(DESTDIR)$(PROJ_includedir)/#'` ; \
cd $(PROJ_SRC_ROOT)/include && \
$(RM) -f `find . -path '*/Internal' -prune -o '(' -type f -name '*.in' \
- -print ')' | sed 's#\.in$$##;s#^#$(PROJ_includedir)/#'` ; \
+ -print ')' | sed 's#\.in$$##;s#^#$(DESTDIR)$(PROJ_includedir)/#'` ; \
fi
endif
endif
diff --git a/README.txt b/README.txt
index 6c2dbb0..2ebe271 100644
--- a/README.txt
+++ b/README.txt
@@ -11,4 +11,5 @@ the license agreement found in LICENSE.txt.
Please see the HTML documentation provided in docs/index.html for further
assistance with LLVM.
-
+If you're writing a package for LLVM, see docs/Packaging.html for our
+suggestions.
diff --git a/Xcode/LLVM.xcodeproj/project.pbxproj b/Xcode/LLVM.xcodeproj/project.pbxproj
deleted file mode 100644
index e2f40f4..0000000
--- a/Xcode/LLVM.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,3303 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 42;
- objects = {
-
-/* Begin PBXAggregateTarget section */
- CF0329BC08D1BE8E0030FD33 /* LLVM full llc */ = {
- isa = PBXAggregateTarget;
- buildConfigurationList = CF0329C708D1BEC40030FD33 /* Build configuration list for PBXAggregateTarget "LLVM full llc" */;
- buildPhases = (
- );
- dependencies = (
- CF0329BE08D1BE970030FD33 /* PBXTargetDependency */,
- CF0329C008D1BE9B0030FD33 /* PBXTargetDependency */,
- );
- name = "LLVM full llc";
- productName = "LLVM full llc";
- };
- CFDF86D00ADE820000D40A3D /* LLVM full llc release */ = {
- isa = PBXAggregateTarget;
- buildConfigurationList = CFDF86D50ADE820000D40A3D /* Build configuration list for PBXAggregateTarget "LLVM full llc release" */;
- buildPhases = (
- );
- dependencies = (
- CFDF86DA0ADE822100D40A3D /* PBXTargetDependency */,
- CFDF86DC0ADE822100D40A3D /* PBXTargetDependency */,
- );
- name = "LLVM full llc release";
- productName = "LLVM full llc";
- };
-/* End PBXAggregateTarget section */
-
-/* Begin PBXContainerItemProxy section */
- CF0329BD08D1BE970030FD33 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = CF0329B608D1BE110030FD33;
- remoteInfo = "LLVM lib";
- };
- CF0329BF08D1BE9B0030FD33 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = CF0329BB08D1BE5D0030FD33;
- remoteInfo = "LLVM llc";
- };
- CFDF86D90ADE822100D40A3D /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = CFDF86BD0ADE819D00D40A3D;
- remoteInfo = "LLVM lib release";
- };
- CFDF86DB0ADE822100D40A3D /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = CFDF86C60ADE81D000D40A3D;
- remoteInfo = "LLVM llc release";
- };
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXFileReference section */
- 354CF6D10CD299440059AF3E /* DeserializeAPInt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeserializeAPInt.cpp; sourceTree = "<group>"; };
- 354CF6D20CD2994D0059AF3E /* SerializeAPInt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerializeAPInt.cpp; sourceTree = "<group>"; };
- 35A9CDED0CD0F6AF008ABC1D /* Deserialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Deserialize.h; sourceTree = "<group>"; };
- 35A9CDEE0CD0F6AF008ABC1D /* Serialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Serialization.h; sourceTree = "<group>"; };
- 35A9CDEF0CD0F6AF008ABC1D /* Serialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Serialize.h; sourceTree = "<group>"; };
- 35A9CDF00CD0F6D5008ABC1D /* Deserialize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Deserialize.cpp; sourceTree = "<group>"; };
- 35A9CDF10CD0F6E1008ABC1D /* Serialize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Serialize.cpp; sourceTree = "<group>"; };
- 35E98A830CBC2ED300C5CDC1 /* DenseSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DenseSet.h; sourceTree = "<group>"; };
- 35E98A840CBC2ED300C5CDC1 /* ImmutableMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImmutableMap.h; sourceTree = "<group>"; };
- 35E98A850CBC2ED300C5CDC1 /* ImmutableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImmutableSet.h; sourceTree = "<group>"; };
- 754221420D171DFC00DDB61B /* MachineLICM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachineLICM.cpp; sourceTree = "<group>"; };
- 84115FFE0B66D87400E1293E /* TargetMachOWriterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetMachOWriterInfo.cpp; sourceTree = "<group>"; };
- 84115FFF0B66D89B00E1293E /* PPCMachOWriterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPCMachOWriterInfo.cpp; sourceTree = "<group>"; };
- 841160000B66D8AC00E1293E /* PPCMachOWriterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCMachOWriterInfo.h; sourceTree = "<group>"; };
- 8443EF210B66B62D00959964 /* TargetMachOWriterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetMachOWriterInfo.h; sourceTree = "<group>"; };
- 9F4B0E5E0D0E02580061F270 /* bitreader_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bitreader_ocaml.c; sourceTree = "<group>"; };
- 9F4B0E5F0D0E02580061F270 /* llvm_bitreader.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_bitreader.ml; sourceTree = "<group>"; };
- 9F4B0E600D0E02580061F270 /* llvm_bitreader.mli */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_bitreader.mli; sourceTree = "<group>"; };
- 9F4B0E8C0D0E05ED0061F270 /* BitReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitReader.cpp; sourceTree = "<group>"; };
- 9F4B0E8D0D0E05ED0061F270 /* DeserializeAPFloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeserializeAPFloat.cpp; sourceTree = "<group>"; };
- 9F502ADB0D1D8CA3007939DF /* executionengine_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = executionengine_ocaml.c; sourceTree = "<group>"; };
- 9F502ADC0D1D8CA3007939DF /* llvm_executionengine.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_executionengine.ml; sourceTree = "<group>"; };
- 9F502ADD0D1D8CA3007939DF /* llvm_executionengine.mli */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_executionengine.mli; sourceTree = "<group>"; };
- 9F502AEC0D1D8CF8007939DF /* executionengine.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = executionengine.ml; sourceTree = "<group>"; };
- 9F502B090D1D8D8D007939DF /* ExecutionEngineBindings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionEngineBindings.cpp; sourceTree = "<group>"; };
- 9F5B90CB0D0CE87100CDFDEA /* StringPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringPool.cpp; sourceTree = "<group>"; };
- 9F5B90CE0D0CE89300CDFDEA /* AlignOf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlignOf.h; sourceTree = "<group>"; };
- 9F5B90CF0D0CE89300CDFDEA /* Registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Registry.h; sourceTree = "<group>"; };
- 9F5B90D00D0CE89300CDFDEA /* StringPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringPool.h; sourceTree = "<group>"; };
- 9F5B90E70D0DF19100CDFDEA /* BitReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitReader.h; sourceTree = "<group>"; };
- 9F68EB010C77AD02004AA152 /* LoopPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopPass.cpp; sourceTree = "<group>"; };
- 9F68EB020C77AD02004AA152 /* MemoryDependenceAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryDependenceAnalysis.cpp; sourceTree = "<group>"; };
- 9F68EB060C77AD2C004AA152 /* BitcodeReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitcodeReader.cpp; sourceTree = "<group>"; };
- 9F68EB070C77AD2C004AA152 /* BitcodeReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BitcodeReader.h; sourceTree = "<group>"; };
- 9F68EB120C77AD2C004AA152 /* BitcodeWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitcodeWriter.cpp; sourceTree = "<group>"; };
- 9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitcodeWriterPass.cpp; sourceTree = "<group>"; };
- 9F68EB250C77AD2C004AA152 /* ValueEnumerator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ValueEnumerator.cpp; sourceTree = "<group>"; };
- 9F68EB260C77AD2C004AA152 /* ValueEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ValueEnumerator.h; sourceTree = "<group>"; };
- 9F6B2CC00D0F6E56000F00FD /* bitreader.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bitreader.ml; sourceTree = "<group>"; };
- 9F70401A0D8D732400FD06FF /* llvm_scalar_opts.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = llvm_scalar_opts.ml; path = transforms/scalar/llvm_scalar_opts.ml; sourceTree = "<group>"; };
- 9F70401B0D8D732400FD06FF /* llvm_scalar_opts.mli */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = llvm_scalar_opts.mli; path = transforms/scalar/llvm_scalar_opts.mli; sourceTree = "<group>"; };
- 9F70401E0D8D735E00FD06FF /* scalar_opts_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scalar_opts_ocaml.c; path = transforms/scalar/scalar_opts_ocaml.c; sourceTree = "<group>"; };
- 9F7793460C73BC2000551F9C /* CodeGenPrepare.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenPrepare.cpp; sourceTree = "<group>"; };
- 9F7793470C73BC2000551F9C /* GVN.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GVN.cpp; sourceTree = "<group>"; };
- 9F7793480C73BC2000551F9C /* GVNPRE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GVNPRE.cpp; sourceTree = "<group>"; };
- 9F7793490C73BC2000551F9C /* LoopIndexSplit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoopIndexSplit.cpp; sourceTree = "<group>"; };
- 9F77934A0C73BC2000551F9C /* LoopRotation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoopRotation.cpp; sourceTree = "<group>"; };
- 9F7793500C73BD1500551F9C /* ELFWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ELFWriter.h; sourceTree = "<group>"; };
- 9F7793510C73BD1500551F9C /* IfConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IfConversion.cpp; sourceTree = "<group>"; };
- 9F7793520C73BD1500551F9C /* LowerSubregs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LowerSubregs.cpp; sourceTree = "<group>"; };
- 9F7793530C73BD1500551F9C /* MachOWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachOWriter.h; sourceTree = "<group>"; };
- 9F7793540C73BD1500551F9C /* PostRASchedulerList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PostRASchedulerList.cpp; sourceTree = "<group>"; };
- 9F7793550C73BD1500551F9C /* RegAllocBigBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegAllocBigBlock.cpp; sourceTree = "<group>"; };
- 9F7793560C73BD1500551F9C /* RegisterScavenging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterScavenging.cpp; sourceTree = "<group>"; };
- 9F7793570C73BD1500551F9C /* SimpleRegisterCoalescing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleRegisterCoalescing.cpp; sourceTree = "<group>"; };
- 9F7793770C73C48A00551F9C /* StripDeadPrototypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StripDeadPrototypes.cpp; sourceTree = "<group>"; };
- 9F7793780C73C49A00551F9C /* BasicInliner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BasicInliner.cpp; sourceTree = "<group>"; };
- 9F7793790C73C49A00551F9C /* CloneLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CloneLoop.cpp; sourceTree = "<group>"; };
- 9F77937A0C73C49A00551F9C /* InlineCost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineCost.cpp; sourceTree = "<group>"; };
- 9F77937B0C73C4F400551F9C /* AutoUpgrade.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AutoUpgrade.cpp; path = ../lib/VMCore/AutoUpgrade.cpp; sourceTree = SOURCE_ROOT; };
- 9F77937C0C73C4F400551F9C /* ConstantFold.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConstantFold.cpp; path = ../lib/VMCore/ConstantFold.cpp; sourceTree = SOURCE_ROOT; };
- 9F77937D0C73C4F400551F9C /* ConstantFold.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConstantFold.h; path = ../lib/VMCore/ConstantFold.h; sourceTree = SOURCE_ROOT; };
- 9F77937E0C73C53000551F9C /* ParameterAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParameterAttributes.h; sourceTree = "<group>"; };
- 9F7793800C73C54C00551F9C /* Archive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Archive.h; sourceTree = "<group>"; };
- 9F7793810C73C54C00551F9C /* BitCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitCodes.h; sourceTree = "<group>"; };
- 9F7793820C73C54C00551F9C /* BitstreamReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitstreamReader.h; sourceTree = "<group>"; };
- 9F7793830C73C54C00551F9C /* BitstreamWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitstreamWriter.h; sourceTree = "<group>"; };
- 9F7793840C73C54C00551F9C /* LLVMBitCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLVMBitCodes.h; sourceTree = "<group>"; };
- 9F7793850C73C54C00551F9C /* ReaderWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderWriter.h; sourceTree = "<group>"; };
- 9F7793860C73C57100551F9C /* CallingConvLower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallingConvLower.h; sourceTree = "<group>"; };
- 9F7793870C73C57100551F9C /* ELFRelocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ELFRelocation.h; sourceTree = "<group>"; };
- 9F7793880C73C57100551F9C /* FileWriters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileWriters.h; sourceTree = "<group>"; };
- 9F7793890C73C57100551F9C /* MachORelocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachORelocation.h; sourceTree = "<group>"; };
- 9F77938A0C73C57100551F9C /* RegisterScavenging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterScavenging.h; sourceTree = "<group>"; };
- 9F7794140C73CB6100551F9C /* Mips.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mips.h; sourceTree = "<group>"; };
- 9F7794150C73CB6100551F9C /* Mips.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Mips.td; sourceTree = "<group>"; };
- 9F7794160C73CB6100551F9C /* MipsAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsAsmPrinter.cpp; sourceTree = "<group>"; };
- 9F7794170C73CB6100551F9C /* MipsCallingConv.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MipsCallingConv.td; sourceTree = "<group>"; };
- 9F7794180C73CB6100551F9C /* MipsInstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MipsInstrFormats.td; sourceTree = "<group>"; };
- 9F7794190C73CB6100551F9C /* MipsInstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsInstrInfo.cpp; sourceTree = "<group>"; };
- 9F77941A0C73CB6100551F9C /* MipsInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MipsInstrInfo.h; sourceTree = "<group>"; };
- 9F77941B0C73CB6100551F9C /* MipsInstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MipsInstrInfo.td; sourceTree = "<group>"; };
- 9F77941C0C73CB6100551F9C /* MipsISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsISelDAGToDAG.cpp; sourceTree = "<group>"; };
- 9F77941D0C73CB6100551F9C /* MipsISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsISelLowering.cpp; sourceTree = "<group>"; };
- 9F77941E0C73CB6100551F9C /* MipsISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MipsISelLowering.h; sourceTree = "<group>"; };
- 9F77941F0C73CB6100551F9C /* MipsMachineFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MipsMachineFunction.h; sourceTree = "<group>"; };
- 9F7794200C73CB6100551F9C /* MipsRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsRegisterInfo.cpp; sourceTree = "<group>"; };
- 9F7794210C73CB6100551F9C /* MipsRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MipsRegisterInfo.h; sourceTree = "<group>"; };
- 9F7794220C73CB6100551F9C /* MipsRegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MipsRegisterInfo.td; sourceTree = "<group>"; };
- 9F7794230C73CB6100551F9C /* MipsSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsSubtarget.cpp; sourceTree = "<group>"; };
- 9F7794240C73CB6100551F9C /* MipsSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MipsSubtarget.h; sourceTree = "<group>"; };
- 9F7794250C73CB6100551F9C /* MipsTargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsTargetAsmInfo.cpp; sourceTree = "<group>"; };
- 9F7794260C73CB6100551F9C /* MipsTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MipsTargetAsmInfo.h; sourceTree = "<group>"; };
- 9F7794270C73CB6100551F9C /* MipsTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MipsTargetMachine.cpp; sourceTree = "<group>"; };
- 9F7794280C73CB6100551F9C /* MipsTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MipsTargetMachine.h; sourceTree = "<group>"; };
- 9F77942F0C73CB7900551F9C /* MSILWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MSILWriter.cpp; sourceTree = "<group>"; };
- 9F7794300C73CB7900551F9C /* MSILWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSILWriter.h; sourceTree = "<group>"; };
- 9F7794880C73D51000551F9C /* MemoryBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryBuffer.h; sourceTree = "<group>"; };
- 9F7794890C73D51000551F9C /* Streams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Streams.h; sourceTree = "<group>"; };
- 9F7C23E50CB81C2100498408 /* Analysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Analysis.h; sourceTree = "<group>"; };
- 9F7C23E60CB81C2B00498408 /* Analysis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Analysis.cpp; sourceTree = "<group>"; };
- 9F7C240C0CB81ECD00498408 /* analysis_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = analysis_ocaml.c; sourceTree = "<group>"; };
- 9F7C240D0CB81ECD00498408 /* llvm_analysis.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_analysis.ml; sourceTree = "<group>"; };
- 9F7C240E0CB81ECD00498408 /* llvm_analysis.mli */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_analysis.mli; sourceTree = "<group>"; };
- 9F7C2C4F0CB9496C00498408 /* analysis.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = analysis.ml; sourceTree = "<group>"; };
- 9F7C2C520CB9496C00498408 /* bitwriter.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bitwriter.ml; sourceTree = "<group>"; };
- 9F7C2C5D0CB9496C00498408 /* vmcore.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = vmcore.ml; sourceTree = "<group>"; };
- 9FA638D90C77B184007F12AE /* AutoUpgrade.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AutoUpgrade.h; sourceTree = "<group>"; };
- 9FA638DA0C77B184007F12AE /* GlobalAlias.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GlobalAlias.h; sourceTree = "<group>"; };
- 9FA638DB0C77B1AB007F12AE /* APInt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = APInt.h; sourceTree = "<group>"; };
- 9FA638DC0C77B1AB007F12AE /* APSInt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = APSInt.h; sourceTree = "<group>"; };
- 9FA638DD0C77B1AB007F12AE /* BitVector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BitVector.h; sourceTree = "<group>"; };
- 9FA638E00C77B1AB007F12AE /* IndexedMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IndexedMap.h; sourceTree = "<group>"; };
- 9FA638E20C77B1AB007F12AE /* SmallPtrSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SmallPtrSet.h; sourceTree = "<group>"; };
- 9FA638E30C77B1AB007F12AE /* SmallSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SmallSet.h; sourceTree = "<group>"; };
- 9FA638E40C77B1AB007F12AE /* StringMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StringMap.h; sourceTree = "<group>"; };
- 9FA638E50C77B203007F12AE /* LoopPass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LoopPass.h; sourceTree = "<group>"; };
- 9FA638E60C77B203007F12AE /* MemoryDependenceAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MemoryDependenceAnalysis.h; sourceTree = "<group>"; };
- 9FA638E70C77B222007F12AE /* Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Disassembler.h; sourceTree = "<group>"; };
- 9FA638E80C77B231007F12AE /* TargetELFWriterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetELFWriterInfo.h; sourceTree = "<group>"; };
- 9FA638EA0C77B252007F12AE /* InlinerPass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlinerPass.h; sourceTree = "<group>"; };
- 9FA638EB0C77B26B007F12AE /* BasicInliner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BasicInliner.h; sourceTree = "<group>"; };
- 9FA638EC0C77B26B007F12AE /* InlineCost.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlineCost.h; sourceTree = "<group>"; };
- 9FD3E5710CA0116100E54D15 /* bitwriter_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = bitwriter_ocaml.c; sourceTree = "<group>"; };
- 9FD3E5720CA0116100E54D15 /* llvm_bitwriter.ml */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm_bitwriter.ml; sourceTree = "<group>"; };
- 9FD3E5730CA0116100E54D15 /* llvm_bitwriter.mli */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm_bitwriter.mli; sourceTree = "<group>"; };
- 9FD3E57B0CA0116100E54D15 /* llvm.ml */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm.ml; sourceTree = "<group>"; };
- 9FD3E57C0CA0116100E54D15 /* llvm.mli */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm.mli; sourceTree = "<group>"; };
- 9FD3E57D0CA0116100E54D15 /* llvm_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = llvm_ocaml.c; sourceTree = "<group>"; };
- 9FD3E58D0CA0125F00E54D15 /* BitWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BitWriter.h; sourceTree = "<group>"; };
- 9FD3E58E0CA0125F00E54D15 /* Core.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Core.h; sourceTree = "<group>"; };
- 9FD3E5900CA0129D00E54D15 /* Core.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Core.cpp; path = ../lib/VMCore/Core.cpp; sourceTree = SOURCE_ROOT; };
- 9FD3E5920CA012B300E54D15 /* BitWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitWriter.cpp; sourceTree = "<group>"; };
- 9FE25D900CAB166D005383FC /* APFloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APFloat.h; sourceTree = "<group>"; };
- 9FE25D910CAB166D005383FC /* SparseBitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SparseBitVector.h; sourceTree = "<group>"; };
- 9FE25D920CAB169F005383FC /* RegisterCoalescer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterCoalescer.h; sourceTree = "<group>"; };
- 9FE25D940CAB16FB005383FC /* RegisterCoalescer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterCoalescer.cpp; sourceTree = "<group>"; };
- 9FE25D950CAB1724005383FC /* APFloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APFloat.cpp; sourceTree = "<group>"; };
- 9FE25D960CAB1759005383FC /* TargetCallingConv.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TargetCallingConv.td; sourceTree = "<group>"; };
- 9FE4508B0C77A77000C4FEA4 /* ARMCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ARMCodeEmitter.cpp; sourceTree = "<group>"; };
- 9FE4508C0C77A77000C4FEA4 /* ARMGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenAsmWriter.inc; sourceTree = "<group>"; };
- 9FE4508D0C77A77000C4FEA4 /* ARMGenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenDAGISel.inc; sourceTree = "<group>"; };
- 9FE4508E0C77A77100C4FEA4 /* ARMGenInstrInfo.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenInstrInfo.inc; sourceTree = "<group>"; };
- 9FE4508F0C77A77100C4FEA4 /* ARMGenInstrNames.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenInstrNames.inc; sourceTree = "<group>"; };
- 9FE450900C77A77100C4FEA4 /* ARMGenRegisterInfo.h.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenRegisterInfo.h.inc; sourceTree = "<group>"; };
- 9FE450910C77A77100C4FEA4 /* ARMGenRegisterInfo.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenRegisterInfo.inc; sourceTree = "<group>"; };
- 9FE450920C77A77100C4FEA4 /* ARMGenRegisterNames.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenRegisterNames.inc; sourceTree = "<group>"; };
- 9FE450930C77A77100C4FEA4 /* ARMGenSubtarget.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenSubtarget.inc; sourceTree = "<group>"; };
- 9FE450940C77A77100C4FEA4 /* ARMJITInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ARMJITInfo.cpp; sourceTree = "<group>"; };
- 9FE450950C77A77100C4FEA4 /* ARMJITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ARMJITInfo.h; sourceTree = "<group>"; };
- 9FE450960C77A77100C4FEA4 /* ARMRelocations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ARMRelocations.h; sourceTree = "<group>"; };
- 9FE450970C77A77100C4FEA4 /* README-Thumb.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "README-Thumb.txt"; sourceTree = "<group>"; };
- 9FE450980C77A77100C4FEA4 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- 9FE4509A0C77A79C00C4FEA4 /* PPCCallingConv.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PPCCallingConv.td; sourceTree = "<group>"; };
- 9FE4509B0C77A79C00C4FEA4 /* PPCGenCallingConv.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = PPCGenCallingConv.inc; sourceTree = "<group>"; };
- 9FE4509C0C77A7BC00C4FEA4 /* README-MMX.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "README-MMX.txt"; sourceTree = "<group>"; };
- 9FE4509D0C77A7BC00C4FEA4 /* X86CallingConv.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = X86CallingConv.td; sourceTree = "<group>"; };
- 9FE4509F0C77A7BC00C4FEA4 /* X86ELFWriterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86ELFWriterInfo.cpp; sourceTree = "<group>"; };
- 9FE450A00C77A7BC00C4FEA4 /* X86ELFWriterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86ELFWriterInfo.h; sourceTree = "<group>"; };
- 9FE450A10C77A7BC00C4FEA4 /* X86GenCallingConv.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = X86GenCallingConv.inc; sourceTree = "<group>"; };
- 9FE450A20C77A7BC00C4FEA4 /* X86InstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = X86InstrFormats.td; sourceTree = "<group>"; };
- 9FE450A50C77AAF000C4FEA4 /* Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Disassembler.cpp; sourceTree = "<group>"; };
- 9FE450A60C77AB3200C4FEA4 /* APInt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = APInt.cpp; sourceTree = "<group>"; };
- 9FE450A70C77AB3200C4FEA4 /* ConstantRange.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantRange.cpp; sourceTree = "<group>"; };
- 9FE450A80C77AB3200C4FEA4 /* MemoryBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryBuffer.cpp; sourceTree = "<group>"; };
- 9FE450A90C77AB3200C4FEA4 /* SmallPtrSet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SmallPtrSet.cpp; sourceTree = "<group>"; };
- 9FE450AA0C77AB3200C4FEA4 /* StringMap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StringMap.cpp; sourceTree = "<group>"; };
- 9FE450AB0C77AB6100C4FEA4 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- 9FE450AC0C77AB6E00C4FEA4 /* CallingConvLower.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CallingConvLower.cpp; sourceTree = "<group>"; };
- 9FE450DF0C77ABE400C4FEA4 /* Archive.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Archive.cpp; sourceTree = "<group>"; };
- 9FE450E00C77ABE400C4FEA4 /* ArchiveInternals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ArchiveInternals.h; sourceTree = "<group>"; };
- 9FE450E10C77ABE400C4FEA4 /* ArchiveReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ArchiveReader.cpp; sourceTree = "<group>"; };
- 9FE450E20C77ABE400C4FEA4 /* ArchiveWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ArchiveWriter.cpp; sourceTree = "<group>"; };
- 9FEB8C550D1CD1E200EE46BC /* ExecutionEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionEngine.h; sourceTree = "<group>"; };
- 9FEDD5F10D8D73AB009F6DF1 /* Scalar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scalar.h; sourceTree = "<group>"; };
- 9FEDD5F70D8D797D009F6DF1 /* Scalar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scalar.cpp; sourceTree = "<group>"; };
- 9FEDD6140D8D7C3B009F6DF1 /* scalar_opts.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = scalar_opts.ml; sourceTree = "<group>"; };
- 9FEDD6B60D8D83D0009F6DF1 /* Target.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Target.cpp; sourceTree = "<group>"; };
- 9FEDD6B80D8D83EC009F6DF1 /* Target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Target.h; sourceTree = "<group>"; };
- 9FEDD6BB0D8D8408009F6DF1 /* lto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lto.h; sourceTree = "<group>"; };
- 9FEDD6BD0D8D8426009F6DF1 /* target.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = target.ml; sourceTree = "<group>"; };
- 9FEDD6C10D8D844E009F6DF1 /* llvm_target.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_target.ml; sourceTree = "<group>"; };
- 9FEDD6C20D8D844E009F6DF1 /* llvm_target.mli */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = llvm_target.mli; sourceTree = "<group>"; };
- 9FEDD6C40D8D844E009F6DF1 /* target_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = target_ocaml.c; sourceTree = "<group>"; };
- CF1ACC9709C9DE4400D3C5EB /* IntrinsicInst.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IntrinsicInst.cpp; path = ../lib/VMCore/IntrinsicInst.cpp; sourceTree = "<group>"; };
- CF26835B09178F5500C5F253 /* TargetInstrItineraries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TargetInstrItineraries.h; sourceTree = "<group>"; };
- CF32AF5C0AEE6A4E00D24CD4 /* LLVMTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLVMTargetMachine.cpp; sourceTree = "<group>"; };
- CF33BE160AF62B4200E93805 /* SmallString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallString.h; sourceTree = "<group>"; };
- CF341DAD0AB07A8B0099B064 /* AlphaTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlphaTargetAsmInfo.h; sourceTree = "<group>"; };
- CF341DAE0AB07A8B0099B064 /* AlphaTargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaTargetAsmInfo.cpp; sourceTree = "<group>"; };
- CF341E010AB080220099B064 /* PPCTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCTargetAsmInfo.h; sourceTree = "<group>"; };
- CF341E020AB080220099B064 /* PPCTargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCTargetAsmInfo.cpp; sourceTree = "<group>"; };
- CF341E220AB0814B0099B064 /* SparcTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SparcTargetAsmInfo.h; sourceTree = "<group>"; };
- CF341E230AB0814B0099B064 /* SparcTargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SparcTargetAsmInfo.cpp; sourceTree = "<group>"; };
- CF341E320AB082D60099B064 /* X86TargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86TargetAsmInfo.h; sourceTree = "<group>"; };
- CF341E330AB082D60099B064 /* X86TargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = X86TargetAsmInfo.cpp; sourceTree = "<group>"; };
- CF42B6BF0AF24F5300D5D47C /* FoldingSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FoldingSet.h; sourceTree = "<group>"; };
- CF42B6C40AF2512000D5D47C /* FoldingSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FoldingSet.cpp; sourceTree = "<group>"; };
- CF47BD380AAF40BC00A8B13E /* TargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TargetAsmInfo.h; sourceTree = "<group>"; };
- CF47BD860AAF487E00A8B13E /* TargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TargetAsmInfo.cpp; sourceTree = "<group>"; };
- CF490D14090541D30072DB1C /* TargetSchedule.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TargetSchedule.td; sourceTree = "<group>"; };
- CF490D15090541D30072DB1C /* TargetSelectionDAG.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TargetSelectionDAG.td; sourceTree = "<group>"; };
- CF490E2F0907BBF80072DB1C /* SubtargetEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtargetEmitter.h; sourceTree = "<group>"; };
- CF490E300907BBF80072DB1C /* SubtargetEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtargetEmitter.cpp; sourceTree = "<group>"; };
- CF4F27E60A7B6E23004359F6 /* MachinePassRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachinePassRegistry.h; sourceTree = "<group>"; };
- CF4F27F60A7B6FA3004359F6 /* MachinePassRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachinePassRegistry.cpp; sourceTree = "<group>"; };
- CF65223409CA39B800C4B521 /* Intrinsics.gen */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Intrinsics.gen; sourceTree = "<group>"; };
- CF6527D909D1A53400C4B521 /* MachineLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachineLocation.h; sourceTree = "<group>"; };
- CF6527FA09D1BA3800C4B521 /* DelaySlotFiller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DelaySlotFiller.cpp; path = ../lib/Target/Sparc/DelaySlotFiller.cpp; sourceTree = SOURCE_ROOT; };
- CF6527FB09D1BA3800C4B521 /* FPMover.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FPMover.cpp; path = ../lib/Target/Sparc/FPMover.cpp; sourceTree = SOURCE_ROOT; };
- CF6527FC09D1BA3800C4B521 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../lib/Target/Sparc/Makefile; sourceTree = SOURCE_ROOT; };
- CF6527FD09D1BA3800C4B521 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = ../lib/Target/Sparc/README.txt; sourceTree = SOURCE_ROOT; };
- CF6527FE09D1BA3800C4B521 /* Sparc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Sparc.h; path = ../lib/Target/Sparc/Sparc.h; sourceTree = SOURCE_ROOT; };
- CF6527FF09D1BA3800C4B521 /* Sparc.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Sparc.td; path = ../lib/Target/Sparc/Sparc.td; sourceTree = SOURCE_ROOT; };
- CF65280009D1BA3800C4B521 /* SparcAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SparcAsmPrinter.cpp; path = ../lib/Target/Sparc/SparcAsmPrinter.cpp; sourceTree = SOURCE_ROOT; };
- CF65280109D1BA3800C4B521 /* SparcGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenAsmWriter.inc; path = ../lib/Target/Sparc/SparcGenAsmWriter.inc; sourceTree = SOURCE_ROOT; };
- CF65280209D1BA3800C4B521 /* SparcGenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenDAGISel.inc; path = ../lib/Target/Sparc/SparcGenDAGISel.inc; sourceTree = SOURCE_ROOT; };
- CF65280309D1BA3800C4B521 /* SparcGenInstrInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenInstrInfo.inc; path = ../lib/Target/Sparc/SparcGenInstrInfo.inc; sourceTree = SOURCE_ROOT; };
- CF65280409D1BA3800C4B521 /* SparcGenInstrNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenInstrNames.inc; path = ../lib/Target/Sparc/SparcGenInstrNames.inc; sourceTree = SOURCE_ROOT; };
- CF65280509D1BA3800C4B521 /* SparcGenRegisterInfo.h.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenRegisterInfo.h.inc; path = ../lib/Target/Sparc/SparcGenRegisterInfo.h.inc; sourceTree = SOURCE_ROOT; };
- CF65280609D1BA3800C4B521 /* SparcGenRegisterInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenRegisterInfo.inc; path = ../lib/Target/Sparc/SparcGenRegisterInfo.inc; sourceTree = SOURCE_ROOT; };
- CF65280709D1BA3800C4B521 /* SparcGenRegisterNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenRegisterNames.inc; path = ../lib/Target/Sparc/SparcGenRegisterNames.inc; sourceTree = SOURCE_ROOT; };
- CF65280809D1BA3800C4B521 /* SparcGenSubtarget.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SparcGenSubtarget.inc; path = ../lib/Target/Sparc/SparcGenSubtarget.inc; sourceTree = SOURCE_ROOT; };
- CF65280909D1BA3800C4B521 /* SparcInstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SparcInstrFormats.td; path = ../lib/Target/Sparc/SparcInstrFormats.td; sourceTree = SOURCE_ROOT; };
- CF65280A09D1BA3800C4B521 /* SparcInstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SparcInstrInfo.cpp; path = ../lib/Target/Sparc/SparcInstrInfo.cpp; sourceTree = SOURCE_ROOT; };
- CF65280B09D1BA3800C4B521 /* SparcInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SparcInstrInfo.h; path = ../lib/Target/Sparc/SparcInstrInfo.h; sourceTree = SOURCE_ROOT; };
- CF65280C09D1BA3800C4B521 /* SparcInstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SparcInstrInfo.td; path = ../lib/Target/Sparc/SparcInstrInfo.td; sourceTree = SOURCE_ROOT; };
- CF65280D09D1BA3800C4B521 /* SparcISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SparcISelDAGToDAG.cpp; path = ../lib/Target/Sparc/SparcISelDAGToDAG.cpp; sourceTree = SOURCE_ROOT; };
- CF65280E09D1BA3800C4B521 /* SparcRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SparcRegisterInfo.cpp; path = ../lib/Target/Sparc/SparcRegisterInfo.cpp; sourceTree = SOURCE_ROOT; };
- CF65280F09D1BA3800C4B521 /* SparcRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SparcRegisterInfo.h; path = ../lib/Target/Sparc/SparcRegisterInfo.h; sourceTree = SOURCE_ROOT; };
- CF65281009D1BA3800C4B521 /* SparcRegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SparcRegisterInfo.td; path = ../lib/Target/Sparc/SparcRegisterInfo.td; sourceTree = SOURCE_ROOT; };
- CF65281109D1BA3800C4B521 /* SparcSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SparcSubtarget.cpp; path = ../lib/Target/Sparc/SparcSubtarget.cpp; sourceTree = SOURCE_ROOT; };
- CF65281209D1BA3800C4B521 /* SparcSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SparcSubtarget.h; path = ../lib/Target/Sparc/SparcSubtarget.h; sourceTree = SOURCE_ROOT; };
- CF65281309D1BA3800C4B521 /* SparcTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SparcTargetMachine.cpp; path = ../lib/Target/Sparc/SparcTargetMachine.cpp; sourceTree = SOURCE_ROOT; };
- CF65281409D1BA3800C4B521 /* SparcTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SparcTargetMachine.h; path = ../lib/Target/Sparc/SparcTargetMachine.h; sourceTree = SOURCE_ROOT; };
- CF6529A6095B21A8007F884E /* MachineModuleInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachineModuleInfo.cpp; sourceTree = "<group>"; };
- CF6B5AFD095C82C300D1EA42 /* DAGCombiner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DAGCombiner.cpp; sourceTree = "<group>"; };
- CF6F487109505E1500BC9E82 /* MachineModuleInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachineModuleInfo.h; sourceTree = "<group>"; };
- CF71B60F0AC45EDA0007F57C /* SmallVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallVector.h; sourceTree = "<group>"; };
- CF73C0A2098A4FDF00627152 /* InlineAsm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineAsm.h; sourceTree = "<group>"; };
- CF73C0A3098A4FDF00627152 /* TypeSymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeSymbolTable.h; sourceTree = "<group>"; };
- CF73C0A4098A4FDF00627152 /* ValueSymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueSymbolTable.h; sourceTree = "<group>"; };
- CF73C0A5098A507300627152 /* ConstantFolding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantFolding.h; sourceTree = "<group>"; };
- CF73C0A9098A50FD00627152 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
- CF73C0AD098A519400627152 /* DataTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTypes.h; sourceTree = "<group>"; };
- CF73C0AE098A51AD00627152 /* Alarm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Alarm.h; sourceTree = "<group>"; };
- CF73C0AF098A51DD00627152 /* RSProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSProfiling.h; sourceTree = "<group>"; };
- CF73C0B0098A523C00627152 /* ConstantFolding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantFolding.cpp; sourceTree = "<group>"; };
- CF73C0B7098A546000627152 /* RSProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RSProfiling.cpp; sourceTree = "<group>"; };
- CF73C0B8098A546000627152 /* RSProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSProfiling.h; sourceTree = "<group>"; };
- CF73C0B9098A546000627152 /* Reg2Mem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg2Mem.cpp; sourceTree = "<group>"; };
- CF73C0BD098A551F00627152 /* InlineAsm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InlineAsm.cpp; path = ../lib/VMCore/InlineAsm.cpp; sourceTree = SOURCE_ROOT; };
- CF73C0BE098A551F00627152 /* TypeSymbolTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSymbolTable.cpp; path = ../lib/VMCore/TypeSymbolTable.cpp; sourceTree = SOURCE_ROOT; };
- CF73C0BF098A551F00627152 /* ValueSymbolTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueSymbolTable.cpp; path = ../lib/VMCore/ValueSymbolTable.cpp; sourceTree = SOURCE_ROOT; };
- CF79495D09B326D4005ADFCA /* Dwarf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Dwarf.cpp; sourceTree = "<group>"; };
- CF7FFA1F0985081C008B0087 /* ScheduleDAGList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScheduleDAGList.cpp; sourceTree = "<group>"; };
- CF7FFA2109850864008B0087 /* ScheduleDAG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScheduleDAG.h; sourceTree = "<group>"; };
- CF8D62FA09C2226F006017BA /* Intrinsics.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Intrinsics.td; sourceTree = "<group>"; };
- CF8E00490989162500DA2399 /* Dwarf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dwarf.h; sourceTree = "<group>"; };
- CF8F1B410B64F6D100BB4199 /* RuntimeLibcalls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeLibcalls.h; sourceTree = "<group>"; };
- CF8F1B420B64F70B00BB4199 /* PassManagers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PassManagers.h; sourceTree = "<group>"; };
- CF8F1B430B64F74400BB4199 /* Allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Allocator.h; sourceTree = "<group>"; };
- CF8F1B440B64F74400BB4199 /* Compiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Compiler.h; sourceTree = "<group>"; };
- CF8F1B460B64F74400BB4199 /* ManagedStatic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ManagedStatic.h; sourceTree = "<group>"; };
- CF8F1B470B64F74400BB4199 /* OutputBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputBuffer.h; sourceTree = "<group>"; };
- CF8F1B490B64F7AB00BB4199 /* LinkTimeOptimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkTimeOptimizer.h; sourceTree = "<group>"; };
- CF8F1B4D0B64F80700BB4199 /* AliasDebugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AliasDebugger.cpp; sourceTree = "<group>"; };
- CF8F1B500B64F86A00BB4199 /* ManagedStatic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ManagedStatic.cpp; sourceTree = "<group>"; };
- CF8F1B510B64F86A00BB4199 /* Streams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Streams.cpp; sourceTree = "<group>"; };
- CF8F1B530B64F8C000BB4199 /* IncludeFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncludeFile.cpp; sourceTree = "<group>"; };
- CF8F1B540B64F90F00BB4199 /* AlphaBranchSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaBranchSelector.cpp; sourceTree = "<group>"; };
- CF8F1B550B64F90F00BB4199 /* AlphaLLRP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaLLRP.cpp; sourceTree = "<group>"; };
- CF8F1B560B64F98900BB4199 /* CBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CBackend.cpp; sourceTree = "<group>"; };
- CF8F1B570B64F9AC00BB4199 /* PPCPredicates.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCPredicates.cpp; sourceTree = "<group>"; };
- CF8F1B580B64F9AC00BB4199 /* PPCPredicates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCPredicates.h; sourceTree = "<group>"; };
- CF8F1B590B64F9E100BB4199 /* X86COFF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86COFF.h; sourceTree = "<group>"; };
- CF8F1B5B0B64FA2F00BB4199 /* PredicateSimplifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PredicateSimplifier.cpp; sourceTree = "<group>"; };
- CF8F1B5C0B64FA7300BB4199 /* PassManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PassManager.cpp; path = ../lib/VMCore/PassManager.cpp; sourceTree = SOURCE_ROOT; };
- CF8F1B680B64FADA00BB4199 /* llvm-upgrade.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "llvm-upgrade.cpp"; sourceTree = "<group>"; };
- CF8F1B720B64FADA00BB4199 /* UpgradeInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpgradeInternals.h; sourceTree = "<group>"; };
- CF8F1B750B64FADA00BB4199 /* UpgradeLexer.l */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lex; path = UpgradeLexer.l; sourceTree = "<group>"; };
- CF8F1B7C0B64FADA00BB4199 /* UpgradeParser.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = UpgradeParser.y; sourceTree = "<group>"; };
- CF8F1B7F0B64FADA00BB4199 /* CppWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CppWriter.cpp; sourceTree = "<group>"; };
- CF8F1B800B64FADA00BB4199 /* CppWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CppWriter.h; sourceTree = "<group>"; };
- CF8F1B870B64FADA00BB4199 /* llvm2cpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = llvm2cpp.cpp; sourceTree = "<group>"; };
- CF8F1B950B64FB5000BB4199 /* ConfigLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConfigLexer.cpp; sourceTree = "<group>"; };
- CF8F1B9D0B64FB7F00BB4199 /* lto-c.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "lto-c.cpp"; sourceTree = "<group>"; };
- CF8F1B9E0B64FB7F00BB4199 /* lto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lto.cpp; sourceTree = "<group>"; };
- CF8F1BAC0B64FB8000BB4199 /* AnalysisWrappers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnalysisWrappers.cpp; sourceTree = "<group>"; };
- CF8F1BB70B64FB8000BB4199 /* GraphPrinters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphPrinters.cpp; sourceTree = "<group>"; };
- CF8F1BB90B64FB8000BB4199 /* opt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opt.cpp; sourceTree = "<group>"; };
- CF8F1BBA0B64FB8000BB4199 /* PrintSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrintSCC.cpp; sourceTree = "<group>"; };
- CF8F1BC90B64FBD500BB4199 /* CodeGenIntrinsics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeGenIntrinsics.h; sourceTree = "<group>"; };
- CF8F1BD10B64FC8A00BB4199 /* ARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARM.h; sourceTree = "<group>"; };
- CF8F1BD20B64FC8A00BB4199 /* ARM.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ARM.td; sourceTree = "<group>"; };
- CF8F1BD30B64FC8A00BB4199 /* ARMAddressingModes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMAddressingModes.h; sourceTree = "<group>"; };
- CF8F1BD40B64FC8A00BB4199 /* ARMAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMAsmPrinter.cpp; sourceTree = "<group>"; };
- CF8F1BD50B64FC8A00BB4199 /* ARMConstantIslandPass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMConstantIslandPass.cpp; sourceTree = "<group>"; };
- CF8F1BD60B64FC8A00BB4199 /* ARMConstantPoolValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMConstantPoolValue.cpp; sourceTree = "<group>"; };
- CF8F1BD70B64FC8A00BB4199 /* ARMConstantPoolValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMConstantPoolValue.h; sourceTree = "<group>"; };
- CF8F1BD80B64FC8A00BB4199 /* ARMFrameInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMFrameInfo.h; sourceTree = "<group>"; };
- CF8F1BD90B64FC8A00BB4199 /* ARMInstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMInstrInfo.cpp; sourceTree = "<group>"; };
- CF8F1BDA0B64FC8A00BB4199 /* ARMInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMInstrInfo.h; sourceTree = "<group>"; };
- CF8F1BDB0B64FC8A00BB4199 /* ARMInstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ARMInstrInfo.td; sourceTree = "<group>"; };
- CF8F1BDC0B64FC8A00BB4199 /* ARMInstrThumb.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ARMInstrThumb.td; sourceTree = "<group>"; };
- CF8F1BDD0B64FC8A00BB4199 /* ARMInstrVFP.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ARMInstrVFP.td; sourceTree = "<group>"; };
- CF8F1BDE0B64FC8A00BB4199 /* ARMISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMISelDAGToDAG.cpp; sourceTree = "<group>"; };
- CF8F1BDF0B64FC8A00BB4199 /* ARMISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMISelLowering.cpp; sourceTree = "<group>"; };
- CF8F1BE00B64FC8A00BB4199 /* ARMISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMISelLowering.h; sourceTree = "<group>"; };
- CF8F1BE10B64FC8A00BB4199 /* ARMLoadStoreOptimizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMLoadStoreOptimizer.cpp; sourceTree = "<group>"; };
- CF8F1BE20B64FC8A00BB4199 /* ARMMachineFunctionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMMachineFunctionInfo.h; sourceTree = "<group>"; };
- CF8F1BE30B64FC8A00BB4199 /* ARMRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMRegisterInfo.cpp; sourceTree = "<group>"; };
- CF8F1BE40B64FC8A00BB4199 /* ARMRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMRegisterInfo.h; sourceTree = "<group>"; };
- CF8F1BE50B64FC8A00BB4199 /* ARMRegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ARMRegisterInfo.td; sourceTree = "<group>"; };
- CF8F1BE60B64FC8A00BB4199 /* ARMSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMSubtarget.cpp; sourceTree = "<group>"; };
- CF8F1BE70B64FC8A00BB4199 /* ARMSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMSubtarget.h; sourceTree = "<group>"; };
- CF8F1BE80B64FC8A00BB4199 /* ARMTargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMTargetAsmInfo.cpp; sourceTree = "<group>"; };
- CF8F1BE90B64FC8A00BB4199 /* ARMTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMTargetAsmInfo.h; sourceTree = "<group>"; };
- CF8F1BEA0B64FC8A00BB4199 /* ARMTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMTargetMachine.cpp; sourceTree = "<group>"; };
- CF8F1BEB0B64FC8A00BB4199 /* ARMTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMTargetMachine.h; sourceTree = "<group>"; };
- CF9720260A9F39B9002CEEDD /* LinkAllPasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkAllPasses.h; sourceTree = "<group>"; };
- CF9720270A9F39B9002CEEDD /* LinkTimeOptimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkTimeOptimizer.h; sourceTree = "<group>"; };
- CF9720340A9F3A41002CEEDD /* IncludeFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncludeFile.h; sourceTree = "<group>"; };
- CF9720350A9F3ADC002CEEDD /* MachOWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachOWriter.cpp; sourceTree = "<group>"; };
- CF9720370A9F3B1C002CEEDD /* TargetLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TargetLowering.cpp; sourceTree = "<group>"; };
- CF97208A0A9F3C6F002CEEDD /* LCSSA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LCSSA.cpp; sourceTree = "<group>"; };
- CF97208B0A9F3C6F002CEEDD /* LowerAllocations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LowerAllocations.cpp; sourceTree = "<group>"; };
- CF97208C0A9F3C6F002CEEDD /* LowerInvoke.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LowerInvoke.cpp; sourceTree = "<group>"; };
- CF97208E0A9F3C6F002CEEDD /* LowerSwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LowerSwitch.cpp; sourceTree = "<group>"; };
- CF97208F0A9F3C6F002CEEDD /* Mem2Reg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mem2Reg.cpp; sourceTree = "<group>"; };
- CF9720900A9F3CA2002CEEDD /* ValueTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueTypes.cpp; path = ../lib/VMCore/ValueTypes.cpp; sourceTree = SOURCE_ROOT; };
- CF9720910A9F3CC7002CEEDD /* FindBugs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FindBugs.cpp; sourceTree = "<group>"; };
- CF9720920A9F3CC7002CEEDD /* ToolRunner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToolRunner.cpp; sourceTree = "<group>"; };
- CF9720930A9F3CC7002CEEDD /* ToolRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToolRunner.h; sourceTree = "<group>"; };
- CF9720970A9F3D4D002CEEDD /* IntrinsicEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicEmitter.cpp; sourceTree = "<group>"; };
- CF9720980A9F3D4D002CEEDD /* IntrinsicEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntrinsicEmitter.h; sourceTree = "<group>"; };
- CF9BCD0808C74DE0001E7011 /* SubtargetFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtargetFeature.h; sourceTree = "<group>"; };
- CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtargetFeature.cpp; sourceTree = "<group>"; };
- CFA702BB0A6FA85F0006009A /* AlphaGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenAsmWriter.inc; sourceTree = "<group>"; };
- CFA702BC0A6FA85F0006009A /* AlphaGenCodeEmitter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenCodeEmitter.inc; sourceTree = "<group>"; };
- CFA702BD0A6FA85F0006009A /* AlphaGenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenDAGISel.inc; sourceTree = "<group>"; };
- CFA702BE0A6FA85F0006009A /* AlphaGenInstrInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenInstrInfo.inc; sourceTree = "<group>"; };
- CFA702BF0A6FA85F0006009A /* AlphaGenInstrNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenInstrNames.inc; sourceTree = "<group>"; };
- CFA702C00A6FA85F0006009A /* AlphaGenRegisterInfo.h.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenRegisterInfo.h.inc; sourceTree = "<group>"; };
- CFA702C10A6FA85F0006009A /* AlphaGenRegisterInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenRegisterInfo.inc; sourceTree = "<group>"; };
- CFA702C20A6FA85F0006009A /* AlphaGenRegisterNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenRegisterNames.inc; sourceTree = "<group>"; };
- CFA702C30A6FA85F0006009A /* AlphaGenSubtarget.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenSubtarget.inc; sourceTree = "<group>"; };
- CFA702CB0A6FA8AD0006009A /* PPCGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenAsmWriter.inc; sourceTree = "<group>"; };
- CFA702CC0A6FA8AD0006009A /* PPCGenCodeEmitter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenCodeEmitter.inc; sourceTree = "<group>"; };
- CFA702CD0A6FA8AD0006009A /* PPCGenDAGISel.inc */ = {isa = PBXFileReference; explicitFileType = sourcecode.pascal; fileEncoding = 4; path = PPCGenDAGISel.inc; sourceTree = "<group>"; };
- CFA702CE0A6FA8AD0006009A /* PPCGenInstrInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenInstrInfo.inc; sourceTree = "<group>"; };
- CFA702CF0A6FA8AD0006009A /* PPCGenInstrNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenInstrNames.inc; sourceTree = "<group>"; };
- CFA702D00A6FA8AD0006009A /* PPCGenRegisterInfo.h.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenRegisterInfo.h.inc; sourceTree = "<group>"; };
- CFA702D10A6FA8AD0006009A /* PPCGenRegisterInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenRegisterInfo.inc; sourceTree = "<group>"; };
- CFA702D20A6FA8AD0006009A /* PPCGenRegisterNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenRegisterNames.inc; sourceTree = "<group>"; };
- CFA702D30A6FA8AD0006009A /* PPCGenSubtarget.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenSubtarget.inc; sourceTree = "<group>"; };
- CFA702D40A6FA8DD0006009A /* X86GenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenAsmWriter.inc; sourceTree = "<group>"; };
- CFA702D50A6FA8DD0006009A /* X86GenAsmWriter1.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenAsmWriter1.inc; sourceTree = "<group>"; };
- CFA702D60A6FA8DD0006009A /* X86GenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenDAGISel.inc; sourceTree = "<group>"; };
- CFA702D70A6FA8DD0006009A /* X86GenInstrInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenInstrInfo.inc; sourceTree = "<group>"; };
- CFA702D80A6FA8DD0006009A /* X86GenInstrNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenInstrNames.inc; sourceTree = "<group>"; };
- CFA702D90A6FA8DD0006009A /* X86GenRegisterInfo.h.inc */ = {isa = PBXFileReference; fileEncoding = 4; languageSpecificationIdentifier = c.cpp; lastKnownFileType = sourcecode.pascal; path = X86GenRegisterInfo.h.inc; sourceTree = "<group>"; };
- CFA702DA0A6FA8DD0006009A /* X86GenRegisterInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenRegisterInfo.inc; sourceTree = "<group>"; };
- CFA702DB0A6FA8DD0006009A /* X86GenRegisterNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenRegisterNames.inc; sourceTree = "<group>"; };
- CFA702DC0A6FA8DD0006009A /* X86GenSubtarget.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = X86GenSubtarget.inc; sourceTree = "<group>"; };
- CFABD0A20B09E342003EB061 /* PPCMachineFunctionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCMachineFunctionInfo.h; sourceTree = "<group>"; };
- CFBD8B1A090E76540020B107 /* AlphaISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaISelDAGToDAG.cpp; sourceTree = "<group>"; };
- CFBD8B1B090E76540020B107 /* AlphaISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaISelLowering.cpp; sourceTree = "<group>"; };
- CFBD8B1C090E76540020B107 /* AlphaISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlphaISelLowering.h; sourceTree = "<group>"; };
- CFBD8B1D090E76540020B107 /* AlphaSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaSubtarget.cpp; sourceTree = "<group>"; };
- CFBD8B1E090E76540020B107 /* AlphaSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlphaSubtarget.h; sourceTree = "<group>"; };
- CFC244570959DEF2009F8C47 /* DwarfWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DwarfWriter.cpp; sourceTree = "<group>"; };
- CFC244BB0959F24C009F8C47 /* X86ISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = X86ISelDAGToDAG.cpp; sourceTree = "<group>"; };
- CFC244BC0959F24C009F8C47 /* X86ISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = X86ISelLowering.cpp; sourceTree = "<group>"; };
- CFC244BD0959F24C009F8C47 /* X86ISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86ISelLowering.h; sourceTree = "<group>"; };
- CFD7E4F30A798FC3000C7379 /* LinkAllCodegenComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkAllCodegenComponents.h; sourceTree = "<group>"; };
- CFD99AA80AFE827B0068D19C /* LICENSE.TXT */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE.TXT; path = ../LICENSE.TXT; sourceTree = SOURCE_ROOT; };
- CFD99AAD0AFE827B0068D19C /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = ../README.txt; sourceTree = SOURCE_ROOT; };
- CFD99AB70AFE848A0068D19C /* Allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Allocator.cpp; sourceTree = "<group>"; };
- CFD99ABA0AFE84D70068D19C /* IncludeFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncludeFile.cpp; sourceTree = "<group>"; };
- CFD99ABB0AFE84EF0068D19C /* Alarm.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = Alarm.inc; sourceTree = "<group>"; };
- CFD99ABE0AFE857A0068D19C /* README-X86-64.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "README-X86-64.txt"; sourceTree = "<group>"; };
- CFD99ADA0AFE87650068D19C /* lto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lto.cpp; path = lto/lto.cpp; sourceTree = "<group>"; };
- CFD99ADB0AFE87870068D19C /* AnalysisWrappers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnalysisWrappers.cpp; path = opt/AnalysisWrappers.cpp; sourceTree = "<group>"; };
- CFD99ADC0AFE87870068D19C /* GraphPrinters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GraphPrinters.cpp; path = opt/GraphPrinters.cpp; sourceTree = "<group>"; };
- CFD99ADD0AFE87870068D19C /* opt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = opt.cpp; path = opt/opt.cpp; sourceTree = "<group>"; };
- CFD99ADE0AFE87870068D19C /* PrintSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PrintSCC.cpp; path = opt/PrintSCC.cpp; sourceTree = "<group>"; };
- CFE21C780A80CC0600D3E908 /* RegAllocRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegAllocRegistry.h; sourceTree = "<group>"; };
- CFE21C7B0A80CC1C00D3E908 /* SchedulerRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchedulerRegistry.h; sourceTree = "<group>"; };
- CFE420FB0A66F67300AB4BF6 /* MachineJumpTableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachineJumpTableInfo.h; sourceTree = "<group>"; };
- CFE420FC0A66F67300AB4BF6 /* ValueTypes.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ValueTypes.td; sourceTree = "<group>"; };
- CFE420FD0A66F67300AB4BF6 /* Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interpreter.h; sourceTree = "<group>"; };
- CFE420FE0A66F67300AB4BF6 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JIT.h; sourceTree = "<group>"; };
- CFE420FF0A66F67300AB4BF6 /* IntrinsicsPowerPC.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IntrinsicsPowerPC.td; sourceTree = "<group>"; };
- CFE421000A66F67300AB4BF6 /* IntrinsicsX86.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IntrinsicsX86.td; sourceTree = "<group>"; };
- CFE421010A66F67300AB4BF6 /* LinkAllVMCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkAllVMCore.h; sourceTree = "<group>"; };
- CFE421060A66F86D00AB4BF6 /* ScheduleDAGRRList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScheduleDAGRRList.cpp; sourceTree = "<group>"; };
- CFE421070A66F8DC00AB4BF6 /* GraphWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphWriter.cpp; sourceTree = "<group>"; };
- CFE421090A66F93300AB4BF6 /* Alarm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Alarm.cpp; sourceTree = "<group>"; };
- CFE4210A0A66F93300AB4BF6 /* Alarm.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = Alarm.inc; sourceTree = "<group>"; };
- CFE4210B0A66F96400AB4BF6 /* AlphaSchedule.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AlphaSchedule.td; sourceTree = "<group>"; };
- CFE421140A66FA2D00AB4BF6 /* PPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPC.h; sourceTree = "<group>"; };
- CFE421150A66FA2D00AB4BF6 /* PPC.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPC.td; sourceTree = "<group>"; };
- CFE421160A66FA2D00AB4BF6 /* PPCAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCAsmPrinter.cpp; sourceTree = "<group>"; };
- CFE421170A66FA2D00AB4BF6 /* PPCBranchSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCBranchSelector.cpp; sourceTree = "<group>"; };
- CFE421180A66FA2D00AB4BF6 /* PPCCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCCodeEmitter.cpp; sourceTree = "<group>"; };
- CFE421190A66FA2D00AB4BF6 /* PPCFrameInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCFrameInfo.h; sourceTree = "<group>"; };
- CFE4211A0A66FA2D00AB4BF6 /* PPCHazardRecognizers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCHazardRecognizers.cpp; sourceTree = "<group>"; };
- CFE4211B0A66FA2D00AB4BF6 /* PPCHazardRecognizers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCHazardRecognizers.h; sourceTree = "<group>"; };
- CFE4211C0A66FA2D00AB4BF6 /* PPCInstr64Bit.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCInstr64Bit.td; sourceTree = "<group>"; };
- CFE4211D0A66FA2D00AB4BF6 /* PPCInstrAltivec.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCInstrAltivec.td; sourceTree = "<group>"; };
- CFE4211E0A66FA2D00AB4BF6 /* PPCInstrBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCInstrBuilder.h; sourceTree = "<group>"; };
- CFE4211F0A66FA2D00AB4BF6 /* PPCInstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCInstrFormats.td; sourceTree = "<group>"; };
- CFE421200A66FA2D00AB4BF6 /* PPCInstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCInstrInfo.cpp; sourceTree = "<group>"; };
- CFE421210A66FA2D00AB4BF6 /* PPCInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCInstrInfo.h; sourceTree = "<group>"; };
- CFE421220A66FA2D00AB4BF6 /* PPCInstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCInstrInfo.td; sourceTree = "<group>"; };
- CFE421230A66FA2D00AB4BF6 /* PPCISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCISelDAGToDAG.cpp; sourceTree = "<group>"; };
- CFE421240A66FA2D00AB4BF6 /* PPCISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCISelLowering.cpp; sourceTree = "<group>"; };
- CFE421250A66FA2D00AB4BF6 /* PPCISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCISelLowering.h; sourceTree = "<group>"; };
- CFE421260A66FA2D00AB4BF6 /* PPCJITInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCJITInfo.cpp; sourceTree = "<group>"; };
- CFE421270A66FA2D00AB4BF6 /* PPCJITInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCJITInfo.h; sourceTree = "<group>"; };
- CFE421280A66FA2D00AB4BF6 /* PPCPerfectShuffle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCPerfectShuffle.h; sourceTree = "<group>"; };
- CFE421290A66FA2D00AB4BF6 /* PPCRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCRegisterInfo.cpp; sourceTree = "<group>"; };
- CFE4212A0A66FA2D00AB4BF6 /* PPCRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCRegisterInfo.h; sourceTree = "<group>"; };
- CFE4212B0A66FA2D00AB4BF6 /* PPCRegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCRegisterInfo.td; sourceTree = "<group>"; };
- CFE4212C0A66FA2D00AB4BF6 /* PPCRelocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCRelocations.h; sourceTree = "<group>"; };
- CFE4212D0A66FA2D00AB4BF6 /* PPCSchedule.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCSchedule.td; sourceTree = "<group>"; };
- CFE4212E0A66FA2D00AB4BF6 /* PPCScheduleG3.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCScheduleG3.td; sourceTree = "<group>"; };
- CFE4212F0A66FA2D00AB4BF6 /* PPCScheduleG4.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCScheduleG4.td; sourceTree = "<group>"; };
- CFE421300A66FA2D00AB4BF6 /* PPCScheduleG4Plus.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCScheduleG4Plus.td; sourceTree = "<group>"; };
- CFE421310A66FA2D00AB4BF6 /* PPCScheduleG5.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPCScheduleG5.td; sourceTree = "<group>"; };
- CFE421320A66FA2E00AB4BF6 /* PPCSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCSubtarget.cpp; sourceTree = "<group>"; };
- CFE421330A66FA2E00AB4BF6 /* PPCSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCSubtarget.h; sourceTree = "<group>"; };
- CFE421340A66FA2E00AB4BF6 /* PPCTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCTargetMachine.cpp; sourceTree = "<group>"; };
- CFE421350A66FA2E00AB4BF6 /* PPCTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCTargetMachine.h; sourceTree = "<group>"; };
- CFE421360A66FA2E00AB4BF6 /* README_ALTIVEC.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README_ALTIVEC.txt; sourceTree = "<group>"; };
- CFE421370A66FA2E00AB4BF6 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- CFE421380A66FA8000AB4BF6 /* README-FPStack.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "README-FPStack.txt"; sourceTree = "<group>"; };
- CFE421390A66FA8000AB4BF6 /* README-SSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "README-SSE.txt"; sourceTree = "<group>"; };
- CFE4213A0A66FA8000AB4BF6 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- CFE4213B0A66FA8000AB4BF6 /* X86MachineFunctionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86MachineFunctionInfo.h; sourceTree = "<group>"; };
- CFE4213D0A66FAE100AB4BF6 /* Hello.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hello.cpp; sourceTree = "<group>"; };
- CFE4213F0A66FB5E00AB4BF6 /* IndMemRemoval.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndMemRemoval.cpp; sourceTree = "<group>"; };
- CFF0DE6309BF6C360031957F /* X86InstrFPStack.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = X86InstrFPStack.td; sourceTree = "<group>"; };
- CFF0DE6409BF6C360031957F /* X86InstrMMX.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = X86InstrMMX.td; sourceTree = "<group>"; };
- CFF0DE6509BF6C360031957F /* X86InstrSSE.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = X86InstrSSE.td; sourceTree = "<group>"; };
- CFF8B434097C605F0047F72A /* UniqueVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UniqueVector.h; sourceTree = "<group>"; };
- DE4DA0390911476D0012D44B /* LoopSimplify.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = LoopSimplify.cpp; path = ../lib/Transforms/Utils/LoopSimplify.cpp; sourceTree = SOURCE_ROOT; };
- DE4DA03C091147920012D44B /* LiveInterval.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LiveInterval.h; path = ../include/llvm/CodeGen/LiveInterval.h; sourceTree = SOURCE_ROOT; };
- DE4DA03D091147920012D44B /* LiveIntervalAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LiveIntervalAnalysis.h; path = ../include/llvm/CodeGen/LiveIntervalAnalysis.h; sourceTree = SOURCE_ROOT; };
- DE4DA065091148520012D44B /* SubtargetEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SubtargetEmitter.cpp; path = ../utils/TableGen/SubtargetEmitter.cpp; sourceTree = SOURCE_ROOT; };
- DE4DA066091148520012D44B /* SubtargetEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SubtargetEmitter.h; path = ../utils/TableGen/SubtargetEmitter.h; sourceTree = SOURCE_ROOT; };
- DE66EC5B08ABE86900323D32 /* AsmWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AsmWriter.cpp; path = ../lib/VMCore/AsmWriter.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC5C08ABE86A00323D32 /* BasicBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BasicBlock.cpp; path = ../lib/VMCore/BasicBlock.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6008ABE86A00323D32 /* Constants.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Constants.cpp; path = ../lib/VMCore/Constants.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6108ABE86A00323D32 /* Dominators.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Dominators.cpp; path = ../lib/VMCore/Dominators.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6208ABE86A00323D32 /* Function.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Function.cpp; path = ../lib/VMCore/Function.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6308ABE86A00323D32 /* Globals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Globals.cpp; path = ../lib/VMCore/Globals.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6408ABE86A00323D32 /* Instruction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Instruction.cpp; path = ../lib/VMCore/Instruction.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6508ABE86A00323D32 /* Instructions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Instructions.cpp; path = ../lib/VMCore/Instructions.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6608ABE86A00323D32 /* LeakDetector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = LeakDetector.cpp; path = ../lib/VMCore/LeakDetector.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6708ABE86A00323D32 /* Mangler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Mangler.cpp; path = ../lib/VMCore/Mangler.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6808ABE86A00323D32 /* Module.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Module.cpp; path = ../lib/VMCore/Module.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6908ABE86A00323D32 /* ModuleProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleProvider.cpp; path = ../lib/VMCore/ModuleProvider.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6A08ABE86A00323D32 /* Pass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Pass.cpp; path = ../lib/VMCore/Pass.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6D08ABE86A00323D32 /* SymbolTableListTraitsImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SymbolTableListTraitsImpl.h; path = ../lib/VMCore/SymbolTableListTraitsImpl.h; sourceTree = SOURCE_ROOT; };
- DE66EC6E08ABE86A00323D32 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Type.cpp; path = ../lib/VMCore/Type.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC6F08ABE86A00323D32 /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Value.cpp; path = ../lib/VMCore/Value.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC7008ABE86A00323D32 /* Verifier.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Verifier.cpp; path = ../lib/VMCore/Verifier.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC8E08ABEAF000323D32 /* llvmAsmParser.y */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.yacc; name = llvmAsmParser.y; path = ../lib/AsmParser/llvmAsmParser.y; sourceTree = SOURCE_ROOT; };
- DE66EC8F08ABEAF000323D32 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = ../lib/AsmParser/Parser.cpp; sourceTree = SOURCE_ROOT; };
- DE66EC9008ABEAF000323D32 /* ParserInternals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ParserInternals.h; path = ../lib/AsmParser/ParserInternals.h; sourceTree = SOURCE_ROOT; };
- DE66ECBE08ABEC0700323D32 /* AliasAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AliasAnalysis.cpp; sourceTree = "<group>"; };
- DE66ECBF08ABEC0700323D32 /* AliasAnalysisCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AliasAnalysisCounter.cpp; sourceTree = "<group>"; };
- DE66ECC008ABEC0700323D32 /* AliasAnalysisEvaluator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AliasAnalysisEvaluator.cpp; sourceTree = "<group>"; };
- DE66ECC108ABEC0700323D32 /* AliasSetTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AliasSetTracker.cpp; sourceTree = "<group>"; };
- DE66ECC208ABEC0700323D32 /* BasicAliasAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BasicAliasAnalysis.cpp; sourceTree = "<group>"; };
- DE66ECC308ABEC0700323D32 /* CFGPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CFGPrinter.cpp; sourceTree = "<group>"; };
- DE66ED1708ABEC0800323D32 /* InstCount.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstCount.cpp; sourceTree = "<group>"; };
- DE66ED1808ABEC0800323D32 /* Interval.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Interval.cpp; sourceTree = "<group>"; };
- DE66ED1908ABEC0800323D32 /* IntervalPartition.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IntervalPartition.cpp; sourceTree = "<group>"; };
- DE66ED1B08ABEC0800323D32 /* Andersens.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Andersens.cpp; sourceTree = "<group>"; };
- DE66ED1C08ABEC0800323D32 /* CallGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CallGraph.cpp; sourceTree = "<group>"; };
- DE66ED1D08ABEC0800323D32 /* CallGraphSCCPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CallGraphSCCPass.cpp; sourceTree = "<group>"; };
- DE66ED2F08ABEC0800323D32 /* FindUsedTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FindUsedTypes.cpp; sourceTree = "<group>"; };
- DE66ED3008ABEC0800323D32 /* GlobalsModRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalsModRef.cpp; sourceTree = "<group>"; };
- DE66ED3308ABEC0800323D32 /* LoadValueNumbering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoadValueNumbering.cpp; sourceTree = "<group>"; };
- DE66ED3408ABEC0800323D32 /* LoopInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopInfo.cpp; sourceTree = "<group>"; };
- DE66ED3608ABEC0800323D32 /* PostDominators.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PostDominators.cpp; sourceTree = "<group>"; };
- DE66ED3708ABEC0800323D32 /* ProfileInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProfileInfo.cpp; sourceTree = "<group>"; };
- DE66ED3808ABEC0800323D32 /* ProfileInfoLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProfileInfoLoader.cpp; sourceTree = "<group>"; };
- DE66ED3908ABEC0800323D32 /* ProfileInfoLoaderPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProfileInfoLoaderPass.cpp; sourceTree = "<group>"; };
- DE66ED3A08ABEC0800323D32 /* ScalarEvolution.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ScalarEvolution.cpp; sourceTree = "<group>"; };
- DE66ED3B08ABEC0800323D32 /* ScalarEvolutionExpander.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ScalarEvolutionExpander.cpp; sourceTree = "<group>"; };
- DE66ED3C08ABEC0800323D32 /* Trace.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Trace.cpp; sourceTree = "<group>"; };
- DE66ED3D08ABEC0800323D32 /* ValueNumbering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ValueNumbering.cpp; sourceTree = "<group>"; };
- DE66ED3F08ABEC2A00323D32 /* AsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AsmPrinter.cpp; sourceTree = "<group>"; };
- DE66ED4008ABEC2A00323D32 /* BranchFolding.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BranchFolding.cpp; sourceTree = "<group>"; };
- DE66ED6F08ABEC2B00323D32 /* ELFWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ELFWriter.cpp; sourceTree = "<group>"; };
- DE66ED7008ABEC2B00323D32 /* IntrinsicLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicLowering.cpp; sourceTree = "<group>"; };
- DE66ED7108ABEC2B00323D32 /* LiveInterval.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiveInterval.cpp; sourceTree = "<group>"; };
- DE66ED7308ABEC2B00323D32 /* LiveIntervalAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiveIntervalAnalysis.cpp; sourceTree = "<group>"; };
- DE66ED7508ABEC2B00323D32 /* LiveVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiveVariables.cpp; sourceTree = "<group>"; };
- DE66ED7608ABEC2B00323D32 /* MachineBasicBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachineBasicBlock.cpp; sourceTree = "<group>"; };
- DE66ED7808ABEC2B00323D32 /* MachineFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachineFunction.cpp; sourceTree = "<group>"; };
- DE66ED7908ABEC2B00323D32 /* MachineInstr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachineInstr.cpp; sourceTree = "<group>"; };
- DE66ED7B08ABEC2B00323D32 /* Passes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Passes.cpp; sourceTree = "<group>"; };
- DE66ED7C08ABEC2B00323D32 /* PHIElimination.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PHIElimination.cpp; sourceTree = "<group>"; };
- DE66ED7D08ABEC2B00323D32 /* PhysRegTracker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PhysRegTracker.h; sourceTree = "<group>"; };
- DE66ED7E08ABEC2B00323D32 /* PrologEpilogInserter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PrologEpilogInserter.cpp; sourceTree = "<group>"; };
- DE66ED8008ABEC2B00323D32 /* RegAllocLinearScan.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RegAllocLinearScan.cpp; sourceTree = "<group>"; };
- DE66ED8108ABEC2B00323D32 /* RegAllocLocal.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RegAllocLocal.cpp; sourceTree = "<group>"; };
- DE66ED8208ABEC2B00323D32 /* RegAllocSimple.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RegAllocSimple.cpp; sourceTree = "<group>"; };
- DE66ED9008ABEC2B00323D32 /* LegalizeDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LegalizeDAG.cpp; sourceTree = "<group>"; };
- DE66ED9208ABEC2B00323D32 /* SelectionDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionDAG.cpp; sourceTree = "<group>"; };
- DE66ED9308ABEC2B00323D32 /* SelectionDAGISel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionDAGISel.cpp; sourceTree = "<group>"; };
- DE66ED9408ABEC2B00323D32 /* SelectionDAGPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionDAGPrinter.cpp; sourceTree = "<group>"; };
- DE66ED9508ABEC2B00323D32 /* TwoAddressInstructionPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TwoAddressInstructionPass.cpp; sourceTree = "<group>"; };
- DE66ED9608ABEC2B00323D32 /* UnreachableBlockElim.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = UnreachableBlockElim.cpp; sourceTree = "<group>"; };
- DE66ED9808ABEC2B00323D32 /* VirtRegMap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = VirtRegMap.cpp; sourceTree = "<group>"; };
- DE66ED9908ABEC2B00323D32 /* VirtRegMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VirtRegMap.h; sourceTree = "<group>"; };
- DE66EDB108ABEC7300323D32 /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Debugger.cpp; sourceTree = "<group>"; };
- DE66EDB508ABEC7300323D32 /* ProgramInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProgramInfo.cpp; sourceTree = "<group>"; };
- DE66EDB608ABEC7300323D32 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- DE66EDB708ABEC7300323D32 /* RuntimeInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeInfo.cpp; sourceTree = "<group>"; };
- DE66EDB808ABEC7300323D32 /* SourceFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SourceFile.cpp; sourceTree = "<group>"; };
- DE66EDB908ABEC7300323D32 /* SourceLanguage-CFamily.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "SourceLanguage-CFamily.cpp"; sourceTree = "<group>"; };
- DE66EDBA08ABEC7300323D32 /* SourceLanguage-CPlusPlus.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "SourceLanguage-CPlusPlus.cpp"; sourceTree = "<group>"; };
- DE66EDBB08ABEC7300323D32 /* SourceLanguage-Unknown.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "SourceLanguage-Unknown.cpp"; sourceTree = "<group>"; };
- DE66EDBC08ABEC7300323D32 /* SourceLanguage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SourceLanguage.cpp; sourceTree = "<group>"; };
- DE66EDC408ABEC9000323D32 /* ExecutionEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionEngine.cpp; sourceTree = "<group>"; };
- DE66EDCE08ABEC9000323D32 /* Execution.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Execution.cpp; sourceTree = "<group>"; };
- DE66EDCF08ABEC9000323D32 /* ExternalFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ExternalFunctions.cpp; sourceTree = "<group>"; };
- DE66EDD008ABEC9000323D32 /* Interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Interpreter.cpp; sourceTree = "<group>"; };
- DE66EDD108ABEC9000323D32 /* Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Interpreter.h; sourceTree = "<group>"; };
- DE66EDDE08ABEC9100323D32 /* Intercept.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Intercept.cpp; sourceTree = "<group>"; };
- DE66EDDF08ABEC9100323D32 /* JIT.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JIT.cpp; sourceTree = "<group>"; };
- DE66EDE008ABEC9100323D32 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JIT.h; sourceTree = "<group>"; };
- DE66EDE108ABEC9100323D32 /* JITEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JITEmitter.cpp; sourceTree = "<group>"; };
- DE66EDE308ABEC9100323D32 /* TargetSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetSelect.cpp; sourceTree = "<group>"; };
- DE66EDF608ABEDD300323D32 /* LinkArchives.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LinkArchives.cpp; sourceTree = "<group>"; };
- DE66EDF708ABEDD300323D32 /* Linker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Linker.cpp; sourceTree = "<group>"; };
- DE66EDF808ABEDD300323D32 /* LinkItems.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LinkItems.cpp; sourceTree = "<group>"; };
- DE66EDF908ABEDD300323D32 /* LinkModules.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LinkModules.cpp; sourceTree = "<group>"; };
- DE66EDFC08ABEDE600323D32 /* Annotation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Annotation.cpp; sourceTree = "<group>"; };
- DE66EE1D08ABEDE600323D32 /* CommandLine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CommandLine.cpp; sourceTree = "<group>"; };
- DE66EE3D08ABEDE600323D32 /* Debug.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Debug.cpp; sourceTree = "<group>"; };
- DE66EE3E08ABEDE600323D32 /* FileUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FileUtilities.cpp; sourceTree = "<group>"; };
- DE66EE3F08ABEDE600323D32 /* IsInf.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IsInf.cpp; sourceTree = "<group>"; };
- DE66EE4008ABEDE600323D32 /* IsNAN.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IsNAN.cpp; sourceTree = "<group>"; };
- DE66EE4208ABEDE600323D32 /* PluginLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PluginLoader.cpp; sourceTree = "<group>"; };
- DE66EE4308ABEDE600323D32 /* SlowOperationInformer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SlowOperationInformer.cpp; sourceTree = "<group>"; };
- DE66EE4408ABEDE600323D32 /* Statistic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Statistic.cpp; sourceTree = "<group>"; };
- DE66EE4508ABEDE700323D32 /* StringExtras.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StringExtras.cpp; sourceTree = "<group>"; };
- DE66EE4608ABEDE700323D32 /* SystemUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SystemUtils.cpp; sourceTree = "<group>"; };
- DE66EE4708ABEDE700323D32 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; };
- DE66EE6008ABEE3400323D32 /* DynamicLibrary.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLibrary.cpp; sourceTree = "<group>"; };
- DE66EE6108ABEE3400323D32 /* LICENSE.TXT */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = LICENSE.TXT; sourceTree = "<group>"; };
- DE66EE6508ABEE3400323D32 /* MappedFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MappedFile.cpp; sourceTree = "<group>"; };
- DE66EE6608ABEE3400323D32 /* Memory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Memory.cpp; sourceTree = "<group>"; };
- DE66EE6708ABEE3400323D32 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = "<group>"; };
- DE66EE6808ABEE3400323D32 /* Path.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Path.cpp; sourceTree = "<group>"; };
- DE66EE6908ABEE3400323D32 /* Process.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Process.cpp; sourceTree = "<group>"; };
- DE66EE6A08ABEE3400323D32 /* Program.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Program.cpp; sourceTree = "<group>"; };
- DE66EE6B08ABEE3400323D32 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- DE66EE7C08ABEE3400323D32 /* Signals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Signals.cpp; sourceTree = "<group>"; };
- DE66EE7D08ABEE3400323D32 /* TimeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TimeValue.cpp; sourceTree = "<group>"; };
- DE66EE7F08ABEE3500323D32 /* MappedFile.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = MappedFile.inc; sourceTree = "<group>"; };
- DE66EE8008ABEE3500323D32 /* Memory.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Memory.inc; sourceTree = "<group>"; };
- DE66EE8108ABEE3500323D32 /* Mutex.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Mutex.inc; sourceTree = "<group>"; };
- DE66EE8208ABEE3500323D32 /* Path.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Path.inc; sourceTree = "<group>"; };
- DE66EE8308ABEE3500323D32 /* Process.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Process.inc; sourceTree = "<group>"; };
- DE66EE8408ABEE3500323D32 /* Program.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Program.inc; sourceTree = "<group>"; };
- DE66EE8508ABEE3500323D32 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- DE66EE8608ABEE3500323D32 /* Signals.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Signals.inc; sourceTree = "<group>"; };
- DE66EE8908ABEE3500323D32 /* TimeValue.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TimeValue.inc; sourceTree = "<group>"; };
- DE66EE8A08ABEE3500323D32 /* Unix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Unix.h; sourceTree = "<group>"; };
- DE66EE8C08ABEE3500323D32 /* DynamicLibrary.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = DynamicLibrary.inc; sourceTree = "<group>"; };
- DE66EE8D08ABEE3500323D32 /* MappedFile.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = MappedFile.inc; sourceTree = "<group>"; };
- DE66EE8E08ABEE3500323D32 /* Memory.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Memory.inc; sourceTree = "<group>"; };
- DE66EE8F08ABEE3500323D32 /* Mutex.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Mutex.inc; sourceTree = "<group>"; };
- DE66EE9008ABEE3500323D32 /* Path.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Path.inc; sourceTree = "<group>"; };
- DE66EE9108ABEE3500323D32 /* Process.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Process.inc; sourceTree = "<group>"; };
- DE66EE9208ABEE3500323D32 /* Program.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Program.inc; sourceTree = "<group>"; };
- DE66EE9308ABEE3500323D32 /* Signals.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Signals.inc; sourceTree = "<group>"; };
- DE66EE9408ABEE3500323D32 /* TimeValue.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TimeValue.inc; sourceTree = "<group>"; };
- DE66EE9508ABEE3500323D32 /* Win32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Win32.h; sourceTree = "<group>"; };
- DE66EE9808ABEE5E00323D32 /* Alpha.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Alpha.h; sourceTree = "<group>"; };
- DE66EE9908ABEE5E00323D32 /* Alpha.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Alpha.td; sourceTree = "<group>"; };
- DE66EE9A08ABEE5E00323D32 /* AlphaAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaAsmPrinter.cpp; sourceTree = "<group>"; };
- DE66EE9B08ABEE5E00323D32 /* AlphaCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaCodeEmitter.cpp; sourceTree = "<group>"; };
- DE66EEA308ABEE5E00323D32 /* AlphaInstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = AlphaInstrFormats.td; sourceTree = "<group>"; };
- DE66EEA408ABEE5E00323D32 /* AlphaInstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaInstrInfo.cpp; sourceTree = "<group>"; };
- DE66EEA508ABEE5E00323D32 /* AlphaInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AlphaInstrInfo.h; sourceTree = "<group>"; };
- DE66EEA608ABEE5E00323D32 /* AlphaInstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = AlphaInstrInfo.td; sourceTree = "<group>"; };
- DE66EEA908ABEE5E00323D32 /* AlphaJITInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaJITInfo.cpp; sourceTree = "<group>"; };
- DE66EEAA08ABEE5E00323D32 /* AlphaJITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AlphaJITInfo.h; sourceTree = "<group>"; };
- DE66EEAB08ABEE5E00323D32 /* AlphaRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaRegisterInfo.cpp; sourceTree = "<group>"; };
- DE66EEAC08ABEE5E00323D32 /* AlphaRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AlphaRegisterInfo.h; sourceTree = "<group>"; };
- DE66EEAD08ABEE5E00323D32 /* AlphaRegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = AlphaRegisterInfo.td; sourceTree = "<group>"; };
- DE66EEAE08ABEE5E00323D32 /* AlphaRelocations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AlphaRelocations.h; sourceTree = "<group>"; };
- DE66EEAF08ABEE5E00323D32 /* AlphaTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaTargetMachine.cpp; sourceTree = "<group>"; };
- DE66EEB008ABEE5E00323D32 /* AlphaTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AlphaTargetMachine.h; sourceTree = "<group>"; };
- DE66EECA08ABEE5E00323D32 /* CTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTargetMachine.h; sourceTree = "<group>"; };
- DE66EF0E08ABEE5E00323D32 /* README */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
- DE66EF1008ABEE5E00323D32 /* TargetRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetRegisterInfo.cpp; sourceTree = "<group>"; };
- DE66F08A08ABEE6000323D32 /* Target.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Target.td; sourceTree = "<group>"; };
- DE66F08B08ABEE6000323D32 /* TargetData.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetData.cpp; sourceTree = "<group>"; };
- DE66F08C08ABEE6000323D32 /* TargetFrameInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetFrameInfo.cpp; sourceTree = "<group>"; };
- DE66F08D08ABEE6000323D32 /* TargetInstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInstrInfo.cpp; sourceTree = "<group>"; };
- DE66F08F08ABEE6000323D32 /* TargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetMachine.cpp; sourceTree = "<group>"; };
- DE66F09008ABEE6000323D32 /* TargetMachineRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetMachineRegistry.cpp; sourceTree = "<group>"; };
- DE66F09208ABEE6000323D32 /* TargetSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetSubtarget.cpp; sourceTree = "<group>"; };
- DE66F0BC08ABEE6000323D32 /* X86.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86.h; sourceTree = "<group>"; };
- DE66F0BD08ABEE6000323D32 /* X86.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = X86.td; sourceTree = "<group>"; };
- DE66F0BE08ABEE6000323D32 /* X86AsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86AsmPrinter.cpp; sourceTree = "<group>"; };
- DE66F0BF08ABEE6000323D32 /* X86AsmPrinter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86AsmPrinter.h; sourceTree = "<group>"; };
- DE66F0C008ABEE6000323D32 /* X86ATTAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86ATTAsmPrinter.cpp; sourceTree = "<group>"; };
- DE66F0C108ABEE6000323D32 /* X86ATTAsmPrinter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86ATTAsmPrinter.h; sourceTree = "<group>"; };
- DE66F0C208ABEE6000323D32 /* X86CodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86CodeEmitter.cpp; sourceTree = "<group>"; };
- DE66F0C408ABEE6000323D32 /* X86FloatingPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86FloatingPoint.cpp; sourceTree = "<group>"; };
- DE66F0CC08ABEE6000323D32 /* X86InstrBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86InstrBuilder.h; sourceTree = "<group>"; };
- DE66F0CD08ABEE6000323D32 /* X86InstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86InstrInfo.cpp; sourceTree = "<group>"; };
- DE66F0CE08ABEE6000323D32 /* X86InstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86InstrInfo.h; sourceTree = "<group>"; };
- DE66F0CF08ABEE6100323D32 /* X86InstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = X86InstrInfo.td; sourceTree = "<group>"; };
- DE66F0D008ABEE6100323D32 /* X86IntelAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86IntelAsmPrinter.cpp; sourceTree = "<group>"; };
- DE66F0D108ABEE6100323D32 /* X86IntelAsmPrinter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86IntelAsmPrinter.h; sourceTree = "<group>"; };
- DE66F0D508ABEE6100323D32 /* X86JITInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86JITInfo.cpp; sourceTree = "<group>"; };
- DE66F0D608ABEE6100323D32 /* X86JITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86JITInfo.h; sourceTree = "<group>"; };
- DE66F0D808ABEE6100323D32 /* X86RegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86RegisterInfo.cpp; sourceTree = "<group>"; };
- DE66F0D908ABEE6100323D32 /* X86RegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86RegisterInfo.h; sourceTree = "<group>"; };
- DE66F0DA08ABEE6100323D32 /* X86RegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = X86RegisterInfo.td; sourceTree = "<group>"; };
- DE66F0DB08ABEE6100323D32 /* X86Relocations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86Relocations.h; sourceTree = "<group>"; };
- DE66F0DC08ABEE6100323D32 /* X86Subtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86Subtarget.cpp; sourceTree = "<group>"; };
- DE66F0DD08ABEE6100323D32 /* X86Subtarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86Subtarget.h; sourceTree = "<group>"; };
- DE66F0DE08ABEE6100323D32 /* X86TargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = X86TargetMachine.cpp; sourceTree = "<group>"; };
- DE66F0DF08ABEE6100323D32 /* X86TargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = X86TargetMachine.h; sourceTree = "<group>"; };
- DE66F0EF08ABEFB300323D32 /* BlockProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BlockProfiling.cpp; sourceTree = "<group>"; };
- DE66F0FE08ABEFB300323D32 /* EdgeProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeProfiling.cpp; sourceTree = "<group>"; };
- DE66F11B08ABEFB300323D32 /* ProfilingUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProfilingUtils.cpp; sourceTree = "<group>"; };
- DE66F11C08ABEFB300323D32 /* ProfilingUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProfilingUtils.h; sourceTree = "<group>"; };
- DE66F12008ABEFB300323D32 /* ArgumentPromotion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ArgumentPromotion.cpp; sourceTree = "<group>"; };
- DE66F12108ABEFB300323D32 /* ConstantMerge.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantMerge.cpp; sourceTree = "<group>"; };
- DE66F12208ABEFB300323D32 /* DeadArgumentElimination.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeadArgumentElimination.cpp; sourceTree = "<group>"; };
- DE66F12308ABEFB300323D32 /* DeadTypeElimination.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeadTypeElimination.cpp; sourceTree = "<group>"; };
- DE66F14C08ABEFB400323D32 /* GlobalDCE.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalDCE.cpp; sourceTree = "<group>"; };
- DE66F14D08ABEFB400323D32 /* GlobalOpt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalOpt.cpp; sourceTree = "<group>"; };
- DE66F14E08ABEFB400323D32 /* Inliner.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Inliner.cpp; sourceTree = "<group>"; };
- DE66F15008ABEFB400323D32 /* InlineSimple.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InlineSimple.cpp; sourceTree = "<group>"; };
- DE66F15108ABEFB400323D32 /* Internalize.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Internalize.cpp; sourceTree = "<group>"; };
- DE66F15208ABEFB400323D32 /* IPConstantPropagation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IPConstantPropagation.cpp; sourceTree = "<group>"; };
- DE66F15308ABEFB400323D32 /* LoopExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopExtractor.cpp; sourceTree = "<group>"; };
- DE66F15408ABEFB400323D32 /* LowerSetJmp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LowerSetJmp.cpp; sourceTree = "<group>"; };
- DE66F15608ABEFB400323D32 /* PruneEH.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PruneEH.cpp; sourceTree = "<group>"; };
- DE66F15708ABEFB400323D32 /* RaiseAllocations.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RaiseAllocations.cpp; sourceTree = "<group>"; };
- DE66F15808ABEFB400323D32 /* SimplifyLibCalls.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SimplifyLibCalls.cpp; sourceTree = "<group>"; };
- DE66F15908ABEFB400323D32 /* StripSymbols.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StripSymbols.cpp; sourceTree = "<group>"; };
- DE66F15E08ABEFB400323D32 /* ADCE.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ADCE.cpp; sourceTree = "<group>"; };
- DE66F15F08ABEFB400323D32 /* BasicBlockPlacement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BasicBlockPlacement.cpp; sourceTree = "<group>"; };
- DE66F16008ABEFB400323D32 /* CondPropagate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CondPropagate.cpp; sourceTree = "<group>"; };
- DE66F16108ABEFB400323D32 /* ConstantProp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantProp.cpp; sourceTree = "<group>"; };
- DE66F16308ABEFB400323D32 /* DCE.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DCE.cpp; sourceTree = "<group>"; };
- DE66F16408ABEFB400323D32 /* DeadStoreElimination.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeadStoreElimination.cpp; sourceTree = "<group>"; };
- DE66F1A308ABEFB400323D32 /* GCSE.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GCSE.cpp; sourceTree = "<group>"; };
- DE66F1A408ABEFB400323D32 /* IndVarSimplify.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IndVarSimplify.cpp; sourceTree = "<group>"; };
- DE66F1A508ABEFB400323D32 /* InstructionCombining.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstructionCombining.cpp; sourceTree = "<group>"; };
- DE66F1A608ABEFB400323D32 /* LICM.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LICM.cpp; sourceTree = "<group>"; };
- DE66F1A808ABEFB400323D32 /* LoopStrengthReduce.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopStrengthReduce.cpp; sourceTree = "<group>"; };
- DE66F1A908ABEFB400323D32 /* LoopUnroll.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopUnroll.cpp; sourceTree = "<group>"; };
- DE66F1AA08ABEFB400323D32 /* LoopUnswitch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopUnswitch.cpp; sourceTree = "<group>"; };
- DE66F1B508ABEFB400323D32 /* Reassociate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Reassociate.cpp; sourceTree = "<group>"; };
- DE66F1B608ABEFB400323D32 /* ScalarReplAggregates.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ScalarReplAggregates.cpp; sourceTree = "<group>"; };
- DE66F1B708ABEFB400323D32 /* SCCP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SCCP.cpp; sourceTree = "<group>"; };
- DE66F1B808ABEFB400323D32 /* SimplifyCFG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SimplifyCFG.cpp; sourceTree = "<group>"; };
- DE66F1B908ABEFB400323D32 /* TailDuplication.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TailDuplication.cpp; sourceTree = "<group>"; };
- DE66F1BA08ABEFB400323D32 /* TailRecursionElimination.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TailRecursionElimination.cpp; sourceTree = "<group>"; };
- DE66F1BE08ABEFB400323D32 /* BasicBlockUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BasicBlockUtils.cpp; sourceTree = "<group>"; };
- DE66F1BF08ABEFB400323D32 /* BreakCriticalEdges.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BreakCriticalEdges.cpp; sourceTree = "<group>"; };
- DE66F1C008ABEFB400323D32 /* CloneFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CloneFunction.cpp; sourceTree = "<group>"; };
- DE66F1C108ABEFB400323D32 /* CloneModule.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CloneModule.cpp; sourceTree = "<group>"; };
- DE66F1C208ABEFB400323D32 /* CloneTrace.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CloneTrace.cpp; sourceTree = "<group>"; };
- DE66F1C308ABEFB400323D32 /* CodeExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CodeExtractor.cpp; sourceTree = "<group>"; };
- DE66F1E008ABEFB400323D32 /* DemoteRegToStack.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DemoteRegToStack.cpp; sourceTree = "<group>"; };
- DE66F1E108ABEFB400323D32 /* InlineFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InlineFunction.cpp; sourceTree = "<group>"; };
- DE66F1E208ABEFB400323D32 /* Local.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Local.cpp; sourceTree = "<group>"; };
- DE66F1E408ABEFB400323D32 /* PromoteMemoryToRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PromoteMemoryToRegister.cpp; sourceTree = "<group>"; };
- DE66F1E508ABEFB400323D32 /* SimplifyCFG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SimplifyCFG.cpp; sourceTree = "<group>"; };
- DE66F1E608ABEFB400323D32 /* UnifyFunctionExitNodes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = UnifyFunctionExitNodes.cpp; sourceTree = "<group>"; };
- DE66F1E708ABEFB400323D32 /* ValueMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ValueMapper.cpp; sourceTree = "<group>"; };
- DE66F1EA08ABF03100323D32 /* AbstractTypeUser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AbstractTypeUser.h; sourceTree = "<group>"; };
- DE66F1EE08ABF03100323D32 /* DenseMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DenseMap.h; sourceTree = "<group>"; };
- DE66F1EF08ABF03100323D32 /* DepthFirstIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DepthFirstIterator.h; sourceTree = "<group>"; };
- DE66F1F008ABF03100323D32 /* EquivalenceClasses.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EquivalenceClasses.h; sourceTree = "<group>"; };
- DE66F1F108ABF03100323D32 /* GraphTraits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GraphTraits.h; sourceTree = "<group>"; };
- DE66F1F308ABF03100323D32 /* hash_map.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = hash_map.in; sourceTree = "<group>"; };
- DE66F1F508ABF03100323D32 /* hash_set.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = hash_set.in; sourceTree = "<group>"; };
- DE66F1F608ABF03100323D32 /* HashExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HashExtras.h; sourceTree = "<group>"; };
- DE66F1F708ABF03100323D32 /* ilist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ilist; sourceTree = "<group>"; };
- DE66F1F908ABF03100323D32 /* iterator.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = iterator.in; sourceTree = "<group>"; };
- DE66F1FA08ABF03100323D32 /* PostOrderIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PostOrderIterator.h; sourceTree = "<group>"; };
- DE66F1FB08ABF03100323D32 /* SCCIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCCIterator.h; sourceTree = "<group>"; };
- DE66F1FC08ABF03100323D32 /* SetOperations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SetOperations.h; sourceTree = "<group>"; };
- DE66F1FD08ABF03100323D32 /* SetVector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SetVector.h; sourceTree = "<group>"; };
- DE66F1FE08ABF03100323D32 /* Statistic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Statistic.h; sourceTree = "<group>"; };
- DE66F1FF08ABF03100323D32 /* STLExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = STLExtras.h; sourceTree = "<group>"; };
- DE66F20008ABF03100323D32 /* StringExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StringExtras.h; sourceTree = "<group>"; };
- DE66F20108ABF03100323D32 /* Tree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Tree.h; sourceTree = "<group>"; };
- DE66F20208ABF03100323D32 /* VectorExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VectorExtras.h; sourceTree = "<group>"; };
- DE66F20408ABF03100323D32 /* AliasAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AliasAnalysis.h; sourceTree = "<group>"; };
- DE66F20508ABF03100323D32 /* AliasSetTracker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AliasSetTracker.h; sourceTree = "<group>"; };
- DE66F20608ABF03100323D32 /* CallGraph.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CallGraph.h; sourceTree = "<group>"; };
- DE66F20708ABF03100323D32 /* CFGPrinter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFGPrinter.h; sourceTree = "<group>"; };
- DE66F20808ABF03100323D32 /* ConstantsScanner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ConstantsScanner.h; sourceTree = "<group>"; };
- DE66F20F08ABF03100323D32 /* Dominators.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Dominators.h; sourceTree = "<group>"; };
- DE66F21208ABF03100323D32 /* FindUsedTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FindUsedTypes.h; sourceTree = "<group>"; };
- DE66F21308ABF03100323D32 /* Interval.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Interval.h; sourceTree = "<group>"; };
- DE66F21408ABF03100323D32 /* IntervalIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntervalIterator.h; sourceTree = "<group>"; };
- DE66F21508ABF03100323D32 /* IntervalPartition.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntervalPartition.h; sourceTree = "<group>"; };
- DE66F21608ABF03100323D32 /* LoadValueNumbering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LoadValueNumbering.h; sourceTree = "<group>"; };
- DE66F21708ABF03100323D32 /* LoopInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LoopInfo.h; sourceTree = "<group>"; };
- DE66F21808ABF03100323D32 /* Passes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Passes.h; sourceTree = "<group>"; };
- DE66F21908ABF03100323D32 /* PostDominators.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PostDominators.h; sourceTree = "<group>"; };
- DE66F21A08ABF03100323D32 /* ProfileInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProfileInfo.h; sourceTree = "<group>"; };
- DE66F21B08ABF03100323D32 /* ProfileInfoLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProfileInfoLoader.h; sourceTree = "<group>"; };
- DE66F21C08ABF03100323D32 /* ProfileInfoTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProfileInfoTypes.h; sourceTree = "<group>"; };
- DE66F21D08ABF03100323D32 /* ScalarEvolution.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScalarEvolution.h; sourceTree = "<group>"; };
- DE66F21E08ABF03100323D32 /* ScalarEvolutionExpander.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScalarEvolutionExpander.h; sourceTree = "<group>"; };
- DE66F21F08ABF03100323D32 /* ScalarEvolutionExpressions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScalarEvolutionExpressions.h; sourceTree = "<group>"; };
- DE66F22008ABF03100323D32 /* Trace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Trace.h; sourceTree = "<group>"; };
- DE66F22108ABF03100323D32 /* ValueNumbering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ValueNumbering.h; sourceTree = "<group>"; };
- DE66F22208ABF03100323D32 /* Verifier.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Verifier.h; sourceTree = "<group>"; };
- DE66F22308ABF03100323D32 /* Argument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Argument.h; sourceTree = "<group>"; };
- DE66F22508ABF03100323D32 /* AsmAnnotationWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AsmAnnotationWriter.h; sourceTree = "<group>"; };
- DE66F22708ABF03100323D32 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = "<group>"; };
- DE66F22808ABF03100323D32 /* PrintModulePass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PrintModulePass.h; sourceTree = "<group>"; };
- DE66F22908ABF03100323D32 /* Writer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Writer.h; sourceTree = "<group>"; };
- DE66F22A08ABF03100323D32 /* BasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BasicBlock.h; sourceTree = "<group>"; };
- DE66F23308ABF03100323D32 /* CallGraphSCCPass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CallGraphSCCPass.h; sourceTree = "<group>"; };
- DE66F23408ABF03100323D32 /* CallingConv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CallingConv.h; sourceTree = "<group>"; };
- DE66F23608ABF03100323D32 /* AsmPrinter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AsmPrinter.h; sourceTree = "<group>"; };
- DE66F23908ABF03100323D32 /* IntrinsicLowering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntrinsicLowering.h; sourceTree = "<group>"; };
- DE66F23A08ABF03100323D32 /* LiveVariables.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LiveVariables.h; sourceTree = "<group>"; };
- DE66F23B08ABF03100323D32 /* MachineBasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineBasicBlock.h; sourceTree = "<group>"; };
- DE66F23C08ABF03100323D32 /* MachineCodeEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineCodeEmitter.h; sourceTree = "<group>"; };
- DE66F23D08ABF03100323D32 /* MachineConstantPool.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineConstantPool.h; sourceTree = "<group>"; };
- DE66F23E08ABF03100323D32 /* MachineFrameInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineFrameInfo.h; sourceTree = "<group>"; };
- DE66F23F08ABF03100323D32 /* MachineFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineFunction.h; sourceTree = "<group>"; };
- DE66F24008ABF03100323D32 /* MachineFunctionPass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineFunctionPass.h; sourceTree = "<group>"; };
- DE66F24108ABF03100323D32 /* MachineInstr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineInstr.h; sourceTree = "<group>"; };
- DE66F24208ABF03100323D32 /* MachineInstrBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineInstrBuilder.h; sourceTree = "<group>"; };
- DE66F24308ABF03100323D32 /* MachineRelocation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachineRelocation.h; sourceTree = "<group>"; };
- DE66F24408ABF03100323D32 /* Passes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Passes.h; sourceTree = "<group>"; };
- DE66F24508ABF03100323D32 /* SchedGraphCommon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SchedGraphCommon.h; sourceTree = "<group>"; };
- DE66F24608ABF03100323D32 /* SelectionDAG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SelectionDAG.h; sourceTree = "<group>"; };
- DE66F24708ABF03100323D32 /* SelectionDAGISel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SelectionDAGISel.h; sourceTree = "<group>"; };
- DE66F24808ABF03100323D32 /* SelectionDAGNodes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SelectionDAGNodes.h; sourceTree = "<group>"; };
- DE66F24B08ABF03100323D32 /* ValueTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ValueTypes.h; sourceTree = "<group>"; };
- DE66F24E08ABF03100323D32 /* alloca.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = alloca.h; sourceTree = "<group>"; };
- DE66F25008ABF03100323D32 /* config.h.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = config.h.in; sourceTree = "<group>"; };
- DE66F25108ABF03100323D32 /* Constant.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Constant.h; sourceTree = "<group>"; };
- DE66F25208ABF03100323D32 /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = "<group>"; };
- DE66F25408ABF03100323D32 /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Debugger.h; sourceTree = "<group>"; };
- DE66F25508ABF03100323D32 /* InferiorProcess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InferiorProcess.h; sourceTree = "<group>"; };
- DE66F25608ABF03100323D32 /* ProgramInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProgramInfo.h; sourceTree = "<group>"; };
- DE66F25708ABF03100323D32 /* RuntimeInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RuntimeInfo.h; sourceTree = "<group>"; };
- DE66F25808ABF03100323D32 /* SourceFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SourceFile.h; sourceTree = "<group>"; };
- DE66F25908ABF03100323D32 /* SourceLanguage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SourceLanguage.h; sourceTree = "<group>"; };
- DE66F25A08ABF03100323D32 /* DerivedTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DerivedTypes.h; sourceTree = "<group>"; };
- DE66F25C08ABF03100323D32 /* ExecutionEngine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ExecutionEngine.h; sourceTree = "<group>"; };
- DE66F25D08ABF03100323D32 /* GenericValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GenericValue.h; sourceTree = "<group>"; };
- DE66F25E08ABF03100323D32 /* Function.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Function.h; sourceTree = "<group>"; };
- DE66F25F08ABF03100323D32 /* GlobalValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GlobalValue.h; sourceTree = "<group>"; };
- DE66F26008ABF03100323D32 /* GlobalVariable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GlobalVariable.h; sourceTree = "<group>"; };
- DE66F26108ABF03100323D32 /* InstrTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstrTypes.h; sourceTree = "<group>"; };
- DE66F26208ABF03100323D32 /* Instruction.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Instruction.def; sourceTree = "<group>"; };
- DE66F26308ABF03100323D32 /* Instruction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Instruction.h; sourceTree = "<group>"; };
- DE66F26408ABF03100323D32 /* Instructions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Instructions.h; sourceTree = "<group>"; };
- DE66F26508ABF03100323D32 /* IntrinsicInst.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntrinsicInst.h; sourceTree = "<group>"; };
- DE66F26608ABF03100323D32 /* Intrinsics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Intrinsics.h; sourceTree = "<group>"; };
- DE66F26708ABF03100323D32 /* Linker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Linker.h; sourceTree = "<group>"; };
- DE66F26808ABF03100323D32 /* Module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Module.h; sourceTree = "<group>"; };
- DE66F26908ABF03200323D32 /* ModuleProvider.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ModuleProvider.h; sourceTree = "<group>"; };
- DE66F26A08ABF03200323D32 /* Pass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Pass.h; sourceTree = "<group>"; };
- DE66F26B08ABF03200323D32 /* PassAnalysisSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PassAnalysisSupport.h; sourceTree = "<group>"; };
- DE66F26C08ABF03200323D32 /* PassManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PassManager.h; sourceTree = "<group>"; };
- DE66F26D08ABF03200323D32 /* PassSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PassSupport.h; sourceTree = "<group>"; };
- DE66F27008ABF03200323D32 /* AIXDataTypesFix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AIXDataTypesFix.h; sourceTree = "<group>"; };
- DE66F27108ABF03200323D32 /* Annotation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Annotation.h; sourceTree = "<group>"; };
- DE66F27208ABF03200323D32 /* CallSite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CallSite.h; sourceTree = "<group>"; };
- DE66F27308ABF03200323D32 /* Casting.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Casting.h; sourceTree = "<group>"; };
- DE66F27408ABF03200323D32 /* CFG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFG.h; sourceTree = "<group>"; };
- DE66F27508ABF03200323D32 /* CommandLine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommandLine.h; sourceTree = "<group>"; };
- DE66F27708ABF03200323D32 /* ConstantRange.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ConstantRange.h; sourceTree = "<group>"; };
- DE66F27908ABF03200323D32 /* DataTypes.h.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = DataTypes.h.in; sourceTree = "<group>"; };
- DE66F27A08ABF03200323D32 /* Debug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Debug.h; sourceTree = "<group>"; };
- DE66F27B08ABF03200323D32 /* DOTGraphTraits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOTGraphTraits.h; sourceTree = "<group>"; };
- DE66F27C08ABF03200323D32 /* DynamicLinker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DynamicLinker.h; sourceTree = "<group>"; };
- DE66F27D08ABF03200323D32 /* ELF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ELF.h; sourceTree = "<group>"; };
- DE66F27E08ABF03200323D32 /* FileUtilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FileUtilities.h; sourceTree = "<group>"; };
- DE66F27F08ABF03200323D32 /* GetElementPtrTypeIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GetElementPtrTypeIterator.h; sourceTree = "<group>"; };
- DE66F28008ABF03200323D32 /* GraphWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GraphWriter.h; sourceTree = "<group>"; };
- DE66F28108ABF03200323D32 /* InstIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstIterator.h; sourceTree = "<group>"; };
- DE66F28208ABF03200323D32 /* InstVisitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstVisitor.h; sourceTree = "<group>"; };
- DE66F28308ABF03200323D32 /* LeakDetector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LeakDetector.h; sourceTree = "<group>"; };
- DE66F28408ABF03200323D32 /* Mangler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Mangler.h; sourceTree = "<group>"; };
- DE66F28508ABF03200323D32 /* MathExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MathExtras.h; sourceTree = "<group>"; };
- DE66F28608ABF03200323D32 /* MutexGuard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MutexGuard.h; sourceTree = "<group>"; };
- DE66F28708ABF03200323D32 /* PassNameParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PassNameParser.h; sourceTree = "<group>"; };
- DE66F28808ABF03200323D32 /* PatternMatch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PatternMatch.h; sourceTree = "<group>"; };
- DE66F28908ABF03200323D32 /* PluginLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PluginLoader.h; sourceTree = "<group>"; };
- DE66F28A08ABF03200323D32 /* SlowOperationInformer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SlowOperationInformer.h; sourceTree = "<group>"; };
- DE66F28B08ABF03200323D32 /* StableBasicBlockNumbering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StableBasicBlockNumbering.h; sourceTree = "<group>"; };
- DE66F28C08ABF03200323D32 /* SystemUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SystemUtils.h; sourceTree = "<group>"; };
- DE66F28E08ABF03200323D32 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; };
- DE66F29008ABF03200323D32 /* type_traits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = type_traits.h; sourceTree = "<group>"; };
- DE66F29308ABF03200323D32 /* SymbolTableListTraits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SymbolTableListTraits.h; sourceTree = "<group>"; };
- DE66F29508ABF03200323D32 /* DynamicLibrary.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DynamicLibrary.h; sourceTree = "<group>"; };
- DE66F29608ABF03200323D32 /* LICENSE.TXT */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = LICENSE.TXT; sourceTree = "<group>"; };
- DE66F29708ABF03200323D32 /* MappedFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MappedFile.h; sourceTree = "<group>"; };
- DE66F29808ABF03200323D32 /* Memory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Memory.h; sourceTree = "<group>"; };
- DE66F29908ABF03200323D32 /* Mutex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Mutex.h; sourceTree = "<group>"; };
- DE66F29A08ABF03200323D32 /* Path.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Path.h; sourceTree = "<group>"; };
- DE66F29B08ABF03200323D32 /* Process.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Process.h; sourceTree = "<group>"; };
- DE66F29C08ABF03200323D32 /* Program.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Program.h; sourceTree = "<group>"; };
- DE66F29D08ABF03200323D32 /* Signals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Signals.h; sourceTree = "<group>"; };
- DE66F29E08ABF03200323D32 /* TimeValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TimeValue.h; sourceTree = "<group>"; };
- DE66F2A008ABF03200323D32 /* TargetRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetRegisterInfo.h; sourceTree = "<group>"; };
- DE66F2A108ABF03200323D32 /* TargetData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetData.h; sourceTree = "<group>"; };
- DE66F2A208ABF03200323D32 /* TargetFrameInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetFrameInfo.h; sourceTree = "<group>"; };
- DE66F2A308ABF03200323D32 /* TargetInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetInstrInfo.h; sourceTree = "<group>"; };
- DE66F2A408ABF03200323D32 /* TargetJITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetJITInfo.h; sourceTree = "<group>"; };
- DE66F2A508ABF03200323D32 /* TargetLowering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetLowering.h; sourceTree = "<group>"; };
- DE66F2A608ABF03200323D32 /* TargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetMachine.h; sourceTree = "<group>"; };
- DE66F2A708ABF03200323D32 /* TargetMachineRegistry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetMachineRegistry.h; sourceTree = "<group>"; };
- DE66F2A808ABF03200323D32 /* TargetOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetOptions.h; sourceTree = "<group>"; };
- DE66F2AA08ABF03200323D32 /* TargetSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetSubtarget.h; sourceTree = "<group>"; };
- DE66F2AC08ABF03200323D32 /* Instrumentation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Instrumentation.h; sourceTree = "<group>"; };
- DE66F2AD08ABF03200323D32 /* IPO.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IPO.h; sourceTree = "<group>"; };
- DE66F2AF08ABF03200323D32 /* Scalar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Scalar.h; sourceTree = "<group>"; };
- DE66F2B108ABF03200323D32 /* BasicBlockUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BasicBlockUtils.h; sourceTree = "<group>"; };
- DE66F2B208ABF03200323D32 /* Cloning.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Cloning.h; sourceTree = "<group>"; };
- DE66F2B308ABF03200323D32 /* FunctionUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FunctionUtils.h; sourceTree = "<group>"; };
- DE66F2B408ABF03200323D32 /* Local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Local.h; sourceTree = "<group>"; };
- DE66F2B508ABF03200323D32 /* PromoteMemToReg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PromoteMemToReg.h; sourceTree = "<group>"; };
- DE66F2B608ABF03200323D32 /* UnifyFunctionExitNodes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = UnifyFunctionExitNodes.h; sourceTree = "<group>"; };
- DE66F2B708ABF03200323D32 /* Type.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Type.h; sourceTree = "<group>"; };
- DE66F2B808ABF03200323D32 /* Use.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Use.h; sourceTree = "<group>"; };
- DE66F2B908ABF03200323D32 /* User.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = User.h; sourceTree = "<group>"; };
- DE66F2BA08ABF03200323D32 /* Value.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Value.h; sourceTree = "<group>"; };
- DE66F2CC08ABF14400323D32 /* BugDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BugDriver.cpp; sourceTree = "<group>"; };
- DE66F2CD08ABF14400323D32 /* BugDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BugDriver.h; sourceTree = "<group>"; };
- DE66F2CE08ABF14400323D32 /* bugpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = bugpoint.cpp; sourceTree = "<group>"; };
- DE66F2CF08ABF14400323D32 /* CrashDebugger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CrashDebugger.cpp; sourceTree = "<group>"; };
- DE66F2E208ABF14400323D32 /* ExecutionDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionDriver.cpp; sourceTree = "<group>"; };
- DE66F2E308ABF14400323D32 /* ExtractFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ExtractFunction.cpp; sourceTree = "<group>"; };
- DE66F2E408ABF14400323D32 /* ListReducer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListReducer.h; sourceTree = "<group>"; };
- DE66F2E608ABF14400323D32 /* Miscompilation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Miscompilation.cpp; sourceTree = "<group>"; };
- DE66F2E708ABF14400323D32 /* OptimizerDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = OptimizerDriver.cpp; sourceTree = "<group>"; };
- DE66F2E808ABF14400323D32 /* TestPasses.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TestPasses.cpp; sourceTree = "<group>"; };
- DE66F30008ABF14400323D32 /* llc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = llc.cpp; path = llc/llc.cpp; sourceTree = "<group>"; };
- DE66F30708ABF14400323D32 /* lli.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lli.cpp; path = lli/lli.cpp; sourceTree = "<group>"; };
- DE66F30E08ABF14400323D32 /* llvm-ar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-ar.cpp"; path = "llvm-ar/llvm-ar.cpp"; sourceTree = "<group>"; };
- DE66F31508ABF14400323D32 /* llvm-as.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-as.cpp"; path = "llvm-as/llvm-as.cpp"; sourceTree = "<group>"; };
- DE66F31C08ABF14400323D32 /* llvm-bcanalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-bcanalyzer.cpp"; path = "llvm-bcanalyzer/llvm-bcanalyzer.cpp"; sourceTree = "<group>"; };
- DE66F31F08ABF14400323D32 /* CLICommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLICommand.h; sourceTree = "<group>"; };
- DE66F32008ABF14400323D32 /* CLIDebugger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLIDebugger.cpp; sourceTree = "<group>"; };
- DE66F32108ABF14400323D32 /* CLIDebugger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLIDebugger.h; sourceTree = "<group>"; };
- DE66F32208ABF14400323D32 /* Commands.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Commands.cpp; sourceTree = "<group>"; };
- DE66F32B08ABF14400323D32 /* llvm-db.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "llvm-db.cpp"; sourceTree = "<group>"; };
- DE66F33208ABF14400323D32 /* llvm-dis.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-dis.cpp"; path = "llvm-dis/llvm-dis.cpp"; sourceTree = "<group>"; };
- DE66F33908ABF14400323D32 /* llvm-extract.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-extract.cpp"; path = "llvm-extract/llvm-extract.cpp"; sourceTree = "<group>"; };
- DE66F34208ABF14400323D32 /* llvm-ld.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "llvm-ld.cpp"; sourceTree = "<group>"; };
- DE66F34408ABF14400323D32 /* Optimize.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Optimize.cpp; sourceTree = "<group>"; };
- DE66F34A08ABF14400323D32 /* llvm-link.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-link.cpp"; path = "llvm-link/llvm-link.cpp"; sourceTree = "<group>"; };
- DE66F35108ABF14400323D32 /* llvm-nm.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-nm.cpp"; path = "llvm-nm/llvm-nm.cpp"; sourceTree = "<group>"; };
- DE66F35808ABF14500323D32 /* llvm-prof.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-prof.cpp"; path = "llvm-prof/llvm-prof.cpp"; sourceTree = "<group>"; };
- DE66F35F08ABF14500323D32 /* llvm-ranlib.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "llvm-ranlib.cpp"; path = "llvm-ranlib/llvm-ranlib.cpp"; sourceTree = "<group>"; };
- DE66F36908ABF14500323D32 /* c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = c; sourceTree = "<group>"; };
- DE66F36A08ABF14500323D32 /* CompilerDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CompilerDriver.cpp; sourceTree = "<group>"; };
- DE66F36B08ABF14500323D32 /* CompilerDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CompilerDriver.h; sourceTree = "<group>"; };
- DE66F36D08ABF14500323D32 /* ConfigLexer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ConfigLexer.h; sourceTree = "<group>"; };
- DE66F36E08ABF14500323D32 /* ConfigLexer.l */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.lex; path = ConfigLexer.l; sourceTree = "<group>"; };
- DE66F36F08ABF14500323D32 /* Configuration.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Configuration.cpp; sourceTree = "<group>"; };
- DE66F37008ABF14500323D32 /* Configuration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Configuration.h; sourceTree = "<group>"; };
- DE66F37108ABF14500323D32 /* cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = cpp; sourceTree = "<group>"; };
- DE66F37D08ABF14500323D32 /* ll */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ll; sourceTree = "<group>"; };
- DE66F37E08ABF14500323D32 /* llvmc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvmc.cpp; sourceTree = "<group>"; };
- DE66F38C08ABF35300323D32 /* CREDITS.TXT */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = CREDITS.TXT; path = ../CREDITS.TXT; sourceTree = SOURCE_ROOT; };
- DE66F38F08ABF35C00323D32 /* AliasAnalysis.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = AliasAnalysis.html; sourceTree = "<group>"; };
- DE66F39008ABF35C00323D32 /* Bugpoint.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = Bugpoint.html; sourceTree = "<group>"; };
- DE66F39208ABF35C00323D32 /* GCCFEBuildInstrs.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = GCCFEBuildInstrs.html; sourceTree = "<group>"; };
- DE66F39308ABF35C00323D32 /* CodeGenerator.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = CodeGenerator.html; sourceTree = "<group>"; };
- DE66F39408ABF35C00323D32 /* CodingStandards.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = CodingStandards.html; sourceTree = "<group>"; };
- DE66F39808ABF35C00323D32 /* bugpoint.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = bugpoint.pod; sourceTree = "<group>"; };
- DE66F39E08ABF35C00323D32 /* index.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = index.html; sourceTree = "<group>"; };
- DE66F39F08ABF35C00323D32 /* llc.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llc.pod; sourceTree = "<group>"; };
- DE66F3A008ABF35C00323D32 /* lli.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = lli.pod; sourceTree = "<group>"; };
- DE66F3A108ABF35C00323D32 /* llvm-ar.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-ar.pod"; sourceTree = "<group>"; };
- DE66F3A208ABF35C00323D32 /* llvm-as.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-as.pod"; sourceTree = "<group>"; };
- DE66F3A308ABF35C00323D32 /* llvm-bcanalyzer.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-bcanalyzer.pod"; sourceTree = "<group>"; };
- DE66F3A408ABF35C00323D32 /* llvm-db.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-db.pod"; sourceTree = "<group>"; };
- DE66F3A508ABF35C00323D32 /* llvm-dis.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-dis.pod"; sourceTree = "<group>"; };
- DE66F3A608ABF35C00323D32 /* llvm-extract.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-extract.pod"; sourceTree = "<group>"; };
- DE66F3A708ABF35C00323D32 /* llvm-ld.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-ld.pod"; sourceTree = "<group>"; };
- DE66F3A808ABF35C00323D32 /* llvm-link.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-link.pod"; sourceTree = "<group>"; };
- DE66F3A908ABF35C00323D32 /* llvm-nm.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-nm.pod"; sourceTree = "<group>"; };
- DE66F3AA08ABF35C00323D32 /* llvm-prof.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-prof.pod"; sourceTree = "<group>"; };
- DE66F3AB08ABF35C00323D32 /* llvm-ranlib.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "llvm-ranlib.pod"; sourceTree = "<group>"; };
- DE66F3AC08ABF35C00323D32 /* llvmc.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvmc.pod; sourceTree = "<group>"; };
- DE66F3AD08ABF35C00323D32 /* llvmgcc.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvmgcc.pod; sourceTree = "<group>"; };
- DE66F3AE08ABF35C00323D32 /* llvmgxx.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvmgxx.pod; sourceTree = "<group>"; };
- DE66F3AF08ABF35C00323D32 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
- DE66F3B408ABF35D00323D32 /* manpage.css */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = manpage.css; sourceTree = "<group>"; };
- DE66F3B508ABF35D00323D32 /* opt.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = opt.pod; sourceTree = "<group>"; };
- DE66F3B808ABF35D00323D32 /* stkrc.pod */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = stkrc.pod; sourceTree = "<group>"; };
- DE66F3B908ABF35D00323D32 /* CommandLine.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = CommandLine.html; sourceTree = "<group>"; };
- DE66F3BA08ABF35D00323D32 /* CompilerDriver.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = CompilerDriver.html; sourceTree = "<group>"; };
- DE66F3BB08ABF35D00323D32 /* CompilerWriterInfo.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = CompilerWriterInfo.html; sourceTree = "<group>"; };
- DE66F3BD08ABF35D00323D32 /* doxygen.cfg.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = doxygen.cfg.in; sourceTree = "<group>"; };
- DE66F3BE08ABF35D00323D32 /* doxygen.css */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = doxygen.css; sourceTree = "<group>"; };
- DE66F3BF08ABF35D00323D32 /* doxygen.footer */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = doxygen.footer; sourceTree = "<group>"; };
- DE66F3C008ABF35D00323D32 /* doxygen.header */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = doxygen.header; sourceTree = "<group>"; };
- DE66F3C108ABF35D00323D32 /* doxygen.intro */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = doxygen.intro; sourceTree = "<group>"; };
- DE66F3C208ABF35D00323D32 /* ExtendingLLVM.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = ExtendingLLVM.html; sourceTree = "<group>"; };
- DE66F3C308ABF35D00323D32 /* FAQ.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = FAQ.html; sourceTree = "<group>"; };
- DE66F3C408ABF35D00323D32 /* GarbageCollection.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = GarbageCollection.html; sourceTree = "<group>"; };
- DE66F3C508ABF35D00323D32 /* GettingStarted.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = GettingStarted.html; sourceTree = "<group>"; };
- DE66F3C608ABF35D00323D32 /* GettingStartedVS.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = GettingStartedVS.html; sourceTree = "<group>"; };
- DE66F3E408ABF35D00323D32 /* HowToSubmitABug.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = HowToSubmitABug.html; sourceTree = "<group>"; };
- DE66F3E608ABF35D00323D32 /* Debugging.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = Debugging.gif; sourceTree = "<group>"; };
- DE66F3E708ABF35D00323D32 /* libdeps.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = libdeps.gif; sourceTree = "<group>"; };
- DE66F3E808ABF35D00323D32 /* lines.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = lines.gif; sourceTree = "<group>"; };
- DE66F3E908ABF35D00323D32 /* objdeps.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = objdeps.gif; sourceTree = "<group>"; };
- DE66F3EA08ABF35D00323D32 /* venusflytrap.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = venusflytrap.jpg; sourceTree = "<group>"; };
- DE66F3EB08ABF35D00323D32 /* index.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = index.html; sourceTree = "<group>"; };
- DE66F3EC08ABF35D00323D32 /* LangRef.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = LangRef.html; sourceTree = "<group>"; };
- DE66F3ED08ABF35D00323D32 /* Lexicon.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = Lexicon.html; sourceTree = "<group>"; };
- DE66F3EE08ABF35D00323D32 /* llvm.css */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm.css; sourceTree = "<group>"; };
- DE66F3F108ABF35D00323D32 /* MakefileGuide.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = MakefileGuide.html; sourceTree = "<group>"; };
- DE66F3F208ABF35D00323D32 /* ProgrammersManual.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = ProgrammersManual.html; sourceTree = "<group>"; };
- DE66F3F308ABF35D00323D32 /* Projects.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = Projects.html; sourceTree = "<group>"; };
- DE66F3F408ABF35D00323D32 /* ReleaseNotes.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = ReleaseNotes.html; sourceTree = "<group>"; };
- DE66F3F508ABF35D00323D32 /* SourceLevelDebugging.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = SourceLevelDebugging.html; sourceTree = "<group>"; };
- DE66F3F708ABF35D00323D32 /* SystemLibrary.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = SystemLibrary.html; sourceTree = "<group>"; };
- DE66F3F808ABF35D00323D32 /* TableGenFundamentals.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = TableGenFundamentals.html; sourceTree = "<group>"; };
- DE66F3F908ABF35D00323D32 /* TestingGuide.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = TestingGuide.html; sourceTree = "<group>"; };
- DE66F3FA08ABF35D00323D32 /* UsingLibraries.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = UsingLibraries.html; sourceTree = "<group>"; };
- DE66F3FB08ABF35D00323D32 /* WritingAnLLVMBackend.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = WritingAnLLVMBackend.html; sourceTree = "<group>"; };
- DE66F3FC08ABF35D00323D32 /* WritingAnLLVMPass.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = WritingAnLLVMPass.html; sourceTree = "<group>"; };
- DE66F40E08ABF37000323D32 /* fibonacci.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = fibonacci.cpp; path = Fibonacci/fibonacci.cpp; sourceTree = "<group>"; };
- DE66F41508ABF37000323D32 /* HowToUseJIT.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HowToUseJIT.cpp; path = HowToUseJIT/HowToUseJIT.cpp; sourceTree = "<group>"; };
- DE66F41E08ABF37000323D32 /* ModuleMaker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleMaker.cpp; path = ModuleMaker/ModuleMaker.cpp; sourceTree = "<group>"; };
- DE66F42608ABF37000323D32 /* ParallelJIT.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParallelJIT.cpp; path = ParallelJIT/ParallelJIT.cpp; sourceTree = "<group>"; };
- DE694D9F08B51E0C0039C106 /* ScheduleDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ScheduleDAG.cpp; sourceTree = "<group>"; };
- DE81704008CFB44D0093BDEF /* fpcmp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = fpcmp.cpp; path = fpcmp/fpcmp.cpp; sourceTree = "<group>"; };
- DE81704F08CFB44D0093BDEF /* NightlyTest.gnuplot */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = NightlyTest.gnuplot; sourceTree = "<group>"; };
- DE81705108CFB44D0093BDEF /* NightlyTestTemplate.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 30; path = NightlyTestTemplate.html; sourceTree = "<group>"; };
- DE81705908CFB44D0093BDEF /* AsmWriterEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AsmWriterEmitter.cpp; sourceTree = "<group>"; };
- DE81705A08CFB44D0093BDEF /* AsmWriterEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AsmWriterEmitter.h; sourceTree = "<group>"; };
- DE81705B08CFB44D0093BDEF /* CodeEmitterGen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CodeEmitterGen.cpp; sourceTree = "<group>"; };
- DE81705C08CFB44D0093BDEF /* CodeEmitterGen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeEmitterGen.h; sourceTree = "<group>"; };
- DE81705D08CFB44D0093BDEF /* CodeGenInstruction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeGenInstruction.h; sourceTree = "<group>"; };
- DE81705E08CFB44D0093BDEF /* CodeGenRegisters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeGenRegisters.h; sourceTree = "<group>"; };
- DE81705F08CFB44D0093BDEF /* CodeGenTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenTarget.cpp; sourceTree = "<group>"; };
- DE81706008CFB44D0093BDEF /* CodeGenTarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CodeGenTarget.h; sourceTree = "<group>"; };
- DE81706708CFB44D0093BDEF /* DAGISelEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DAGISelEmitter.cpp; sourceTree = "<group>"; };
- DE81706808CFB44D0093BDEF /* DAGISelEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DAGISelEmitter.h; sourceTree = "<group>"; };
- DE81708908CFB44D0093BDEF /* InstrInfoEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstrInfoEmitter.cpp; sourceTree = "<group>"; };
- DE81708A08CFB44D0093BDEF /* InstrInfoEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstrInfoEmitter.h; sourceTree = "<group>"; };
- DE81708E08CFB44D0093BDEF /* Record.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Record.cpp; sourceTree = "<group>"; };
- DE81708F08CFB44D0093BDEF /* Record.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Record.h; sourceTree = "<group>"; };
- DE81709008CFB44D0093BDEF /* RegisterInfoEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterInfoEmitter.cpp; sourceTree = "<group>"; };
- DE81709108CFB44D0093BDEF /* RegisterInfoEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RegisterInfoEmitter.h; sourceTree = "<group>"; };
- DE8170AA08CFB44D0093BDEF /* TableGen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGen.cpp; sourceTree = "<group>"; };
- DE8170AB08CFB44D0093BDEF /* TableGenBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGenBackend.cpp; sourceTree = "<group>"; };
- DE8170AC08CFB44D0093BDEF /* TableGenBackend.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TableGenBackend.h; sourceTree = "<group>"; };
- DEFAB19D0959E9A100E0AB42 /* DwarfWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DwarfWriter.h; path = ../include/llvm/CodeGen/DwarfWriter.h; sourceTree = SOURCE_ROOT; };
- F22627320DAE34D10008F441 /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
- F22627330DAE34D20008F441 /* JITTutorial1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = JITTutorial1.html; sourceTree = "<group>"; };
- F22627340DAE34D20008F441 /* JITTutorial2-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "JITTutorial2-1.png"; sourceTree = "<group>"; };
- F22627350DAE34D20008F441 /* JITTutorial2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = JITTutorial2.html; sourceTree = "<group>"; };
- F22627360DAE34D20008F441 /* LangImpl1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl1.html; sourceTree = "<group>"; };
- F22627370DAE34D20008F441 /* LangImpl2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl2.html; sourceTree = "<group>"; };
- F22627380DAE34D20008F441 /* LangImpl3.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl3.html; sourceTree = "<group>"; };
- F22627390DAE34D20008F441 /* LangImpl4.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl4.html; sourceTree = "<group>"; };
- F226273A0DAE34D20008F441 /* LangImpl5-cfg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "LangImpl5-cfg.png"; sourceTree = "<group>"; };
- F226273B0DAE34D20008F441 /* LangImpl5.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl5.html; sourceTree = "<group>"; };
- F226273C0DAE34D20008F441 /* LangImpl6.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl6.html; sourceTree = "<group>"; };
- F226273D0DAE34D20008F441 /* LangImpl7.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl7.html; sourceTree = "<group>"; };
- F226273E0DAE34D20008F441 /* LangImpl8.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LangImpl8.html; sourceTree = "<group>"; };
- F226273F0DAE34D20008F441 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
- F22627400DAE34D20008F441 /* OCamlLangImpl1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OCamlLangImpl1.html; sourceTree = "<group>"; };
- F22627410DAE34D20008F441 /* OCamlLangImpl2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OCamlLangImpl2.html; sourceTree = "<group>"; };
- F22627420DAE34D20008F441 /* OCamlLangImpl3.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OCamlLangImpl3.html; sourceTree = "<group>"; };
- F22627430DAE34D20008F441 /* OCamlLangImpl4.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OCamlLangImpl4.html; sourceTree = "<group>"; };
- F22627440DAE34D20008F441 /* OCamlLangImpl5.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OCamlLangImpl5.html; sourceTree = "<group>"; };
- F22627450DAE34D20008F441 /* OCamlLangImpl6.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OCamlLangImpl6.html; sourceTree = "<group>"; };
- F22627460DAE34D20008F441 /* OCamlLangImpl7.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OCamlLangImpl7.html; sourceTree = "<group>"; };
- F22761DF0DAD09CD003D8065 /* BrainF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BrainF.cpp; path = BrainF/BrainF.cpp; sourceTree = "<group>"; };
- F22761E00DAD09CD003D8065 /* BrainF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrainF.h; path = BrainF/BrainF.h; sourceTree = "<group>"; };
- F22761E10DAD09CD003D8065 /* BrainFDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BrainFDriver.cpp; path = BrainF/BrainFDriver.cpp; sourceTree = "<group>"; };
- F27C8CE90DAD2EF900A33844 /* IRBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IRBuilder.h; sourceTree = "<group>"; };
- F27C8CFF0DAD307700A33844 /* ShadowStackCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowStackCollector.cpp; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXGroup section */
- 08FB7794FE84155DC02AAC07 /* LLVM */ = {
- isa = PBXGroup;
- children = (
- DE66F1E908ABF03100323D32 /* include/llvm */,
- CF8F1B480B64F7AB00BB4199 /* include/llvm-c */,
- DE66ECBD08ABEC0700323D32 /* lib/Analysis */,
- 9FE450DE0C77ABE400C4FEA4 /* lib/Archive */,
- DE66EC8808ABEAC900323D32 /* lib/AsmParser */,
- 9F68EB030C77AD2C004AA152 /* lib/Bitcode */,
- DE66ED3E08ABEC2A00323D32 /* lib/CodeGen */,
- DE66ED9A08ABEC7200323D32 /* lib/Debugger */,
- DE66EDBF08ABEC8F00323D32 /* lib/ExecutionEngine */,
- DE66EDEB08ABEDD300323D32 /* lib/Linker */,
- DE66EDFB08ABEDE600323D32 /* lib/Support */,
- DE66EE4908ABEE3400323D32 /* lib/System */,
- DE66EE9608ABEE5D00323D32 /* lib/Target */,
- DE66F0E108ABEFB300323D32 /* lib/Transforms */,
- DE66EC7508ABE8EF00323D32 /* lib/VMCore */,
- DE66F2BD08ABF14400323D32 /* tools */,
- DE816FAC08CFB44C0093BDEF /* utils */,
- DE66F38D08ABF35C00323D32 /* docs */,
- 9FD3E56D0CA0116100E54D15 /* bindings */,
- 9F7C2B690CB9496B00498408 /* test */,
- DE66F3FD08ABF37000323D32 /* examples */,
- DE66F38C08ABF35300323D32 /* CREDITS.TXT */,
- CFD99AA80AFE827B0068D19C /* LICENSE.TXT */,
- CFD99AAD0AFE827B0068D19C /* README.txt */,
- 721CA1750D0B44D200D5004F /* Products */,
- );
- name = LLVM;
- sourceTree = "<group>";
- };
- 721CA1750D0B44D200D5004F /* Products */ = {
- isa = PBXGroup;
- children = (
- );
- name = Products;
- sourceTree = "<group>";
- };
- 9F4B0E5D0D0E02580061F270 /* bitreader */ = {
- isa = PBXGroup;
- children = (
- 9F4B0E5E0D0E02580061F270 /* bitreader_ocaml.c */,
- 9F4B0E5F0D0E02580061F270 /* llvm_bitreader.ml */,
- 9F4B0E600D0E02580061F270 /* llvm_bitreader.mli */,
- );
- path = bitreader;
- sourceTree = "<group>";
- };
- 9F502ACD0D1D8CA3007939DF /* executionengine */ = {
- isa = PBXGroup;
- children = (
- 9F502ADB0D1D8CA3007939DF /* executionengine_ocaml.c */,
- 9F502ADC0D1D8CA3007939DF /* llvm_executionengine.ml */,
- 9F502ADD0D1D8CA3007939DF /* llvm_executionengine.mli */,
- );
- path = executionengine;
- sourceTree = "<group>";
- };
- 9F68EB030C77AD2C004AA152 /* lib/Bitcode */ = {
- isa = PBXGroup;
- children = (
- 9F68EB050C77AD2C004AA152 /* Reader */,
- 9F68EB110C77AD2C004AA152 /* Writer */,
- );
- name = lib/Bitcode;
- path = ../lib/Bitcode;
- sourceTree = SOURCE_ROOT;
- };
- 9F68EB050C77AD2C004AA152 /* Reader */ = {
- isa = PBXGroup;
- children = (
- 35A9CDF00CD0F6D5008ABC1D /* Deserialize.cpp */,
- 9F4B0E8D0D0E05ED0061F270 /* DeserializeAPFloat.cpp */,
- 354CF6D10CD299440059AF3E /* DeserializeAPInt.cpp */,
- 9F68EB060C77AD2C004AA152 /* BitcodeReader.cpp */,
- 9F68EB070C77AD2C004AA152 /* BitcodeReader.h */,
- 9F4B0E8C0D0E05ED0061F270 /* BitReader.cpp */,
- );
- path = Reader;
- sourceTree = "<group>";
- };
- 9F68EB110C77AD2C004AA152 /* Writer */ = {
- isa = PBXGroup;
- children = (
- 354CF6D20CD2994D0059AF3E /* SerializeAPInt.cpp */,
- 9FD3E5920CA012B300E54D15 /* BitWriter.cpp */,
- 9F68EB120C77AD2C004AA152 /* BitcodeWriter.cpp */,
- 9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */,
- 9F68EB250C77AD2C004AA152 /* ValueEnumerator.cpp */,
- 9F68EB260C77AD2C004AA152 /* ValueEnumerator.h */,
- 35A9CDF10CD0F6E1008ABC1D /* Serialize.cpp */,
- );
- path = Writer;
- sourceTree = "<group>";
- };
- 9F7040170D8D72FF00FD06FF /* transforms */ = {
- isa = PBXGroup;
- children = (
- 9F7040190D8D730A00FD06FF /* scalar */,
- );
- name = transforms;
- sourceTree = "<group>";
- };
- 9F7040190D8D730A00FD06FF /* scalar */ = {
- isa = PBXGroup;
- children = (
- 9F70401A0D8D732400FD06FF /* llvm_scalar_opts.ml */,
- 9F70401B0D8D732400FD06FF /* llvm_scalar_opts.mli */,
- 9F70401E0D8D735E00FD06FF /* scalar_opts_ocaml.c */,
- );
- name = scalar;
- sourceTree = "<group>";
- };
- 9F77937F0C73C54C00551F9C /* Bitcode */ = {
- isa = PBXGroup;
- children = (
- 9F7793800C73C54C00551F9C /* Archive.h */,
- 9F7793810C73C54C00551F9C /* BitCodes.h */,
- 9F7793820C73C54C00551F9C /* BitstreamReader.h */,
- 9F7793830C73C54C00551F9C /* BitstreamWriter.h */,
- 9F7793840C73C54C00551F9C /* LLVMBitCodes.h */,
- 9F7793850C73C54C00551F9C /* ReaderWriter.h */,
- 35A9CDEE0CD0F6AF008ABC1D /* Serialization.h */,
- 35A9CDEF0CD0F6AF008ABC1D /* Serialize.h */,
- 35A9CDED0CD0F6AF008ABC1D /* Deserialize.h */,
- );
- path = Bitcode;
- sourceTree = "<group>";
- };
- 9F7794120C73CB6100551F9C /* Mips */ = {
- isa = PBXGroup;
- children = (
- 9F7794140C73CB6100551F9C /* Mips.h */,
- 9F7794150C73CB6100551F9C /* Mips.td */,
- 9F7794160C73CB6100551F9C /* MipsAsmPrinter.cpp */,
- 9F7794170C73CB6100551F9C /* MipsCallingConv.td */,
- 9F7794180C73CB6100551F9C /* MipsInstrFormats.td */,
- 9F7794190C73CB6100551F9C /* MipsInstrInfo.cpp */,
- 9F77941A0C73CB6100551F9C /* MipsInstrInfo.h */,
- 9F77941B0C73CB6100551F9C /* MipsInstrInfo.td */,
- 9F77941C0C73CB6100551F9C /* MipsISelDAGToDAG.cpp */,
- 9F77941D0C73CB6100551F9C /* MipsISelLowering.cpp */,
- 9F77941E0C73CB6100551F9C /* MipsISelLowering.h */,
- 9F77941F0C73CB6100551F9C /* MipsMachineFunction.h */,
- 9F7794200C73CB6100551F9C /* MipsRegisterInfo.cpp */,
- 9F7794210C73CB6100551F9C /* MipsRegisterInfo.h */,
- 9F7794220C73CB6100551F9C /* MipsRegisterInfo.td */,
- 9F7794230C73CB6100551F9C /* MipsSubtarget.cpp */,
- 9F7794240C73CB6100551F9C /* MipsSubtarget.h */,
- 9F7794250C73CB6100551F9C /* MipsTargetAsmInfo.cpp */,
- 9F7794260C73CB6100551F9C /* MipsTargetAsmInfo.h */,
- 9F7794270C73CB6100551F9C /* MipsTargetMachine.cpp */,
- 9F7794280C73CB6100551F9C /* MipsTargetMachine.h */,
- );
- path = Mips;
- sourceTree = "<group>";
- };
- 9F7794290C73CB7900551F9C /* MSIL */ = {
- isa = PBXGroup;
- children = (
- 9F77942F0C73CB7900551F9C /* MSILWriter.cpp */,
- 9F7794300C73CB7900551F9C /* MSILWriter.h */,
- );
- path = MSIL;
- sourceTree = "<group>";
- };
- 9F7C240B0CB81ECD00498408 /* analysis */ = {
- isa = PBXGroup;
- children = (
- 9F7C240C0CB81ECD00498408 /* analysis_ocaml.c */,
- 9F7C240D0CB81ECD00498408 /* llvm_analysis.ml */,
- 9F7C240E0CB81ECD00498408 /* llvm_analysis.mli */,
- );
- path = analysis;
- sourceTree = "<group>";
- };
- 9F7C2B690CB9496B00498408 /* test */ = {
- isa = PBXGroup;
- children = (
- 9F7C2C4B0CB9496C00498408 /* Bindings */,
- );
- name = test;
- path = ../test;
- sourceTree = SOURCE_ROOT;
- };
- 9F7C2C4B0CB9496C00498408 /* Bindings */ = {
- isa = PBXGroup;
- children = (
- 9F7C2C4C0CB9496C00498408 /* Ocaml */,
- );
- path = Bindings;
- sourceTree = "<group>";
- };
- 9F7C2C4C0CB9496C00498408 /* Ocaml */ = {
- isa = PBXGroup;
- children = (
- 9F7C2C4F0CB9496C00498408 /* analysis.ml */,
- 9F6B2CC00D0F6E56000F00FD /* bitreader.ml */,
- 9F7C2C520CB9496C00498408 /* bitwriter.ml */,
- 9F502AEC0D1D8CF8007939DF /* executionengine.ml */,
- 9FEDD6140D8D7C3B009F6DF1 /* scalar_opts.ml */,
- 9FEDD6BD0D8D8426009F6DF1 /* target.ml */,
- 9F7C2C5D0CB9496C00498408 /* vmcore.ml */,
- );
- path = Ocaml;
- sourceTree = "<group>";
- };
- 9FA638E90C77B252007F12AE /* IPO */ = {
- isa = PBXGroup;
- children = (
- 9FA638EA0C77B252007F12AE /* InlinerPass.h */,
- );
- path = IPO;
- sourceTree = "<group>";
- };
- 9FD3E56D0CA0116100E54D15 /* bindings */ = {
- isa = PBXGroup;
- children = (
- 9FD3E56F0CA0116100E54D15 /* ocaml */,
- );
- name = bindings;
- path = ../bindings;
- sourceTree = SOURCE_ROOT;
- };
- 9FD3E56F0CA0116100E54D15 /* ocaml */ = {
- isa = PBXGroup;
- children = (
- 9F502ACD0D1D8CA3007939DF /* executionengine */,
- 9F7C240B0CB81ECD00498408 /* analysis */,
- 9F4B0E5D0D0E02580061F270 /* bitreader */,
- 9FD3E5700CA0116100E54D15 /* bitwriter */,
- 9FD3E57A0CA0116100E54D15 /* llvm */,
- 9FEDD6C00D8D844E009F6DF1 /* target */,
- 9F7040170D8D72FF00FD06FF /* transforms */,
- );
- path = ocaml;
- sourceTree = "<group>";
- };
- 9FD3E5700CA0116100E54D15 /* bitwriter */ = {
- isa = PBXGroup;
- children = (
- 9FD3E5710CA0116100E54D15 /* bitwriter_ocaml.c */,
- 9FD3E5720CA0116100E54D15 /* llvm_bitwriter.ml */,
- 9FD3E5730CA0116100E54D15 /* llvm_bitwriter.mli */,
- );
- path = bitwriter;
- sourceTree = "<group>";
- };
- 9FD3E57A0CA0116100E54D15 /* llvm */ = {
- isa = PBXGroup;
- children = (
- 9FD3E57B0CA0116100E54D15 /* llvm.ml */,
- 9FD3E57C0CA0116100E54D15 /* llvm.mli */,
- 9FD3E57D0CA0116100E54D15 /* llvm_ocaml.c */,
- );
- path = llvm;
- sourceTree = "<group>";
- };
- 9FE450DE0C77ABE400C4FEA4 /* lib/Archive */ = {
- isa = PBXGroup;
- children = (
- 9FE450DF0C77ABE400C4FEA4 /* Archive.cpp */,
- 9FE450E00C77ABE400C4FEA4 /* ArchiveInternals.h */,
- 9FE450E10C77ABE400C4FEA4 /* ArchiveReader.cpp */,
- 9FE450E20C77ABE400C4FEA4 /* ArchiveWriter.cpp */,
- );
- name = lib/Archive;
- path = ../lib/Archive;
- sourceTree = SOURCE_ROOT;
- };
- 9FEDD5F00D8D73AB009F6DF1 /* Transforms */ = {
- isa = PBXGroup;
- children = (
- 9FEDD5F10D8D73AB009F6DF1 /* Scalar.h */,
- );
- path = Transforms;
- sourceTree = "<group>";
- };
- 9FEDD6C00D8D844E009F6DF1 /* target */ = {
- isa = PBXGroup;
- children = (
- 9FEDD6C10D8D844E009F6DF1 /* llvm_target.ml */,
- 9FEDD6C20D8D844E009F6DF1 /* llvm_target.mli */,
- 9FEDD6C40D8D844E009F6DF1 /* target_ocaml.c */,
- );
- path = target;
- sourceTree = "<group>";
- };
- CF8F1B480B64F7AB00BB4199 /* include/llvm-c */ = {
- isa = PBXGroup;
- children = (
- 9F7C23E50CB81C2100498408 /* Analysis.h */,
- 9F5B90E70D0DF19100CDFDEA /* BitReader.h */,
- 9FD3E58D0CA0125F00E54D15 /* BitWriter.h */,
- 9FD3E58E0CA0125F00E54D15 /* Core.h */,
- 9FEB8C550D1CD1E200EE46BC /* ExecutionEngine.h */,
- CF8F1B490B64F7AB00BB4199 /* LinkTimeOptimizer.h */,
- 9FEDD6BB0D8D8408009F6DF1 /* lto.h */,
- 9FEDD6B80D8D83EC009F6DF1 /* Target.h */,
- 9FEDD5F00D8D73AB009F6DF1 /* Transforms */,
- );
- name = "include/llvm-c";
- path = "../include/llvm-c";
- sourceTree = SOURCE_ROOT;
- };
- CF8F1B5E0B64FADA00BB4199 /* llvm-upgrade */ = {
- isa = PBXGroup;
- children = (
- CF8F1B680B64FADA00BB4199 /* llvm-upgrade.cpp */,
- CF8F1B720B64FADA00BB4199 /* UpgradeInternals.h */,
- CF8F1B750B64FADA00BB4199 /* UpgradeLexer.l */,
- CF8F1B7C0B64FADA00BB4199 /* UpgradeParser.y */,
- );
- path = "llvm-upgrade";
- sourceTree = "<group>";
- };
- CF8F1B7E0B64FADA00BB4199 /* llvm2cpp */ = {
- isa = PBXGroup;
- children = (
- CF8F1B7F0B64FADA00BB4199 /* CppWriter.cpp */,
- CF8F1B800B64FADA00BB4199 /* CppWriter.h */,
- CF8F1B870B64FADA00BB4199 /* llvm2cpp.cpp */,
- );
- path = llvm2cpp;
- sourceTree = "<group>";
- };
- CF8F1B960B64FB7F00BB4199 /* lto */ = {
- isa = PBXGroup;
- children = (
- CF8F1B9D0B64FB7F00BB4199 /* lto-c.cpp */,
- CF8F1B9E0B64FB7F00BB4199 /* lto.cpp */,
- );
- path = lto;
- sourceTree = "<group>";
- };
- CF8F1BAB0B64FB8000BB4199 /* opt */ = {
- isa = PBXGroup;
- children = (
- CF8F1BAC0B64FB8000BB4199 /* AnalysisWrappers.cpp */,
- CF8F1BB70B64FB8000BB4199 /* GraphPrinters.cpp */,
- CF8F1BB90B64FB8000BB4199 /* opt.cpp */,
- CF8F1BBA0B64FB8000BB4199 /* PrintSCC.cpp */,
- );
- path = opt;
- sourceTree = "<group>";
- };
- CF8F1BCF0B64FC8A00BB4199 /* ARM */ = {
- isa = PBXGroup;
- children = (
- 9FE4508B0C77A77000C4FEA4 /* ARMCodeEmitter.cpp */,
- 9FE4508C0C77A77000C4FEA4 /* ARMGenAsmWriter.inc */,
- 9FE4508D0C77A77000C4FEA4 /* ARMGenDAGISel.inc */,
- 9FE4508E0C77A77100C4FEA4 /* ARMGenInstrInfo.inc */,
- 9FE4508F0C77A77100C4FEA4 /* ARMGenInstrNames.inc */,
- 9FE450900C77A77100C4FEA4 /* ARMGenRegisterInfo.h.inc */,
- 9FE450910C77A77100C4FEA4 /* ARMGenRegisterInfo.inc */,
- 9FE450920C77A77100C4FEA4 /* ARMGenRegisterNames.inc */,
- 9FE450930C77A77100C4FEA4 /* ARMGenSubtarget.inc */,
- 9FE450940C77A77100C4FEA4 /* ARMJITInfo.cpp */,
- 9FE450950C77A77100C4FEA4 /* ARMJITInfo.h */,
- 9FE450960C77A77100C4FEA4 /* ARMRelocations.h */,
- 9FE450970C77A77100C4FEA4 /* README-Thumb.txt */,
- 9FE450980C77A77100C4FEA4 /* README.txt */,
- CF8F1BD10B64FC8A00BB4199 /* ARM.h */,
- CF8F1BD20B64FC8A00BB4199 /* ARM.td */,
- CF8F1BD30B64FC8A00BB4199 /* ARMAddressingModes.h */,
- CF8F1BD40B64FC8A00BB4199 /* ARMAsmPrinter.cpp */,
- CF8F1BD50B64FC8A00BB4199 /* ARMConstantIslandPass.cpp */,
- CF8F1BD60B64FC8A00BB4199 /* ARMConstantPoolValue.cpp */,
- CF8F1BD70B64FC8A00BB4199 /* ARMConstantPoolValue.h */,
- CF8F1BD80B64FC8A00BB4199 /* ARMFrameInfo.h */,
- CF8F1BD90B64FC8A00BB4199 /* ARMInstrInfo.cpp */,
- CF8F1BDA0B64FC8A00BB4199 /* ARMInstrInfo.h */,
- CF8F1BDB0B64FC8A00BB4199 /* ARMInstrInfo.td */,
- CF8F1BDC0B64FC8A00BB4199 /* ARMInstrThumb.td */,
- CF8F1BDD0B64FC8A00BB4199 /* ARMInstrVFP.td */,
- CF8F1BDE0B64FC8A00BB4199 /* ARMISelDAGToDAG.cpp */,
- CF8F1BDF0B64FC8A00BB4199 /* ARMISelLowering.cpp */,
- CF8F1BE00B64FC8A00BB4199 /* ARMISelLowering.h */,
- CF8F1BE10B64FC8A00BB4199 /* ARMLoadStoreOptimizer.cpp */,
- CF8F1BE20B64FC8A00BB4199 /* ARMMachineFunctionInfo.h */,
- CF8F1BE30B64FC8A00BB4199 /* ARMRegisterInfo.cpp */,
- CF8F1BE40B64FC8A00BB4199 /* ARMRegisterInfo.h */,
- CF8F1BE50B64FC8A00BB4199 /* ARMRegisterInfo.td */,
- CF8F1BE60B64FC8A00BB4199 /* ARMSubtarget.cpp */,
- CF8F1BE70B64FC8A00BB4199 /* ARMSubtarget.h */,
- CF8F1BE80B64FC8A00BB4199 /* ARMTargetAsmInfo.cpp */,
- CF8F1BE90B64FC8A00BB4199 /* ARMTargetAsmInfo.h */,
- CF8F1BEA0B64FC8A00BB4199 /* ARMTargetMachine.cpp */,
- CF8F1BEB0B64FC8A00BB4199 /* ARMTargetMachine.h */,
- );
- path = ARM;
- sourceTree = "<group>";
- };
- CFD99ADF0AFE878F0068D19C /* opt */ = {
- isa = PBXGroup;
- children = (
- CFD99ADB0AFE87870068D19C /* AnalysisWrappers.cpp */,
- CFD99ADC0AFE87870068D19C /* GraphPrinters.cpp */,
- CFD99ADD0AFE87870068D19C /* opt.cpp */,
- CFD99ADE0AFE87870068D19C /* PrintSCC.cpp */,
- );
- name = opt;
- sourceTree = "<group>";
- };
- CFE4213C0A66FAE100AB4BF6 /* Hello */ = {
- isa = PBXGroup;
- children = (
- CFE4213D0A66FAE100AB4BF6 /* Hello.cpp */,
- );
- path = Hello;
- sourceTree = "<group>";
- };
- DE66EC7508ABE8EF00323D32 /* lib/VMCore */ = {
- isa = PBXGroup;
- children = (
- DE66EC5B08ABE86900323D32 /* AsmWriter.cpp */,
- 9F77937B0C73C4F400551F9C /* AutoUpgrade.cpp */,
- DE66EC5C08ABE86A00323D32 /* BasicBlock.cpp */,
- 9F77937C0C73C4F400551F9C /* ConstantFold.cpp */,
- 9F77937D0C73C4F400551F9C /* ConstantFold.h */,
- DE66EC6008ABE86A00323D32 /* Constants.cpp */,
- 9FD3E5900CA0129D00E54D15 /* Core.cpp */,
- DE66EC6108ABE86A00323D32 /* Dominators.cpp */,
- DE66EC6208ABE86A00323D32 /* Function.cpp */,
- DE66EC6308ABE86A00323D32 /* Globals.cpp */,
- CF73C0BD098A551F00627152 /* InlineAsm.cpp */,
- DE66EC6408ABE86A00323D32 /* Instruction.cpp */,
- DE66EC6508ABE86A00323D32 /* Instructions.cpp */,
- CF1ACC9709C9DE4400D3C5EB /* IntrinsicInst.cpp */,
- DE66EC6608ABE86A00323D32 /* LeakDetector.cpp */,
- DE66EC6708ABE86A00323D32 /* Mangler.cpp */,
- DE66EC6808ABE86A00323D32 /* Module.cpp */,
- DE66EC6908ABE86A00323D32 /* ModuleProvider.cpp */,
- DE66EC6A08ABE86A00323D32 /* Pass.cpp */,
- CF8F1B5C0B64FA7300BB4199 /* PassManager.cpp */,
- DE66EC6D08ABE86A00323D32 /* SymbolTableListTraitsImpl.h */,
- DE66EC6E08ABE86A00323D32 /* Type.cpp */,
- CF73C0BE098A551F00627152 /* TypeSymbolTable.cpp */,
- DE66EC6F08ABE86A00323D32 /* Value.cpp */,
- CF73C0BF098A551F00627152 /* ValueSymbolTable.cpp */,
- CF9720900A9F3CA2002CEEDD /* ValueTypes.cpp */,
- DE66EC7008ABE86A00323D32 /* Verifier.cpp */,
- );
- name = lib/VMCore;
- sourceTree = "<group>";
- };
- DE66EC8808ABEAC900323D32 /* lib/AsmParser */ = {
- isa = PBXGroup;
- children = (
- DE66EC8E08ABEAF000323D32 /* llvmAsmParser.y */,
- DE66EC8F08ABEAF000323D32 /* Parser.cpp */,
- DE66EC9008ABEAF000323D32 /* ParserInternals.h */,
- );
- name = lib/AsmParser;
- sourceTree = "<group>";
- };
- DE66ECBD08ABEC0700323D32 /* lib/Analysis */ = {
- isa = PBXGroup;
- children = (
- DE66ED1A08ABEC0800323D32 /* IPA */,
- DE66ECBE08ABEC0700323D32 /* AliasAnalysis.cpp */,
- DE66ECBF08ABEC0700323D32 /* AliasAnalysisCounter.cpp */,
- DE66ECC008ABEC0700323D32 /* AliasAnalysisEvaluator.cpp */,
- CF8F1B4D0B64F80700BB4199 /* AliasDebugger.cpp */,
- DE66ECC108ABEC0700323D32 /* AliasSetTracker.cpp */,
- 9F7C23E60CB81C2B00498408 /* Analysis.cpp */,
- DE66ECC208ABEC0700323D32 /* BasicAliasAnalysis.cpp */,
- DE66ECC308ABEC0700323D32 /* CFGPrinter.cpp */,
- CF73C0B0098A523C00627152 /* ConstantFolding.cpp */,
- DE66ED1708ABEC0800323D32 /* InstCount.cpp */,
- DE66ED1808ABEC0800323D32 /* Interval.cpp */,
- DE66ED1908ABEC0800323D32 /* IntervalPartition.cpp */,
- DE66ED3308ABEC0800323D32 /* LoadValueNumbering.cpp */,
- DE66ED3408ABEC0800323D32 /* LoopInfo.cpp */,
- 9F68EB010C77AD02004AA152 /* LoopPass.cpp */,
- 9F68EB020C77AD02004AA152 /* MemoryDependenceAnalysis.cpp */,
- DE66ED3608ABEC0800323D32 /* PostDominators.cpp */,
- DE66ED3708ABEC0800323D32 /* ProfileInfo.cpp */,
- DE66ED3808ABEC0800323D32 /* ProfileInfoLoader.cpp */,
- DE66ED3908ABEC0800323D32 /* ProfileInfoLoaderPass.cpp */,
- DE66ED3A08ABEC0800323D32 /* ScalarEvolution.cpp */,
- DE66ED3B08ABEC0800323D32 /* ScalarEvolutionExpander.cpp */,
- DE66ED3C08ABEC0800323D32 /* Trace.cpp */,
- DE66ED3D08ABEC0800323D32 /* ValueNumbering.cpp */,
- );
- name = lib/Analysis;
- path = ../lib/Analysis;
- sourceTree = SOURCE_ROOT;
- };
- DE66ED1A08ABEC0800323D32 /* IPA */ = {
- isa = PBXGroup;
- children = (
- DE66ED1B08ABEC0800323D32 /* Andersens.cpp */,
- DE66ED1C08ABEC0800323D32 /* CallGraph.cpp */,
- DE66ED1D08ABEC0800323D32 /* CallGraphSCCPass.cpp */,
- DE66ED2F08ABEC0800323D32 /* FindUsedTypes.cpp */,
- DE66ED3008ABEC0800323D32 /* GlobalsModRef.cpp */,
- );
- path = IPA;
- sourceTree = "<group>";
- };
- DE66ED3E08ABEC2A00323D32 /* lib/CodeGen */ = {
- isa = PBXGroup;
- children = (
- F27C8CFF0DAD307700A33844 /* ShadowStackCollector.cpp */,
- 754221420D171DFC00DDB61B /* MachineLICM.cpp */,
- 9FE450AB0C77AB6100C4FEA4 /* README.txt */,
- DE66ED8308ABEC2B00323D32 /* SelectionDAG */,
- DE66ED3F08ABEC2A00323D32 /* AsmPrinter.cpp */,
- DE66ED4008ABEC2A00323D32 /* BranchFolding.cpp */,
- CFC244570959DEF2009F8C47 /* DwarfWriter.cpp */,
- 9F7793500C73BD1500551F9C /* ELFWriter.h */,
- DE66ED6F08ABEC2B00323D32 /* ELFWriter.cpp */,
- 9F7793510C73BD1500551F9C /* IfConversion.cpp */,
- DE66ED7008ABEC2B00323D32 /* IntrinsicLowering.cpp */,
- DE66ED7108ABEC2B00323D32 /* LiveInterval.cpp */,
- DE66ED7308ABEC2B00323D32 /* LiveIntervalAnalysis.cpp */,
- DE66ED7508ABEC2B00323D32 /* LiveVariables.cpp */,
- CF32AF5C0AEE6A4E00D24CD4 /* LLVMTargetMachine.cpp */,
- 9F7793520C73BD1500551F9C /* LowerSubregs.cpp */,
- DE66ED7608ABEC2B00323D32 /* MachineBasicBlock.cpp */,
- CF6529A6095B21A8007F884E /* MachineModuleInfo.cpp */,
- DE66ED7808ABEC2B00323D32 /* MachineFunction.cpp */,
- DE66ED7908ABEC2B00323D32 /* MachineInstr.cpp */,
- CF4F27F60A7B6FA3004359F6 /* MachinePassRegistry.cpp */,
- 9F7793530C73BD1500551F9C /* MachOWriter.h */,
- CF9720350A9F3ADC002CEEDD /* MachOWriter.cpp */,
- DE66ED7B08ABEC2B00323D32 /* Passes.cpp */,
- DE66ED7C08ABEC2B00323D32 /* PHIElimination.cpp */,
- 9F7793540C73BD1500551F9C /* PostRASchedulerList.cpp */,
- DE66ED7D08ABEC2B00323D32 /* PhysRegTracker.h */,
- DE66ED7E08ABEC2B00323D32 /* PrologEpilogInserter.cpp */,
- 9F7793550C73BD1500551F9C /* RegAllocBigBlock.cpp */,
- DE66ED8008ABEC2B00323D32 /* RegAllocLinearScan.cpp */,
- DE66ED8108ABEC2B00323D32 /* RegAllocLocal.cpp */,
- 9FE25D940CAB16FB005383FC /* RegisterCoalescer.cpp */,
- 9F7793560C73BD1500551F9C /* RegisterScavenging.cpp */,
- DE66ED8208ABEC2B00323D32 /* RegAllocSimple.cpp */,
- 9F7793570C73BD1500551F9C /* SimpleRegisterCoalescing.cpp */,
- DE66ED9508ABEC2B00323D32 /* TwoAddressInstructionPass.cpp */,
- DE66ED9608ABEC2B00323D32 /* UnreachableBlockElim.cpp */,
- DE66ED9808ABEC2B00323D32 /* VirtRegMap.cpp */,
- DE66ED9908ABEC2B00323D32 /* VirtRegMap.h */,
- );
- name = lib/CodeGen;
- path = ../lib/CodeGen;
- sourceTree = SOURCE_ROOT;
- };
- DE66ED8308ABEC2B00323D32 /* SelectionDAG */ = {
- isa = PBXGroup;
- children = (
- 9FE450AC0C77AB6E00C4FEA4 /* CallingConvLower.cpp */,
- CF6B5AFD095C82C300D1EA42 /* DAGCombiner.cpp */,
- DE66ED9008ABEC2B00323D32 /* LegalizeDAG.cpp */,
- CF7FFA1F0985081C008B0087 /* ScheduleDAGList.cpp */,
- DE694D9F08B51E0C0039C106 /* ScheduleDAG.cpp */,
- DE66ED9208ABEC2B00323D32 /* SelectionDAG.cpp */,
- DE66ED9308ABEC2B00323D32 /* SelectionDAGISel.cpp */,
- DE66ED9408ABEC2B00323D32 /* SelectionDAGPrinter.cpp */,
- CFE421060A66F86D00AB4BF6 /* ScheduleDAGRRList.cpp */,
- CF9720370A9F3B1C002CEEDD /* TargetLowering.cpp */,
- );
- path = SelectionDAG;
- sourceTree = "<group>";
- };
- DE66ED9A08ABEC7200323D32 /* lib/Debugger */ = {
- isa = PBXGroup;
- children = (
- DE66EDB108ABEC7300323D32 /* Debugger.cpp */,
- DE66EDB508ABEC7300323D32 /* ProgramInfo.cpp */,
- DE66EDB608ABEC7300323D32 /* README.txt */,
- DE66EDB708ABEC7300323D32 /* RuntimeInfo.cpp */,
- DE66EDB808ABEC7300323D32 /* SourceFile.cpp */,
- DE66EDB908ABEC7300323D32 /* SourceLanguage-CFamily.cpp */,
- DE66EDBA08ABEC7300323D32 /* SourceLanguage-CPlusPlus.cpp */,
- DE66EDBB08ABEC7300323D32 /* SourceLanguage-Unknown.cpp */,
- DE66EDBC08ABEC7300323D32 /* SourceLanguage.cpp */,
- );
- name = lib/Debugger;
- path = ../lib/Debugger;
- sourceTree = SOURCE_ROOT;
- };
- DE66EDBF08ABEC8F00323D32 /* lib/ExecutionEngine */ = {
- isa = PBXGroup;
- children = (
- DE66EDC508ABEC9000323D32 /* Interpreter */,
- DE66EDD308ABEC9000323D32 /* JIT */,
- DE66EDC408ABEC9000323D32 /* ExecutionEngine.cpp */,
- 9F502B090D1D8D8D007939DF /* ExecutionEngineBindings.cpp */,
- );
- name = lib/ExecutionEngine;
- path = ../lib/ExecutionEngine;
- sourceTree = SOURCE_ROOT;
- };
- DE66EDC508ABEC9000323D32 /* Interpreter */ = {
- isa = PBXGroup;
- children = (
- DE66EDCE08ABEC9000323D32 /* Execution.cpp */,
- DE66EDCF08ABEC9000323D32 /* ExternalFunctions.cpp */,
- DE66EDD008ABEC9000323D32 /* Interpreter.cpp */,
- DE66EDD108ABEC9000323D32 /* Interpreter.h */,
- );
- path = Interpreter;
- sourceTree = "<group>";
- };
- DE66EDD308ABEC9000323D32 /* JIT */ = {
- isa = PBXGroup;
- children = (
- DE66EDDE08ABEC9100323D32 /* Intercept.cpp */,
- DE66EDDF08ABEC9100323D32 /* JIT.cpp */,
- DE66EDE008ABEC9100323D32 /* JIT.h */,
- DE66EDE108ABEC9100323D32 /* JITEmitter.cpp */,
- DE66EDE308ABEC9100323D32 /* TargetSelect.cpp */,
- );
- path = JIT;
- sourceTree = "<group>";
- };
- DE66EDEB08ABEDD300323D32 /* lib/Linker */ = {
- isa = PBXGroup;
- children = (
- DE66EDF608ABEDD300323D32 /* LinkArchives.cpp */,
- DE66EDF708ABEDD300323D32 /* Linker.cpp */,
- DE66EDF808ABEDD300323D32 /* LinkItems.cpp */,
- DE66EDF908ABEDD300323D32 /* LinkModules.cpp */,
- );
- name = lib/Linker;
- path = ../lib/Linker;
- sourceTree = SOURCE_ROOT;
- };
- DE66EDFB08ABEDE600323D32 /* lib/Support */ = {
- isa = PBXGroup;
- children = (
- 9FE25D950CAB1724005383FC /* APFloat.cpp */,
- 9FE450A60C77AB3200C4FEA4 /* APInt.cpp */,
- 9FE450A70C77AB3200C4FEA4 /* ConstantRange.cpp */,
- 9FE450A80C77AB3200C4FEA4 /* MemoryBuffer.cpp */,
- 9FE450A90C77AB3200C4FEA4 /* SmallPtrSet.cpp */,
- 9FE450AA0C77AB3200C4FEA4 /* StringMap.cpp */,
- CFD99AB70AFE848A0068D19C /* Allocator.cpp */,
- DE66EDFC08ABEDE600323D32 /* Annotation.cpp */,
- DE66EE1D08ABEDE600323D32 /* CommandLine.cpp */,
- DE66EE3D08ABEDE600323D32 /* Debug.cpp */,
- CF79495D09B326D4005ADFCA /* Dwarf.cpp */,
- DE66EE3E08ABEDE600323D32 /* FileUtilities.cpp */,
- CF42B6C40AF2512000D5D47C /* FoldingSet.cpp */,
- CFE421070A66F8DC00AB4BF6 /* GraphWriter.cpp */,
- DE66EE3F08ABEDE600323D32 /* IsInf.cpp */,
- DE66EE4008ABEDE600323D32 /* IsNAN.cpp */,
- CF8F1B500B64F86A00BB4199 /* ManagedStatic.cpp */,
- DE66EE4208ABEDE600323D32 /* PluginLoader.cpp */,
- DE66EE4308ABEDE600323D32 /* SlowOperationInformer.cpp */,
- DE66EE4408ABEDE600323D32 /* Statistic.cpp */,
- CF8F1B510B64F86A00BB4199 /* Streams.cpp */,
- DE66EE4508ABEDE700323D32 /* StringExtras.cpp */,
- 9F5B90CB0D0CE87100CDFDEA /* StringPool.cpp */,
- DE66EE4608ABEDE700323D32 /* SystemUtils.cpp */,
- DE66EE4708ABEDE700323D32 /* Timer.cpp */,
- );
- name = lib/Support;
- path = ../lib/Support;
- sourceTree = SOURCE_ROOT;
- };
- DE66EE4908ABEE3400323D32 /* lib/System */ = {
- isa = PBXGroup;
- children = (
- 9FE450A50C77AAF000C4FEA4 /* Disassembler.cpp */,
- DE66EE7E08ABEE3500323D32 /* Unix */,
- DE66EE8B08ABEE3500323D32 /* Win32 */,
- CFE421090A66F93300AB4BF6 /* Alarm.cpp */,
- DE66EE6008ABEE3400323D32 /* DynamicLibrary.cpp */,
- CF8F1B530B64F8C000BB4199 /* IncludeFile.cpp */,
- DE66EE6108ABEE3400323D32 /* LICENSE.TXT */,
- CFD99ABA0AFE84D70068D19C /* IncludeFile.cpp */,
- DE66EE6508ABEE3400323D32 /* MappedFile.cpp */,
- DE66EE6608ABEE3400323D32 /* Memory.cpp */,
- DE66EE6708ABEE3400323D32 /* Mutex.cpp */,
- DE66EE6808ABEE3400323D32 /* Path.cpp */,
- DE66EE6908ABEE3400323D32 /* Process.cpp */,
- DE66EE6A08ABEE3400323D32 /* Program.cpp */,
- DE66EE6B08ABEE3400323D32 /* README.txt */,
- DE66EE7C08ABEE3400323D32 /* Signals.cpp */,
- DE66EE7D08ABEE3400323D32 /* TimeValue.cpp */,
- );
- name = lib/System;
- path = ../lib/System;
- sourceTree = SOURCE_ROOT;
- };
- DE66EE7E08ABEE3500323D32 /* Unix */ = {
- isa = PBXGroup;
- children = (
- CFD99ABB0AFE84EF0068D19C /* Alarm.inc */,
- DE66EE7F08ABEE3500323D32 /* MappedFile.inc */,
- DE66EE8008ABEE3500323D32 /* Memory.inc */,
- DE66EE8108ABEE3500323D32 /* Mutex.inc */,
- DE66EE8208ABEE3500323D32 /* Path.inc */,
- DE66EE8308ABEE3500323D32 /* Process.inc */,
- DE66EE8408ABEE3500323D32 /* Program.inc */,
- DE66EE8508ABEE3500323D32 /* README.txt */,
- DE66EE8608ABEE3500323D32 /* Signals.inc */,
- DE66EE8908ABEE3500323D32 /* TimeValue.inc */,
- DE66EE8A08ABEE3500323D32 /* Unix.h */,
- );
- path = Unix;
- sourceTree = "<group>";
- };
- DE66EE8B08ABEE3500323D32 /* Win32 */ = {
- isa = PBXGroup;
- children = (
- CFE4210A0A66F93300AB4BF6 /* Alarm.inc */,
- DE66EE8C08ABEE3500323D32 /* DynamicLibrary.inc */,
- DE66EE8D08ABEE3500323D32 /* MappedFile.inc */,
- DE66EE8E08ABEE3500323D32 /* Memory.inc */,
- DE66EE8F08ABEE3500323D32 /* Mutex.inc */,
- DE66EE9008ABEE3500323D32 /* Path.inc */,
- DE66EE9108ABEE3500323D32 /* Process.inc */,
- DE66EE9208ABEE3500323D32 /* Program.inc */,
- DE66EE9308ABEE3500323D32 /* Signals.inc */,
- DE66EE9408ABEE3500323D32 /* TimeValue.inc */,
- DE66EE9508ABEE3500323D32 /* Win32.h */,
- );
- path = Win32;
- sourceTree = "<group>";
- };
- DE66EE9608ABEE5D00323D32 /* lib/Target */ = {
- isa = PBXGroup;
- children = (
- 9F7794290C73CB7900551F9C /* MSIL */,
- DE66EE9708ABEE5D00323D32 /* Alpha */,
- CF8F1BCF0B64FC8A00BB4199 /* ARM */,
- DE66EEC908ABEE5E00323D32 /* CBackend */,
- 9F7794120C73CB6100551F9C /* Mips */,
- DE66EF1108ABEE5E00323D32 /* PowerPC */,
- DE66EF7008ABEE5F00323D32 /* Sparc */,
- DE66F09308ABEE6000323D32 /* X86 */,
- DE66EF1008ABEE5E00323D32 /* TargetRegisterInfo.cpp */,
- CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */,
- 9FEDD6B60D8D83D0009F6DF1 /* Target.cpp */,
- DE66F08A08ABEE6000323D32 /* Target.td */,
- CF47BD860AAF487E00A8B13E /* TargetAsmInfo.cpp */,
- 9FE25D960CAB1759005383FC /* TargetCallingConv.td */,
- DE66F08B08ABEE6000323D32 /* TargetData.cpp */,
- DE66F08C08ABEE6000323D32 /* TargetFrameInfo.cpp */,
- DE66F08D08ABEE6000323D32 /* TargetInstrInfo.cpp */,
- DE66F08F08ABEE6000323D32 /* TargetMachine.cpp */,
- DE66F09008ABEE6000323D32 /* TargetMachineRegistry.cpp */,
- 84115FFE0B66D87400E1293E /* TargetMachOWriterInfo.cpp */,
- CF490D14090541D30072DB1C /* TargetSchedule.td */,
- CF490D15090541D30072DB1C /* TargetSelectionDAG.td */,
- DE66F09208ABEE6000323D32 /* TargetSubtarget.cpp */,
- );
- name = lib/Target;
- path = ../lib/Target;
- sourceTree = SOURCE_ROOT;
- };
- DE66EE9708ABEE5D00323D32 /* Alpha */ = {
- isa = PBXGroup;
- children = (
- DE66EE9808ABEE5E00323D32 /* Alpha.h */,
- DE66EE9908ABEE5E00323D32 /* Alpha.td */,
- DE66EE9A08ABEE5E00323D32 /* AlphaAsmPrinter.cpp */,
- CF8F1B540B64F90F00BB4199 /* AlphaBranchSelector.cpp */,
- DE66EE9B08ABEE5E00323D32 /* AlphaCodeEmitter.cpp */,
- CFA702BB0A6FA85F0006009A /* AlphaGenAsmWriter.inc */,
- CFA702BC0A6FA85F0006009A /* AlphaGenCodeEmitter.inc */,
- CFA702BD0A6FA85F0006009A /* AlphaGenDAGISel.inc */,
- CFA702BE0A6FA85F0006009A /* AlphaGenInstrInfo.inc */,
- CFA702BF0A6FA85F0006009A /* AlphaGenInstrNames.inc */,
- CFA702C00A6FA85F0006009A /* AlphaGenRegisterInfo.h.inc */,
- CFA702C10A6FA85F0006009A /* AlphaGenRegisterInfo.inc */,
- CFA702C20A6FA85F0006009A /* AlphaGenRegisterNames.inc */,
- CFA702C30A6FA85F0006009A /* AlphaGenSubtarget.inc */,
- DE66EEA308ABEE5E00323D32 /* AlphaInstrFormats.td */,
- DE66EEA408ABEE5E00323D32 /* AlphaInstrInfo.cpp */,
- DE66EEA508ABEE5E00323D32 /* AlphaInstrInfo.h */,
- DE66EEA608ABEE5E00323D32 /* AlphaInstrInfo.td */,
- CFBD8B1A090E76540020B107 /* AlphaISelDAGToDAG.cpp */,
- CFBD8B1B090E76540020B107 /* AlphaISelLowering.cpp */,
- CFBD8B1C090E76540020B107 /* AlphaISelLowering.h */,
- DE66EEA908ABEE5E00323D32 /* AlphaJITInfo.cpp */,
- DE66EEAA08ABEE5E00323D32 /* AlphaJITInfo.h */,
- CF8F1B550B64F90F00BB4199 /* AlphaLLRP.cpp */,
- DE66EEAB08ABEE5E00323D32 /* AlphaRegisterInfo.cpp */,
- DE66EEAC08ABEE5E00323D32 /* AlphaRegisterInfo.h */,
- DE66EEAD08ABEE5E00323D32 /* AlphaRegisterInfo.td */,
- DE66EEAE08ABEE5E00323D32 /* AlphaRelocations.h */,
- CFE4210B0A66F96400AB4BF6 /* AlphaSchedule.td */,
- CFBD8B1D090E76540020B107 /* AlphaSubtarget.cpp */,
- CFBD8B1E090E76540020B107 /* AlphaSubtarget.h */,
- CF341DAE0AB07A8B0099B064 /* AlphaTargetAsmInfo.cpp */,
- CF341DAD0AB07A8B0099B064 /* AlphaTargetAsmInfo.h */,
- DE66EEAF08ABEE5E00323D32 /* AlphaTargetMachine.cpp */,
- DE66EEB008ABEE5E00323D32 /* AlphaTargetMachine.h */,
- );
- path = Alpha;
- sourceTree = "<group>";
- };
- DE66EEC908ABEE5E00323D32 /* CBackend */ = {
- isa = PBXGroup;
- children = (
- CF8F1B560B64F98900BB4199 /* CBackend.cpp */,
- DE66EECA08ABEE5E00323D32 /* CTargetMachine.h */,
- );
- path = CBackend;
- sourceTree = "<group>";
- };
- DE66EF1108ABEE5E00323D32 /* PowerPC */ = {
- isa = PBXGroup;
- children = (
- 9FE4509A0C77A79C00C4FEA4 /* PPCCallingConv.td */,
- 9FE4509B0C77A79C00C4FEA4 /* PPCGenCallingConv.inc */,
- 841160000B66D8AC00E1293E /* PPCMachOWriterInfo.h */,
- 84115FFF0B66D89B00E1293E /* PPCMachOWriterInfo.cpp */,
- CFA702CB0A6FA8AD0006009A /* PPCGenAsmWriter.inc */,
- CFA702CC0A6FA8AD0006009A /* PPCGenCodeEmitter.inc */,
- CFA702CD0A6FA8AD0006009A /* PPCGenDAGISel.inc */,
- CFA702CE0A6FA8AD0006009A /* PPCGenInstrInfo.inc */,
- CFA702CF0A6FA8AD0006009A /* PPCGenInstrNames.inc */,
- CFA702D00A6FA8AD0006009A /* PPCGenRegisterInfo.h.inc */,
- CFA702D10A6FA8AD0006009A /* PPCGenRegisterInfo.inc */,
- CFA702D20A6FA8AD0006009A /* PPCGenRegisterNames.inc */,
- CFA702D30A6FA8AD0006009A /* PPCGenSubtarget.inc */,
- CFE421140A66FA2D00AB4BF6 /* PPC.h */,
- CFE421150A66FA2D00AB4BF6 /* PPC.td */,
- CFE421160A66FA2D00AB4BF6 /* PPCAsmPrinter.cpp */,
- CFE421170A66FA2D00AB4BF6 /* PPCBranchSelector.cpp */,
- CFE421180A66FA2D00AB4BF6 /* PPCCodeEmitter.cpp */,
- CFE421190A66FA2D00AB4BF6 /* PPCFrameInfo.h */,
- CFE4211A0A66FA2D00AB4BF6 /* PPCHazardRecognizers.cpp */,
- CFE4211B0A66FA2D00AB4BF6 /* PPCHazardRecognizers.h */,
- CFE4211C0A66FA2D00AB4BF6 /* PPCInstr64Bit.td */,
- CFE4211D0A66FA2D00AB4BF6 /* PPCInstrAltivec.td */,
- CFE4211E0A66FA2D00AB4BF6 /* PPCInstrBuilder.h */,
- CFE4211F0A66FA2D00AB4BF6 /* PPCInstrFormats.td */,
- CFE421200A66FA2D00AB4BF6 /* PPCInstrInfo.cpp */,
- CFE421210A66FA2D00AB4BF6 /* PPCInstrInfo.h */,
- CFE421220A66FA2D00AB4BF6 /* PPCInstrInfo.td */,
- CFE421230A66FA2D00AB4BF6 /* PPCISelDAGToDAG.cpp */,
- CFE421240A66FA2D00AB4BF6 /* PPCISelLowering.cpp */,
- CFE421250A66FA2D00AB4BF6 /* PPCISelLowering.h */,
- CFE421260A66FA2D00AB4BF6 /* PPCJITInfo.cpp */,
- CFE421270A66FA2D00AB4BF6 /* PPCJITInfo.h */,
- CFABD0A20B09E342003EB061 /* PPCMachineFunctionInfo.h */,
- CFE421280A66FA2D00AB4BF6 /* PPCPerfectShuffle.h */,
- CF8F1B570B64F9AC00BB4199 /* PPCPredicates.cpp */,
- CF8F1B580B64F9AC00BB4199 /* PPCPredicates.h */,
- CFE421290A66FA2D00AB4BF6 /* PPCRegisterInfo.cpp */,
- CFE4212A0A66FA2D00AB4BF6 /* PPCRegisterInfo.h */,
- CFE4212B0A66FA2D00AB4BF6 /* PPCRegisterInfo.td */,
- CFE4212C0A66FA2D00AB4BF6 /* PPCRelocations.h */,
- CFE4212D0A66FA2D00AB4BF6 /* PPCSchedule.td */,
- CFE4212E0A66FA2D00AB4BF6 /* PPCScheduleG3.td */,
- CFE4212F0A66FA2D00AB4BF6 /* PPCScheduleG4.td */,
- CFE421300A66FA2D00AB4BF6 /* PPCScheduleG4Plus.td */,
- CFE421310A66FA2D00AB4BF6 /* PPCScheduleG5.td */,
- CFE421320A66FA2E00AB4BF6 /* PPCSubtarget.cpp */,
- CFE421330A66FA2E00AB4BF6 /* PPCSubtarget.h */,
- CF341E020AB080220099B064 /* PPCTargetAsmInfo.cpp */,
- CF341E010AB080220099B064 /* PPCTargetAsmInfo.h */,
- CFE421340A66FA2E00AB4BF6 /* PPCTargetMachine.cpp */,
- CFE421350A66FA2E00AB4BF6 /* PPCTargetMachine.h */,
- CFE421360A66FA2E00AB4BF6 /* README_ALTIVEC.txt */,
- CFE421370A66FA2E00AB4BF6 /* README.txt */,
- );
- path = PowerPC;
- sourceTree = "<group>";
- };
- DE66EF7008ABEE5F00323D32 /* Sparc */ = {
- isa = PBXGroup;
- children = (
- CF65280109D1BA3800C4B521 /* SparcGenAsmWriter.inc */,
- CF65280209D1BA3800C4B521 /* SparcGenDAGISel.inc */,
- CF65280309D1BA3800C4B521 /* SparcGenInstrInfo.inc */,
- CF65280409D1BA3800C4B521 /* SparcGenInstrNames.inc */,
- CF65280509D1BA3800C4B521 /* SparcGenRegisterInfo.h.inc */,
- CF65280609D1BA3800C4B521 /* SparcGenRegisterInfo.inc */,
- CF65280709D1BA3800C4B521 /* SparcGenRegisterNames.inc */,
- CF65280809D1BA3800C4B521 /* SparcGenSubtarget.inc */,
- CF6527FA09D1BA3800C4B521 /* DelaySlotFiller.cpp */,
- CF6527FB09D1BA3800C4B521 /* FPMover.cpp */,
- CF6527FC09D1BA3800C4B521 /* Makefile */,
- CF6527FD09D1BA3800C4B521 /* README.txt */,
- CF6527FE09D1BA3800C4B521 /* Sparc.h */,
- CF6527FF09D1BA3800C4B521 /* Sparc.td */,
- CF65280009D1BA3800C4B521 /* SparcAsmPrinter.cpp */,
- CF65280909D1BA3800C4B521 /* SparcInstrFormats.td */,
- CF65280A09D1BA3800C4B521 /* SparcInstrInfo.cpp */,
- CF65280B09D1BA3800C4B521 /* SparcInstrInfo.h */,
- CF65280C09D1BA3800C4B521 /* SparcInstrInfo.td */,
- CF65280D09D1BA3800C4B521 /* SparcISelDAGToDAG.cpp */,
- CF65280E09D1BA3800C4B521 /* SparcRegisterInfo.cpp */,
- CF65280F09D1BA3800C4B521 /* SparcRegisterInfo.h */,
- CF65281009D1BA3800C4B521 /* SparcRegisterInfo.td */,
- CF65281109D1BA3800C4B521 /* SparcSubtarget.cpp */,
- CF65281209D1BA3800C4B521 /* SparcSubtarget.h */,
- CF341E230AB0814B0099B064 /* SparcTargetAsmInfo.cpp */,
- CF341E220AB0814B0099B064 /* SparcTargetAsmInfo.h */,
- CF65281309D1BA3800C4B521 /* SparcTargetMachine.cpp */,
- CF65281409D1BA3800C4B521 /* SparcTargetMachine.h */,
- );
- path = Sparc;
- sourceTree = "<group>";
- };
- DE66F09308ABEE6000323D32 /* X86 */ = {
- isa = PBXGroup;
- children = (
- 9FE4509C0C77A7BC00C4FEA4 /* README-MMX.txt */,
- 9FE4509D0C77A7BC00C4FEA4 /* X86CallingConv.td */,
- 9FE4509F0C77A7BC00C4FEA4 /* X86ELFWriterInfo.cpp */,
- 9FE450A00C77A7BC00C4FEA4 /* X86ELFWriterInfo.h */,
- 9FE450A10C77A7BC00C4FEA4 /* X86GenCallingConv.inc */,
- 9FE450A20C77A7BC00C4FEA4 /* X86InstrFormats.td */,
- CFA702D40A6FA8DD0006009A /* X86GenAsmWriter.inc */,
- CFA702D50A6FA8DD0006009A /* X86GenAsmWriter1.inc */,
- CFA702D60A6FA8DD0006009A /* X86GenDAGISel.inc */,
- CFA702D70A6FA8DD0006009A /* X86GenInstrInfo.inc */,
- CFA702D80A6FA8DD0006009A /* X86GenInstrNames.inc */,
- CFA702D90A6FA8DD0006009A /* X86GenRegisterInfo.h.inc */,
- CFA702DA0A6FA8DD0006009A /* X86GenRegisterInfo.inc */,
- CFA702DB0A6FA8DD0006009A /* X86GenRegisterNames.inc */,
- CFA702DC0A6FA8DD0006009A /* X86GenSubtarget.inc */,
- CFE421380A66FA8000AB4BF6 /* README-FPStack.txt */,
- CFE421390A66FA8000AB4BF6 /* README-SSE.txt */,
- CFD99ABE0AFE857A0068D19C /* README-X86-64.txt */,
- CFE4213A0A66FA8000AB4BF6 /* README.txt */,
- CFF0DE6309BF6C360031957F /* X86InstrFPStack.td */,
- CFF0DE6409BF6C360031957F /* X86InstrMMX.td */,
- CFF0DE6509BF6C360031957F /* X86InstrSSE.td */,
- DE66F0BC08ABEE6000323D32 /* X86.h */,
- DE66F0BD08ABEE6000323D32 /* X86.td */,
- DE66F0BE08ABEE6000323D32 /* X86AsmPrinter.cpp */,
- DE66F0BF08ABEE6000323D32 /* X86AsmPrinter.h */,
- DE66F0C008ABEE6000323D32 /* X86ATTAsmPrinter.cpp */,
- DE66F0C108ABEE6000323D32 /* X86ATTAsmPrinter.h */,
- DE66F0C208ABEE6000323D32 /* X86CodeEmitter.cpp */,
- CF8F1B590B64F9E100BB4199 /* X86COFF.h */,
- DE66F0C408ABEE6000323D32 /* X86FloatingPoint.cpp */,
- DE66F0CC08ABEE6000323D32 /* X86InstrBuilder.h */,
- DE66F0CD08ABEE6000323D32 /* X86InstrInfo.cpp */,
- DE66F0CE08ABEE6000323D32 /* X86InstrInfo.h */,
- DE66F0CF08ABEE6100323D32 /* X86InstrInfo.td */,
- DE66F0D008ABEE6100323D32 /* X86IntelAsmPrinter.cpp */,
- DE66F0D108ABEE6100323D32 /* X86IntelAsmPrinter.h */,
- DE66F0D508ABEE6100323D32 /* X86JITInfo.cpp */,
- DE66F0D608ABEE6100323D32 /* X86JITInfo.h */,
- CFE4213B0A66FA8000AB4BF6 /* X86MachineFunctionInfo.h */,
- DE66F0D808ABEE6100323D32 /* X86RegisterInfo.cpp */,
- DE66F0D908ABEE6100323D32 /* X86RegisterInfo.h */,
- DE66F0DA08ABEE6100323D32 /* X86RegisterInfo.td */,
- DE66F0DB08ABEE6100323D32 /* X86Relocations.h */,
- CFC244BB0959F24C009F8C47 /* X86ISelDAGToDAG.cpp */,
- CFC244BC0959F24C009F8C47 /* X86ISelLowering.cpp */,
- CFC244BD0959F24C009F8C47 /* X86ISelLowering.h */,
- DE66F0DC08ABEE6100323D32 /* X86Subtarget.cpp */,
- DE66F0DD08ABEE6100323D32 /* X86Subtarget.h */,
- CF341E330AB082D60099B064 /* X86TargetAsmInfo.cpp */,
- CF341E320AB082D60099B064 /* X86TargetAsmInfo.h */,
- DE66F0DE08ABEE6100323D32 /* X86TargetMachine.cpp */,
- DE66F0DF08ABEE6100323D32 /* X86TargetMachine.h */,
- );
- path = X86;
- sourceTree = "<group>";
- };
- DE66F0E108ABEFB300323D32 /* lib/Transforms */ = {
- isa = PBXGroup;
- children = (
- DE66F0EE08ABEFB300323D32 /* Instrumentation */,
- CFE4213C0A66FAE100AB4BF6 /* Hello */,
- DE66F11F08ABEFB300323D32 /* IPO */,
- DE66F15C08ABEFB400323D32 /* Scalar */,
- DE66F1BD08ABEFB400323D32 /* Utils */,
- );
- name = lib/Transforms;
- path = ../lib/Transforms;
- sourceTree = SOURCE_ROOT;
- };
- DE66F0EE08ABEFB300323D32 /* Instrumentation */ = {
- isa = PBXGroup;
- children = (
- DE66F0EF08ABEFB300323D32 /* BlockProfiling.cpp */,
- DE66F0FE08ABEFB300323D32 /* EdgeProfiling.cpp */,
- DE66F11B08ABEFB300323D32 /* ProfilingUtils.cpp */,
- DE66F11C08ABEFB300323D32 /* ProfilingUtils.h */,
- CF73C0B7098A546000627152 /* RSProfiling.cpp */,
- CF73C0B8098A546000627152 /* RSProfiling.h */,
- );
- path = Instrumentation;
- sourceTree = "<group>";
- };
- DE66F11F08ABEFB300323D32 /* IPO */ = {
- isa = PBXGroup;
- children = (
- 9F7793770C73C48A00551F9C /* StripDeadPrototypes.cpp */,
- DE66F12008ABEFB300323D32 /* ArgumentPromotion.cpp */,
- DE66F12108ABEFB300323D32 /* ConstantMerge.cpp */,
- DE66F12208ABEFB300323D32 /* DeadArgumentElimination.cpp */,
- DE66F12308ABEFB300323D32 /* DeadTypeElimination.cpp */,
- DE66F14C08ABEFB400323D32 /* GlobalDCE.cpp */,
- DE66F14D08ABEFB400323D32 /* GlobalOpt.cpp */,
- CFE4213F0A66FB5E00AB4BF6 /* IndMemRemoval.cpp */,
- DE66F14E08ABEFB400323D32 /* Inliner.cpp */,
- DE66F15008ABEFB400323D32 /* InlineSimple.cpp */,
- DE66F15108ABEFB400323D32 /* Internalize.cpp */,
- DE66F15208ABEFB400323D32 /* IPConstantPropagation.cpp */,
- DE66F15308ABEFB400323D32 /* LoopExtractor.cpp */,
- DE66F15408ABEFB400323D32 /* LowerSetJmp.cpp */,
- DE66F15608ABEFB400323D32 /* PruneEH.cpp */,
- DE66F15708ABEFB400323D32 /* RaiseAllocations.cpp */,
- DE66F15808ABEFB400323D32 /* SimplifyLibCalls.cpp */,
- DE66F15908ABEFB400323D32 /* StripSymbols.cpp */,
- );
- path = IPO;
- sourceTree = "<group>";
- };
- DE66F15C08ABEFB400323D32 /* Scalar */ = {
- isa = PBXGroup;
- children = (
- DE66F15E08ABEFB400323D32 /* ADCE.cpp */,
- DE66F15F08ABEFB400323D32 /* BasicBlockPlacement.cpp */,
- 9F7793460C73BC2000551F9C /* CodeGenPrepare.cpp */,
- DE66F16008ABEFB400323D32 /* CondPropagate.cpp */,
- DE66F16108ABEFB400323D32 /* ConstantProp.cpp */,
- DE66F16308ABEFB400323D32 /* DCE.cpp */,
- DE66F16408ABEFB400323D32 /* DeadStoreElimination.cpp */,
- DE66F1A308ABEFB400323D32 /* GCSE.cpp */,
- 9F7793470C73BC2000551F9C /* GVN.cpp */,
- 9F7793480C73BC2000551F9C /* GVNPRE.cpp */,
- DE66F1A408ABEFB400323D32 /* IndVarSimplify.cpp */,
- DE66F1A508ABEFB400323D32 /* InstructionCombining.cpp */,
- DE66F1A608ABEFB400323D32 /* LICM.cpp */,
- 9F77934A0C73BC2000551F9C /* LoopRotation.cpp */,
- 9F7793490C73BC2000551F9C /* LoopIndexSplit.cpp */,
- DE66F1A808ABEFB400323D32 /* LoopStrengthReduce.cpp */,
- DE66F1A908ABEFB400323D32 /* LoopUnroll.cpp */,
- DE66F1AA08ABEFB400323D32 /* LoopUnswitch.cpp */,
- CF8F1B5B0B64FA2F00BB4199 /* PredicateSimplifier.cpp */,
- DE66F1B508ABEFB400323D32 /* Reassociate.cpp */,
- CF73C0B9098A546000627152 /* Reg2Mem.cpp */,
- 9FEDD5F70D8D797D009F6DF1 /* Scalar.cpp */,
- DE66F1B608ABEFB400323D32 /* ScalarReplAggregates.cpp */,
- DE66F1B708ABEFB400323D32 /* SCCP.cpp */,
- DE66F1B808ABEFB400323D32 /* SimplifyCFG.cpp */,
- DE66F1B908ABEFB400323D32 /* TailDuplication.cpp */,
- DE66F1BA08ABEFB400323D32 /* TailRecursionElimination.cpp */,
- );
- path = Scalar;
- sourceTree = "<group>";
- };
- DE66F1BD08ABEFB400323D32 /* Utils */ = {
- isa = PBXGroup;
- children = (
- DE66F1BE08ABEFB400323D32 /* BasicBlockUtils.cpp */,
- 9F7793780C73C49A00551F9C /* BasicInliner.cpp */,
- DE66F1BF08ABEFB400323D32 /* BreakCriticalEdges.cpp */,
- DE66F1C008ABEFB400323D32 /* CloneFunction.cpp */,
- 9F7793790C73C49A00551F9C /* CloneLoop.cpp */,
- DE66F1C108ABEFB400323D32 /* CloneModule.cpp */,
- DE66F1C208ABEFB400323D32 /* CloneTrace.cpp */,
- DE66F1C308ABEFB400323D32 /* CodeExtractor.cpp */,
- DE66F1E008ABEFB400323D32 /* DemoteRegToStack.cpp */,
- 9F77937A0C73C49A00551F9C /* InlineCost.cpp */,
- DE66F1E108ABEFB400323D32 /* InlineFunction.cpp */,
- CF97208A0A9F3C6F002CEEDD /* LCSSA.cpp */,
- DE66F1E208ABEFB400323D32 /* Local.cpp */,
- DE4DA0390911476D0012D44B /* LoopSimplify.cpp */,
- CF97208B0A9F3C6F002CEEDD /* LowerAllocations.cpp */,
- CF97208C0A9F3C6F002CEEDD /* LowerInvoke.cpp */,
- CF97208E0A9F3C6F002CEEDD /* LowerSwitch.cpp */,
- CF97208F0A9F3C6F002CEEDD /* Mem2Reg.cpp */,
- DE66F1E408ABEFB400323D32 /* PromoteMemoryToRegister.cpp */,
- DE66F1E508ABEFB400323D32 /* SimplifyCFG.cpp */,
- DE66F1E608ABEFB400323D32 /* UnifyFunctionExitNodes.cpp */,
- DE66F1E708ABEFB400323D32 /* ValueMapper.cpp */,
- );
- path = Utils;
- sourceTree = "<group>";
- };
- DE66F1E908ABF03100323D32 /* include/llvm */ = {
- isa = PBXGroup;
- children = (
- DE66F1EB08ABF03100323D32 /* ADT */,
- DE66F20308ABF03100323D32 /* Analysis */,
- DE66F22408ABF03100323D32 /* Assembly */,
- 9F77937F0C73C54C00551F9C /* Bitcode */,
- DE66F23508ABF03100323D32 /* CodeGen */,
- DE66F24C08ABF03100323D32 /* Config */,
- DE66F25308ABF03100323D32 /* Debugger */,
- DE66F25B08ABF03100323D32 /* ExecutionEngine */,
- DE66F26E08ABF03200323D32 /* Support */,
- DE66F29408ABF03200323D32 /* System */,
- DE66F29F08ABF03200323D32 /* Target */,
- DE66F2AB08ABF03200323D32 /* Transforms */,
- DE66F1EA08ABF03100323D32 /* AbstractTypeUser.h */,
- DE66F22308ABF03100323D32 /* Argument.h */,
- 9FA638D90C77B184007F12AE /* AutoUpgrade.h */,
- DE66F22A08ABF03100323D32 /* BasicBlock.h */,
- DE66F23308ABF03100323D32 /* CallGraphSCCPass.h */,
- DE66F23408ABF03100323D32 /* CallingConv.h */,
- DE66F25108ABF03100323D32 /* Constant.h */,
- DE66F25208ABF03100323D32 /* Constants.h */,
- DE66F25A08ABF03100323D32 /* DerivedTypes.h */,
- DE66F25E08ABF03100323D32 /* Function.h */,
- 9FA638DA0C77B184007F12AE /* GlobalAlias.h */,
- DE66F25F08ABF03100323D32 /* GlobalValue.h */,
- DE66F26008ABF03100323D32 /* GlobalVariable.h */,
- CF73C0A2098A4FDF00627152 /* InlineAsm.h */,
- DE66F26108ABF03100323D32 /* InstrTypes.h */,
- DE66F26208ABF03100323D32 /* Instruction.def */,
- DE66F26308ABF03100323D32 /* Instruction.h */,
- DE66F26408ABF03100323D32 /* Instructions.h */,
- DE66F26508ABF03100323D32 /* IntrinsicInst.h */,
- DE66F26608ABF03100323D32 /* Intrinsics.h */,
- CF65223409CA39B800C4B521 /* Intrinsics.gen */,
- CFE420FF0A66F67300AB4BF6 /* IntrinsicsPowerPC.td */,
- CFE421000A66F67300AB4BF6 /* IntrinsicsX86.td */,
- CF8D62FA09C2226F006017BA /* Intrinsics.td */,
- CF9720260A9F39B9002CEEDD /* LinkAllPasses.h */,
- CFE421010A66F67300AB4BF6 /* LinkAllVMCore.h */,
- CF9720270A9F39B9002CEEDD /* LinkTimeOptimizer.h */,
- DE66F26708ABF03100323D32 /* Linker.h */,
- DE66F26808ABF03100323D32 /* Module.h */,
- DE66F26908ABF03200323D32 /* ModuleProvider.h */,
- 9F77937E0C73C53000551F9C /* ParameterAttributes.h */,
- DE66F26A08ABF03200323D32 /* Pass.h */,
- DE66F26B08ABF03200323D32 /* PassAnalysisSupport.h */,
- DE66F26C08ABF03200323D32 /* PassManager.h */,
- CF8F1B420B64F70B00BB4199 /* PassManagers.h */,
- DE66F26D08ABF03200323D32 /* PassSupport.h */,
- DE66F29308ABF03200323D32 /* SymbolTableListTraits.h */,
- DE66F2B708ABF03200323D32 /* Type.h */,
- CF73C0A3098A4FDF00627152 /* TypeSymbolTable.h */,
- DE66F2B808ABF03200323D32 /* Use.h */,
- DE66F2B908ABF03200323D32 /* User.h */,
- DE66F2BA08ABF03200323D32 /* Value.h */,
- CF73C0A4098A4FDF00627152 /* ValueSymbolTable.h */,
- );
- name = include/llvm;
- path = ../include/llvm;
- sourceTree = SOURCE_ROOT;
- };
- DE66F1EB08ABF03100323D32 /* ADT */ = {
- isa = PBXGroup;
- children = (
- 35E98A830CBC2ED300C5CDC1 /* DenseSet.h */,
- 35E98A840CBC2ED300C5CDC1 /* ImmutableMap.h */,
- 35E98A850CBC2ED300C5CDC1 /* ImmutableSet.h */,
- 9FA638DD0C77B1AB007F12AE /* BitVector.h */,
- DE66F1EE08ABF03100323D32 /* DenseMap.h */,
- DE66F1EF08ABF03100323D32 /* DepthFirstIterator.h */,
- DE66F1F008ABF03100323D32 /* EquivalenceClasses.h */,
- CF42B6BF0AF24F5300D5D47C /* FoldingSet.h */,
- CF42B6BF0AF24F5300D5D47C /* FoldingSet.h */,
- DE66F1F108ABF03100323D32 /* GraphTraits.h */,
- DE66F1F308ABF03100323D32 /* hash_map.in */,
- DE66F1F508ABF03100323D32 /* hash_set.in */,
- DE66F1F608ABF03100323D32 /* HashExtras.h */,
- DE66F1F708ABF03100323D32 /* ilist */,
- 9FA638E00C77B1AB007F12AE /* IndexedMap.h */,
- 9FE25D900CAB166D005383FC /* APFloat.h */,
- 9FA638DB0C77B1AB007F12AE /* APInt.h */,
- 9FA638DC0C77B1AB007F12AE /* APSInt.h */,
- DE66F1F908ABF03100323D32 /* iterator.in */,
- DE66F1FA08ABF03100323D32 /* PostOrderIterator.h */,
- DE66F1FB08ABF03100323D32 /* SCCIterator.h */,
- DE66F1FC08ABF03100323D32 /* SetOperations.h */,
- DE66F1FD08ABF03100323D32 /* SetVector.h */,
- 9FA638E20C77B1AB007F12AE /* SmallPtrSet.h */,
- 9FA638E30C77B1AB007F12AE /* SmallSet.h */,
- CF33BE160AF62B4200E93805 /* SmallString.h */,
- CF71B60F0AC45EDA0007F57C /* SmallVector.h */,
- 9FE25D910CAB166D005383FC /* SparseBitVector.h */,
- 9FA638E40C77B1AB007F12AE /* StringMap.h */,
- DE66F1FE08ABF03100323D32 /* Statistic.h */,
- DE66F1FF08ABF03100323D32 /* STLExtras.h */,
- DE66F20008ABF03100323D32 /* StringExtras.h */,
- DE66F20108ABF03100323D32 /* Tree.h */,
- CFF8B434097C605F0047F72A /* UniqueVector.h */,
- DE66F20208ABF03100323D32 /* VectorExtras.h */,
- );
- path = ADT;
- sourceTree = "<group>";
- };
- DE66F20308ABF03100323D32 /* Analysis */ = {
- isa = PBXGroup;
- children = (
- 9FA638E50C77B203007F12AE /* LoopPass.h */,
- 9FA638E60C77B203007F12AE /* MemoryDependenceAnalysis.h */,
- DE66F20408ABF03100323D32 /* AliasAnalysis.h */,
- DE66F20508ABF03100323D32 /* AliasSetTracker.h */,
- DE66F20608ABF03100323D32 /* CallGraph.h */,
- DE66F20708ABF03100323D32 /* CFGPrinter.h */,
- CF73C0A5098A507300627152 /* ConstantFolding.h */,
- DE66F20808ABF03100323D32 /* ConstantsScanner.h */,
- DE66F20F08ABF03100323D32 /* Dominators.h */,
- DE66F21208ABF03100323D32 /* FindUsedTypes.h */,
- DE66F21308ABF03100323D32 /* Interval.h */,
- DE66F21408ABF03100323D32 /* IntervalIterator.h */,
- DE66F21508ABF03100323D32 /* IntervalPartition.h */,
- DE66F21608ABF03100323D32 /* LoadValueNumbering.h */,
- DE66F21708ABF03100323D32 /* LoopInfo.h */,
- DE66F21808ABF03100323D32 /* Passes.h */,
- DE66F21908ABF03100323D32 /* PostDominators.h */,
- DE66F21A08ABF03100323D32 /* ProfileInfo.h */,
- DE66F21B08ABF03100323D32 /* ProfileInfoLoader.h */,
- DE66F21C08ABF03100323D32 /* ProfileInfoTypes.h */,
- DE66F21D08ABF03100323D32 /* ScalarEvolution.h */,
- DE66F21E08ABF03100323D32 /* ScalarEvolutionExpander.h */,
- DE66F21F08ABF03100323D32 /* ScalarEvolutionExpressions.h */,
- DE66F22008ABF03100323D32 /* Trace.h */,
- DE66F22108ABF03100323D32 /* ValueNumbering.h */,
- DE66F22208ABF03100323D32 /* Verifier.h */,
- );
- path = Analysis;
- sourceTree = "<group>";
- };
- DE66F22408ABF03100323D32 /* Assembly */ = {
- isa = PBXGroup;
- children = (
- DE66F22508ABF03100323D32 /* AsmAnnotationWriter.h */,
- DE66F22708ABF03100323D32 /* Parser.h */,
- DE66F22808ABF03100323D32 /* PrintModulePass.h */,
- DE66F22908ABF03100323D32 /* Writer.h */,
- );
- path = Assembly;
- sourceTree = "<group>";
- };
- DE66F23508ABF03100323D32 /* CodeGen */ = {
- isa = PBXGroup;
- children = (
- DE66F23608ABF03100323D32 /* AsmPrinter.h */,
- 9F7793860C73C57100551F9C /* CallingConvLower.h */,
- DEFAB19D0959E9A100E0AB42 /* DwarfWriter.h */,
- 9F7793870C73C57100551F9C /* ELFRelocation.h */,
- 9F7793880C73C57100551F9C /* FileWriters.h */,
- DE66F23908ABF03100323D32 /* IntrinsicLowering.h */,
- CFD7E4F30A798FC3000C7379 /* LinkAllCodegenComponents.h */,
- DE4DA03C091147920012D44B /* LiveInterval.h */,
- DE4DA03D091147920012D44B /* LiveIntervalAnalysis.h */,
- DE66F23A08ABF03100323D32 /* LiveVariables.h */,
- DE66F23B08ABF03100323D32 /* MachineBasicBlock.h */,
- DE66F23C08ABF03100323D32 /* MachineCodeEmitter.h */,
- DE66F23D08ABF03100323D32 /* MachineConstantPool.h */,
- CF6F487109505E1500BC9E82 /* MachineModuleInfo.h */,
- DE66F23E08ABF03100323D32 /* MachineFrameInfo.h */,
- DE66F23F08ABF03100323D32 /* MachineFunction.h */,
- DE66F24008ABF03100323D32 /* MachineFunctionPass.h */,
- DE66F24108ABF03100323D32 /* MachineInstr.h */,
- DE66F24208ABF03100323D32 /* MachineInstrBuilder.h */,
- CFE420FB0A66F67300AB4BF6 /* MachineJumpTableInfo.h */,
- CF6527D909D1A53400C4B521 /* MachineLocation.h */,
- CF4F27E60A7B6E23004359F6 /* MachinePassRegistry.h */,
- DE66F24308ABF03100323D32 /* MachineRelocation.h */,
- 9F7793890C73C57100551F9C /* MachORelocation.h */,
- DE66F24408ABF03100323D32 /* Passes.h */,
- CFE21C780A80CC0600D3E908 /* RegAllocRegistry.h */,
- 9FE25D920CAB169F005383FC /* RegisterCoalescer.h */,
- 9F77938A0C73C57100551F9C /* RegisterScavenging.h */,
- CF8F1B410B64F6D100BB4199 /* RuntimeLibcalls.h */,
- DE66F24508ABF03100323D32 /* SchedGraphCommon.h */,
- CF7FFA2109850864008B0087 /* ScheduleDAG.h */,
- CFE21C7B0A80CC1C00D3E908 /* SchedulerRegistry.h */,
- DE66F24608ABF03100323D32 /* SelectionDAG.h */,
- DE66F24708ABF03100323D32 /* SelectionDAGISel.h */,
- DE66F24808ABF03100323D32 /* SelectionDAGNodes.h */,
- DE66F24B08ABF03100323D32 /* ValueTypes.h */,
- CFE420FC0A66F67300AB4BF6 /* ValueTypes.td */,
- );
- path = CodeGen;
- sourceTree = "<group>";
- };
- DE66F24C08ABF03100323D32 /* Config */ = {
- isa = PBXGroup;
- children = (
- DE66F24E08ABF03100323D32 /* alloca.h */,
- CF73C0A9098A50FD00627152 /* config.h */,
- DE66F25008ABF03100323D32 /* config.h.in */,
- );
- path = Config;
- sourceTree = "<group>";
- };
- DE66F25308ABF03100323D32 /* Debugger */ = {
- isa = PBXGroup;
- children = (
- DE66F25408ABF03100323D32 /* Debugger.h */,
- DE66F25508ABF03100323D32 /* InferiorProcess.h */,
- DE66F25608ABF03100323D32 /* ProgramInfo.h */,
- DE66F25708ABF03100323D32 /* RuntimeInfo.h */,
- DE66F25808ABF03100323D32 /* SourceFile.h */,
- DE66F25908ABF03100323D32 /* SourceLanguage.h */,
- );
- path = Debugger;
- sourceTree = "<group>";
- };
- DE66F25B08ABF03100323D32 /* ExecutionEngine */ = {
- isa = PBXGroup;
- children = (
- DE66F25C08ABF03100323D32 /* ExecutionEngine.h */,
- DE66F25D08ABF03100323D32 /* GenericValue.h */,
- CFE420FD0A66F67300AB4BF6 /* Interpreter.h */,
- CFE420FE0A66F67300AB4BF6 /* JIT.h */,
- );
- path = ExecutionEngine;
- sourceTree = "<group>";
- };
- DE66F26E08ABF03200323D32 /* Support */ = {
- isa = PBXGroup;
- children = (
- F27C8CE90DAD2EF900A33844 /* IRBuilder.h */,
- DE66F27008ABF03200323D32 /* AIXDataTypesFix.h */,
- 9F5B90CE0D0CE89300CDFDEA /* AlignOf.h */,
- CF8F1B430B64F74400BB4199 /* Allocator.h */,
- DE66F27108ABF03200323D32 /* Annotation.h */,
- DE66F27208ABF03200323D32 /* CallSite.h */,
- DE66F27308ABF03200323D32 /* Casting.h */,
- DE66F27408ABF03200323D32 /* CFG.h */,
- DE66F27508ABF03200323D32 /* CommandLine.h */,
- CF8F1B440B64F74400BB4199 /* Compiler.h */,
- DE66F27708ABF03200323D32 /* ConstantRange.h */,
- CF73C0AD098A519400627152 /* DataTypes.h */,
- DE66F27908ABF03200323D32 /* DataTypes.h.in */,
- DE66F27A08ABF03200323D32 /* Debug.h */,
- DE66F27B08ABF03200323D32 /* DOTGraphTraits.h */,
- DE66F27C08ABF03200323D32 /* DynamicLinker.h */,
- DE66F27D08ABF03200323D32 /* ELF.h */,
- CF8E00490989162500DA2399 /* Dwarf.h */,
- DE66F27E08ABF03200323D32 /* FileUtilities.h */,
- DE66F27F08ABF03200323D32 /* GetElementPtrTypeIterator.h */,
- DE66F28008ABF03200323D32 /* GraphWriter.h */,
- DE66F28108ABF03200323D32 /* InstIterator.h */,
- DE66F28208ABF03200323D32 /* InstVisitor.h */,
- DE66F28308ABF03200323D32 /* LeakDetector.h */,
- CF8F1B460B64F74400BB4199 /* ManagedStatic.h */,
- DE66F28408ABF03200323D32 /* Mangler.h */,
- DE66F28508ABF03200323D32 /* MathExtras.h */,
- 9F7794880C73D51000551F9C /* MemoryBuffer.h */,
- DE66F28608ABF03200323D32 /* MutexGuard.h */,
- CF8F1B470B64F74400BB4199 /* OutputBuffer.h */,
- DE66F28708ABF03200323D32 /* PassNameParser.h */,
- DE66F28808ABF03200323D32 /* PatternMatch.h */,
- DE66F28908ABF03200323D32 /* PluginLoader.h */,
- 9F5B90CF0D0CE89300CDFDEA /* Registry.h */,
- DE66F28A08ABF03200323D32 /* SlowOperationInformer.h */,
- DE66F28B08ABF03200323D32 /* StableBasicBlockNumbering.h */,
- 9F7794890C73D51000551F9C /* Streams.h */,
- 9F5B90D00D0CE89300CDFDEA /* StringPool.h */,
- DE66F28C08ABF03200323D32 /* SystemUtils.h */,
- DE66F28E08ABF03200323D32 /* Timer.h */,
- DE66F29008ABF03200323D32 /* type_traits.h */,
- );
- path = Support;
- sourceTree = "<group>";
- };
- DE66F29408ABF03200323D32 /* System */ = {
- isa = PBXGroup;
- children = (
- CF73C0AE098A51AD00627152 /* Alarm.h */,
- 9FA638E70C77B222007F12AE /* Disassembler.h */,
- DE66F29508ABF03200323D32 /* DynamicLibrary.h */,
- CF9720340A9F3A41002CEEDD /* IncludeFile.h */,
- DE66F29608ABF03200323D32 /* LICENSE.TXT */,
- DE66F29708ABF03200323D32 /* MappedFile.h */,
- DE66F29808ABF03200323D32 /* Memory.h */,
- DE66F29908ABF03200323D32 /* Mutex.h */,
- DE66F29A08ABF03200323D32 /* Path.h */,
- DE66F29B08ABF03200323D32 /* Process.h */,
- DE66F29C08ABF03200323D32 /* Program.h */,
- DE66F29D08ABF03200323D32 /* Signals.h */,
- DE66F29E08ABF03200323D32 /* TimeValue.h */,
- );
- path = System;
- sourceTree = "<group>";
- };
- DE66F29F08ABF03200323D32 /* Target */ = {
- isa = PBXGroup;
- children = (
- DE66F2A008ABF03200323D32 /* TargetRegisterInfo.h */,
- CF9BCD0808C74DE0001E7011 /* SubtargetFeature.h */,
- CF47BD380AAF40BC00A8B13E /* TargetAsmInfo.h */,
- DE66F2A108ABF03200323D32 /* TargetData.h */,
- 9FA638E80C77B231007F12AE /* TargetELFWriterInfo.h */,
- DE66F2A208ABF03200323D32 /* TargetFrameInfo.h */,
- DE66F2A308ABF03200323D32 /* TargetInstrInfo.h */,
- CF26835B09178F5500C5F253 /* TargetInstrItineraries.h */,
- DE66F2A408ABF03200323D32 /* TargetJITInfo.h */,
- DE66F2A508ABF03200323D32 /* TargetLowering.h */,
- DE66F2A608ABF03200323D32 /* TargetMachine.h */,
- DE66F2A708ABF03200323D32 /* TargetMachineRegistry.h */,
- 8443EF210B66B62D00959964 /* TargetMachOWriterInfo.h */,
- DE66F2A808ABF03200323D32 /* TargetOptions.h */,
- DE66F2AA08ABF03200323D32 /* TargetSubtarget.h */,
- );
- path = Target;
- sourceTree = "<group>";
- };
- DE66F2AB08ABF03200323D32 /* Transforms */ = {
- isa = PBXGroup;
- children = (
- DE66F2AC08ABF03200323D32 /* Instrumentation.h */,
- 9FA638E90C77B252007F12AE /* IPO */,
- DE66F2AD08ABF03200323D32 /* IPO.h */,
- CF73C0AF098A51DD00627152 /* RSProfiling.h */,
- DE66F2AF08ABF03200323D32 /* Scalar.h */,
- DE66F2B008ABF03200323D32 /* Utils */,
- );
- path = Transforms;
- sourceTree = "<group>";
- };
- DE66F2B008ABF03200323D32 /* Utils */ = {
- isa = PBXGroup;
- children = (
- DE66F2B108ABF03200323D32 /* BasicBlockUtils.h */,
- 9FA638EB0C77B26B007F12AE /* BasicInliner.h */,
- DE66F2B208ABF03200323D32 /* Cloning.h */,
- DE66F2B308ABF03200323D32 /* FunctionUtils.h */,
- 9FA638EC0C77B26B007F12AE /* InlineCost.h */,
- DE66F2B408ABF03200323D32 /* Local.h */,
- DE66F2B508ABF03200323D32 /* PromoteMemToReg.h */,
- DE66F2B608ABF03200323D32 /* UnifyFunctionExitNodes.h */,
- );
- path = Utils;
- sourceTree = "<group>";
- };
- DE66F2BD08ABF14400323D32 /* tools */ = {
- isa = PBXGroup;
- children = (
- CFD99ADF0AFE878F0068D19C /* opt */,
- DE66F2CB08ABF14400323D32 /* bugpoint */,
- DE66F2F008ABF14400323D32 /* gccld */,
- DE66F31E08ABF14400323D32 /* llvm-db */,
- DE66F33B08ABF14400323D32 /* llvm-ld */,
- DE66F36808ABF14500323D32 /* llvmc */,
- CF8F1B5E0B64FADA00BB4199 /* llvm-upgrade */,
- CF8F1B7E0B64FADA00BB4199 /* llvm2cpp */,
- CFD99ADA0AFE87650068D19C /* lto.cpp */,
- DE66F30008ABF14400323D32 /* llc.cpp */,
- DE66F30708ABF14400323D32 /* lli.cpp */,
- DE66F30E08ABF14400323D32 /* llvm-ar.cpp */,
- DE66F31508ABF14400323D32 /* llvm-as.cpp */,
- DE66F31C08ABF14400323D32 /* llvm-bcanalyzer.cpp */,
- DE66F33208ABF14400323D32 /* llvm-dis.cpp */,
- DE66F33908ABF14400323D32 /* llvm-extract.cpp */,
- DE66F34A08ABF14400323D32 /* llvm-link.cpp */,
- DE66F35108ABF14400323D32 /* llvm-nm.cpp */,
- DE66F35808ABF14500323D32 /* llvm-prof.cpp */,
- DE66F35F08ABF14500323D32 /* llvm-ranlib.cpp */,
- CF8F1B960B64FB7F00BB4199 /* lto */,
- CF8F1BAB0B64FB8000BB4199 /* opt */,
- );
- name = tools;
- path = ../tools;
- sourceTree = SOURCE_ROOT;
- };
- DE66F2CB08ABF14400323D32 /* bugpoint */ = {
- isa = PBXGroup;
- children = (
- DE66F2CC08ABF14400323D32 /* BugDriver.cpp */,
- DE66F2CD08ABF14400323D32 /* BugDriver.h */,
- DE66F2CE08ABF14400323D32 /* bugpoint.cpp */,
- DE66F2CF08ABF14400323D32 /* CrashDebugger.cpp */,
- DE66F2E208ABF14400323D32 /* ExecutionDriver.cpp */,
- DE66F2E308ABF14400323D32 /* ExtractFunction.cpp */,
- CF9720910A9F3CC7002CEEDD /* FindBugs.cpp */,
- DE66F2E408ABF14400323D32 /* ListReducer.h */,
- DE66F2E608ABF14400323D32 /* Miscompilation.cpp */,
- DE66F2E708ABF14400323D32 /* OptimizerDriver.cpp */,
- DE66F2E808ABF14400323D32 /* TestPasses.cpp */,
- CF9720920A9F3CC7002CEEDD /* ToolRunner.cpp */,
- CF9720930A9F3CC7002CEEDD /* ToolRunner.h */,
- );
- path = bugpoint;
- sourceTree = "<group>";
- };
- DE66F2F008ABF14400323D32 /* gccld */ = {
- isa = PBXGroup;
- children = (
- );
- path = gccld;
- sourceTree = "<group>";
- };
- DE66F31E08ABF14400323D32 /* llvm-db */ = {
- isa = PBXGroup;
- children = (
- DE66F31F08ABF14400323D32 /* CLICommand.h */,
- DE66F32008ABF14400323D32 /* CLIDebugger.cpp */,
- DE66F32108ABF14400323D32 /* CLIDebugger.h */,
- DE66F32208ABF14400323D32 /* Commands.cpp */,
- DE66F32B08ABF14400323D32 /* llvm-db.cpp */,
- );
- path = "llvm-db";
- sourceTree = "<group>";
- };
- DE66F33B08ABF14400323D32 /* llvm-ld */ = {
- isa = PBXGroup;
- children = (
- DE66F34208ABF14400323D32 /* llvm-ld.cpp */,
- DE66F34408ABF14400323D32 /* Optimize.cpp */,
- );
- path = "llvm-ld";
- sourceTree = "<group>";
- };
- DE66F36808ABF14500323D32 /* llvmc */ = {
- isa = PBXGroup;
- children = (
- DE66F36908ABF14500323D32 /* c */,
- DE66F36A08ABF14500323D32 /* CompilerDriver.cpp */,
- DE66F36B08ABF14500323D32 /* CompilerDriver.h */,
- CF8F1B950B64FB5000BB4199 /* ConfigLexer.cpp */,
- DE66F36D08ABF14500323D32 /* ConfigLexer.h */,
- DE66F36E08ABF14500323D32 /* ConfigLexer.l */,
- DE66F36F08ABF14500323D32 /* Configuration.cpp */,
- DE66F37008ABF14500323D32 /* Configuration.h */,
- DE66F37108ABF14500323D32 /* cpp */,
- DE66F37D08ABF14500323D32 /* ll */,
- DE66F37E08ABF14500323D32 /* llvmc.cpp */,
- );
- path = llvmc;
- sourceTree = "<group>";
- };
- DE66F38D08ABF35C00323D32 /* docs */ = {
- isa = PBXGroup;
- children = (
- F22627310DAE34D10008F441 /* tutorial */,
- DE66F38F08ABF35C00323D32 /* AliasAnalysis.html */,
- DE66F39008ABF35C00323D32 /* Bugpoint.html */,
- DE66F39208ABF35C00323D32 /* GCCFEBuildInstrs.html */,
- DE66F39308ABF35C00323D32 /* CodeGenerator.html */,
- DE66F39408ABF35C00323D32 /* CodingStandards.html */,
- DE66F39508ABF35C00323D32 /* CommandGuide */,
- DE66F3B908ABF35D00323D32 /* CommandLine.html */,
- DE66F3BA08ABF35D00323D32 /* CompilerDriver.html */,
- DE66F3BB08ABF35D00323D32 /* CompilerWriterInfo.html */,
- DE66F3BD08ABF35D00323D32 /* doxygen.cfg.in */,
- DE66F3BE08ABF35D00323D32 /* doxygen.css */,
- DE66F3BF08ABF35D00323D32 /* doxygen.footer */,
- DE66F3C008ABF35D00323D32 /* doxygen.header */,
- DE66F3C108ABF35D00323D32 /* doxygen.intro */,
- DE66F3C208ABF35D00323D32 /* ExtendingLLVM.html */,
- DE66F3C308ABF35D00323D32 /* FAQ.html */,
- DE66F3C408ABF35D00323D32 /* GarbageCollection.html */,
- DE66F3C508ABF35D00323D32 /* GettingStarted.html */,
- DE66F3C608ABF35D00323D32 /* GettingStartedVS.html */,
- DE66F3E408ABF35D00323D32 /* HowToSubmitABug.html */,
- DE66F3E508ABF35D00323D32 /* img */,
- DE66F3EB08ABF35D00323D32 /* index.html */,
- DE66F3EC08ABF35D00323D32 /* LangRef.html */,
- DE66F3ED08ABF35D00323D32 /* Lexicon.html */,
- DE66F3EE08ABF35D00323D32 /* llvm.css */,
- DE66F3F108ABF35D00323D32 /* MakefileGuide.html */,
- DE66F3F208ABF35D00323D32 /* ProgrammersManual.html */,
- DE66F3F308ABF35D00323D32 /* Projects.html */,
- DE66F3F408ABF35D00323D32 /* ReleaseNotes.html */,
- DE66F3F508ABF35D00323D32 /* SourceLevelDebugging.html */,
- DE66F3F708ABF35D00323D32 /* SystemLibrary.html */,
- DE66F3F808ABF35D00323D32 /* TableGenFundamentals.html */,
- DE66F3F908ABF35D00323D32 /* TestingGuide.html */,
- DE66F3FA08ABF35D00323D32 /* UsingLibraries.html */,
- DE66F3FB08ABF35D00323D32 /* WritingAnLLVMBackend.html */,
- DE66F3FC08ABF35D00323D32 /* WritingAnLLVMPass.html */,
- );
- name = docs;
- path = ../docs;
- sourceTree = SOURCE_ROOT;
- };
- DE66F39508ABF35C00323D32 /* CommandGuide */ = {
- isa = PBXGroup;
- children = (
- DE66F39808ABF35C00323D32 /* bugpoint.pod */,
- DE66F39E08ABF35C00323D32 /* index.html */,
- DE66F39F08ABF35C00323D32 /* llc.pod */,
- DE66F3A008ABF35C00323D32 /* lli.pod */,
- DE66F3A108ABF35C00323D32 /* llvm-ar.pod */,
- DE66F3A208ABF35C00323D32 /* llvm-as.pod */,
- DE66F3A308ABF35C00323D32 /* llvm-bcanalyzer.pod */,
- DE66F3A408ABF35C00323D32 /* llvm-db.pod */,
- DE66F3A508ABF35C00323D32 /* llvm-dis.pod */,
- DE66F3A608ABF35C00323D32 /* llvm-extract.pod */,
- DE66F3A708ABF35C00323D32 /* llvm-ld.pod */,
- DE66F3A808ABF35C00323D32 /* llvm-link.pod */,
- DE66F3A908ABF35C00323D32 /* llvm-nm.pod */,
- DE66F3AA08ABF35C00323D32 /* llvm-prof.pod */,
- DE66F3AB08ABF35C00323D32 /* llvm-ranlib.pod */,
- DE66F3AC08ABF35C00323D32 /* llvmc.pod */,
- DE66F3AD08ABF35C00323D32 /* llvmgcc.pod */,
- DE66F3AE08ABF35C00323D32 /* llvmgxx.pod */,
- DE66F3AF08ABF35C00323D32 /* Makefile */,
- DE66F3B408ABF35D00323D32 /* manpage.css */,
- DE66F3B508ABF35D00323D32 /* opt.pod */,
- DE66F3B808ABF35D00323D32 /* stkrc.pod */,
- );
- path = CommandGuide;
- sourceTree = "<group>";
- };
- DE66F3E508ABF35D00323D32 /* img */ = {
- isa = PBXGroup;
- children = (
- DE66F3E608ABF35D00323D32 /* Debugging.gif */,
- DE66F3E708ABF35D00323D32 /* libdeps.gif */,
- DE66F3E808ABF35D00323D32 /* lines.gif */,
- DE66F3E908ABF35D00323D32 /* objdeps.gif */,
- DE66F3EA08ABF35D00323D32 /* venusflytrap.jpg */,
- );
- path = img;
- sourceTree = "<group>";
- };
- DE66F3FD08ABF37000323D32 /* examples */ = {
- isa = PBXGroup;
- children = (
- F22761DF0DAD09CD003D8065 /* BrainF.cpp */,
- F22761E00DAD09CD003D8065 /* BrainF.h */,
- F22761E10DAD09CD003D8065 /* BrainFDriver.cpp */,
- DE66F40E08ABF37000323D32 /* fibonacci.cpp */,
- DE66F41508ABF37000323D32 /* HowToUseJIT.cpp */,
- DE66F41E08ABF37000323D32 /* ModuleMaker.cpp */,
- DE66F42608ABF37000323D32 /* ParallelJIT.cpp */,
- );
- name = examples;
- path = ../examples;
- sourceTree = SOURCE_ROOT;
- };
- DE816FAC08CFB44C0093BDEF /* utils */ = {
- isa = PBXGroup;
- children = (
- DE81705708CFB44D0093BDEF /* TableGen */,
- DE81704008CFB44D0093BDEF /* fpcmp.cpp */,
- DE81704F08CFB44D0093BDEF /* NightlyTest.gnuplot */,
- DE81705108CFB44D0093BDEF /* NightlyTestTemplate.html */,
- );
- name = utils;
- path = ../utils;
- sourceTree = SOURCE_ROOT;
- };
- DE81705708CFB44D0093BDEF /* TableGen */ = {
- isa = PBXGroup;
- children = (
- DE81705908CFB44D0093BDEF /* AsmWriterEmitter.cpp */,
- DE81705A08CFB44D0093BDEF /* AsmWriterEmitter.h */,
- DE81705B08CFB44D0093BDEF /* CodeEmitterGen.cpp */,
- DE81705C08CFB44D0093BDEF /* CodeEmitterGen.h */,
- DE81705D08CFB44D0093BDEF /* CodeGenInstruction.h */,
- CF8F1BC90B64FBD500BB4199 /* CodeGenIntrinsics.h */,
- DE81705E08CFB44D0093BDEF /* CodeGenRegisters.h */,
- DE81705F08CFB44D0093BDEF /* CodeGenTarget.cpp */,
- DE81706008CFB44D0093BDEF /* CodeGenTarget.h */,
- DE81706708CFB44D0093BDEF /* DAGISelEmitter.cpp */,
- DE81706808CFB44D0093BDEF /* DAGISelEmitter.h */,
- CF9720970A9F3D4D002CEEDD /* IntrinsicEmitter.cpp */,
- CF9720980A9F3D4D002CEEDD /* IntrinsicEmitter.h */,
- DE81708908CFB44D0093BDEF /* InstrInfoEmitter.cpp */,
- DE81708A08CFB44D0093BDEF /* InstrInfoEmitter.h */,
- DE81708E08CFB44D0093BDEF /* Record.cpp */,
- DE81708F08CFB44D0093BDEF /* Record.h */,
- DE81709008CFB44D0093BDEF /* RegisterInfoEmitter.cpp */,
- DE81709108CFB44D0093BDEF /* RegisterInfoEmitter.h */,
- DE4DA065091148520012D44B /* SubtargetEmitter.cpp */,
- DE4DA066091148520012D44B /* SubtargetEmitter.h */,
- DE8170AA08CFB44D0093BDEF /* TableGen.cpp */,
- DE8170AB08CFB44D0093BDEF /* TableGenBackend.cpp */,
- DE8170AC08CFB44D0093BDEF /* TableGenBackend.h */,
- CF490E300907BBF80072DB1C /* SubtargetEmitter.cpp */,
- CF490E2F0907BBF80072DB1C /* SubtargetEmitter.h */,
- );
- path = TableGen;
- sourceTree = "<group>";
- };
- F22627310DAE34D10008F441 /* tutorial */ = {
- isa = PBXGroup;
- children = (
- F22627320DAE34D10008F441 /* index.html */,
- F22627330DAE34D20008F441 /* JITTutorial1.html */,
- F22627340DAE34D20008F441 /* JITTutorial2-1.png */,
- F22627350DAE34D20008F441 /* JITTutorial2.html */,
- F22627360DAE34D20008F441 /* LangImpl1.html */,
- F22627370DAE34D20008F441 /* LangImpl2.html */,
- F22627380DAE34D20008F441 /* LangImpl3.html */,
- F22627390DAE34D20008F441 /* LangImpl4.html */,
- F226273A0DAE34D20008F441 /* LangImpl5-cfg.png */,
- F226273B0DAE34D20008F441 /* LangImpl5.html */,
- F226273C0DAE34D20008F441 /* LangImpl6.html */,
- F226273D0DAE34D20008F441 /* LangImpl7.html */,
- F226273E0DAE34D20008F441 /* LangImpl8.html */,
- F226273F0DAE34D20008F441 /* Makefile */,
- F22627400DAE34D20008F441 /* OCamlLangImpl1.html */,
- F22627410DAE34D20008F441 /* OCamlLangImpl2.html */,
- F22627420DAE34D20008F441 /* OCamlLangImpl3.html */,
- F22627430DAE34D20008F441 /* OCamlLangImpl4.html */,
- F22627440DAE34D20008F441 /* OCamlLangImpl5.html */,
- F22627450DAE34D20008F441 /* OCamlLangImpl6.html */,
- F22627460DAE34D20008F441 /* OCamlLangImpl7.html */,
- );
- path = tutorial;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXLegacyTarget section */
- CF0329B608D1BE110030FD33 /* LLVM lib */ = {
- isa = PBXLegacyTarget;
- buildArgumentsString = "$(ACTION) -j 2";
- buildConfigurationList = CF0329B708D1BE530030FD33 /* Build configuration list for PBXLegacyTarget "LLVM lib" */;
- buildPhases = (
- );
- buildToolPath = /usr/bin/make;
- buildWorkingDirectory = "$(SRCROOT)/../lib";
- dependencies = (
- );
- name = "LLVM lib";
- passBuildSettingsInEnvironment = 0;
- productName = "LLVM lib";
- };
- CF0329BB08D1BE5D0030FD33 /* LLVM llc */ = {
- isa = PBXLegacyTarget;
- buildArgumentsString = "$(ACTION) -j 2";
- buildConfigurationList = CF0329C308D1BEC40030FD33 /* Build configuration list for PBXLegacyTarget "LLVM llc" */;
- buildPhases = (
- );
- buildToolPath = /usr/bin/make;
- buildWorkingDirectory = "$(SRCROOT)/../tools/llc";
- dependencies = (
- );
- name = "LLVM llc";
- passBuildSettingsInEnvironment = 0;
- productName = "LLVM llc";
- };
- CF490E830907CDAB0072DB1C /* LLVM TableGen */ = {
- isa = PBXLegacyTarget;
- buildArgumentsString = "$(ACTION) -j 2";
- buildConfigurationList = CF490E840907CDAB0072DB1C /* Build configuration list for PBXLegacyTarget "LLVM TableGen" */;
- buildPhases = (
- );
- buildToolPath = /usr/bin/make;
- buildWorkingDirectory = "${SRCROOT}/../utils/TableGen";
- dependencies = (
- );
- name = "LLVM TableGen";
- passBuildSettingsInEnvironment = 0;
- productName = "LLVM llc";
- };
- CFDF86BD0ADE819D00D40A3D /* LLVM lib release */ = {
- isa = PBXLegacyTarget;
- buildArgumentsString = "$(ACTION) -j 2 ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1";
- buildConfigurationList = CFDF86BE0ADE819D00D40A3D /* Build configuration list for PBXLegacyTarget "LLVM lib release" */;
- buildPhases = (
- );
- buildToolPath = /usr/bin/make;
- buildWorkingDirectory = "$(SRCROOT)/../lib";
- dependencies = (
- );
- name = "LLVM lib release";
- passBuildSettingsInEnvironment = 0;
- productName = "LLVM lib";
- };
- CFDF86C60ADE81D000D40A3D /* LLVM llc release */ = {
- isa = PBXLegacyTarget;
- buildArgumentsString = "$(ACTION) -j 2 ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1";
- buildConfigurationList = CFDF86C70ADE81D000D40A3D /* Build configuration list for PBXLegacyTarget "LLVM llc release" */;
- buildPhases = (
- );
- buildToolPath = /usr/bin/make;
- buildWorkingDirectory = "$(SRCROOT)/../tools/llc";
- dependencies = (
- );
- name = "LLVM llc release";
- passBuildSettingsInEnvironment = 0;
- productName = "LLVM llc";
- };
- D28A88AD04BDD90700651E21 /* LLVM */ = {
- isa = PBXLegacyTarget;
- buildArgumentsString = "$(ACTION) -j 2";
- buildConfigurationList = DE66EC4C08ABE78900323D32 /* Build configuration list for PBXLegacyTarget "LLVM" */;
- buildPhases = (
- );
- buildToolPath = /usr/bin/make;
- buildWorkingDirectory = "$(SRCROOT)/../";
- dependencies = (
- );
- name = LLVM;
- passBuildSettingsInEnvironment = 0;
- productName = LLVM;
- };
-/* End PBXLegacyTarget section */
-
-/* Begin PBXProject section */
- 08FB7793FE84155DC02AAC07 /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = DE66EC5008ABE78900323D32 /* Build configuration list for PBXProject "LLVM" */;
- compatibilityVersion = "Xcode 2.4";
- hasScannedForEncodings = 1;
- mainGroup = 08FB7794FE84155DC02AAC07 /* LLVM */;
- productRefGroup = 721CA1750D0B44D200D5004F /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- D28A88AD04BDD90700651E21 /* LLVM */,
- CF0329B608D1BE110030FD33 /* LLVM lib */,
- CF0329BB08D1BE5D0030FD33 /* LLVM llc */,
- CF0329BC08D1BE8E0030FD33 /* LLVM full llc */,
- CF490E830907CDAB0072DB1C /* LLVM TableGen */,
- CFDF86BD0ADE819D00D40A3D /* LLVM lib release */,
- CFDF86C60ADE81D000D40A3D /* LLVM llc release */,
- CFDF86D00ADE820000D40A3D /* LLVM full llc release */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXTargetDependency section */
- CF0329BE08D1BE970030FD33 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = CF0329B608D1BE110030FD33 /* LLVM lib */;
- targetProxy = CF0329BD08D1BE970030FD33 /* PBXContainerItemProxy */;
- };
- CF0329C008D1BE9B0030FD33 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = CF0329BB08D1BE5D0030FD33 /* LLVM llc */;
- targetProxy = CF0329BF08D1BE9B0030FD33 /* PBXContainerItemProxy */;
- };
- CFDF86DA0ADE822100D40A3D /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = CFDF86BD0ADE819D00D40A3D /* LLVM lib release */;
- targetProxy = CFDF86D90ADE822100D40A3D /* PBXContainerItemProxy */;
- };
- CFDF86DC0ADE822100D40A3D /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = CFDF86C60ADE81D000D40A3D /* LLVM llc release */;
- targetProxy = CFDF86DB0ADE822100D40A3D /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
- CF0329B808D1BE530030FD33 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM lib";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Debug;
- };
- CF0329B908D1BE530030FD33 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM lib";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Release;
- };
- CF0329C408D1BEC40030FD33 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Debug;
- };
- CF0329C508D1BEC40030FD33 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Release;
- };
- CF0329C808D1BEC40030FD33 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM full llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Debug;
- };
- CF0329C908D1BEC40030FD33 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM full llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Release;
- };
- CF490E850907CDAB0072DB1C /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM TableGen";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Debug;
- };
- CF490E860907CDAB0072DB1C /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Release;
- };
- CFDF86BF0ADE819D00D40A3D /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM lib";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Debug;
- };
- CFDF86C00ADE819D00D40A3D /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM lib";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Release;
- };
- CFDF86C80ADE81D000D40A3D /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Debug;
- };
- CFDF86C90ADE81D000D40A3D /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Release;
- };
- CFDF86D60ADE820000D40A3D /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM full llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Debug;
- };
- CFDF86D70ADE820000D40A3D /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = "LLVM full llc";
- SECTORDER_FLAGS = "";
- WARNING_CFLAGS = (
- "-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- };
- name = Release;
- };
- DE66EC4D08ABE78900323D32 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- DEBUGGING_SYMBOLS = YES;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- PRODUCT_NAME = LLVM;
- ZERO_LINK = YES;
- };
- name = Debug;
- };
- DE66EC4E08ABE78900323D32 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- ENABLE_OPTIMIZED = 1;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- PRODUCT_NAME = LLVM;
- ZERO_LINK = NO;
- };
- name = Release;
- };
- DE66EC5108ABE78900323D32 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- DEBUG_INFORMATION_FORMAT = dwarf;
- GCC_OPTIMIZATION_LEVEL = 0;
- USER_HEADER_SEARCH_PATHS = "../include/**";
- };
- name = Debug;
- };
- DE66EC5208ABE78900323D32 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- DEBUG_INFORMATION_FORMAT = dwarf;
- USER_HEADER_SEARCH_PATHS = "../include/**";
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- CF0329B708D1BE530030FD33 /* Build configuration list for PBXLegacyTarget "LLVM lib" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CF0329B808D1BE530030FD33 /* Debug */,
- CF0329B908D1BE530030FD33 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- CF0329C308D1BEC40030FD33 /* Build configuration list for PBXLegacyTarget "LLVM llc" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CF0329C408D1BEC40030FD33 /* Debug */,
- CF0329C508D1BEC40030FD33 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- CF0329C708D1BEC40030FD33 /* Build configuration list for PBXAggregateTarget "LLVM full llc" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CF0329C808D1BEC40030FD33 /* Debug */,
- CF0329C908D1BEC40030FD33 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- CF490E840907CDAB0072DB1C /* Build configuration list for PBXLegacyTarget "LLVM TableGen" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CF490E850907CDAB0072DB1C /* Debug */,
- CF490E860907CDAB0072DB1C /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- CFDF86BE0ADE819D00D40A3D /* Build configuration list for PBXLegacyTarget "LLVM lib release" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CFDF86BF0ADE819D00D40A3D /* Debug */,
- CFDF86C00ADE819D00D40A3D /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- CFDF86C70ADE81D000D40A3D /* Build configuration list for PBXLegacyTarget "LLVM llc release" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CFDF86C80ADE81D000D40A3D /* Debug */,
- CFDF86C90ADE81D000D40A3D /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- CFDF86D50ADE820000D40A3D /* Build configuration list for PBXAggregateTarget "LLVM full llc release" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CFDF86D60ADE820000D40A3D /* Debug */,
- CFDF86D70ADE820000D40A3D /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DE66EC4C08ABE78900323D32 /* Build configuration list for PBXLegacyTarget "LLVM" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DE66EC4D08ABE78900323D32 /* Debug */,
- DE66EC4E08ABE78900323D32 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DE66EC5008ABE78900323D32 /* Build configuration list for PBXProject "LLVM" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DE66EC5108ABE78900323D32 /* Debug */,
- DE66EC5208ABE78900323D32 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/Xcode/README.txt b/Xcode/README.txt
deleted file mode 100644
index 614cd67..0000000
--- a/Xcode/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-Xcode project files for LLVM, for Xcode 2.1
diff --git a/autoconf/ExportMap.map b/autoconf/ExportMap.map
index 43e310e..17b185f 100644
--- a/autoconf/ExportMap.map
+++ b/autoconf/ExportMap.map
@@ -1,4 +1,7 @@
{
global: main;
+ __progname;
+ environ;
+
local: *;
};
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 40f77d8..a5cb788 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -80,6 +80,7 @@ do
llvm-tv) AC_CONFIG_SUBDIRS([projects/llvm-tv]) ;;
llvm-poolalloc) AC_CONFIG_SUBDIRS([projects/llvm-poolalloc]) ;;
poolalloc) AC_CONFIG_SUBDIRS([projects/poolalloc]) ;;
+ safecode) AC_CONFIG_SUBDIRS([projects/safecode]) ;;
llvm-kernel) AC_CONFIG_SUBDIRS([projects/llvm-kernel]) ;;
*)
AC_MSG_WARN([Unknown project (${i}) won't be configured automatically])
@@ -184,7 +185,7 @@ AC_CACHE_CHECK([type of operating system we're going to host on],
llvm_cv_link_all_option="-Wl,--whole-archive"
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
llvm_cv_os_type="Haiku"
- llvm_cv_platform_type="Unix" ;;
+ llvm_cv_platform_type="Unix" ;;
*-unknown-eabi*)
llvm_cv_link_all_option="-Wl,--whole-archive"
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
@@ -236,7 +237,7 @@ AC_CACHE_CHECK([type of operating system we're going to target],
*-*-mingw*)
llvm_cv_target_os_type="MingW" ;;
*-*-haiku*)
- llvm_cv_target_os_type="Haiku" ;;
+ llvm_cv_target_os_type="Haiku" ;;
*-unknown-eabi*)
llvm_cv_target_os_type="Freestanding" ;;
*)
@@ -291,6 +292,7 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
msp430-*) llvm_cv_target_arch="MSP430" ;;
s390x-*) llvm_cv_target_arch="SystemZ" ;;
bfin-*) llvm_cv_target_arch="Blackfin" ;;
+ mblaze-*) llvm_cv_target_arch="MBlaze" ;;
*) llvm_cv_target_arch="Unknown" ;;
esac])
@@ -427,6 +429,7 @@ else
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
Blackfin) AC_SUBST(TARGET_HAS_JIT,0) ;;
+ MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
*) AC_SUBST(TARGET_HAS_JIT,0) ;;
esac
fi
@@ -470,6 +473,18 @@ esac
AC_DEFINE_UNQUOTED([ENABLE_PIC],$ENABLE_PIC,
[Define if position independent code is enabled])
+dnl Allow building a shared library and linking tools against it.
+AC_ARG_ENABLE(shared,
+ AS_HELP_STRING([--enable-shared],
+ [Build a shared library and link tools against it (default is NO)]),,
+ enableval=default)
+case "$enableval" in
+ yes) AC_SUBST(ENABLE_SHARED,[1]) ;;
+ no) AC_SUBST(ENABLE_SHARED,[0]) ;;
+ default) AC_SUBST(ENABLE_SHARED,[0]) ;;
+ *) AC_MSG_ERROR([Invalid setting for --enable-shared. Use "yes" or "no"]) ;;
+esac
+
dnl Allow specific targets to be specified for building (or not)
TARGETS_TO_BUILD=""
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
@@ -481,7 +496,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
- all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" ;;
+ all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -500,6 +515,7 @@ case "$enableval" in
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
+ mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -508,6 +524,7 @@ case "$enableval" in
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
+ MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
@@ -612,6 +629,56 @@ if test -n "$LLVMGXX" && test -z "$LLVMGCC"; then
AC_MSG_ERROR([Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used]);
fi
+dnl Allow a specific Clang compiler to be used with this LLVM config.
+AC_ARG_WITH(clang,
+ AS_HELP_STRING([--with-clang],
+ [Specify location of clang compiler (default is --with-built-clang)]),
+ [],[with_clang=default])
+
+dnl Enable use of the built Clang.
+AC_ARG_WITH(built-clang,
+ AS_HELP_STRING([--with-built-clang],
+ [Use the compiled Clang as the LLVM compiler (default=check)]),
+ [],[with_built_clang=check])
+
+dnl Select the Clang compiler option.
+dnl
+dnl If --with-clang is given, always honor that; otherwise honor
+dnl --with-built-clang, or check if we have the clang sources.
+AC_MSG_CHECKING([clang compiler])
+WITH_CLANGPATH=""
+WITH_BUILT_CLANG=0
+if test "$with_clang" != "default"; then
+ WITH_CLANGPATH="$with_clang"
+ if ! test -x "$WITH_CLANGPATH"; then
+ AC_MSG_ERROR([invalid --with-clang, path does not specify an executable])
+ fi
+elif test "$with_built_clang" = "yes"; then
+ WITH_BUILT_CLANG=1
+elif test "$with_built_clang" = "no"; then
+ WITH_BUILT_CLANG=0
+else
+ if test "$with_built_clang" != "check"; then
+ AC_MSG_ERROR([invalid value for --with-built-clang.])
+ fi
+
+ if test -f ${srcdir}/tools/clang/README.txt; then
+ WITH_BUILT_CLANG=1
+ fi
+fi
+
+if ! test -z "$WITH_CLANGPATH"; then
+ AC_MSG_RESULT([$WITH_CLANGPATH])
+ WITH_CLANGXXPATH=`"$WITH_CLANGPATH" --print-prog-name=clang++`
+elif test "$WITH_BUILT_CLANG" = "1"; then
+ AC_MSG_RESULT([built])
+else
+ AC_MSG_RESULT([none])
+fi
+AC_SUBST(CLANGPATH,$WITH_CLANGPATH)
+AC_SUBST(CLANGXXPATH,$WITH_CLANGXXPATH)
+AC_SUBST(ENABLE_BUILT_CLANG,$WITH_BUILT_CLANG)
+
dnl Override the option to use for optimized builds.
AC_ARG_WITH(optimize-option,
AS_HELP_STRING([--with-optimize-option],
@@ -946,6 +1013,29 @@ else
AC_SUBST(LLVMGXXCOMMAND,$LLVMGXXCOMMAND)
fi
+dnl Select the LLVM capable compiler to use, we default to using llvm-gcc if
+dnl found, otherwise clang if available.
+AC_ARG_WITH(llvmcc,
+ AS_HELP_STRING([--with-llvmcc=<name>],
+ [Choose the LLVM capable compiler to use (llvm-gcc, clang, or none; default=check)]),
+ [],[with_llvmcc=check])
+AC_MSG_CHECKING([LLVM capable compiler])
+if test "$with_llvmcc" != "check"; then
+ if (test "$with_llvmcc" != "llvm-gcc" &&
+ test "$with_llvmcc" != "clang" &&
+ test "$with_llvmcc" != "none"); then
+ AC_MSG_ERROR([invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'.])
+ fi
+ WITH_LLVMCC="$with_llvmcc"
+elif test -n "$LLVMGCC"; then
+ WITH_LLVMCC=llvm-gcc
+elif test -n "$WITH_CLANGPATH" || test "$WITH_BUILT_CLANG" -ne "0"; then
+ WITH_LLVMCC=clang
+else
+ WITH_LLVMCC=none
+fi
+AC_MSG_RESULT([$WITH_LLVMCC])
+AC_SUBST(LLVMCC_OPTION,$WITH_LLVMCC)
AC_MSG_CHECKING([tool compatibility])
@@ -994,7 +1084,7 @@ fi
dnl Tool compatibility is okay if we make it here.
AC_MSG_RESULT([ok])
-dnl Check optional compiler flags.
+dnl Check optional compiler flags.
AC_MSG_CHECKING([optional compiler flags])
CXX_FLAG_CHECK(NO_VARIADIC_MACROS, [-Wno-variadic-macros])
CXX_FLAG_CHECK(NO_MISSING_FIELD_INITIALIZERS, [-Wno-missing-field-initializers])
@@ -1250,12 +1340,6 @@ if test "$llvm_cv_llvmgcc_sanity" = "yes" ; then
AC_SUBST(LLVMCC1PLUS,$llvmcc1pluspath)
llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'`
AC_SUBST(LLVMGCCDIR,$llvmgccdir)
- llvmgcclibexec=`echo "$llvmcc1path" | sed 's,/cc1,,'`
- AC_SUBST(LLVMGCCLIBEXEC,$llvmgcclibexec)
- llvmgccversion=[`"$LLVMGCC" -dumpversion 2>&1 | sed 's/^\([0-9.]*\).*/\1/'`]
- llvmgccmajvers=[`echo $llvmgccversion | sed 's/^\([0-9]\).*/\1/'`]
- AC_SUBST(LLVMGCC_VERSION,$llvmgccversion)
- AC_SUBST(LLVMGCC_MAJVERS,$llvmgccmajvers)
llvmgcclangs=[`"$LLVMGCC" -v --help 2>&1 | grep '^Configured with:' | sed 's/^.*--enable-languages=\([^ ]*\).*/\1/'`]
AC_SUBST(LLVMGCC_LANGS,$llvmgcclangs)
AC_MSG_RESULT([ok])
@@ -1265,6 +1349,10 @@ dnl Propagate the shared library extension that the libltdl checks did to
dnl the Makefiles so we can use it there too
AC_SUBST(SHLIBEXT,$libltdl_cv_shlibext)
+dnl Propagate the run-time library path variable that the libltdl
+dnl checks found to the Makefiles so we can use it there too
+AC_SUBST(SHLIBPATH_VAR,$libltdl_cv_shlibpath_var)
+
# Translate the various configuration directories and other basic
# information into substitutions that will end up in Makefile.config.in
# that these configured values can be used by the makefiles
@@ -1275,7 +1363,7 @@ eval LLVM_PREFIX="${prefix}";
eval LLVM_BINDIR="${prefix}/bin";
eval LLVM_LIBDIR="${prefix}/lib";
eval LLVM_DATADIR="${prefix}/share/llvm";
-eval LLVM_DOCSDIR="${prefix}/docs/llvm";
+eval LLVM_DOCSDIR="${prefix}/share/doc/llvm";
eval LLVM_ETCDIR="${prefix}/etc/llvm";
eval LLVM_INCLUDEDIR="${prefix}/include";
eval LLVM_INFODIR="${prefix}/info";
diff --git a/autoconf/m4/huge_val.m4 b/autoconf/m4/huge_val.m4
index fd94c11..5fffbfc 100644
--- a/autoconf/m4/huge_val.m4
+++ b/autoconf/m4/huge_val.m4
@@ -5,6 +5,7 @@
AC_DEFUN([AC_HUGE_VAL_CHECK],[
AC_CACHE_CHECK([for HUGE_VAL sanity], [ac_cv_huge_val_sanity],[
AC_LANG_PUSH([C++])
+ ac_save_CXXFLAGS=$CXXFLAGS
CXXFLAGS=-pedantic
AC_RUN_IFELSE(
AC_LANG_PROGRAM(
@@ -12,6 +13,7 @@ AC_DEFUN([AC_HUGE_VAL_CHECK],[
[double x = HUGE_VAL; return x != x; ]),
[ac_cv_huge_val_sanity=yes],[ac_cv_huge_val_sanity=no],
[ac_cv_huge_val_sanity=yes])
+ CXXFLAGS=$ac_save_CXXFLAGS
AC_LANG_POP([C++])
])
AC_SUBST(HUGE_VAL_SANITY,$ac_cv_huge_val_sanity)
diff --git a/bindings/ocaml/bitreader/bitreader_ocaml.c b/bindings/ocaml/bitreader/bitreader_ocaml.c
index 5fd9f85..ef72ce2 100644
--- a/bindings/ocaml/bitreader/bitreader_ocaml.c
+++ b/bindings/ocaml/bitreader/bitreader_ocaml.c
@@ -46,17 +46,16 @@ static void llvm_raise(value Prototype, char *Message) {
/*===-- Modules -----------------------------------------------------------===*/
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
-CAMLprim value llvm_get_module_provider(LLVMContextRef C,
- LLVMMemoryBufferRef MemBuf) {
+CAMLprim value llvm_get_module(LLVMContextRef C, LLVMMemoryBufferRef MemBuf) {
CAMLparam0();
CAMLlocal2(Variant, MessageVal);
char *Message;
- LLVMModuleProviderRef MP;
- if (LLVMGetBitcodeModuleProviderInContext(C, MemBuf, &MP, &Message))
+ LLVMModuleRef M;
+ if (LLVMGetBitcodeModuleInContext(C, MemBuf, &M, &Message))
llvm_raise(llvm_bitreader_error_exn, Message);
- CAMLreturn((value) MemBuf);
+ CAMLreturn((value) M);
}
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
diff --git a/bindings/ocaml/bitreader/llvm_bitreader.ml b/bindings/ocaml/bitreader/llvm_bitreader.ml
index 88587cb..8b9d01d 100644
--- a/bindings/ocaml/bitreader/llvm_bitreader.ml
+++ b/bindings/ocaml/bitreader/llvm_bitreader.ml
@@ -13,9 +13,8 @@ exception Error of string
external register_exns : exn -> unit = "llvm_register_bitreader_exns"
let _ = register_exns (Error "")
-external get_module_provider : Llvm.llcontext -> Llvm.llmemorybuffer ->
- Llvm.llmoduleprovider
- = "llvm_get_module_provider"
+external get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
+ = "llvm_get_module"
external parse_bitcode : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
= "llvm_parse_bitcode"
diff --git a/bindings/ocaml/bitreader/llvm_bitreader.mli b/bindings/ocaml/bitreader/llvm_bitreader.mli
index 5648b35..5e22409 100644
--- a/bindings/ocaml/bitreader/llvm_bitreader.mli
+++ b/bindings/ocaml/bitreader/llvm_bitreader.mli
@@ -14,14 +14,12 @@
exception Error of string
-(** [get_module_provider context mb] reads the bitcode for a new
- module provider [m] from the memory buffer [mb] in the context [context].
- Returns [m] if successful, or raises [Error msg] otherwise, where [msg] is a
- description of the error encountered. See the function
- [llvm::getBitcodeModuleProvider]. *)
-external get_module_provider : Llvm.llcontext -> Llvm.llmemorybuffer ->
- Llvm.llmoduleprovider
- = "llvm_get_module_provider"
+(** [get_module context mb] reads the bitcode for a new module [m] from the
+ memory buffer [mb] in the context [context]. Returns [m] if successful, or
+ raises [Error msg] otherwise, where [msg] is a description of the error
+ encountered. See the function [llvm::getBitcodeModule]. *)
+external get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
+ = "llvm_get_module"
(** [parse_bitcode context mb] parses the bitcode for a new module [m] from the
memory buffer [mb] in the context [context]. Returns [m] if successful, or
diff --git a/bindings/ocaml/bitwriter/bitwriter_ocaml.c b/bindings/ocaml/bitwriter/bitwriter_ocaml.c
index 41aca25..53c93cb 100644
--- a/bindings/ocaml/bitwriter/bitwriter_ocaml.c
+++ b/bindings/ocaml/bitwriter/bitwriter_ocaml.c
@@ -28,3 +28,18 @@ CAMLprim value llvm_write_bitcode_file(value M, value Path) {
int res = LLVMWriteBitcodeToFile((LLVMModuleRef) M, String_val(Path));
return Val_bool(res == 0);
}
+
+/* ?unbuffered:bool -> Llvm.llmodule -> Unix.file_descr -> bool */
+CAMLprim value llvm_write_bitcode_to_fd(value U, value M, value FD) {
+ int Unbuffered;
+ int res;
+
+ if (U == Val_int(0)) {
+ Unbuffered = 0;
+ } else {
+ Unbuffered = Bool_val(Field(U,0));
+ }
+
+ res = LLVMWriteBitcodeToFD((LLVMModuleRef) M, Int_val(FD), 0, Unbuffered);
+ return Val_bool(res == 0);
+}
diff --git a/bindings/ocaml/bitwriter/llvm_bitwriter.ml b/bindings/ocaml/bitwriter/llvm_bitwriter.ml
index 7b45c53..3e69a3c 100644
--- a/bindings/ocaml/bitwriter/llvm_bitwriter.ml
+++ b/bindings/ocaml/bitwriter/llvm_bitwriter.ml
@@ -16,3 +16,10 @@
(* Writes the bitcode for module the given path. Returns true if successful. *)
external write_bitcode_file : Llvm.llmodule -> string -> bool
= "llvm_write_bitcode_file"
+
+external write_bitcode_to_fd : ?unbuffered:bool -> Llvm.llmodule
+ -> Unix.file_descr -> bool
+ = "llvm_write_bitcode_to_fd"
+
+let output_bitcode ?unbuffered channel m =
+ write_bitcode_to_fd ?unbuffered m (Unix.descr_of_out_channel channel)
diff --git a/bindings/ocaml/bitwriter/llvm_bitwriter.mli b/bindings/ocaml/bitwriter/llvm_bitwriter.mli
index 2f782a1..ea9a876 100644
--- a/bindings/ocaml/bitwriter/llvm_bitwriter.mli
+++ b/bindings/ocaml/bitwriter/llvm_bitwriter.mli
@@ -16,3 +16,15 @@
[path]. Returns [true] if successful, [false] otherwise. *)
external write_bitcode_file : Llvm.llmodule -> string -> bool
= "llvm_write_bitcode_file"
+
+(** [write_bitcode_to_fd ~unbuffered fd m] writes the bitcode for module
+ [m] to the channel [c]. If [unbuffered] is [true], after every write the fd
+ will be flushed. Returns [true] if successful, [false] otherwise. *)
+external write_bitcode_to_fd : ?unbuffered:bool -> Llvm.llmodule
+ -> Unix.file_descr -> bool
+ = "llvm_write_bitcode_to_fd"
+
+(** [output_bitcode ~unbuffered c m] writes the bitcode for module [m]
+ to the channel [c]. If [unbuffered] is [true], after every write the fd
+ will be flushed. Returns [true] if successful, [false] otherwise. *)
+val output_bitcode : ?unbuffered:bool -> out_channel -> Llvm.llmodule -> bool
diff --git a/bindings/ocaml/executionengine/executionengine_ocaml.c b/bindings/ocaml/executionengine/executionengine_ocaml.c
index 072d583..5b1e32e 100644
--- a/bindings/ocaml/executionengine/executionengine_ocaml.c
+++ b/bindings/ocaml/executionengine/executionengine_ocaml.c
@@ -91,7 +91,7 @@ CAMLprim value llvm_genericvalue_of_float(LLVMTypeRef Ty, value N) {
}
/* 'a -> t */
-CAMLprim value llvm_genericvalue_of_value(value V) {
+CAMLprim value llvm_genericvalue_of_pointer(value V) {
CAMLparam1(V);
CAMLreturn(alloc_generic_value(LLVMCreateGenericValueOfPointer(Op_val(V))));
}
@@ -130,7 +130,7 @@ CAMLprim value llvm_genericvalue_as_float(LLVMTypeRef Ty, value GenVal) {
}
/* t -> 'a */
-CAMLprim value llvm_genericvalue_as_value(value GenVal) {
+CAMLprim value llvm_genericvalue_as_pointer(value GenVal) {
return Val_op(LLVMGenericValueToPointer(Genericvalue_val(GenVal)));
}
@@ -168,41 +168,31 @@ CAMLprim value llvm_genericvalue_as_nativeint(value GenVal) {
/*--... Operations on execution engines ....................................--*/
-/* llmoduleprovider -> ExecutionEngine.t */
-CAMLprim LLVMExecutionEngineRef llvm_ee_create(LLVMModuleProviderRef MP) {
+/* llmodule -> ExecutionEngine.t */
+CAMLprim LLVMExecutionEngineRef llvm_ee_create(LLVMModuleRef M) {
LLVMExecutionEngineRef Interp;
char *Error;
- if (LLVMCreateExecutionEngine(&Interp, MP, &Error))
+ if (LLVMCreateExecutionEngineForModule(&Interp, M, &Error))
llvm_raise(llvm_ee_error_exn, Error);
return Interp;
}
-/* llmoduleprovider -> ExecutionEngine.t */
+/* llmodule -> ExecutionEngine.t */
CAMLprim LLVMExecutionEngineRef
-llvm_ee_create_interpreter(LLVMModuleProviderRef MP) {
+llvm_ee_create_interpreter(LLVMModuleRef M) {
LLVMExecutionEngineRef Interp;
char *Error;
- if (LLVMCreateInterpreter(&Interp, MP, &Error))
+ if (LLVMCreateInterpreterForModule(&Interp, M, &Error))
llvm_raise(llvm_ee_error_exn, Error);
return Interp;
}
-/* llmoduleprovider -> ExecutionEngine.t */
+/* llmodule -> int -> ExecutionEngine.t */
CAMLprim LLVMExecutionEngineRef
-llvm_ee_create_jit(LLVMModuleProviderRef MP) {
+llvm_ee_create_jit(LLVMModuleRef M, value OptLevel) {
LLVMExecutionEngineRef JIT;
char *Error;
- if (LLVMCreateJITCompiler(&JIT, MP, 3, &Error))
- llvm_raise(llvm_ee_error_exn, Error);
- return JIT;
-}
-
-/* llmoduleprovider -> ExecutionEngine.t */
-CAMLprim LLVMExecutionEngineRef
-llvm_ee_create_fast_jit(LLVMModuleProviderRef MP) {
- LLVMExecutionEngineRef JIT;
- char *Error;
- if (LLVMCreateJITCompiler(&JIT, MP, 0, &Error))
+ if (LLVMCreateJITCompilerForModule(&JIT, M, Int_val(OptLevel), &Error))
llvm_raise(llvm_ee_error_exn, Error);
return JIT;
}
@@ -213,19 +203,18 @@ CAMLprim value llvm_ee_dispose(LLVMExecutionEngineRef EE) {
return Val_unit;
}
-/* llmoduleprovider -> ExecutionEngine.t -> unit */
-CAMLprim value llvm_ee_add_mp(LLVMModuleProviderRef MP,
- LLVMExecutionEngineRef EE) {
- LLVMAddModuleProvider(EE, MP);
+/* llmodule -> ExecutionEngine.t -> unit */
+CAMLprim value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
+ LLVMAddModule(EE, M);
return Val_unit;
}
-/* llmoduleprovider -> ExecutionEngine.t -> llmodule */
-CAMLprim LLVMModuleRef llvm_ee_remove_mp(LLVMModuleProviderRef MP,
- LLVMExecutionEngineRef EE) {
+/* llmodule -> ExecutionEngine.t -> llmodule */
+CAMLprim LLVMModuleRef llvm_ee_remove_module(LLVMModuleRef M,
+ LLVMExecutionEngineRef EE) {
LLVMModuleRef RemovedModule;
char *Error;
- if (LLVMRemoveModuleProvider(EE, MP, &RemovedModule, &Error))
+ if (LLVMRemoveModule(EE, M, &RemovedModule, &Error))
llvm_raise(llvm_ee_error_exn, Error);
return RemovedModule;
}
@@ -237,7 +226,7 @@ CAMLprim value llvm_ee_find_function(value Name, LLVMExecutionEngineRef EE) {
LLVMValueRef Found;
if (LLVMFindFunction(EE, String_val(Name), &Found))
CAMLreturn(Val_unit);
- Option = alloc(1, 1);
+ Option = alloc(1, 0);
Field(Option, 0) = Val_op(Found);
CAMLreturn(Option);
}
diff --git a/bindings/ocaml/executionengine/llvm_executionengine.ml b/bindings/ocaml/executionengine/llvm_executionengine.ml
index c9e8f18..a8535b2 100644
--- a/bindings/ocaml/executionengine/llvm_executionengine.ml
+++ b/bindings/ocaml/executionengine/llvm_executionengine.ml
@@ -20,7 +20,7 @@ module GenericValue = struct
external of_float: Llvm.lltype -> float -> t
= "llvm_genericvalue_of_float"
external of_pointer: 'a -> t
- = "llvm_genericvalue_of_value"
+ = "llvm_genericvalue_of_pointer"
external of_int32: Llvm.lltype -> int32 -> t
= "llvm_genericvalue_of_int32"
external of_int: Llvm.lltype -> int -> t
@@ -33,7 +33,7 @@ module GenericValue = struct
external as_float: Llvm.lltype -> t -> float
= "llvm_genericvalue_as_float"
external as_pointer: t -> 'a
- = "llvm_genericvalue_as_value"
+ = "llvm_genericvalue_as_pointer"
external as_int32: t -> int32
= "llvm_genericvalue_as_int32"
external as_int: t -> int
@@ -56,20 +56,18 @@ module ExecutionEngine = struct
call into LLVM. *)
let _ = register_exns (Error "")
- external create: Llvm.llmoduleprovider -> t
+ external create: Llvm.llmodule -> t
= "llvm_ee_create"
- external create_interpreter: Llvm.llmoduleprovider -> t
+ external create_interpreter: Llvm.llmodule -> t
= "llvm_ee_create_interpreter"
- external create_jit: Llvm.llmoduleprovider -> t
+ external create_jit: Llvm.llmodule -> int -> t
= "llvm_ee_create_jit"
- external create_fast_jit: Llvm.llmoduleprovider -> t
- = "llvm_ee_create_fast_jit"
external dispose: t -> unit
= "llvm_ee_dispose"
- external add_module_provider: Llvm.llmoduleprovider -> t -> unit
- = "llvm_ee_add_mp"
- external remove_module_provider: Llvm.llmoduleprovider -> t -> Llvm.llmodule
- = "llvm_ee_remove_mp"
+ external add_module: Llvm.llmodule -> t -> unit
+ = "llvm_ee_add_module"
+ external remove_module: Llvm.llmodule -> t -> Llvm.llmodule
+ = "llvm_ee_remove_module"
external find_function: string -> t -> Llvm.llvalue option
= "llvm_ee_find_function"
external run_function: Llvm.llvalue -> GenericValue.t array -> t ->
diff --git a/bindings/ocaml/executionengine/llvm_executionengine.mli b/bindings/ocaml/executionengine/llvm_executionengine.mli
index 6c2fdfb..ce25f9d 100644
--- a/bindings/ocaml/executionengine/llvm_executionengine.mli
+++ b/bindings/ocaml/executionengine/llvm_executionengine.mli
@@ -25,57 +25,58 @@ module GenericValue: sig
(** [of_float fpty n] boxes the float [n] in a float-valued generic value
according to the floating point type [fpty]. See the fields
[llvm::GenericValue::DoubleVal] and [llvm::GenericValue::FloatVal]. *)
- val of_float: Llvm.lltype -> float -> t
+ external of_float : Llvm.lltype -> float -> t = "llvm_genericvalue_of_float"
(** [of_pointer v] boxes the pointer value [v] in a generic value. See the
field [llvm::GenericValue::PointerVal]. *)
- val of_pointer: 'a -> t
+ external of_pointer : 'a -> t = "llvm_genericvalue_of_pointer"
(** [of_int32 n w] boxes the int32 [i] in a generic value with the bitwidth
[w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_int32: Llvm.lltype -> int32 -> t
+ external of_int32 : Llvm.lltype -> int32 -> t = "llvm_genericvalue_of_int32"
(** [of_int n w] boxes the int [i] in a generic value with the bitwidth
[w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_int: Llvm.lltype -> int -> t
+ external of_int : Llvm.lltype -> int -> t = "llvm_genericvalue_of_int"
(** [of_natint n w] boxes the native int [i] in a generic value with the
bitwidth [w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_nativeint: Llvm.lltype -> nativeint -> t
-
+ external of_nativeint : Llvm.lltype -> nativeint -> t
+ = "llvm_genericvalue_of_nativeint"
+
(** [of_int64 n w] boxes the int64 [i] in a generic value with the bitwidth
[w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_int64: Llvm.lltype -> int64 -> t
-
+ external of_int64 : Llvm.lltype -> int64 -> t = "llvm_genericvalue_of_int64"
+
(** [as_float fpty gv] unboxes the floating point-valued generic value [gv] of
floating point type [fpty]. See the fields [llvm::GenericValue::DoubleVal]
and [llvm::GenericValue::FloatVal]. *)
- val as_float: Llvm.lltype -> t -> float
+ external as_float : Llvm.lltype -> t -> float = "llvm_genericvalue_as_float"
(** [as_pointer gv] unboxes the pointer-valued generic value [gv]. See the
field [llvm::GenericValue::PointerVal]. *)
- val as_pointer: t -> 'a
+ external as_pointer : t -> 'a = "llvm_genericvalue_as_pointer"
(** [as_int32 gv] unboxes the integer-valued generic value [gv] as an [int32].
Is invalid if [gv] has a bitwidth greater than 32 bits. See the field
[llvm::GenericValue::IntVal]. *)
- val as_int32: t -> int32
+ external as_int32 : t -> int32 = "llvm_genericvalue_as_int32"
(** [as_int gv] unboxes the integer-valued generic value [gv] as an [int].
Is invalid if [gv] has a bitwidth greater than the host bit width (but the
most significant bit may be lost). See the field
[llvm::GenericValue::IntVal]. *)
- val as_int: t -> int
+ external as_int : t -> int = "llvm_genericvalue_as_int"
(** [as_natint gv] unboxes the integer-valued generic value [gv] as a
[nativeint]. Is invalid if [gv] has a bitwidth greater than
[nativeint]. See the field [llvm::GenericValue::IntVal]. *)
- val as_nativeint: t -> nativeint
+ external as_nativeint : t -> nativeint = "llvm_genericvalue_as_nativeint"
(** [as_int64 gv] returns the integer-valued generic value [gv] as an [int64].
Is invalid if [gv] has a bitwidth greater than [int64]. See the field
[llvm::GenericValue::IntVal]. *)
- val as_int64: t -> int64
+ external as_int64 : t -> int64 = "llvm_genericvalue_as_int64"
end
@@ -85,81 +86,77 @@ module ExecutionEngine: sig
invoking a static compiler and generating a native executable. *)
type t
- (** [create mp] creates a new execution engine, taking ownership of the
- module provider [mp] if successful. Creates a JIT if possible, else falls
- back to an interpreter. Raises [Error msg] if an error occurrs. The
- execution engine is not garbage collected and must be destroyed with
- [dispose ee]. See the function [llvm::EngineBuilder::create]. *)
- val create: Llvm.llmoduleprovider -> t
-
- (** [create_interpreter mp] creates a new interpreter, taking ownership of the
- module provider [mp] if successful. Raises [Error msg] if an error
- occurrs. The execution engine is not garbage collected and must be
- destroyed with [dispose ee].
+ (** [create m] creates a new execution engine, taking ownership of the
+ module [m] if successful. Creates a JIT if possible, else falls back to an
+ interpreter. Raises [Error msg] if an error occurrs. The execution engine
+ is not garbage collected and must be destroyed with [dispose ee].
See the function [llvm::EngineBuilder::create]. *)
- val create_interpreter: Llvm.llmoduleprovider -> t
+ external create : Llvm.llmodule -> t = "llvm_ee_create"
- (** [create_jit mp] creates a new JIT (just-in-time compiler), taking
- ownership of the module provider [mp] if successful. This function creates
- a JIT which favors code quality over compilation speed. Raises [Error msg]
- if an error occurrs. The execution engine is not garbage collected and
- must be destroyed with [dispose ee].
+ (** [create_interpreter m] creates a new interpreter, taking ownership of the
+ module [m] if successful. Raises [Error msg] if an error occurrs. The
+ execution engine is not garbage collected and must be destroyed with
+ [dispose ee].
See the function [llvm::EngineBuilder::create]. *)
- val create_jit: Llvm.llmoduleprovider -> t
+ external create_interpreter : Llvm.llmodule -> t = "llvm_ee_create_interpreter"
- (** [create_fast_jit mp] creates a new JIT (just-in-time compiler) which
- favors compilation speed over code quality. It takes ownership of the
- module provider [mp] if successful. Raises [Error msg] if an error
- occurrs. The execution engine is not garbage collected and must be
- destroyed with [dispose ee].
+ (** [create_jit m optlevel] creates a new JIT (just-in-time compiler), taking
+ ownership of the module [m] if successful with the desired optimization
+ level [optlevel]. Raises [Error msg] if an error occurrs. The execution
+ engine is not garbage collected and must be destroyed with [dispose ee].
See the function [llvm::EngineBuilder::create]. *)
- val create_fast_jit: Llvm.llmoduleprovider -> t
-
+ external create_jit : Llvm.llmodule -> int -> t = "llvm_ee_create_jit"
+
(** [dispose ee] releases the memory used by the execution engine and must be
invoked to avoid memory leaks. *)
- val dispose: t -> unit
+ external dispose : t -> unit = "llvm_ee_dispose"
- (** [add_module_provider mp ee] adds the module provider [mp] to the execution
- engine [ee]. *)
- val add_module_provider: Llvm.llmoduleprovider -> t -> unit
+ (** [add_module m ee] adds the module [m] to the execution engine [ee]. *)
+ external add_module : Llvm.llmodule -> t -> unit = "llvm_ee_add_module"
- (** [remove_module_provider mp ee] removes the module provider [mp] from the
- execution engine [ee], disposing of [mp] and the module referenced by
- [mp]. Raises [Error msg] if an error occurs. *)
- val remove_module_provider: Llvm.llmoduleprovider -> t -> Llvm.llmodule
+ (** [remove_module m ee] removes the module [m] from the execution engine
+ [ee], disposing of [m] and the module referenced by [mp]. Raises
+ [Error msg] if an error occurs. *)
+ external remove_module : Llvm.llmodule -> t -> Llvm.llmodule
+ = "llvm_ee_remove_module"
(** [find_function n ee] finds the function named [n] defined in any of the
modules owned by the execution engine [ee]. Returns [None] if the function
is not found and [Some f] otherwise. *)
- val find_function: string -> t -> Llvm.llvalue option
+ external find_function : string -> t -> Llvm.llvalue option
+ = "llvm_ee_find_function"
(** [run_function f args ee] synchronously executes the function [f] with the
arguments [args], which must be compatible with the parameter types. *)
- val run_function: Llvm.llvalue -> GenericValue.t array -> t ->
- GenericValue.t
+ external run_function : Llvm.llvalue -> GenericValue.t array -> t ->
+ GenericValue.t
+ = "llvm_ee_run_function"
(** [run_static_ctors ee] executes the static constructors of each module in
the execution engine [ee]. *)
- val run_static_ctors: t -> unit
+ external run_static_ctors : t -> unit = "llvm_ee_run_static_ctors"
(** [run_static_dtors ee] executes the static destructors of each module in
the execution engine [ee]. *)
- val run_static_dtors: t -> unit
+ external run_static_dtors : t -> unit = "llvm_ee_run_static_dtors"
(** [run_function_as_main f args env ee] executes the function [f] as a main
function, passing it [argv] and [argc] according to the string array
[args], and [envp] as specified by the array [env]. Returns the integer
return value of the function. *)
- val run_function_as_main: Llvm.llvalue -> string array ->
- (string * string) array -> t -> int
+ external run_function_as_main : Llvm.llvalue -> string array ->
+ (string * string) array -> t -> int
+ = "llvm_ee_run_function_as_main"
(** [free_machine_code f ee] releases the memory in the execution engine [ee]
used to store the machine code for the function [f]. *)
- val free_machine_code: Llvm.llvalue -> t -> unit
+ external free_machine_code : Llvm.llvalue -> t -> unit
+ = "llvm_ee_free_machine_code"
(** [target_data ee] is the target data owned by the execution engine
[ee]. *)
- val target_data: t -> Llvm_target.TargetData.t
+ external target_data : t -> Llvm_target.TargetData.t
+ = "LLVMGetExecutionEngineTargetData"
end
external initialize_native_target : unit -> bool
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml
index 7e4acbf..e801c49 100644
--- a/bindings/ocaml/llvm/llvm.ml
+++ b/bindings/ocaml/llvm/llvm.ml
@@ -13,9 +13,9 @@ type llmodule
type lltype
type lltypehandle
type llvalue
+type lluse
type llbasicblock
type llbuilder
-type llmoduleprovider
type llmemorybuffer
module TypeKind = struct
@@ -35,6 +35,7 @@ module TypeKind = struct
| Opaque
| Vector
| Metadata
+ | Union
end
module Linkage = struct
@@ -89,11 +90,13 @@ module Attribute = struct
| Optsize
| Ssp
| Sspreq
+ | Alignment
| Nocapture
| Noredzone
| Noimplicitfloat
| Naked
| Inlinehint
+ | Stackalignment
end
module Icmp = struct
@@ -147,6 +150,7 @@ type ('a, 'b) llrev_pos =
external create_context : unit -> llcontext = "llvm_create_context"
external dispose_context : llcontext -> unit = "llvm_dispose_context"
external global_context : unit -> llcontext = "llvm_global_context"
+external mdkind_id : llcontext -> string -> int = "llvm_mdkind_id"
(*===-- Modules -----------------------------------------------------------===*)
external create_module : llcontext -> string -> llmodule = "llvm_create_module"
@@ -163,6 +167,8 @@ external define_type_name : string -> lltype -> llmodule -> bool
= "llvm_add_type_name"
external delete_type_name : string -> llmodule -> unit
= "llvm_delete_type_name"
+external type_by_name : llmodule -> string -> lltype option
+ = "llvm_type_by_name"
external dump_module : llmodule -> unit = "llvm_dump_module"
(*===-- Types -------------------------------------------------------------===*)
@@ -198,9 +204,15 @@ external param_types : lltype -> lltype array = "llvm_param_types"
external struct_type : llcontext -> lltype array -> lltype = "llvm_struct_type"
external packed_struct_type : llcontext -> lltype array -> lltype
= "llvm_packed_struct_type"
-external element_types : lltype -> lltype array = "llvm_element_types"
+external struct_element_types : lltype -> lltype array
+ = "llvm_struct_element_types"
external is_packed : lltype -> bool = "llvm_is_packed"
+(*--... Operations on union types ..........................................--*)
+external union_type : llcontext -> lltype array -> lltype = "llvm_union_type"
+external union_element_types : lltype -> lltype array
+ = "llvm_union_element_types"
+
(*--... Operations on pointer, vector, and array types .....................--*)
external array_type : lltype -> int -> lltype = "llvm_array_type"
external pointer_type : lltype -> lltype = "llvm_pointer_type"
@@ -229,15 +241,63 @@ external type_of : llvalue -> lltype = "llvm_type_of"
external value_name : llvalue -> string = "llvm_value_name"
external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
external dump_value : llvalue -> unit = "llvm_dump_value"
+external replace_all_uses_with : llvalue -> llvalue -> unit
+ = "LLVMReplaceAllUsesWith"
+
+(*--... Operations on uses .................................................--*)
+external use_begin : llvalue -> lluse option = "llvm_use_begin"
+external use_succ : lluse -> lluse option = "llvm_use_succ"
+external user : lluse -> llvalue = "llvm_user"
+external used_value : lluse -> llvalue = "llvm_used_value"
+
+let iter_uses f v =
+ let rec aux = function
+ | None -> ()
+ | Some u ->
+ f u;
+ aux (use_succ u)
+ in
+ aux (use_begin v)
+
+let fold_left_uses f init v =
+ let rec aux init u =
+ match u with
+ | None -> init
+ | Some u -> aux (f init u) (use_succ u)
+ in
+ aux init (use_begin v)
+
+let fold_right_uses f v init =
+ let rec aux u init =
+ match u with
+ | None -> init
+ | Some u -> f u (aux (use_succ u) init)
+ in
+ aux (use_begin v) init
+
+
+(*--... Operations on users ................................................--*)
+external operand : llvalue -> int -> llvalue = "llvm_operand"
(*--... Operations on constants of (mostly) any type .......................--*)
external is_constant : llvalue -> bool = "llvm_is_constant"
external const_null : lltype -> llvalue = "LLVMConstNull"
external const_all_ones : (*int|vec*)lltype -> llvalue = "LLVMConstAllOnes"
+external const_pointer_null : lltype -> llvalue = "LLVMConstPointerNull"
external undef : lltype -> llvalue = "LLVMGetUndef"
external is_null : llvalue -> bool = "llvm_is_null"
external is_undef : llvalue -> bool = "llvm_is_undef"
+(*--... Operations on instructions .........................................--*)
+external has_metadata : llvalue -> bool = "llvm_has_metadata"
+external metadata : llvalue -> int -> llvalue option = "llvm_metadata"
+external set_metadata : llvalue -> int -> llvalue -> unit = "llvm_set_metadata"
+external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata"
+
+(*--... Operations on metadata .......,.....................................--*)
+external mdstring : llcontext -> string -> llvalue = "llvm_mdstring"
+external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode"
+
(*--... Operations on scalar constants .....................................--*)
external const_int : lltype -> int -> llvalue = "llvm_const_int"
external const_of_int64 : lltype -> Int64.t -> bool -> llvalue
@@ -257,19 +317,27 @@ external const_struct : llcontext -> llvalue array -> llvalue
external const_packed_struct : llcontext -> llvalue array -> llvalue
= "llvm_const_packed_struct"
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
+external const_union : lltype -> llvalue -> llvalue = "LLVMConstUnion"
(*--... Constant expressions ...............................................--*)
external align_of : lltype -> llvalue = "LLVMAlignOf"
external size_of : lltype -> llvalue = "LLVMSizeOf"
external const_neg : llvalue -> llvalue = "LLVMConstNeg"
+external const_nsw_neg : llvalue -> llvalue = "LLVMConstNSWNeg"
+external const_nuw_neg : llvalue -> llvalue = "LLVMConstNUWNeg"
external const_fneg : llvalue -> llvalue = "LLVMConstFNeg"
external const_not : llvalue -> llvalue = "LLVMConstNot"
external const_add : llvalue -> llvalue -> llvalue = "LLVMConstAdd"
external const_nsw_add : llvalue -> llvalue -> llvalue = "LLVMConstNSWAdd"
+external const_nuw_add : llvalue -> llvalue -> llvalue = "LLVMConstNUWAdd"
external const_fadd : llvalue -> llvalue -> llvalue = "LLVMConstFAdd"
external const_sub : llvalue -> llvalue -> llvalue = "LLVMConstSub"
+external const_nsw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNSWSub"
+external const_nuw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNUWSub"
external const_fsub : llvalue -> llvalue -> llvalue = "LLVMConstFSub"
external const_mul : llvalue -> llvalue -> llvalue = "LLVMConstMul"
+external const_nsw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNSWMul"
+external const_nuw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNUWMul"
external const_fmul : llvalue -> llvalue -> llvalue = "LLVMConstFMul"
external const_udiv : llvalue -> llvalue -> llvalue = "LLVMConstUDiv"
external const_sdiv : llvalue -> llvalue -> llvalue = "LLVMConstSDiv"
@@ -325,6 +393,10 @@ external const_extractvalue : llvalue -> int array -> llvalue
= "llvm_const_extractvalue"
external const_insertvalue : llvalue -> llvalue -> int array -> llvalue
= "llvm_const_insertvalue"
+external const_inline_asm : lltype -> string -> string -> bool -> bool ->
+ llvalue
+ = "llvm_const_inline_asm"
+external block_address : llvalue -> llbasicblock -> llvalue = "LLVMBlockAddress"
(*--... Operations on global variables, functions, and aliases (globals) ...--*)
external global_parent : llvalue -> llmodule = "LLVMGetGlobalParent"
@@ -344,8 +416,14 @@ external set_global_constant : bool -> llvalue -> unit
(*--... Operations on global variables .....................................--*)
external declare_global : lltype -> string -> llmodule -> llvalue
= "llvm_declare_global"
+external declare_qualified_global : lltype -> string -> int -> llmodule ->
+ llvalue
+ = "llvm_declare_qualified_global"
external define_global : string -> llvalue -> llmodule -> llvalue
= "llvm_define_global"
+external define_qualified_global : string -> llvalue -> int -> llmodule ->
+ llvalue
+ = "llvm_define_qualified_global"
external lookup_global : string -> llmodule -> llvalue option
= "llvm_lookup_global"
external delete_global : llvalue -> unit = "llvm_delete_global"
@@ -403,6 +481,10 @@ let rec fold_right_global_range f i e init =
let fold_right_globals f m init =
fold_right_global_range f (global_end m) (At_start m) init
+(*--... Operations on aliases ..............................................--*)
+external add_alias : llmodule -> lltype -> llvalue -> string -> llvalue
+ = "llvm_add_alias"
+
(*--... Operations on functions ............................................--*)
external declare_function : string -> lltype -> llmodule -> llvalue
= "llvm_declare_function"
@@ -680,6 +762,17 @@ let position_before i = position_builder (Before i)
let position_at_end bb = position_builder (At_end bb)
+(*--... Metadata ...........................................................--*)
+external set_current_debug_location : llbuilder -> llvalue -> unit
+ = "llvm_set_current_debug_location"
+external clear_current_debug_location : llbuilder -> unit
+ = "llvm_clear_current_debug_location"
+external current_debug_location : llbuilder -> llvalue option
+ = "llvm_current_debug_location"
+external set_inst_debug_location : llbuilder -> llvalue -> unit
+ = "llvm_set_inst_debug_location"
+
+
(*--... Terminators ........................................................--*)
external build_ret_void : llbuilder -> llvalue = "llvm_build_ret_void"
external build_ret : llvalue -> llbuilder -> llvalue = "llvm_build_ret"
@@ -692,6 +785,10 @@ external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
= "llvm_build_switch"
external add_case : llvalue -> llvalue -> llbasicblock -> unit
= "llvm_add_case"
+external build_indirect_br : llvalue -> int -> llbuilder -> llvalue
+ = "llvm_build_indirect_br"
+external add_destination : llvalue -> llbasicblock -> unit
+ = "llvm_add_destination"
external build_invoke : llvalue -> llvalue array -> llbasicblock ->
llbasicblock -> string -> llbuilder -> llvalue
= "llvm_build_invoke_bc" "llvm_build_invoke_nat"
@@ -703,14 +800,24 @@ external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_add"
external build_nsw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_nsw_add"
+external build_nuw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_add"
external build_fadd : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_fadd"
external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_sub"
+external build_nsw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nsw_sub"
+external build_nuw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_sub"
external build_fsub : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_fsub"
external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_mul"
+external build_nsw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nsw_mul"
+external build_nuw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_mul"
external build_fmul : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_fmul"
external build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
@@ -741,19 +848,20 @@ external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_xor"
external build_neg : llvalue -> string -> llbuilder -> llvalue
= "llvm_build_neg"
+external build_nsw_neg : llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nsw_neg"
+external build_nuw_neg : llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_neg"
+external build_fneg : llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_fneg"
external build_not : llvalue -> string -> llbuilder -> llvalue
= "llvm_build_not"
(*--... Memory .............................................................--*)
-external build_malloc : lltype -> string -> llbuilder -> llvalue
- = "llvm_build_malloc"
-external build_array_malloc : lltype -> llvalue -> string -> llbuilder ->
- llvalue = "llvm_build_array_malloc"
external build_alloca : lltype -> string -> llbuilder -> llvalue
= "llvm_build_alloca"
external build_array_alloca : lltype -> llvalue -> string -> llbuilder ->
llvalue = "llvm_build_array_alloca"
-external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free"
external build_load : llvalue -> string -> llbuilder -> llvalue
= "llvm_build_load"
external build_store : llvalue -> llvalue -> llbuilder -> llvalue
@@ -841,14 +949,6 @@ external build_is_not_null : llvalue -> string -> llbuilder -> llvalue
external build_ptrdiff : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_ptrdiff"
-(*===-- Module providers --------------------------------------------------===*)
-
-module ModuleProvider = struct
- external create : llmodule -> llmoduleprovider
- = "LLVMCreateModuleProviderForExistingModule"
- external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
-end
-
(*===-- Memory buffers ----------------------------------------------------===*)
@@ -865,7 +965,7 @@ module PassManager = struct
type 'a t
type any = [ `Module | `Function ]
external create : unit -> [ `Module ] t = "llvm_passmanager_create"
- external create_function : llmoduleprovider -> [ `Function ] t
+ external create_function : llmodule -> [ `Function ] t
= "LLVMCreateFunctionPassManager"
external run_module : llmodule -> [ `Module ] t -> bool
= "llvm_passmanager_run_module"
@@ -897,11 +997,14 @@ let rec string_of_lltype ty =
| TypeKind.Pointer -> (string_of_lltype (element_type ty)) ^ "*"
| TypeKind.Struct ->
let s = "{ " ^ (concat2 ", " (
- Array.map string_of_lltype (element_types ty)
+ Array.map string_of_lltype (struct_element_types ty)
)) ^ " }" in
if is_packed ty
then "<" ^ s ^ ">"
else s
+ | TypeKind.Union -> "union { " ^ (concat2 ", " (
+ Array.map string_of_lltype (union_element_types ty)
+ )) ^ " }"
| TypeKind.Array -> "[" ^ (string_of_int (array_length ty)) ^
" x " ^ (string_of_lltype (element_type ty)) ^ "]"
| TypeKind.Vector -> "<" ^ (string_of_int (vector_size ty)) ^
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index bcdcb2c..4b0c06d 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -39,6 +39,9 @@ type lltypehandle
This type covers a wide range of subclasses. *)
type llvalue
+(** Used to store users and usees of values. See the [llvm::Use] class. *)
+type lluse
+
(** A basic block in LLVM IR. See the [llvm::BasicBlock] class. *)
type llbasicblock
@@ -46,10 +49,6 @@ type llbasicblock
class. *)
type llbuilder
-(** Used to provide a module to JIT or interpreter.
- See the [llvm::ModuleProvider] class. *)
-type llmoduleprovider
-
(** Used to efficiently handle large buffers of read-only binary data.
See the [llvm::MemoryBuffer] class. *)
type llmemorybuffer
@@ -73,6 +72,7 @@ module TypeKind : sig
| Opaque
| Vector
| Metadata
+ | Union
end
(** The linkage of a global value, accessed with {!linkage} and
@@ -139,11 +139,13 @@ module Attribute : sig
| Optsize
| Ssp
| Sspreq
+ | Alignment
| Nocapture
| Noredzone
| Noimplicitfloat
| Naked
| Inlinehint
+ | Stackalignment
end
(** The predicate for an integer comparison ([icmp]) instruction.
@@ -220,6 +222,11 @@ external dispose_context : llcontext -> unit = "llvm_dispose_context"
(** See the function [llvm::getGlobalContext]. *)
external global_context : unit -> llcontext = "llvm_global_context"
+(** [mdkind_id context name] returns the MDKind ID that corresponds to the
+ name [name] in the context [context]. See the function
+ [llvm::LLVMContext::getMDKindID]. *)
+external mdkind_id : llcontext -> string -> int = "llvm_mdkind_id"
+
(** {6 Modules} *)
@@ -268,6 +275,11 @@ external define_type_name : string -> lltype -> llmodule -> bool
external delete_type_name : string -> llmodule -> unit
= "llvm_delete_type_name"
+(** [type_by_name m n] returns the type in the module [m] named [n], or [None]
+ if it does not exist. See the method [llvm::Module::getTypeByName]. *)
+external type_by_name : llmodule -> string -> lltype option
+ = "llvm_type_by_name"
+
(** [dump_module m] prints the .ll representation of the module [m] to standard
error. See the method [llvm::Module::dump]. *)
external dump_module : llmodule -> unit = "llvm_dump_module"
@@ -381,15 +393,29 @@ external struct_type : llcontext -> lltype array -> lltype
external packed_struct_type : llcontext -> lltype array -> lltype
= "llvm_packed_struct_type"
-(** [element_types sty] returns the constituent types of the struct type [sty].
- See the method [llvm::StructType::getElementType]. *)
-external element_types : lltype -> lltype array = "llvm_element_types"
+(** [struct_element_types sty] returns the constituent types of the struct type
+ [sty]. See the method [llvm::StructType::getElementType]. *)
+external struct_element_types : lltype -> lltype array
+ = "llvm_struct_element_types"
(** [is_packed sty] returns [true] if the structure type [sty] is packed,
[false] otherwise. See the method [llvm::StructType::isPacked]. *)
external is_packed : lltype -> bool = "llvm_is_packed"
+(** {7 Operations on union types} *)
+
+(** [union_type context tys] returns the union type in the context [context]
+ containing the types in the array [tys]. See the method
+ [llvm::UnionType::get] *)
+external union_type : llcontext -> lltype array -> lltype = "llvm_union_type"
+
+(** [union_element_types uty] returns the constituent types of the union type
+ [uty]. See the method [llvm::UnionType::getElementType]. *)
+external union_element_types : lltype -> lltype array
+ = "llvm_union_element_types"
+
+
(** {7 Operations on pointer, vector, and array types} *)
(** [array_type ty n] returns the array type containing [n] elements of type
@@ -482,6 +508,50 @@ external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
error. See the method [llvm::Value::dump]. *)
external dump_value : llvalue -> unit = "llvm_dump_value"
+(** [replace_all_uses_with old new] replaces all uses of the value [old]
+ * with the value [new]. See the method [llvm::Value::replaceAllUsesWith]. *)
+external replace_all_uses_with : llvalue -> llvalue -> unit
+ = "LLVMReplaceAllUsesWith"
+
+
+(* {6 Uses} *)
+
+(** [use_begin v] returns the first position in the use list for the value [v].
+ [use_begin] and [use_succ] can e used to iterate over the use list in order.
+ See the method [llvm::Value::use_begin]. *)
+external use_begin : llvalue -> lluse option = "llvm_use_begin"
+
+(** [use_succ u] returns the use list position succeeding [u].
+ See the method [llvm::use_value_iterator::operator++]. *)
+external use_succ : lluse -> lluse option = "llvm_use_succ"
+
+(** [user u] returns the user of the use [u].
+ See the method [llvm::Use::getUser]. *)
+external user : lluse -> llvalue = "llvm_user"
+
+(** [used_value u] returns the usee of the use [u].
+ See the method [llvm::Use::getUsedValue]. *)
+external used_value : lluse -> llvalue = "llvm_used_value"
+
+(** [iter_uses f v] applies function [f] to each of the users of the value [v]
+ in order. Tail recursive. *)
+val iter_uses : (lluse -> unit) -> llvalue -> unit
+
+(** [fold_left_uses f init v] is [f (... (f init u1) ...) uN] where
+ [u1,...,uN] are the users of the value [v]. Tail recursive. *)
+val fold_left_uses : ('a -> lluse -> 'a) -> 'a -> llvalue -> 'a
+
+(** [fold_right_uses f v init] is [f u1 (... (f uN init) ...)] where
+ [u1,...,uN] are the users of the value [v]. Not tail recursive. *)
+val fold_right_uses : (lluse -> 'a -> 'a) -> llvalue -> 'a -> 'a
+
+
+(* {6 Users} *)
+
+(** [operand v i] returns the operand at index [i] for the value [v]. See the
+ method [llvm::User::getOperand]. *)
+external operand : llvalue -> int -> llvalue = "llvm_operand"
+
(** {7 Operations on constants of (mostly) any type} *)
@@ -497,6 +567,10 @@ external const_null : lltype -> llvalue = "LLVMConstNull"
[ty]. See the method [llvm::Constant::getAllOnesValue]. *)
external const_all_ones : (*int|vec*)lltype -> llvalue = "LLVMConstAllOnes"
+(** [const_pointer_null ty] returns the constant null (zero) pointer of the type
+ [ty]. See the method [llvm::ConstantPointerNull::get]. *)
+external const_pointer_null : lltype -> llvalue = "LLVMConstPointerNull"
+
(** [undef ty] returns the undefined value of the type [ty].
See the method [llvm::UndefValue::get]. *)
external undef : lltype -> llvalue = "LLVMGetUndef"
@@ -510,6 +584,39 @@ external is_null : llvalue -> bool = "llvm_is_null"
external is_undef : llvalue -> bool = "llvm_is_undef"
+(** {7 Operations on instructions} *)
+
+(** [has_metadata i] returns whether or not the instruction [i] has any
+ metadata attached to it. See the function
+ [llvm::Instruction::hasMetadata]. *)
+external has_metadata : llvalue -> bool = "llvm_has_metadata"
+
+(** [metadata i kind] optionally returns the metadata associated with the
+ kind [kind] in the instruction [i] See the function
+ [llvm::Instruction::getMetadata]. *)
+external metadata : llvalue -> int -> llvalue option = "llvm_metadata"
+
+(** [set_metadata i kind md] sets the metadata [md] of kind [kind] in the
+ instruction [i]. See the function [llvm::Instruction::setMetadata]. *)
+external set_metadata : llvalue -> int -> llvalue -> unit = "llvm_set_metadata"
+
+(** [clear_metadata i kind] clears the metadata of kind [kind] in the
+ instruction [i]. See the function [llvm::Instruction::setMetadata]. *)
+external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata"
+
+
+(** {7 Operations on metadata} *)
+
+(** [mdstring c s] returns the MDString of the string [s] in the context [c].
+ See the method [llvm::MDNode::get]. *)
+external mdstring : llcontext -> string -> llvalue = "llvm_mdstring"
+
+(** [mdnode c elts] returns the MDNode containing the values [elts] in the
+ context [c].
+ See the method [llvm::MDNode::get]. *)
+external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode"
+
+
(** {7 Operations on scalar constants} *)
(** [const_int ty i] returns the integer constant of type [ty] and value [i].
@@ -577,6 +684,10 @@ external const_packed_struct : llcontext -> llvalue array -> llvalue
values [elts]. See the method [llvm::ConstantVector::get]. *)
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
+(** [const_union ty v] returns the union constant of type [union_type tys] and
+ containing the value [v]. See the method [llvm::ConstantUnion::get]. *)
+external const_union : lltype -> llvalue -> llvalue = "LLVMConstUnion"
+
(** {7 Constant expressions} *)
@@ -596,6 +707,16 @@ external size_of : lltype -> llvalue = "LLVMSizeOf"
See the method [llvm::ConstantExpr::getNeg]. *)
external const_neg : llvalue -> llvalue = "LLVMConstNeg"
+(** [const_nsw_neg c] returns the arithmetic negation of the constant [c] with
+ no signed wrapping. The result is undefined if the negation overflows.
+ See the method [llvm::ConstantExpr::getNSWNeg]. *)
+external const_nsw_neg : llvalue -> llvalue = "LLVMConstNSWNeg"
+
+(** [const_nuw_neg c] returns the arithmetic negation of the constant [c] with
+ no unsigned wrapping. The result is undefined if the negation overflows.
+ See the method [llvm::ConstantExpr::getNUWNeg]. *)
+external const_nuw_neg : llvalue -> llvalue = "LLVMConstNUWNeg"
+
(** [const_fneg c] returns the arithmetic negation of the constant float [c].
See the method [llvm::ConstantExpr::getFNeg]. *)
external const_fneg : llvalue -> llvalue = "LLVMConstFNeg"
@@ -613,6 +734,11 @@ external const_add : llvalue -> llvalue -> llvalue = "LLVMConstAdd"
See the method [llvm::ConstantExpr::getNSWAdd]. *)
external const_nsw_add : llvalue -> llvalue -> llvalue = "LLVMConstNSWAdd"
+(** [const_nuw_add c1 c2] returns the constant sum of two constants with no
+ unsigned wrapping. The result is undefined if the sum overflows.
+ See the method [llvm::ConstantExpr::getNSWAdd]. *)
+external const_nuw_add : llvalue -> llvalue -> llvalue = "LLVMConstNUWAdd"
+
(** [const_fadd c1 c2] returns the constant sum of two constant floats.
See the method [llvm::ConstantExpr::getFAdd]. *)
external const_fadd : llvalue -> llvalue -> llvalue = "LLVMConstFAdd"
@@ -621,6 +747,16 @@ external const_fadd : llvalue -> llvalue -> llvalue = "LLVMConstFAdd"
constants. See the method [llvm::ConstantExpr::getSub]. *)
external const_sub : llvalue -> llvalue -> llvalue = "LLVMConstSub"
+(** [const_nsw_sub c1 c2] returns the constant difference of two constants with
+ no signed wrapping. The result is undefined if the sum overflows.
+ See the method [llvm::ConstantExpr::getNSWSub]. *)
+external const_nsw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNSWSub"
+
+(** [const_nuw_sub c1 c2] returns the constant difference of two constants with
+ no unsigned wrapping. The result is undefined if the sum overflows.
+ See the method [llvm::ConstantExpr::getNSWSub]. *)
+external const_nuw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNUWSub"
+
(** [const_fsub c1 c2] returns the constant difference, [c1 - c2], of two
constant floats. See the method [llvm::ConstantExpr::getFSub]. *)
external const_fsub : llvalue -> llvalue -> llvalue = "LLVMConstFSub"
@@ -629,6 +765,16 @@ external const_fsub : llvalue -> llvalue -> llvalue = "LLVMConstFSub"
See the method [llvm::ConstantExpr::getMul]. *)
external const_mul : llvalue -> llvalue -> llvalue = "LLVMConstMul"
+(** [const_nsw_mul c1 c2] returns the constant product of two constants with
+ no signed wrapping. The result is undefined if the sum overflows.
+ See the method [llvm::ConstantExpr::getNSWMul]. *)
+external const_nsw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNSWMul"
+
+(** [const_nuw_mul c1 c2] returns the constant product of two constants with
+ no unsigned wrapping. The result is undefined if the sum overflows.
+ See the method [llvm::ConstantExpr::getNSWMul]. *)
+external const_nuw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNUWMul"
+
(** [const_fmul c1 c2] returns the constant product of two constants floats.
See the method [llvm::ConstantExpr::getFMul]. *)
external const_fmul : llvalue -> llvalue -> llvalue = "LLVMConstFMul"
@@ -858,6 +1004,16 @@ external const_extractvalue : llvalue -> int array -> llvalue
external const_insertvalue : llvalue -> llvalue -> int array -> llvalue
= "llvm_const_insertvalue"
+(** [const_inline_asm ty asm con side align] inserts a inline assembly string.
+ See the method [llvm::InlineAsm::get]. *)
+external const_inline_asm : lltype -> string -> string -> bool -> bool ->
+ llvalue
+ = "llvm_const_inline_asm"
+
+(** [block_address f bb] returns the address of the basic block [bb] in the
+ function [f]. See the method [llvm::BasicBlock::get]. *)
+external block_address : llvalue -> llbasicblock -> llvalue = "LLVMBlockAddress"
+
(** {7 Operations on global variables, functions, and aliases (globals)} *)
@@ -907,19 +1063,36 @@ external set_alignment : int -> llvalue -> unit = "llvm_set_alignment"
(** {7 Operations on global variables} *)
(** [declare_global ty name m] returns a new global variable of type [ty] and
- with name [name] in module [m]. If such a global variable already exists,
- it is returned. If the type of the existing global differs, then a bitcast
- to [ty] is returned. *)
+ with name [name] in module [m] in the default address space (0). If such a
+ global variable already exists, it is returned. If the type of the existing
+ global differs, then a bitcast to [ty] is returned. *)
external declare_global : lltype -> string -> llmodule -> llvalue
= "llvm_declare_global"
+(** [declare_qualified_global ty name addrspace m] returns a new global variable
+ of type [ty] and with name [name] in module [m] in the address space
+ [addrspace]. If such a global variable already exists, it is returned. If
+ the type of the existing global differs, then a bitcast to [ty] is
+ returned. *)
+external declare_qualified_global : lltype -> string -> int -> llmodule ->
+ llvalue
+ = "llvm_declare_qualified_global"
+
(** [define_global name init m] returns a new global with name [name] and
- initializer [init] in module [m]. If the named global already exists, it is
- renamed.
+ initializer [init] in module [m] in the default address space (0). If the
+ named global already exists, it is renamed.
See the constructor of [llvm::GlobalVariable]. *)
external define_global : string -> llvalue -> llmodule -> llvalue
= "llvm_define_global"
+(** [define_qualified_global name init addrspace m] returns a new global with
+ name [name] and initializer [init] in module [m] in the address space
+ [addrspace]. If the named global already exists, it is renamed.
+ See the constructor of [llvm::GlobalVariable]. *)
+external define_qualified_global : string -> llvalue -> int -> llmodule ->
+ llvalue
+ = "llvm_define_qualified_global"
+
(** [lookup_global name m] returns [Some g] if a global variable with name
[name] exists in module [m]. If no such global exists, returns [None].
See the [llvm::GlobalVariable] constructor. *)
@@ -1008,6 +1181,15 @@ external is_thread_local : llvalue -> bool = "llvm_is_thread_local"
external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local"
+(** {7 Operations on aliases} *)
+
+(** [add_alias m t a n] inserts an alias in the module [m] with the type [t] and
+ the aliasee [a] with the name [n].
+ See the constructor for [llvm::GlobalAlias]. *)
+external add_alias : llmodule -> lltype -> llvalue -> string -> llvalue
+ = "llvm_add_alias"
+
+
(** {7 Operations on functions} *)
(** [declare_function name ty m] returns a new function of type [ty] and
@@ -1397,6 +1579,30 @@ external insertion_block : llbuilder -> llbasicblock = "llvm_insertion_block"
external insert_into_builder : llvalue -> string -> llbuilder -> unit
= "llvm_insert_into_builder"
+(** {7 Metadata} *)
+
+(** [set_current_debug_location b md] sets the current debug location [md] in
+ the builder [b].
+ See the method [llvm::IRBuilder::SetDebugLocation]. *)
+external set_current_debug_location : llbuilder -> llvalue -> unit
+ = "llvm_set_current_debug_location"
+
+(** [clear_current_debug_location b] clears the current debug location in the
+ builder [b]. *)
+external clear_current_debug_location : llbuilder -> unit
+ = "llvm_clear_current_debug_location"
+
+(** [current_debug_location b] returns the current debug location, or None
+ if none is currently set.
+ See the method [llvm::IRBuilder::GetDebugLocation]. *)
+external current_debug_location : llbuilder -> llvalue option
+ = "llvm_current_debug_location"
+
+(** [set_inst_debug_location b i] sets the current debug location of the builder
+ [b] to the instruction [i].
+ See the method [llvm::IRBuilder::SetInstDebugLocation]. *)
+external set_inst_debug_location : llbuilder -> llvalue -> unit
+ = "llvm_set_inst_debug_location"
(** {7 Terminators} *)
@@ -1420,13 +1626,13 @@ external build_aggregate_ret : llvalue array -> llbuilder -> llvalue
= "llvm_build_aggregate_ret"
(** [build_br bb b] creates a
- [b %bb]
+ [br %bb]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateBr]. *)
external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br"
(** [build_cond_br cond tbb fbb b] creates a
- [b %cond, %tbb, %fbb]
+ [br %cond, %tbb, %fbb]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateCondBr]. *)
external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder ->
@@ -1446,6 +1652,20 @@ external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
external add_case : llvalue -> llvalue -> llbasicblock -> unit
= "llvm_add_case"
+(** [build_indirect_br addr count b] creates a
+ [indirectbr %addr]
+ instruction at the position specified by the instruction builder [b] with
+ space reserved for [count] destinations.
+ See the method [llvm::LLVMBuilder::CreateIndirectBr]. *)
+external build_indirect_br : llvalue -> int -> llbuilder -> llvalue
+ = "llvm_build_indirect_br"
+
+(** [add_destination br bb] adds the basic block [bb] as a possible branch
+ location for the indirectbr instruction [br].
+ See the method [llvm::IndirectBrInst::addDestination]. **)
+external add_destination : llvalue -> llbasicblock -> unit
+ = "llvm_add_destination"
+
(** [build_invoke fn args tobb unwindbb name b] creates an
[%name = invoke %fn(args) to %tobb unwind %unwindbb]
instruction at the position specified by the instruction builder [b].
@@ -1476,13 +1696,20 @@ external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable"
external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_add"
-(** [build_nswadd x y name b] creates a
+(** [build_nsw_add x y name b] creates a
[%name = nsw add %x, %y]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateNSWAdd]. *)
external build_nsw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_nsw_add"
+(** [build_nuw_add x y name b] creates a
+ [%name = nuw add %x, %y]
+ instruction at the position specified by the instruction builder [b].
+ See the method [llvm::LLVMBuilder::CreateNUWAdd]. *)
+external build_nuw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_add"
+
(** [build_fadd x y name b] creates a
[%name = fadd %x, %y]
instruction at the position specified by the instruction builder [b].
@@ -1497,6 +1724,20 @@ external build_fadd : llvalue -> llvalue -> string -> llbuilder -> llvalue
external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_sub"
+(** [build_nsw_sub x y name b] creates a
+ [%name = nsw sub %x, %y]
+ instruction at the position specified by the instruction builder [b].
+ See the method [llvm::LLVMBuilder::CreateNSWSub]. *)
+external build_nsw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nsw_sub"
+
+(** [build_nuw_sub x y name b] creates a
+ [%name = nuw sub %x, %y]
+ instruction at the position specified by the instruction builder [b].
+ See the method [llvm::LLVMBuilder::CreateNUWSub]. *)
+external build_nuw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_sub"
+
(** [build_fsub x y name b] creates a
[%name = fsub %x, %y]
instruction at the position specified by the instruction builder [b].
@@ -1511,6 +1752,20 @@ external build_fsub : llvalue -> llvalue -> string -> llbuilder -> llvalue
external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_mul"
+(** [build_nsw_mul x y name b] creates a
+ [%name = nsw mul %x, %y]
+ instruction at the position specified by the instruction builder [b].
+ See the method [llvm::LLVMBuilder::CreateNSWMul]. *)
+external build_nsw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nsw_mul"
+
+(** [build_nuw_mul x y name b] creates a
+ [%name = nuw mul %x, %y]
+ instruction at the position specified by the instruction builder [b].
+ See the method [llvm::LLVMBuilder::CreateNUWMul]. *)
+external build_nuw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_mul"
+
(** [build_fmul x y name b] creates a
[%name = fmul %x, %y]
instruction at the position specified by the instruction builder [b].
@@ -1617,6 +1872,30 @@ external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue
external build_neg : llvalue -> string -> llbuilder -> llvalue
= "llvm_build_neg"
+(** [build_nsw_neg x name b] creates a
+ [%name = nsw sub 0, %x]
+ instruction at the position specified by the instruction builder [b].
+ [-0.0] is used for floating point types to compute the correct sign.
+ See the method [llvm::LLVMBuilder::CreateNeg]. *)
+external build_nsw_neg : llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nsw_neg"
+
+(** [build_nuw_neg x name b] creates a
+ [%name = nuw sub 0, %x]
+ instruction at the position specified by the instruction builder [b].
+ [-0.0] is used for floating point types to compute the correct sign.
+ See the method [llvm::LLVMBuilder::CreateNeg]. *)
+external build_nuw_neg : llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_nuw_neg"
+
+(** [build_fneg x name b] creates a
+ [%name = fsub 0, %x]
+ instruction at the position specified by the instruction builder [b].
+ [-0.0] is used for floating point types to compute the correct sign.
+ See the method [llvm::LLVMBuilder::CreateFNeg]. *)
+external build_fneg : llvalue -> string -> llbuilder -> llvalue
+ = "llvm_build_fneg"
+
(** [build_xor x name b] creates a
[%name = xor %x, -1]
instruction at the position specified by the instruction builder [b].
@@ -1628,20 +1907,6 @@ external build_not : llvalue -> string -> llbuilder -> llvalue
(** {7 Memory} *)
-(** [build_malloc ty name b] creates a
- [%name = malloc %ty]
- instruction at the position specified by the instruction builder [b].
- See the method [llvm::LLVMBuilder::CreateAlloca]. *)
-external build_malloc : lltype -> string -> llbuilder -> llvalue
- = "llvm_build_malloc"
-
-(** [build_array_malloc ty n name b] creates a
- [%name = malloc %ty, %n]
- instruction at the position specified by the instruction builder [b].
- See the method [llvm::LLVMBuilder::CreateMalloc]. *)
-external build_array_malloc : lltype -> llvalue -> string -> llbuilder ->
- llvalue = "llvm_build_array_malloc"
-
(** [build_alloca ty name b] creates a
[%name = alloca %ty]
instruction at the position specified by the instruction builder [b].
@@ -1656,12 +1921,6 @@ external build_alloca : lltype -> string -> llbuilder -> llvalue
external build_array_alloca : lltype -> llvalue -> string -> llbuilder ->
llvalue = "llvm_build_array_alloca"
-(** [build_free v b] creates a
- [free %v]
- instruction at the position specified by the instruction builder [b].
- See the method [llvm::LLVMBuilder::CreateFree]. *)
-external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free"
-
(** [build_load v name b] creates a
[%name = load %v]
instruction at the position specified by the instruction builder [b].
@@ -1938,20 +2197,6 @@ external build_is_not_null : llvalue -> string -> llbuilder -> llvalue
external build_ptrdiff : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_ptrdiff"
-(** {6 Module providers} *)
-
-module ModuleProvider : sig
- (** [create_module_provider m] encapsulates [m] in a module provider and takes
- ownership of the module. See the constructor
- [llvm::ExistingModuleProvider::ExistingModuleProvider]. *)
- external create : llmodule -> llmoduleprovider
- = "LLVMCreateModuleProviderForExistingModule"
-
- (** [dispose_module_provider mp] destroys the module provider [mp] as well as
- the contained module. *)
- external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
-end
-
(** {6 Memory buffers} *)
@@ -1983,12 +2228,12 @@ module PassManager : sig
See the constructor of [llvm::PassManager]. *)
external create : unit -> [ `Module ] t = "llvm_passmanager_create"
- (** [PassManager.create_function mp] constructs a new function-by-function
- pass pipeline over the module provider [mp]. It does not take ownership of
- [mp]. This type of pipeline is suitable for code generation and JIT
- compilation tasks.
+ (** [PassManager.create_function m] constructs a new function-by-function
+ pass pipeline over the module [m]. It does not take ownership of [m].
+ This type of pipeline is suitable for code generation and JIT compilation
+ tasks.
See the constructor of [llvm::FunctionPassManager]. *)
- external create_function : llmoduleprovider -> [ `Function ] t
+ external create_function : llmodule -> [ `Function ] t
= "LLVMCreateFunctionPassManager"
(** [run_module m pm] initializes, executes on the module [m], and finalizes
@@ -2018,7 +2263,7 @@ module PassManager : sig
external finalize : [ `Function ] t -> bool = "llvm_passmanager_finalize"
(** Frees the memory of a pass pipeline. For function pipelines, does not free
- the module provider.
+ the module.
See the destructor of [llvm::BasePassManager]. *)
external dispose : [< any ] t -> unit = "llvm_passmanager_dispose"
end
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index 8fdcac5..d526a05 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -110,6 +110,13 @@ CAMLprim LLVMContextRef llvm_global_context(value Unit) {
return LLVMGetGlobalContext();
}
+/* llcontext -> string -> int */
+CAMLprim value llvm_mdkind_id(LLVMContextRef C, value Name) {
+ unsigned MDKindID = LLVMGetMDKindIDInContext(C, String_val(Name),
+ caml_string_length(Name));
+ return Val_int(MDKindID);
+}
+
/*===-- Modules -----------------------------------------------------------===*/
/* llcontext -> string -> llmodule */
@@ -157,6 +164,18 @@ CAMLprim value llvm_delete_type_name(value Name, LLVMModuleRef M) {
return Val_unit;
}
+/* llmodule -> string -> lltype option */
+CAMLprim value llvm_type_by_name(LLVMModuleRef M, value Name) {
+ CAMLparam1(Name);
+ LLVMTypeRef T;
+ if ((T = LLVMGetTypeByName(M, String_val(Name)))) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) T;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
/* llmodule -> unit */
CAMLprim value llvm_dump_module(LLVMModuleRef M) {
LLVMDumpModule(M);
@@ -283,7 +302,7 @@ CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C,
}
/* lltype -> lltype array */
-CAMLprim value llvm_element_types(LLVMTypeRef StructTy) {
+CAMLprim value llvm_struct_element_types(LLVMTypeRef StructTy) {
value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0);
LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys);
return Tys;
@@ -294,6 +313,21 @@ CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
return Val_bool(LLVMIsPackedStruct(StructTy));
}
+/*--... Operations on union types ..........................................--*/
+
+/* llcontext -> lltype array -> lltype */
+CAMLprim LLVMTypeRef llvm_union_type(LLVMContextRef C, value ElementTypes) {
+ return LLVMUnionTypeInContext(C, (LLVMTypeRef *) ElementTypes,
+ Wosize_val(ElementTypes));
+}
+
+/* lltype -> lltype array */
+CAMLprim value llvm_union_element_types(LLVMTypeRef UnionTy) {
+ value Tys = alloc(LLVMCountUnionElementTypes(UnionTy), 0);
+ LLVMGetUnionElementTypes(UnionTy, (LLVMTypeRef *) Tys);
+ return Tys;
+}
+
/*--... Operations on array, pointer, and vector types .....................--*/
/* lltype -> int -> lltype */
@@ -406,6 +440,13 @@ CAMLprim value llvm_dump_value(LLVMValueRef Val) {
return Val_unit;
}
+/*--... Operations on users ................................................--*/
+
+/* llvalue -> int -> llvalue */
+CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) {
+ return LLVMGetOperand(V, Int_val(I));
+}
+
/*--... Operations on constants of (mostly) any type .......................--*/
/* llvalue -> bool */
@@ -423,6 +464,52 @@ CAMLprim value llvm_is_undef(LLVMValueRef Val) {
return Val_bool(LLVMIsUndef(Val));
}
+/*--... Operations on instructions .........................................--*/
+
+/* llvalue -> bool */
+CAMLprim value llvm_has_metadata(LLVMValueRef Val) {
+ return Val_bool(LLVMHasMetadata(Val));
+}
+
+/* llvalue -> int -> llvalue option */
+CAMLprim value llvm_metadata(LLVMValueRef Val, value MDKindID) {
+ CAMLparam1(MDKindID);
+ LLVMValueRef MD;
+ if ((MD = LLVMGetMetadata(Val, Int_val(MDKindID)))) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) MD;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* llvalue -> int -> llvalue -> unit */
+CAMLprim value llvm_set_metadata(LLVMValueRef Val, value MDKindID,
+ LLVMValueRef MD) {
+ LLVMSetMetadata(Val, Int_val(MDKindID), MD);
+ return Val_unit;
+}
+
+/* llvalue -> int -> unit */
+CAMLprim value llvm_clear_metadata(LLVMValueRef Val, value MDKindID) {
+ LLVMSetMetadata(Val, Int_val(MDKindID), NULL);
+ return Val_unit;
+}
+
+
+/*--... Operations on metadata .............................................--*/
+
+/* llcontext -> string -> llvalue */
+CAMLprim LLVMValueRef llvm_mdstring(LLVMContextRef C, value S) {
+ return LLVMMDStringInContext(C, String_val(S), caml_string_length(S));
+}
+
+/* llcontext -> llvalue array -> llvalue */
+CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) {
+ return LLVMMDNodeInContext(C, (LLVMValueRef*) Op_val(ElementVals),
+ Wosize_val(ElementVals));
+}
+
/*--... Operations on scalar constants .....................................--*/
/* lltype -> int -> llvalue */
@@ -561,6 +648,14 @@ CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate,
CAMLreturnT(LLVMValueRef, result);
}
+/* lltype -> string -> string -> bool -> bool -> llvalue */
+CAMLprim LLVMValueRef llvm_const_inline_asm(LLVMTypeRef Ty, value Asm,
+ value Constraints, value HasSideEffects,
+ value IsAlignStack) {
+ return LLVMConstInlineAsm(Ty, String_val(Asm), String_val(Constraints),
+ Bool_val(HasSideEffects), Bool_val(IsAlignStack));
+}
+
/*--... Operations on global variables, functions, and aliases (globals) ...--*/
/* llvalue -> bool */
@@ -612,6 +707,42 @@ CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
return Val_unit;
}
+/*--... Operations on uses .................................................--*/
+
+/* llvalue -> lluse option */
+CAMLprim value llvm_use_begin(LLVMValueRef Val) {
+ CAMLparam0();
+ LLVMUseRef First;
+ if ((First = LLVMGetFirstUse(Val))) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) First;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* lluse -> lluse option */
+CAMLprim value llvm_use_succ(LLVMUseRef U) {
+ CAMLparam0();
+ LLVMUseRef Next;
+ if ((Next = LLVMGetNextUse(U))) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) Next;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* lluse -> llvalue */
+CAMLprim LLVMValueRef llvm_user(LLVMUseRef UR) {
+ return LLVMGetUser(UR);
+}
+
+/* lluse -> llvalue */
+CAMLprim LLVMValueRef llvm_used_value(LLVMUseRef UR) {
+ return LLVMGetUsedValue(UR);
+}
+
/*--... Operations on global variables .....................................--*/
DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef,
@@ -629,6 +760,20 @@ CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
return LLVMAddGlobal(M, Ty, String_val(Name));
}
+/* lltype -> string -> int -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
+ value AddressSpace,
+ LLVMModuleRef M) {
+ LLVMValueRef GlobalVar;
+ if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
+ if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
+ return LLVMConstBitCast(GlobalVar,
+ LLVMPointerType(Ty, Int_val(AddressSpace)));
+ return GlobalVar;
+ }
+ return LLVMAddGlobal(M, Ty, String_val(Name));
+}
+
/* string -> llmodule -> llvalue option */
CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) {
CAMLparam1(Name);
@@ -650,6 +795,19 @@ CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
return GlobalVar;
}
+/* string -> llvalue -> int -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_define_qualified_global(value Name,
+ LLVMValueRef Initializer,
+ value AddressSpace,
+ LLVMModuleRef M) {
+ LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(M,
+ LLVMTypeOf(Initializer),
+ String_val(Name),
+ Int_val(AddressSpace));
+ LLVMSetInitializer(GlobalVar, Initializer);
+ return GlobalVar;
+}
+
/* llvalue -> unit */
CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
LLVMDeleteGlobal(GlobalVar);
@@ -692,6 +850,13 @@ CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
return Val_unit;
}
+/*--... Operations on aliases ..............................................--*/
+
+CAMLprim LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty,
+ LLVMValueRef Aliasee, value Name) {
+ return LLVMAddAlias(M, Ty, Aliasee, String_val(Name));
+}
+
/*--... Operations on functions ............................................--*/
DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
@@ -978,7 +1143,7 @@ CAMLprim value llvm_position_builder(value Pos, value B) {
}
/* llbuilder -> llbasicblock */
-CAMLprim LLVMBasicBlockRef llvm_insertion_block(LLVMBuilderRef B) {
+CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
if (!InsertBlock)
raise_not_found();
@@ -986,12 +1151,44 @@ CAMLprim LLVMBasicBlockRef llvm_insertion_block(LLVMBuilderRef B) {
}
/* llvalue -> string -> llbuilder -> unit */
-CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name,
- LLVMBuilderRef B) {
- LLVMInsertIntoBuilderWithName(B, I, String_val(Name));
+CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
+ LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
+ return Val_unit;
+}
+
+/*--... Metadata ...........................................................--*/
+
+/* llbuilder -> llvalue -> unit */
+CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) {
+ LLVMSetCurrentDebugLocation(Builder_val(B), V);
return Val_unit;
}
+/* llbuilder -> unit */
+CAMLprim value llvm_clear_current_debug_location(value B) {
+ LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
+ return Val_unit;
+}
+
+/* llbuilder -> llvalue option */
+CAMLprim value llvm_current_debug_location(value B) {
+ CAMLparam0();
+ LLVMValueRef L;
+ if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) L;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* llbuilder -> llvalue -> unit */
+CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
+ LLVMSetInstDebugLocation(Builder_val(B), V);
+ return Val_unit;
+}
+
+
/*--... Terminators ........................................................--*/
/* llbuilder -> llvalue */
@@ -1031,13 +1228,27 @@ CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
}
-CAMLprim value llvm_add_case(LLVMValueRef Switch,
- LLVMValueRef OnVal,
+/* llvalue -> llvalue -> llbasicblock -> unit */
+CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
LLVMBasicBlockRef Dest) {
LLVMAddCase(Switch, OnVal, Dest);
return Val_unit;
}
+/* llvalue -> llbasicblock -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr,
+ value EstimatedDests,
+ value B) {
+ return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
+}
+
+/* llvalue -> llvalue -> llbasicblock -> unit */
+CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr,
+ LLVMBasicBlockRef Dest) {
+ LLVMAddDestination(IndirectBr, Dest);
+ return Val_unit;
+}
+
/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
@@ -1082,6 +1293,12 @@ CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
}
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
value Name, value B) {
return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
@@ -1094,6 +1311,18 @@ CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
}
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
value Name, value B) {
return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
@@ -1106,6 +1335,18 @@ CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
}
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
value Name, value B) {
return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
@@ -1196,25 +1437,31 @@ CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
}
/* llvalue -> string -> llbuilder -> llvalue */
-CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
- value Name, value B) {
- return LLVMBuildNot(Builder_val(B), X, String_val(Name));
+CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
}
-/*--... Memory .............................................................--*/
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
+}
-/* lltype -> string -> llbuilder -> llvalue */
-CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty,
- value Name, value B) {
- return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
}
-/* lltype -> llvalue -> string -> llbuilder -> llvalue */
-CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty, LLVMValueRef Size,
- value Name, value B) {
- return LLVMBuildArrayMalloc(Builder_val(B), Ty, Size, String_val(Name));
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildNot(Builder_val(B), X, String_val(Name));
}
+/*--... Memory .............................................................--*/
+
/* lltype -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
value Name, value B) {
@@ -1227,11 +1474,6 @@ CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
}
-/* llvalue -> llbuilder -> llvalue */
-CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef Pointer, value B) {
- return LLVMBuildFree(Builder_val(B), Pointer);
-}
-
/* llvalue -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
value Name, value B) {
@@ -1510,14 +1752,6 @@ CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
}
-/*===-- Module Providers --------------------------------------------------===*/
-
-/* llmoduleprovider -> unit */
-CAMLprim value llvm_dispose_module_provider(LLVMModuleProviderRef MP) {
- LLVMDisposeModuleProvider(MP);
- return Val_unit;
-}
-
/*===-- Memory buffers ----------------------------------------------------===*/
diff --git a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml
index b4563b7..5699152 100644
--- a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml
+++ b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml
@@ -10,9 +10,38 @@
external add_constant_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_constant_propagation"
-external add_instruction_combining : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_instruction_combining"
+external add_sccp : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_sccp"
+external add_dead_store_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_dead_store_elimination"
+external add_aggressive_dce : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_aggressive_dce"
+external
+add_scalar_repl_aggregation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregation"
+external add_ind_var_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_ind_var_simplification"
+external
+add_instruction_combination : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_instruction_combination"
+external add_licm : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_licm"
+external add_loop_unswitch : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_unswitch"
+external add_loop_unroll : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_unroll"
+external add_loop_rotation : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_rotation"
+external add_loop_index_split : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_index_split"
external
add_memory_to_register_promotion : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
@@ -21,12 +50,26 @@ external
add_memory_to_register_demotion : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_memory_to_register_demotion"
-external add_reassociation : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
+external add_reassociation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_reassociation"
-external add_gvn : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_gvn"
+external add_jump_threading : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_jump_threading"
external add_cfg_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_cfg_simplification"
+external
+add_tail_call_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_tail_call_elimination"
+external add_gvn : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_gvn"
+external add_memcpy_opt : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_memcpy_opt"
+external add_loop_deletion : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_deletion"
+external
+add_lib_call_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_lib_call_simplification"
diff --git a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli
index 6fcce04..9f95fbc 100644
--- a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli
+++ b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli
@@ -17,10 +17,59 @@ external add_constant_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_constant_propagation"
+(** See the [llvm::createSCCPPass] function. *)
+external add_sccp : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_sccp"
+
+(** See [llvm::createDeadStoreEliminationPass] function. *)
+external add_dead_store_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_dead_store_elimination"
+
+(** See The [llvm::createAggressiveDCEPass] function. *)
+external add_aggressive_dce : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_aggressive_dce"
+
+(** See the [llvm::createScalarReplAggregatesPass] function. *)
+external
+add_scalar_repl_aggregation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregation"
+
+(** See the [llvm::createIndVarSimplifyPass] function. *)
+external add_ind_var_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_ind_var_simplification"
+
(** See the [llvm::createInstructionCombiningPass] function. *)
-external add_instruction_combining : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_instruction_combining"
+external
+add_instruction_combination : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_instruction_combination"
+
+(** See the [llvm::createLICMPass] function. *)
+external add_licm : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_licm"
+
+(** See the [llvm::createLoopUnswitchPass] function. *)
+external add_loop_unswitch : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_unswitch"
+
+(** See the [llvm::createLoopUnrollPass] function. *)
+external add_loop_unroll : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_unroll"
+
+(** See the [llvm::createLoopRotatePass] function. *)
+external add_loop_rotation : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_rotation"
+
+(** See the [llvm::createLoopIndexSplitPass] function. *)
+external add_loop_index_split : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_index_split"
(** See the [llvm::createPromoteMemoryToRegisterPass] function. *)
external
@@ -35,16 +84,40 @@ add_memory_to_register_demotion : [<Llvm.PassManager.any] Llvm.PassManager.t
= "llvm_add_memory_to_register_demotion"
(** See the [llvm::createReassociatePass] function. *)
-external add_reassociation : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
+external add_reassociation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_reassociation"
-(** See the [llvm::createGVNPass] function. *)
-external add_gvn : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_gvn"
+(** See the [llvm::createJumpThreadingPass] function. *)
+external add_jump_threading : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_jump_threading"
(** See the [llvm::createCFGSimplificationPass] function. *)
external add_cfg_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_cfg_simplification"
+
+(** See the [llvm::createTailCallEliminationPass] function. *)
+external
+add_tail_call_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_tail_call_elimination"
+
+(** See the [llvm::createGVNPass] function. *)
+external add_gvn : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_gvn"
+
+(** See the [llvm::createMemCpyOptPass] function. *)
+external add_memcpy_opt : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_memcpy_opt"
+
+(** See the [llvm::createLoopDeletionPass] function. *)
+external add_loop_deletion : [<Llvm.PassManager.any] Llvm.PassManager.t
+ -> unit
+ = "llvm_add_loop_deletion"
+
+(** See the [llvm::createSimplifyLibCallsPass] function. *)
+external
+add_lib_call_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_lib_call_simplification"
diff --git a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c b/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c
index 87c1060..c20bdde 100644
--- a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c
+++ b/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c
@@ -26,12 +26,72 @@ CAMLprim value llvm_add_constant_propagation(LLVMPassManagerRef PM) {
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_instruction_combining(LLVMPassManagerRef PM) {
+CAMLprim value llvm_add_sccp(LLVMPassManagerRef PM) {
+ LLVMAddSCCPPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_dead_store_elimination(LLVMPassManagerRef PM) {
+ LLVMAddDeadStoreEliminationPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_aggressive_dce(LLVMPassManagerRef PM) {
+ LLVMAddAggressiveDCEPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_scalar_repl_aggregation(LLVMPassManagerRef PM) {
+ LLVMAddScalarReplAggregatesPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_ind_var_simplification(LLVMPassManagerRef PM) {
+ LLVMAddIndVarSimplifyPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_instruction_combination(LLVMPassManagerRef PM) {
LLVMAddInstructionCombiningPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_licm(LLVMPassManagerRef PM) {
+ LLVMAddLICMPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_unswitch(LLVMPassManagerRef PM) {
+ LLVMAddLoopUnrollPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_unroll(LLVMPassManagerRef PM) {
+ LLVMAddLoopUnrollPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_rotation(LLVMPassManagerRef PM) {
+ LLVMAddLoopRotatePass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_index_split(LLVMPassManagerRef PM) {
+ LLVMAddLoopIndexSplitPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_memory_to_register_promotion(LLVMPassManagerRef PM) {
LLVMAddPromoteMemoryToRegisterPass(PM);
return Val_unit;
@@ -50,8 +110,8 @@ CAMLprim value llvm_add_reassociation(LLVMPassManagerRef PM) {
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_gvn(LLVMPassManagerRef PM) {
- LLVMAddGVNPass(PM);
+CAMLprim value llvm_add_jump_threading(LLVMPassManagerRef PM) {
+ LLVMAddJumpThreadingPass(PM);
return Val_unit;
}
@@ -60,3 +120,33 @@ CAMLprim value llvm_add_cfg_simplification(LLVMPassManagerRef PM) {
LLVMAddCFGSimplificationPass(PM);
return Val_unit;
}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_tail_call_elimination(LLVMPassManagerRef PM) {
+ LLVMAddTailCallEliminationPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_gvn(LLVMPassManagerRef PM) {
+ LLVMAddGVNPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_memcpy_opt(LLVMPassManagerRef PM) {
+ LLVMAddMemCpyOptPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_deletion(LLVMPassManagerRef PM) {
+ LLVMAddLoopDeletionPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_lib_call_simplification(LLVMPassManagerRef PM) {
+ LLVMAddSimplifyLibCallsPass(PM);
+ return Val_unit;
+}
diff --git a/clear_tblgen_vars.mk b/clear_tblgen_vars.mk
new file mode 100644
index 0000000..6c9623e
--- /dev/null
+++ b/clear_tblgen_vars.mk
@@ -0,0 +1,2 @@
+TBLGEN_TABLES :=
+TBLGEN_TD_DIR :=
diff --git a/configure b/configure
index 88050f3..2b597a1 100755
--- a/configure
+++ b/configure
@@ -689,12 +689,16 @@ TARGET_HAS_JIT
ENABLE_DOXYGEN
ENABLE_THREADS
ENABLE_PIC
+ENABLE_SHARED
TARGETS_TO_BUILD
LLVM_ENUM_TARGETS
LLVM_ENUM_ASM_PRINTERS
LLVM_ENUM_ASM_PARSERS
LLVM_ENUM_DISASSEMBLERS
ENABLE_CBE_PRINTF_A
+CLANGPATH
+CLANGXXPATH
+ENABLE_BUILT_CLANG
OPTIMIZE_OPTION
EXTRA_OPTIONS
BINUTILS_INCDIR
@@ -754,6 +758,7 @@ LLVMGCCCOMMAND
LLVMGXXCOMMAND
LLVMGCC
LLVMGXX
+LLVMCC_OPTION
NO_VARIADIC_MACROS
NO_MISSING_FIELD_INITIALIZERS
USE_UDIS86
@@ -764,11 +769,9 @@ MMAP_FILE
LLVMCC1
LLVMCC1PLUS
LLVMGCCDIR
-LLVMGCCLIBEXEC
-LLVMGCC_VERSION
-LLVMGCC_MAJVERS
LLVMGCC_LANGS
SHLIBEXT
+SHLIBPATH_VAR
LLVM_PREFIX
LLVM_BINDIR
LLVM_LIBDIR
@@ -810,6 +813,7 @@ projects/llvm-java
projects/llvm-tv
projects/llvm-poolalloc
projects/poolalloc
+projects/safecode
projects/llvm-kernel'
# Initialize some variables set by options.
@@ -1401,6 +1405,8 @@ Optional Features:
--enable-threads Use threads if available (default is YES)
--enable-pic Build LLVM with Position Independent Code (default
is YES)
+ --enable-shared Build a shared library and link tools against it
+ (default is NO)
--enable-targets Build specific host targets: all or
target1,target2,... Valid targets are: host, x86,
x86_64, sparc, powerpc, alpha, arm, mips, spu,
@@ -1426,6 +1432,10 @@ Optional Packages:
searches PATH)
--with-llvmgxx Specify location of llvm-g++ driver (default
searches PATH)
+ --with-clang Specify location of clang compiler (default is
+ --with-built-clang)
+ --with-built-clang Use the compiled Clang as the LLVM compiler
+ (default=check)
--with-optimize-option Select the compiler options to use for optimized
builds
--with-extra-options Specify additional options to compile LLVM with
@@ -1442,6 +1452,8 @@ Optional Packages:
--with-binutils-include Specify path to binutils/include/ containing
plugin-api.h file for gold plugin.
--with-tclinclude directory where tcl headers are
+ --with-llvmcc=<name> Choose the LLVM capable compiler to use (llvm-gcc,
+ clang, or none; default=check)
--with-udis86=<path> Use udis86 external x86 disassembler library
--with-oprofile=<prefix>
Tell OProfile >= 0.9.4 how to symbolize JIT output
@@ -1968,6 +1980,8 @@ do
;;
poolalloc) subdirs="$subdirs projects/poolalloc"
;;
+ safecode) subdirs="$subdirs projects/safecode"
+ ;;
llvm-kernel) subdirs="$subdirs projects/llvm-kernel"
;;
*)
@@ -2320,6 +2334,7 @@ else
msp430-*) llvm_cv_target_arch="MSP430" ;;
s390x-*) llvm_cv_target_arch="SystemZ" ;;
bfin-*) llvm_cv_target_arch="Blackfin" ;;
+ mblaze-*) llvm_cv_target_arch="MBlaze" ;;
*) llvm_cv_target_arch="Unknown" ;;
esac
fi
@@ -4785,6 +4800,8 @@ else
;;
Blackfin) TARGET_HAS_JIT=0
;;
+ MBlaze) TARGET_HAS_JIT=0
+ ;;
*) TARGET_HAS_JIT=0
;;
esac
@@ -4857,6 +4874,25 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval=$enable_shared;
+else
+ enableval=default
+fi
+
+case "$enableval" in
+ yes) ENABLE_SHARED=1
+ ;;
+ no) ENABLE_SHARED=0
+ ;;
+ default) ENABLE_SHARED=0
+ ;;
+ *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-shared. Use \"yes\" or \"no\"" >&5
+echo "$as_me: error: Invalid setting for --enable-shared. Use \"yes\" or \"no\"" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+
TARGETS_TO_BUILD=""
# Check whether --enable-targets was given.
if test "${enable_targets+set}" = set; then
@@ -4869,7 +4905,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
- all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" ;;
+ all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -4888,6 +4924,7 @@ case "$enableval" in
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
+ mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -4896,6 +4933,7 @@ case "$enableval" in
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
+ MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
@@ -5029,6 +5067,69 @@ echo "$as_me: error: Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is
fi
+# Check whether --with-clang was given.
+if test "${with_clang+set}" = set; then
+ withval=$with_clang;
+else
+ with_clang=default
+fi
+
+
+
+# Check whether --with-built-clang was given.
+if test "${with_built_clang+set}" = set; then
+ withval=$with_built_clang;
+else
+ with_built_clang=check
+fi
+
+
+{ echo "$as_me:$LINENO: checking clang compiler" >&5
+echo $ECHO_N "checking clang compiler... $ECHO_C" >&6; }
+WITH_CLANGPATH=""
+WITH_BUILT_CLANG=0
+if test "$with_clang" != "default"; then
+ WITH_CLANGPATH="$with_clang"
+ if ! test -x "$WITH_CLANGPATH"; then
+ { { echo "$as_me:$LINENO: error: invalid --with-clang, path does not specify an executable" >&5
+echo "$as_me: error: invalid --with-clang, path does not specify an executable" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+elif test "$with_built_clang" = "yes"; then
+ WITH_BUILT_CLANG=1
+elif test "$with_built_clang" = "no"; then
+ WITH_BUILT_CLANG=0
+else
+ if test "$with_built_clang" != "check"; then
+ { { echo "$as_me:$LINENO: error: invalid value for --with-built-clang." >&5
+echo "$as_me: error: invalid value for --with-built-clang." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ if test -f ${srcdir}/tools/clang/README.txt; then
+ WITH_BUILT_CLANG=1
+ fi
+fi
+
+if ! test -z "$WITH_CLANGPATH"; then
+ { echo "$as_me:$LINENO: result: $WITH_CLANGPATH" >&5
+echo "${ECHO_T}$WITH_CLANGPATH" >&6; }
+ WITH_CLANGXXPATH=`"$WITH_CLANGPATH" --print-prog-name=clang++`
+elif test "$WITH_BUILT_CLANG" = "1"; then
+ { echo "$as_me:$LINENO: result: built" >&5
+echo "${ECHO_T}built" >&6; }
+else
+ { echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6; }
+fi
+CLANGPATH=$WITH_CLANGPATH
+
+CLANGXXPATH=$WITH_CLANGXXPATH
+
+ENABLE_BUILT_CLANG=$WITH_BUILT_CLANG
+
+
+
# Check whether --with-optimize-option was given.
if test "${with_optimize_option+set}" = set; then
withval=$with_optimize_option;
@@ -11035,7 +11136,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 11038 "configure"
+#line 11139 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12805,6 +12906,36 @@ else
fi
+# Check whether --with-llvmcc was given.
+if test "${with_llvmcc+set}" = set; then
+ withval=$with_llvmcc;
+else
+ with_llvmcc=check
+fi
+
+{ echo "$as_me:$LINENO: checking LLVM capable compiler" >&5
+echo $ECHO_N "checking LLVM capable compiler... $ECHO_C" >&6; }
+if test "$with_llvmcc" != "check"; then
+ if (test "$with_llvmcc" != "llvm-gcc" &&
+ test "$with_llvmcc" != "clang" &&
+ test "$with_llvmcc" != "none"); then
+ { { echo "$as_me:$LINENO: error: invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'." >&5
+echo "$as_me: error: invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ WITH_LLVMCC="$with_llvmcc"
+elif test -n "$LLVMGCC"; then
+ WITH_LLVMCC=llvm-gcc
+elif test -n "$WITH_CLANGPATH" || test "$WITH_BUILT_CLANG" -ne "0"; then
+ WITH_LLVMCC=clang
+else
+ WITH_LLVMCC=none
+fi
+{ echo "$as_me:$LINENO: result: $WITH_LLVMCC" >&5
+echo "${ECHO_T}$WITH_LLVMCC" >&6; }
+LLVMCC_OPTION=$WITH_LLVMCC
+
+
{ echo "$as_me:$LINENO: checking tool compatibility" >&5
echo $ECHO_N "checking tool compatibility... $ECHO_C" >&6; }
@@ -16413,6 +16544,7 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+ ac_save_CXXFLAGS=$CXXFLAGS
CXXFLAGS=-pedantic
if test "$cross_compiling" = yes; then
ac_cv_huge_val_sanity=yes
@@ -16465,6 +16597,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$a
fi
+ CXXFLAGS=$ac_save_CXXFLAGS
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -19576,15 +19709,6 @@ echo $ECHO_N "checking llvm-gcc component support... $ECHO_C" >&6; }
llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'`
LLVMGCCDIR=$llvmgccdir
- llvmgcclibexec=`echo "$llvmcc1path" | sed 's,/cc1,,'`
- LLVMGCCLIBEXEC=$llvmgcclibexec
-
- llvmgccversion=`"$LLVMGCC" -dumpversion 2>&1 | sed 's/^\([0-9.]*\).*/\1/'`
- llvmgccmajvers=`echo $llvmgccversion | sed 's/^\([0-9]\).*/\1/'`
- LLVMGCC_VERSION=$llvmgccversion
-
- LLVMGCC_MAJVERS=$llvmgccmajvers
-
llvmgcclangs=`"$LLVMGCC" -v --help 2>&1 | grep '^Configured with:' | sed 's/^.*--enable-languages=\([^ ]*\).*/\1/'`
LLVMGCC_LANGS=$llvmgcclangs
@@ -19595,6 +19719,9 @@ fi
SHLIBEXT=$libltdl_cv_shlibext
+SHLIBPATH_VAR=$libltdl_cv_shlibpath_var
+
+
# Translate the various configuration directories and other basic
# information into substitutions that will end up in Makefile.config.in
# that these configured values can be used by the makefiles
@@ -19605,7 +19732,7 @@ eval LLVM_PREFIX="${prefix}";
eval LLVM_BINDIR="${prefix}/bin";
eval LLVM_LIBDIR="${prefix}/lib";
eval LLVM_DATADIR="${prefix}/share/llvm";
-eval LLVM_DOCSDIR="${prefix}/docs/llvm";
+eval LLVM_DOCSDIR="${prefix}/share/doc/llvm";
eval LLVM_ETCDIR="${prefix}/etc/llvm";
eval LLVM_INCLUDEDIR="${prefix}/include";
eval LLVM_INFODIR="${prefix}/info";
@@ -20652,16 +20779,16 @@ TARGET_HAS_JIT!$TARGET_HAS_JIT$ac_delim
ENABLE_DOXYGEN!$ENABLE_DOXYGEN$ac_delim
ENABLE_THREADS!$ENABLE_THREADS$ac_delim
ENABLE_PIC!$ENABLE_PIC$ac_delim
+ENABLE_SHARED!$ENABLE_SHARED$ac_delim
TARGETS_TO_BUILD!$TARGETS_TO_BUILD$ac_delim
LLVM_ENUM_TARGETS!$LLVM_ENUM_TARGETS$ac_delim
LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim
LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim
LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim
ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim
-OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim
-EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim
-BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim
-ENABLE_LLVMC_DYNAMIC!$ENABLE_LLVMC_DYNAMIC$ac_delim
+CLANGPATH!$CLANGPATH$ac_delim
+CLANGXXPATH!$CLANGXXPATH$ac_delim
+ENABLE_BUILT_CLANG!$ENABLE_BUILT_CLANG$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -20703,6 +20830,10 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim
+EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim
+BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim
+ENABLE_LLVMC_DYNAMIC!$ENABLE_LLVMC_DYNAMIC$ac_delim
ENABLE_LLVMC_DYNAMIC_PLUGINS!$ENABLE_LLVMC_DYNAMIC_PLUGINS$ac_delim
CXX!$CXX$ac_delim
CXXFLAGS!$CXXFLAGS$ac_delim
@@ -20758,6 +20889,7 @@ LLVMGCCCOMMAND!$LLVMGCCCOMMAND$ac_delim
LLVMGXXCOMMAND!$LLVMGXXCOMMAND$ac_delim
LLVMGCC!$LLVMGCC$ac_delim
LLVMGXX!$LLVMGXX$ac_delim
+LLVMCC_OPTION!$LLVMCC_OPTION$ac_delim
NO_VARIADIC_MACROS!$NO_VARIADIC_MACROS$ac_delim
NO_MISSING_FIELD_INITIALIZERS!$NO_MISSING_FIELD_INITIALIZERS$ac_delim
USE_UDIS86!$USE_UDIS86$ac_delim
@@ -20768,11 +20900,9 @@ MMAP_FILE!$MMAP_FILE$ac_delim
LLVMCC1!$LLVMCC1$ac_delim
LLVMCC1PLUS!$LLVMCC1PLUS$ac_delim
LLVMGCCDIR!$LLVMGCCDIR$ac_delim
-LLVMGCCLIBEXEC!$LLVMGCCLIBEXEC$ac_delim
-LLVMGCC_VERSION!$LLVMGCC_VERSION$ac_delim
-LLVMGCC_MAJVERS!$LLVMGCC_MAJVERS$ac_delim
LLVMGCC_LANGS!$LLVMGCC_LANGS$ac_delim
SHLIBEXT!$SHLIBEXT$ac_delim
+SHLIBPATH_VAR!$SHLIBPATH_VAR$ac_delim
LLVM_PREFIX!$LLVM_PREFIX$ac_delim
LLVM_BINDIR!$LLVM_BINDIR$ac_delim
LLVM_LIBDIR!$LLVM_LIBDIR$ac_delim
@@ -20793,7 +20923,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 88; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/device/include/llvm/Config/AsmParsers.def b/device/include/llvm/Config/AsmParsers.def
new file mode 100644
index 0000000..d009351
--- /dev/null
+++ b/device/include/llvm/Config/AsmParsers.def
@@ -0,0 +1,29 @@
+//===- llvm/Config/AsmParsers.def - LLVM Assembly Parsers -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language parsers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PARSER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly parsers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASM_PARSER
+# error Please define the macro LLVM_ASM_PARSER(TargetName)
+#endif
+
+LLVM_ASM_PARSER(ARM)
+
+#undef LLVM_ASM_PARSER
diff --git a/device/include/llvm/Config/AsmPrinters.def b/device/include/llvm/Config/AsmPrinters.def
new file mode 100644
index 0000000..6706bd3
--- /dev/null
+++ b/device/include/llvm/Config/AsmPrinters.def
@@ -0,0 +1,29 @@
+//===- llvm/Config/AsmPrinters.def - LLVM Assembly Printers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language printers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PRINTER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly printers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASM_PRINTER
+# error Please define the macro LLVM_ASM_PRINTER(TargetName)
+#endif
+
+LLVM_ASM_PRINTER(ARM)
+
+#undef LLVM_ASM_PRINTER
diff --git a/device/include/llvm/Config/Disassemblers.def b/device/include/llvm/Config/Disassemblers.def
new file mode 100644
index 0000000..7221c15
--- /dev/null
+++ b/device/include/llvm/Config/Disassemblers.def
@@ -0,0 +1,27 @@
+//===- llvm/Config/Disassemblers.def - LLVM Assembly Parsers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language parsers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PARSER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly parsers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DISASSEMBLER
+# error Please define the macro LLVM_DISASSEMBLER(TargetName)
+#endif
+
+#undef LLVM_DISASSEMBLER
diff --git a/device/include/llvm/Config/Targets.def b/device/include/llvm/Config/Targets.def
new file mode 100644
index 0000000..c50df96
--- /dev/null
+++ b/device/include/llvm/Config/Targets.def
@@ -0,0 +1,28 @@
+/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file enumerates all of the target architectures supported by *|
+|* this build of LLVM. Clients of this file should define the *|
+|* LLVM_TARGET macro to be a function-like macro with a single *|
+|* parameter (the name of the target); including this file will then *|
+|* enumerate all of the targets. *|
+|* *|
+|* The set of targets supported by LLVM is generated at configuration *|
+|* time, at which point this header is generated. Do not modify this *|
+|* header directly. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_TARGET
+# error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+LLVM_TARGET(ARM)
+
+#undef LLVM_TARGET
diff --git a/device/include/llvm/Config/config.h b/device/include/llvm/Config/config.h
new file mode 100644
index 0000000..d8128de
--- /dev/null
+++ b/device/include/llvm/Config/config.h
@@ -0,0 +1,586 @@
+/* include/llvm/Config/config.h. Generated from config.h.in by configure. */
+/* include/llvm/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */
+
+/* 32 bit multilib directory. */
+#define CXX_INCLUDE_32BIT_DIR ""
+
+/* 64 bit multilib directory. */
+#define CXX_INCLUDE_64BIT_DIR ""
+
+/* Arch the libstdc++ headers. */
+#define CXX_INCLUDE_ARCH ""
+
+/* Directory with the libstdc++ headers. */
+#define CXX_INCLUDE_ROOT ""
+
+/* Directories clang will search for headers */
+#define C_INCLUDE_DIRS ""
+
+/* Define if CBE is enabled for printf %a output */
+#define ENABLE_CBE_PRINTF_A 1
+
+/* Define if position independent code is enabled */
+#define ENABLE_PIC 0
+
+/* Define if threads enabled */
+#define ENABLE_THREADS 0
+
+/* Define to 1 if you have the `argz_append' function. */
+#define HAVE_ARGZ_APPEND 1
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+#define HAVE_ARGZ_CREATE_SEP 1
+
+/* Define to 1 if you have the <argz.h> header file. */
+#define HAVE_ARGZ_H 1
+
+/* Define to 1 if you have the `argz_insert' function. */
+#define HAVE_ARGZ_INSERT 1
+
+/* Define to 1 if you have the `argz_next' function. */
+#define HAVE_ARGZ_NEXT 1
+
+/* Define to 1 if you have the `argz_stringify' function. */
+#define HAVE_ARGZ_STRINGIFY 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `backtrace' function. */
+#undef HAVE_BACKTRACE
+
+/* Define to 1 if you have the `bcopy' function. */
+/* #undef HAVE_BCOPY */
+
+/* Define to 1 if you have the `ceilf' function. */
+#define HAVE_CEILF 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_CIRCO */
+
+/* Define to 1 if you have the `closedir' function. */
+#define HAVE_CLOSEDIR 1
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the GNU dld library. */
+/* #undef HAVE_DLD */
+
+/* Define to 1 if you have the <dld.h> header file. */
+/* #undef HAVE_DLD_H */
+
+/* Define to 1 if you have the `dlerror' function. */
+#define HAVE_DLERROR 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define if dlopen() is available on this platform. */
+#define HAVE_DLOPEN 1
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define if the dot program is available */
+/* #undef HAVE_DOT */
+
+/* Define if the dotty program is available */
+/* #undef HAVE_DOTTY */
+
+/* Define if you have the _dyld_func_lookup function. */
+/* #undef HAVE_DYLD */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if the system has the type `error_t'. */
+#define HAVE_ERROR_T 1
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+/* #undef HAVE_EXECINFO_H */
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_FDP */
+
+/* Define if libffi is available on this platform. */
+/* #undef HAVE_FFI_CALL */
+
+/* Define to 1 if you have the <ffi/ffi.h> header file. */
+/* #undef HAVE_FFI_FFI_H */
+
+/* Define to 1 if you have the <ffi.h> header file. */
+/* #undef HAVE_FFI_H */
+
+/* Set to 1 if the finite function is found in <ieeefp.h> */
+/* #undef HAVE_FINITE_IN_IEEEFP_H */
+
+/* Define to 1 if you have the `floorf' function. */
+#define HAVE_FLOORF 1
+
+/* Define to 1 if you have the `fmodf' function. */
+#define HAVE_FMODF 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the `getrusage' function. */
+#define HAVE_GETRUSAGE 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if the Graphviz program is available */
+/* #undef HAVE_GRAPHVIZ */
+
+/* Define if the gv program is available */
+/* #undef HAVE_GV */
+
+/* Define to 1 if you have the `index' function. */
+/* #undef HAVE_INDEX */
+
+/* Define to 1 if the system has the type `int64_t'. */
+#define HAVE_INT64_T 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `isatty' function. */
+#define HAVE_ISATTY 1
+
+/* Set to 1 if the isinf function is found in <cmath> */
+#define HAVE_ISINF_IN_CMATH 1
+
+/* Set to 1 if the isinf function is found in <math.h> */
+#define HAVE_ISINF_IN_MATH_H 1
+
+/* Set to 1 if the isnan function is found in <cmath> */
+#define HAVE_ISNAN_IN_CMATH 1
+
+/* Set to 1 if the isnan function is found in <math.h> */
+#define HAVE_ISNAN_IN_MATH_H 1
+
+/* Define if you have the libdl library or equivalent. */
+#define HAVE_LIBDL 1
+
+/* Define to 1 if you have the `imagehlp' library (-limagehlp). */
+/* #undef HAVE_LIBIMAGEHLP */
+
+/* Define to 1 if you have the `m' library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define to 1 if you have the `psapi' library (-lpsapi). */
+/* #undef HAVE_LIBPSAPI */
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define to 1 if you have the `udis86' library (-ludis86). */
+/* #undef HAVE_LIBUDIS86 */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you can use -Wl,-export-dynamic. */
+#define HAVE_LINK_EXPORT_DYNAMIC 1
+
+/* Define to 1 if you have the <link.h> header file. */
+#define HAVE_LINK_H 1
+
+/* Define if you can use -Wl,-R. to pass -R. to the linker, in order to add
+ the current directory to the dynamic linker search path. */
+#define HAVE_LINK_R 1
+
+/* Define to 1 if you have the `longjmp' function. */
+#define HAVE_LONGJMP 1
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+/* #undef HAVE_MACH_MACH_H */
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+/* #undef HAVE_MACH_O_DYLD_H */
+
+/* Define if mallinfo() is available on this platform. */
+#define HAVE_MALLINFO 1
+
+/* Define to 1 if you have the <malloc/malloc.h> header file. */
+/* #undef HAVE_MALLOC_MALLOC_H */
+
+/* Define to 1 if you have the `malloc_zone_statistics' function. */
+/* #undef HAVE_MALLOC_ZONE_STATISTICS */
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkdtemp' function. */
+/* #undef HAVE_MKDTEMP */
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the `mktemp' function. */
+#define HAVE_MKTEMP 1
+
+/* Define to 1 if you have a working `mmap' system call. */
+#define HAVE_MMAP 1
+
+/* Define if mmap() uses MAP_ANONYMOUS to map anonymous pages, or undefine if
+ it uses MAP_ANON */
+#define HAVE_MMAP_ANONYMOUS 1
+
+/* Define if mmap() can map files into memory */
+#define HAVE_MMAP_FILE
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the `nearbyintf' function. */
+#define HAVE_NEARBYINTF 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_NEATO */
+
+/* Define to 1 if you have the `opendir' function. */
+#define HAVE_OPENDIR 1
+
+/* Define to 1 if you have the `powf' function. */
+#define HAVE_POWF 1
+
+/* Define if libtool can extract symbol lists from object files. */
+#define HAVE_PRELOADED_SYMBOLS 1
+
+/* Define to have the %a format string */
+#define HAVE_PRINTF_A 1
+
+/* Have pthread_getspecific */
+/* #undef HAVE_PTHREAD_GETSPECIFIC */
+
+/* Define to 1 if you have the <pthread.h> header file. */
+/* #undef HAVE_PTHREAD_H */
+
+/* Have pthread_mutex_lock */
+/* #undef HAVE_PTHREAD_MUTEX_LOCK */
+
+/* Have pthread_rwlock_init */
+/* #undef HAVE_PTHREAD_RWLOCK_INIT */
+
+/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
+#define HAVE_RAND48 1
+
+/* Define to 1 if you have the `readdir' function. */
+#define HAVE_READDIR 1
+
+/* Define to 1 if you have the `realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define to 1 if you have the `rindex' function. */
+/* #undef HAVE_RINDEX */
+
+/* Define to 1 if you have the `rintf' function. */
+#define HAVE_RINTF 1
+
+/* Define to 1 if you have the `round' function. */
+#define HAVE_ROUND 1
+
+/* Define to 1 if you have the `roundf' function. */
+#define HAVE_ROUNDF 1
+
+/* Define to 1 if you have the `sbrk' function. */
+#define HAVE_SBRK 1
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `setjmp' function. */
+#define HAVE_SETJMP 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define if you have the shl_load function. */
+/* #undef HAVE_SHL_LOAD */
+
+/* Define to 1 if you have the `siglongjmp' function. */
+#define HAVE_SIGLONGJMP 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the `sigsetjmp' function. */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Set to 1 if the std::isinf function is found in <cmath> */
+/* #undef HAVE_STD_ISINF_IN_CMATH */
+
+/* Set to 1 if the std::isnan function is found in <cmath> */
+#define HAVE_STD_ISNAN_IN_CMATH 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strcmp' function. */
+#define HAVE_STRCMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `strerror_s' function. */
+/* #undef HAVE_STRERROR_S */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the `strtof' function. */
+#define HAVE_STRTOF 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoq' function. */
+#define HAVE_STRTOQ 1
+
+/* Define to 1 if you have the `sysconf' function. */
+#define HAVE_SYSCONF 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/dl.h> header file. */
+/* #undef HAVE_SYS_DL_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_TWOPI */
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#define HAVE_UINT64_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if the system has the type `u_int64_t'. */
+/* #undef HAVE_U_INT64_T */
+
+/* Define to 1 if you have the <windows.h> header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the `__dso_handle' function. */
+#define HAVE___DSO_HANDLE 1
+
+/* Installation directory for binary executables */
+#define LLVM_BINDIR "/usr/local/google/llvm/bin"
+
+/* Time at which LLVM was configured */
+#define LLVM_CONFIGTIME "Fri Feb 26 12:17:10 CST 2010"
+
+/* Installation directory for data files */
+#define LLVM_DATADIR "/usr/local/google/llvm/share/llvm"
+
+/* Installation directory for documentation */
+#define LLVM_DOCSDIR "/usr/local/google/llvm/docs/llvm"
+
+/* Installation directory for config files */
+#define LLVM_ETCDIR "/usr/local/google/llvm/etc/llvm"
+
+/* Host triple we were built on */
+#define LLVM_HOSTTRIPLE "x86_64-unknown-linux-gnu"
+
+/* Installation directory for include files */
+#define LLVM_INCLUDEDIR "/usr/local/google/llvm/include"
+
+/* Installation directory for .info files */
+#define LLVM_INFODIR "/usr/local/google/llvm/info"
+
+/* Installation directory for libraries */
+#define LLVM_LIBDIR "/usr/local/google/llvm/lib"
+
+/* Installation directory for man pages */
+#define LLVM_MANDIR "/usr/local/google/llvm/man"
+
+/* Build multithreading support into LLVM */
+/* #undef LLVM_MULTITHREADED */
+
+/* LLVM architecture name for the native architecture, if available */
+#define LLVM_NATIVE_ARCH ARMTarget
+
+/* Define if this is Unixish platform */
+#define LLVM_ON_UNIX 1
+
+/* Define if this is Win32ish platform */
+/* #undef LLVM_ON_WIN32 */
+
+/* Define to path to circo program if found or 'echo circo' otherwise */
+/* #undef LLVM_PATH_CIRCO */
+
+/* Define to path to dot program if found or 'echo dot' otherwise */
+/* #undef LLVM_PATH_DOT */
+
+/* Define to path to dotty program if found or 'echo dotty' otherwise */
+/* #undef LLVM_PATH_DOTTY */
+
+/* Define to path to fdp program if found or 'echo fdp' otherwise */
+/* #undef LLVM_PATH_FDP */
+
+/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
+/* #undef LLVM_PATH_GRAPHVIZ */
+
+/* Define to path to gv program if found or 'echo gv' otherwise */
+/* #undef LLVM_PATH_GV */
+
+/* Define to path to neato program if found or 'echo neato' otherwise */
+/* #undef LLVM_PATH_NEATO */
+
+/* Define to path to twopi program if found or 'echo twopi' otherwise */
+/* #undef LLVM_PATH_TWOPI */
+
+/* Installation prefix directory */
+#define LLVM_PREFIX "/usr/local/google/llvm"
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+/* #undef LTDL_DLOPEN_DEPLIBS */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LTDL_OBJDIR ".libs/"
+
+/* Define to the name of the environment variable that determines the dynamic
+ library search path. */
+#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH"
+
+/* Define to the extension used for shared libraries, say, ".so". */
+#define LTDL_SHLIB_EXT ".so"
+
+/* Define to the system default library search path. */
+#define LTDL_SYSSEARCHPATH "/lib:/usr/lib:/usr/local/lib:/lib:/usr/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib32:/usr/lib32:/usr/local/lib32:/usr/x86_64-pc-linux-gnu/lib:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/32:/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2:/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/32"
+
+/* Define if /dev/zero should be used when mapping RWX memory, or undefine if
+ its not necessary */
+/* #undef NEED_DEV_ZERO_FOR_MMAP */
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+/* #undef NEED_USCORE */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "llvm"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "llvm 2.7svn"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "-llvm-"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.7svn"
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define if we have the oprofile JIT-support library */
+#define USE_OPROFILE 0
+
+/* Define if use udis86 library */
+#define USE_UDIS86 0
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to a type to use for `error_t' if it is not otherwise available. */
+/* #undef error_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/docs/AliasAnalysis.html b/docs/AliasAnalysis.html
index 74b593c..6edd9f5 100644
--- a/docs/AliasAnalysis.html
+++ b/docs/AliasAnalysis.html
@@ -403,7 +403,7 @@ implementing, you just override the interfaces you can improve.</p>
href="#basic-aa">basicaa</a></tt> and <a href="#no-aa"><tt>no-aa</tt></a>
passes) every alias analysis pass chains to another alias analysis
implementation (for example, the user can specify "<tt>-basicaa -ds-aa
--anders-aa -licm</tt>" to get the maximum benefit from the three alias
+-licm</tt>" to get the maximum benefit from both alias
analyses). The alias analysis class automatically takes care of most of this
for methods that you don't override. For methods that you do override, in code
paths that return a conservative MayAlias or Mod/Ref result, simply return
@@ -705,25 +705,6 @@ non-address taken globals), but is very quick analysis.</p>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
- <a name="anders-aa">The <tt>-anders-aa</tt> pass</a>
-</div>
-
-<div class="doc_text">
-
-<p>The <tt>-anders-aa</tt> pass implements the well-known "Andersen's algorithm"
-for interprocedural alias analysis. This algorithm is a subset-based,
-flow-insensitive, context-insensitive, and field-insensitive alias analysis that
-is widely believed to be fairly precise. Unfortunately, this algorithm is also
-O(N<sup>3</sup>). The LLVM implementation currently does not implement any of
-the refinements (such as "online cycle elimination" or "offline variable
-substitution") to improve its efficiency, so it can be quite slow in common
-cases.
-</p>
-
-</div>
-
-<!-- _______________________________________________________________________ -->
-<div class="doc_subsubsection">
<a name="steens-aa">The <tt>-steens-aa</tt> pass</a>
</div>
@@ -855,7 +836,7 @@ pointer.</p>
<div class="doc_text">
<p>These passes are useful for evaluating the various alias analysis
-implementations. You can use them with commands like '<tt>opt -anders-aa -ds-aa
+implementations. You can use them with commands like '<tt>opt -ds-aa
-aa-eval foo.bc -disable-output -stats</tt>'.</p>
</div>
@@ -949,7 +930,7 @@ analysis directly.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-11-22 08:01:44 -0800 (Sun, 22 Nov 2009) $
+ Last modified: $Date: 2010-03-02 03:24:17 +0800 (二, 02 3月 2010) $
</address>
</body>
diff --git a/docs/BitCodeFormat.html b/docs/BitCodeFormat.html
index 2284b3e..de2e65a 100644
--- a/docs/BitCodeFormat.html
+++ b/docs/BitCodeFormat.html
@@ -1157,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: 2010-01-20 09:53:51 -0800 (Wed, 20 Jan 2010) $
+Last modified: $Date: 2010-01-21 01:53:51 +0800 (四, 21 1月 2010) $
</address>
</body>
</html>
diff --git a/docs/Bugpoint.html b/docs/Bugpoint.html
index 8d1400b..6a381b3 100644
--- a/docs/Bugpoint.html
+++ b/docs/Bugpoint.html
@@ -243,7 +243,7 @@ non-obvious ways. Here are some hints and tips:<p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-12 11:12:47 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2009-10-13 02:12:47 +0800 (二, 13 10月 2009) $
</address>
</body>
diff --git a/docs/CodeGenerator.html b/docs/CodeGenerator.html
index b446eebc..5baa4a7 100644
--- a/docs/CodeGenerator.html
+++ b/docs/CodeGenerator.html
@@ -1041,9 +1041,9 @@ ret
<div class="doc_code">
<pre>
-%t1 = add float %W, %X
-%t2 = mul float %t1, %Y
-%t3 = add float %t2, %Z
+%t1 = fadd float %W, %X
+%t2 = fmul float %t1, %Y
+%t3 = fadd float %t2, %Z
</pre>
</div>
@@ -2116,7 +2116,7 @@ MOVSX32rm16 -&gt; movsx, 32-bit register, 16-bit memory
<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 10:53:47 -0800 (Mon, 11 Jan 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
diff --git a/docs/CodingStandards.html b/docs/CodingStandards.html
index 8f8f890..601c5ec 100644
--- a/docs/CodingStandards.html
+++ b/docs/CodingStandards.html
@@ -194,9 +194,9 @@ something sane goes a long ways towards avoiding writing documentation.</p>
<b>Method information</b>
<p>Methods defined in a class (as well as any global functions) should also be
-documented properly. A quick note about what it does any a description of the
+documented properly. A quick note about what it does and a description of the
borderline behaviour is all that is necessary here (unless something
-particularly tricky or insideous is going on). The hope is that people can
+particularly tricky or insidious is going on). The hope is that people can
figure out how to use your interfaces without reading the code itself... that is
the goal metric.</p>
@@ -1346,7 +1346,7 @@ something.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2010-02-27 04:18:32 +0800 (六, 27 2月 2010) $
</address>
</body>
diff --git a/docs/CommandGuide/FileCheck.pod b/docs/CommandGuide/FileCheck.pod
index 32516ad..433979a 100644
--- a/docs/CommandGuide/FileCheck.pod
+++ b/docs/CommandGuide/FileCheck.pod
@@ -25,7 +25,7 @@ match. The file to verify is always read from standard input.
=over
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
diff --git a/docs/CommandGuide/Makefile b/docs/CommandGuide/Makefile
index 3b65183..2c2d076 100644
--- a/docs/CommandGuide/Makefile
+++ b/docs/CommandGuide/Makefile
@@ -77,9 +77,9 @@ EXTRA_DIST := $(POD) index.html
clean-local::
$(Verb) $(RM) -f pod2htm*.*~~ $(HTML) $(MAN) $(PS)
-HTML_DIR := $(PROJ_docsdir)/html/CommandGuide
-MAN_DIR := $(PROJ_mandir)/man1
-PS_DIR := $(PROJ_docsdir)/ps
+HTML_DIR := $(DESTDIR)$(PROJ_docsdir)/html/CommandGuide
+MAN_DIR := $(DESTDIR)$(PROJ_mandir)/man1
+PS_DIR := $(DESTDIR)$(PROJ_docsdir)/ps
install-local:: $(HTML) $(INSTALL_MANS) $(PS)
$(Echo) Installing HTML CommandGuide Documentation
diff --git a/docs/CommandGuide/bugpoint.pod b/docs/CommandGuide/bugpoint.pod
index 204ea4d..7afeea1 100644
--- a/docs/CommandGuide/bugpoint.pod
+++ b/docs/CommandGuide/bugpoint.pod
@@ -85,7 +85,7 @@ mis-management.
Continually randomize the specified passes and run them on the test program
until a bug is found or the user kills B<bugpoint>.
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
@@ -99,9 +99,9 @@ it runs, to come from that file.
Load the dynamic object F<plugin> into B<bugpoint> itself. This object should
register new optimization passes. Once loaded, the object will add new command
line options to enable various optimizations. To see the new complete list of
-optimizations, use the B<--help> and B<--load> options together; for example:
+optimizations, use the B<-help> and B<--load> options together; for example:
- bugpoint --load myNewPass.so --help
+ bugpoint --load myNewPass.so -help
=item B<--mlimit> F<megabytes>
diff --git a/docs/CommandGuide/index.html b/docs/CommandGuide/index.html
index 88bb87c..0bdba7e 100644
--- a/docs/CommandGuide/index.html
+++ b/docs/CommandGuide/index.html
@@ -17,7 +17,7 @@
for all of the LLVM tools. These pages describe how to use the LLVM commands
and what their options are. Note that these pages do not describe all of the
options available for all tools. To get a complete listing, pass the
-<tt>--help</tt> (general options) or <tt>--help-hidden</tt> (general+debugging
+<tt>-help</tt> (general options) or <tt>-help-hidden</tt> (general+debugging
options) arguments to the tool you are interested in.</p>
</div>
@@ -148,7 +148,7 @@ options) arguments to the tool you are interested in.</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: 2009-10-18 20:54:13 -0700 (Sun, 18 Oct 2009) $
+ Last modified: $Date: 2010-02-18 22:08:13 +0800 (四, 18 2月 2010) $
</address>
</body>
diff --git a/docs/CommandGuide/llc.pod b/docs/CommandGuide/llc.pod
index 8adfb68..ac24aab 100644
--- a/docs/CommandGuide/llc.pod
+++ b/docs/CommandGuide/llc.pod
@@ -38,7 +38,7 @@ Other B<llc> options are as follows:
=over
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
@@ -56,7 +56,7 @@ string.
=item B<-march>=I<arch>
Specify the architecture for which to generate assembly, overriding the target
-encoded in the input file. See the output of B<llc --help> for a list of
+encoded in the input file. See the output of B<llc -help> for a list of
valid architectures. By default this is inferred from the target triple or
autodetected to the current architecture.
diff --git a/docs/CommandGuide/lli.pod b/docs/CommandGuide/lli.pod
index e9fdf74..6d1e1c6 100644
--- a/docs/CommandGuide/lli.pod
+++ b/docs/CommandGuide/lli.pod
@@ -73,7 +73,7 @@ architecture which is not compatible with the current system.
=item B<-march>=I<arch>
Specify the architecture for which to generate assembly, overriding the target
-encoded in the bitcode file. See the output of B<llc --help> for a list of
+encoded in the bitcode file. See the output of B<llc -help> for a list of
valid architectures. By default this is inferred from the target triple or
autodetected to the current architecture.
@@ -170,7 +170,7 @@ Instruction schedulers available (before register allocation):
=item B<-regalloc>=I<allocator>
-Register allocator to use: (default = linearscan)
+Register allocator to use (default=linearscan)
=bigblock: Big-block register allocator
=linearscan: linear scan register allocator =local - local register allocator
@@ -186,7 +186,7 @@ Choose relocation model from:
=item B<-spiller>
-Spiller to use: (default: local)
+Spiller to use (default=local)
=simple: simple spiller
=local: local spiller
diff --git a/docs/CommandGuide/llvm-as.pod b/docs/CommandGuide/llvm-as.pod
index 045a924..185c009 100644
--- a/docs/CommandGuide/llvm-as.pod
+++ b/docs/CommandGuide/llvm-as.pod
@@ -50,7 +50,7 @@ Enable binary output on terminals. Normally, B<llvm-as> will refuse to
write raw bitcode output if the output stream is a terminal. With this option,
B<llvm-as> will write raw bitcode regardless of the output device.
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
diff --git a/docs/CommandGuide/llvm-bcanalyzer.pod b/docs/CommandGuide/llvm-bcanalyzer.pod
index f60b513..b0bc0cd 100644
--- a/docs/CommandGuide/llvm-bcanalyzer.pod
+++ b/docs/CommandGuide/llvm-bcanalyzer.pod
@@ -43,7 +43,7 @@ Causes B<llvm-bcanalyzer> to verify the module produced by reading the
bitcode. This ensures that the statistics generated are based on a consistent
module.
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
diff --git a/docs/CommandGuide/llvm-config.pod b/docs/CommandGuide/llvm-config.pod
index 06f10de..4e38dae 100644
--- a/docs/CommandGuide/llvm-config.pod
+++ b/docs/CommandGuide/llvm-config.pod
@@ -30,7 +30,7 @@ To link against the JIT:
Print the version number of LLVM.
-=item B<--help>
+=item B<-help>
Print a summary of B<llvm-config> arguments.
diff --git a/docs/CommandGuide/llvm-db.pod b/docs/CommandGuide/llvm-db.pod
deleted file mode 100644
index 1324176..0000000
--- a/docs/CommandGuide/llvm-db.pod
+++ /dev/null
@@ -1,16 +0,0 @@
-=pod
-
-=head1 NAME
-
-llvm-db - LLVM debugger (alpha)
-
-=head1 SYNOPSIS
-
-Details coming soon. Please see
-L<http://llvm.org/docs/SourceLevelDebugging.html> in the meantime.
-
-=head1 AUTHORS
-
-Maintained by the LLVM Team (L<http://llvm.org>).
-
-=cut
diff --git a/docs/CommandGuide/llvm-dis.pod b/docs/CommandGuide/llvm-dis.pod
index 2b83290..5b2f4ef 100644
--- a/docs/CommandGuide/llvm-dis.pod
+++ b/docs/CommandGuide/llvm-dis.pod
@@ -33,7 +33,7 @@ Enable binary output on terminals. Normally, B<llvm-dis> will refuse to
write raw bitcode output if the output stream is a terminal. With this option,
B<llvm-dis> will write raw bitcode regardless of the output device.
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
diff --git a/docs/CommandGuide/llvm-extract.pod b/docs/CommandGuide/llvm-extract.pod
index b62e8ae..d4baab7 100644
--- a/docs/CommandGuide/llvm-extract.pod
+++ b/docs/CommandGuide/llvm-extract.pod
@@ -34,9 +34,15 @@ B<llvm-extract> will write raw bitcode regardless of the output device.
=item B<--func> I<function-name>
-Extract the function named I<function-name> from the LLVM bitcode.
+Extract the function named I<function-name> from the LLVM bitcode. May be
+specified multiple times to extract multiple functions at once.
-=item B<--help>
+=item B<--glob> I<global-name>
+
+Extract the global variable named I<global-name> from the LLVM bitcode. May be
+specified multiple times to extract multiple global variables at once.
+
+=item B<-help>
Print a summary of command line options.
diff --git a/docs/CommandGuide/llvm-link.pod b/docs/CommandGuide/llvm-link.pod
index e1a1267..8d06cc9 100644
--- a/docs/CommandGuide/llvm-link.pod
+++ b/docs/CommandGuide/llvm-link.pod
@@ -51,7 +51,7 @@ Write output in LLVM intermediate language (instead of bitcode).
If specified, B<llvm-link> prints a human-readable version of the output
bitcode file to standard error.
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
diff --git a/docs/CommandGuide/llvm-nm.pod b/docs/CommandGuide/llvm-nm.pod
index 995ac08..a580d3f 100644
--- a/docs/CommandGuide/llvm-nm.pod
+++ b/docs/CommandGuide/llvm-nm.pod
@@ -77,7 +77,7 @@ Use POSIX.2 output format. Alias for B<--format=posix>.
Use BSD output format. Alias for B<--format=bsd>.
-=item B<--help>
+=item B<-help>
Print a summary of command-line options and their meanings.
diff --git a/docs/CommandGuide/llvm-prof.pod b/docs/CommandGuide/llvm-prof.pod
index 381387d..9541b05 100644
--- a/docs/CommandGuide/llvm-prof.pod
+++ b/docs/CommandGuide/llvm-prof.pod
@@ -18,7 +18,7 @@ where the program hotspots are.
This program is often used in conjunction with the F<utils/profile.pl>
script. This script automatically instruments a program, runs it with the JIT,
then runs B<llvm-prof> to format a report. To get more information about
-F<utils/profile.pl>, execute it with the B<--help> option.
+F<utils/profile.pl>, execute it with the B<-help> option.
=head1 OPTIONS
diff --git a/docs/CommandGuide/llvm-ranlib.pod b/docs/CommandGuide/llvm-ranlib.pod
index 130edb0..53cd34b 100644
--- a/docs/CommandGuide/llvm-ranlib.pod
+++ b/docs/CommandGuide/llvm-ranlib.pod
@@ -6,7 +6,7 @@ llvm-ranlib - Generate index for LLVM archive
=head1 SYNOPSIS
-B<llvm-ranlib> [--version] [--help] <archive-file>
+B<llvm-ranlib> [--version] [-help] <archive-file>
=head1 DESCRIPTION
@@ -30,7 +30,7 @@ Specifies the archive-file to which the symbol table is added or updated.
Print the version of B<llvm-ranlib> and exit without building a symbol table.
-=item F<--help>
+=item F<-help>
Print usage help for B<llvm-ranlib> and exit without building a symbol table.
diff --git a/docs/CommandGuide/llvmc.pod b/docs/CommandGuide/llvmc.pod
index e5e0651..d237ca4 100644
--- a/docs/CommandGuide/llvmc.pod
+++ b/docs/CommandGuide/llvmc.pod
@@ -77,11 +77,11 @@ Store temporary files in the given directory. This directory is deleted on exit
unless I<--save-temps> is specified. If I<--save-temps=obj> is also specified,
I<--temp-dir> is given the precedence.
-=item B<--help>
+=item B<-help>
Print a summary of command-line options and exit.
-=item B<--help-hidden>
+=item B<-help-hidden>
Print a summary of command-line options and exit. Print help even for
options intended for developers.
diff --git a/docs/CommandGuide/tblgen.pod b/docs/CommandGuide/tblgen.pod
index c8244af..d127492 100644
--- a/docs/CommandGuide/tblgen.pod
+++ b/docs/CommandGuide/tblgen.pod
@@ -26,7 +26,7 @@ to read as input.
=over
-=item B<--help>
+=item B<-help>
Print a summary of command line options.
diff --git a/docs/CommandLine.html b/docs/CommandLine.html
index 38421c7..d477609 100644
--- a/docs/CommandLine.html
+++ b/docs/CommandLine.html
@@ -44,7 +44,7 @@
<li><a href="#modifiers">Option Modifiers</a>
<ul>
- <li><a href="#hiding">Hiding an option from <tt>--help</tt>
+ <li><a href="#hiding">Hiding an option from <tt>-help</tt>
output</a></li>
<li><a href="#numoccurrences">Controlling the number of occurrences
required and allowed</a></li>
@@ -161,7 +161,7 @@ you declare it. <a href="#customparser">Custom parsers</a> are no problem.</li>
<li>Labor Saving: The CommandLine library cuts down on the amount of grunt work
that you, the user, have to do. For example, it automatically provides a
-<tt>--help</tt> option that shows the available command line options for your
+<tt>-help</tt> option that shows the available command line options for your
tool. Additionally, it does most of the basic correctness checking for
you.</li>
@@ -239,14 +239,14 @@ href="#list">"<tt>cl::list</tt> template</a>), and tell the CommandLine library
that the data type that we are parsing is a string.</p>
<p>The second and third parameters (which are optional) are used to specify what
-to output for the "<tt>--help</tt>" option. In this case, we get a line that
+to output for the "<tt>-help</tt>" option. In this case, we get a line that
looks like this:</p>
<div class="doc_code"><pre>
USAGE: compiler [options]
OPTIONS:
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
<b>-o &lt;filename&gt; - Specify output filename</b>
</pre></div>
@@ -308,14 +308,14 @@ the CommandLine library will automatically issue an error if the argument is not
specified, which shifts all of the command line option verification code out of
your application into the library. This is just one example of how using flags
can alter the default behaviour of the library, on a per-option basis. By
-adding one of the declarations above, the <tt>--help</tt> option synopsis is now
+adding one of the declarations above, the <tt>-help</tt> option synopsis is now
extended to:</p>
<div class="doc_code"><pre>
USAGE: compiler [options] <b>&lt;input file&gt;</b>
OPTIONS:
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
-o &lt;filename&gt; - Specify output filename
</pre></div>
@@ -346,8 +346,8 @@ declaring options of boolean type like this:</p>
("<tt>Force</tt>", "<tt>Quiet</tt>", and "<tt>Quiet2</tt>") to recognize these
options. Note that the "<tt>-q</tt>" option is specified with the "<a
href="#cl::Hidden"><tt>cl::Hidden</tt></a>" flag. This modifier prevents it
-from being shown by the standard "<tt>--help</tt>" output (note that it is still
-shown in the "<tt>--help-hidden</tt>" output).</p>
+from being shown by the standard "<tt>-help</tt>" output (note that it is still
+shown in the "<tt>-help-hidden</tt>" output).</p>
<p>The CommandLine library uses a <a href="#builtinparsers">different parser</a>
for different data types. For example, in the string case, the argument passed
@@ -372,7 +372,7 @@ href="#doubleparser">double</a>, and <a href="#intparser">int</a> parsers work
like you would expect, using the '<tt>strtol</tt>' and '<tt>strtod</tt>' C
library calls to parse the string value into the specified data type.</p>
-<p>With the declarations above, "<tt>compiler --help</tt>" emits this:</p>
+<p>With the declarations above, "<tt>compiler -help</tt>" emits this:</p>
<div class="doc_code"><pre>
USAGE: compiler [options] &lt;input file&gt;
@@ -381,10 +381,10 @@ OPTIONS:
<b>-f - Enable binary output on terminals</b>
-o - Override output filename
<b>-quiet - Don't print informational messages</b>
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
</pre></div>
-<p>and "<tt>compiler --help-hidden</tt>" prints this:</p>
+<p>and "<tt>compiler -help-hidden</tt>" prints this:</p>
<div class="doc_code"><pre>
USAGE: compiler [options] &lt;input file&gt;
@@ -394,7 +394,7 @@ OPTIONS:
-o - Override output filename
<b>-q - Don't print informational messages</b>
-quiet - Don't print informational messages
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
</pre></div>
<p>This brief example has shown you how to use the '<tt><a
@@ -438,7 +438,7 @@ the <tt><a href="#cl::aliasopt">cl::aliasopt</a></tt> modifier) whenever it is
specified. Because aliases do not hold state, the only thing the program has to
query is the <tt>Quiet</tt> variable now. Another nice feature of aliases is
that they automatically hide themselves from the <tt>-help</tt> output
-(although, again, they are still visible in the <tt>--help-hidden
+(although, again, they are still visible in the <tt>-help-hidden
output</tt>).</p>
<p>Now the application code can simply use:</p>
@@ -531,7 +531,7 @@ OPTIONS:
-O2 - Enable default optimizations
-O3 - Enable expensive optimizations</b>
-f - Enable binary output on terminals
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
-o &lt;filename&gt; - Specify output filename
-quiet - Don't print informational messages
</pre></div>
@@ -599,7 +599,7 @@ enum DebugLev {
<p>This definition defines an enumerated command line variable of type "<tt>enum
DebugLev</tt>", which works exactly the same way as before. The difference here
is just the interface exposed to the user of your program and the help output by
-the "<tt>--help</tt>" option:</p>
+the "<tt>-help</tt>" option:</p>
<div class="doc_code"><pre>
USAGE: compiler [options] &lt;input file&gt;
@@ -615,7 +615,7 @@ OPTIONS:
=quick - enable quick debug information
=detailed - enable detailed debug information</b>
-f - Enable binary output on terminals
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
-o &lt;filename&gt; - Specify output filename
-quiet - Don't print informational messages
</pre></div>
@@ -706,7 +706,7 @@ checking we have to do.</p>
<div class="doc_text">
<p>Instead of collecting sets of options in a list, it is also possible to
-gather information for enum values in a <b>bit vector</b>. The represention used by
+gather information for enum values in a <b>bit vector</b>. The representation used by
the <a href="#bits"><tt>cl::bits</tt></a> class is an <tt>unsigned</tt>
integer. An enum value is represented by a 0/1 in the enum's ordinal value bit
position. 1 indicating that the enum was specified, 0 otherwise. As each
@@ -794,7 +794,7 @@ USAGE: compiler [options] &lt;input file&gt;
OPTIONS:
...
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
-o &lt;filename&gt; - Specify output filename
</pre></div>
@@ -835,14 +835,14 @@ Using the CommandLine library, this would be specified as:</p>
<a href="#cl::opt">cl::opt</a>&lt;string&gt; Filename(<a href="#cl::Positional">cl::Positional</a>, <a href="#cl::desc">cl::desc</a>("<i>&lt;input file&gt;</i>"), <a href="#cl::init">cl::init</a>("<i>-</i>"));
</pre></div>
-<p>Given these two option declarations, the <tt>--help</tt> output for our grep
+<p>Given these two option declarations, the <tt>-help</tt> output for our grep
replacement would look like this:</p>
<div class="doc_code"><pre>
USAGE: spiffygrep [options] <b>&lt;regular expression&gt; &lt;input file&gt;</b>
OPTIONS:
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
</pre></div>
<p>... and the resultant program could be used just like the standard
@@ -872,7 +872,7 @@ Note that the system <tt>grep</tt> has the same problem:</p>
<div class="doc_code"><pre>
$ spiffygrep '-foo' test.txt
- Unknown command line argument '-foo'. Try: spiffygrep --help'
+ Unknown command line argument '-foo'. Try: spiffygrep -help'
$ grep '-foo' test.txt
grep: illegal option -- f
@@ -986,7 +986,7 @@ shell itself. Using the CommandLine library, we would specify this as:</p>
USAGE: spiffysh [options] <b>&lt;input script&gt; &lt;program arguments&gt;...</b>
OPTIONS:
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
<b>-x - Enable trace output</b>
</pre></div>
@@ -1098,11 +1098,11 @@ This option is specified in simple double quotes:
</li>
<li><a name="cl::desc">The <b><tt>cl::desc</tt></b></a> attribute specifies a
-description for the option to be shown in the <tt>--help</tt> output for the
+description for the option to be shown in the <tt>-help</tt> output for the
program.</li>
<li><a name="cl::value_desc">The <b><tt>cl::value_desc</tt></b></a> attribute
-specifies a string that can be used to fine tune the <tt>--help</tt> output for
+specifies a string that can be used to fine tune the <tt>-help</tt> output for
a command line option. Look <a href="#value_desc_example">here</a> for an
example.</li>
@@ -1130,7 +1130,7 @@ the string-to-value mapping to be used by the generic parser. It takes a
<b>clEnumValEnd terminated</b> list of (option, value, description) triplets
that
specify the option name, the value mapped to, and the description shown in the
-<tt>--help</tt> for the tool. Because the generic parser is used most
+<tt>-help</tt> for the tool. Because the generic parser is used most
frequently with enum values, two macros are often useful:
<ol>
@@ -1175,13 +1175,13 @@ obviously).</li>
<p>Option modifiers are the flags and expressions that you pass into the
constructors for <tt><a href="#cl::opt">cl::opt</a></tt> and <tt><a
href="#cl::list">cl::list</a></tt>. These modifiers give you the ability to
-tweak how options are parsed and how <tt>--help</tt> output is generated to fit
+tweak how options are parsed and how <tt>-help</tt> output is generated to fit
your application well.</p>
<p>These options fall into five main categories:</p>
<ol>
-<li><a href="#hiding">Hiding an option from <tt>--help</tt> output</a></li>
+<li><a href="#hiding">Hiding an option from <tt>-help</tt> output</a></li>
<li><a href="#numoccurrences">Controlling the number of occurrences
required and allowed</a></li>
<li><a href="#valrequired">Controlling whether or not a value must be
@@ -1200,14 +1200,14 @@ usually shouldn't have to worry about these.</p>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
- <a name="hiding">Hiding an option from <tt>--help</tt> output</a>
+ <a name="hiding">Hiding an option from <tt>-help</tt> output</a>
</div>
<div class="doc_text">
<p>The <tt>cl::NotHidden</tt>, <tt>cl::Hidden</tt>, and
<tt>cl::ReallyHidden</tt> modifiers are used to control whether or not an option
-appears in the <tt>--help</tt> and <tt>--help-hidden</tt> output for the
+appears in the <tt>-help</tt> and <tt>-help-hidden</tt> output for the
compiled program:</p>
<ul>
@@ -1219,8 +1219,8 @@ in both help listings.</li>
<li><a name="cl::Hidden">The <b><tt>cl::Hidden</tt></b></a> modifier (which is the
default for <tt><a href="#cl::alias">cl::alias</a></tt> options) indicates that
-the option should not appear in the <tt>--help</tt> output, but should appear in
-the <tt>--help-hidden</tt> output.</li>
+the option should not appear in the <tt>-help</tt> output, but should appear in
+the <tt>-help-hidden</tt> output.</li>
<li><a name="cl::ReallyHidden">The <b><tt>cl::ReallyHidden</tt></b></a> modifier
indicates that the option should not appear in any help output.</li>
@@ -1508,7 +1508,7 @@ available.</p>
<p>The <tt>cl::ParseCommandLineOptions</tt> function requires two parameters
(<tt>argc</tt> and <tt>argv</tt>), but may also take an optional third parameter
which holds <a href="#description">additional extra text</a> to emit when the
-<tt>--help</tt> option is invoked, and a fourth boolean parameter that enables
+<tt>-help</tt> option is invoked, and a fourth boolean parameter that enables
<a href="#response">response files</a>.</p>
</div>
@@ -1535,7 +1535,7 @@ does.</p>
not be available, it can't just look in <tt>argv[0]</tt>), the name of the
environment variable to examine, the optional
<a href="#description">additional extra text</a> to emit when the
-<tt>--help</tt> option is invoked, and the boolean
+<tt>-help</tt> option is invoked, and the boolean
switch that controls whether <a href="#response">response files</a>
should be read.</p>
@@ -1689,7 +1689,7 @@ the conversion from string to data.</p>
<div class="doc_text">
<p>The <tt>cl::extrahelp</tt> class is a nontemplated class that allows extra
-help text to be printed out for the <tt>--help</tt> option.</p>
+help text to be printed out for the <tt>-help</tt> option.</p>
<div class="doc_code"><pre>
<b>namespace</b> cl {
@@ -1906,7 +1906,7 @@ MFS(<i>"max-file-size"</i>, <a href="#cl::desc">cl::desc</a>(<i>"Maximum file si
<div class="doc_code"><pre>
OPTIONS:
- -help - display available options (--help-hidden for more)
+ -help - display available options (-help-hidden for more)
...
<b>-max-file-size=&lt;size&gt; - Maximum file size to accept</b>
</pre></div>
@@ -1972,7 +1972,7 @@ tutorial.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2010-02-27 04:18:32 +0800 (六, 27 2月 2010) $
</address>
</body>
diff --git a/docs/CompilerDriver.html b/docs/CompilerDriver.html
index c4e618b..db82889 100644
--- a/docs/CompilerDriver.html
+++ b/docs/CompilerDriver.html
@@ -132,7 +132,7 @@ directory with the compilation graph description in Graphviz format (identical
to the file used by the <tt class="docutils literal"><span class="pre">--view-graph</span></tt> option). The <tt class="docutils literal"><span class="pre">-o</span></tt> option can be
used to set the output file name. Hidden option, useful for debugging LLVMC
plugins.</li>
-<li><tt class="docutils literal"><span class="pre">--help</span></tt>, <tt class="docutils literal"><span class="pre">--help-hidden</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt> - These options have
+<li><tt class="docutils literal"><span class="pre">-help</span></tt>, <tt class="docutils literal"><span class="pre">-help-hidden</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt> - These options have
their standard meaning.</li>
</ul>
</div>
@@ -325,7 +325,7 @@ aliased option name. Usage example: <tt class="docutils literal"><span class="pr
<li><p class="first">Possible option properties:</p>
<blockquote>
<ul class="simple">
-<li><tt class="docutils literal"><span class="pre">help</span></tt> - help string associated with this option. Used for <tt class="docutils literal"><span class="pre">--help</span></tt>
+<li><tt class="docutils literal"><span class="pre">help</span></tt> - help string associated with this option. Used for <tt class="docutils literal"><span class="pre">-help</span></tt>
output.</li>
<li><tt class="docutils literal"><span class="pre">required</span></tt> - this option must be specified exactly once (or, in case of
the list options without the <tt class="docutils literal"><span class="pre">multi_val</span></tt> property, at least
@@ -338,7 +338,7 @@ it is synonymous with <tt class="docutils literal"><span class="pre">required</s
for list options in conjunction with <tt class="docutils literal"><span class="pre">multi_val</span></tt>. Incompatible with
<tt class="docutils literal"><span class="pre">required</span></tt> and <tt class="docutils literal"><span class="pre">one_or_more</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">hidden</span></tt> - the description of this option will not appear in
-the <tt class="docutils literal"><span class="pre">--help</span></tt> output (but will appear in the <tt class="docutils literal"><span class="pre">--help-hidden</span></tt>
+the <tt class="docutils literal"><span class="pre">-help</span></tt> output (but will appear in the <tt class="docutils literal"><span class="pre">-help-hidden</span></tt>
output).</li>
<li><tt class="docutils literal"><span class="pre">really_hidden</span></tt> - the option will not be mentioned in any help
output.</li>
@@ -748,7 +748,7 @@ the <tt class="docutils literal"><span class="pre">Base</span></tt> plugin behav
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
-Last modified: $Date: 2009-12-23 04:49:51 -0800 (Wed, 23 Dec 2009) $
+Last modified: $Date: 2010-02-18 22:08:13 +0800 (四, 18 2月 2010) $
</address></div>
</div>
</div>
diff --git a/docs/CompilerWriterInfo.html b/docs/CompilerWriterInfo.html
index efeddc0..397bd5d 100644
--- a/docs/CompilerWriterInfo.html
+++ b/docs/CompilerWriterInfo.html
@@ -256,7 +256,7 @@ processors.</li>
<a href="http://misha.brukman.net">Misha Brukman</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2008-12-11 09:34:48 -0800 (Thu, 11 Dec 2008) $
+ Last modified: $Date: 2008-12-12 01:34:48 +0800 (五, 12 12月 2008) $
</address>
</body>
diff --git a/docs/DeveloperPolicy.html b/docs/DeveloperPolicy.html
index 98172cc..f6ccdd0 100644
--- a/docs/DeveloperPolicy.html
+++ b/docs/DeveloperPolicy.html
@@ -520,7 +520,7 @@ Changes</a></div>
<p>We intend to keep LLVM perpetually open source and to use a liberal open
source license. The current license is the
<a href="http://www.opensource.org/licenses/UoI-NCSA.php">University of
- llinois/NCSA Open Source License</a>, which boils down to this:</p>
+ Illinois/NCSA Open Source License</a>, which boils down to this:</p>
<ul>
<li>You can freely distribute LLVM.</li>
@@ -601,7 +601,7 @@ Changes</a></div>
Written by the
<a href="mailto:llvm-oversight@cs.uiuc.edu">LLVM Oversight Group</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-10 14:37:16 -0700 (Sat, 10 Oct 2009) $
+ Last modified: $Date: 2010-02-27 04:18:32 +0800 (六, 27 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/ExceptionHandling.html b/docs/ExceptionHandling.html
index 4267215..f427f7d 100644
--- a/docs/ExceptionHandling.html
+++ b/docs/ExceptionHandling.html
@@ -599,7 +599,7 @@
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-27 17:45:32 -0800 (Wed, 27 Jan 2010) $
+ Last modified: $Date: 2010-01-28 09:45:32 +0800 (四, 28 1月 2010) $
</address>
</body>
diff --git a/docs/ExtendingLLVM.html b/docs/ExtendingLLVM.html
index 925816a..e937e42 100644
--- a/docs/ExtendingLLVM.html
+++ b/docs/ExtendingLLVM.html
@@ -384,7 +384,7 @@ void calcTypeName(const Type *Ty,
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a>
<br>
- Last modified: $Date: 2008-12-11 10:23:24 -0800 (Thu, 11 Dec 2008) $
+ Last modified: $Date: 2008-12-12 02:23:24 +0800 (五, 12 12月 2008) $
</address>
</body>
diff --git a/docs/FAQ.html b/docs/FAQ.html
index 8d8ddb3..c693bc5 100644
--- a/docs/FAQ.html
+++ b/docs/FAQ.html
@@ -437,7 +437,7 @@ Stop.
<div class="answer">
<p>The <tt>GNUmakefile</tt> in the top-level directory of LLVM-GCC is a special
<tt>Makefile</tt> used by Apple to invoke the <tt>build_gcc</tt> script after
- setting up a special environment. This has the unforunate side-effect that
+ setting up a special environment. This has the unfortunate side-effect that
trying to build LLVM-GCC with srcdir == objdir in a "non-Apple way" invokes
the <tt>GNUmakefile</tt> instead of <tt>Makefile</tt>. Because the
environment isn't set up correctly to do this, the build fails.</p>
@@ -931,7 +931,7 @@ F.i:
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: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2010-02-26 07:41:41 +0800 (五, 26 2月 2010) $
</address>
</body>
diff --git a/docs/GCCFEBuildInstrs.html b/docs/GCCFEBuildInstrs.html
index 08844ec..36ab9fc 100644
--- a/docs/GCCFEBuildInstrs.html
+++ b/docs/GCCFEBuildInstrs.html
@@ -272,7 +272,7 @@ More information is <a href="FAQ.html#license">available in the FAQ</a>.
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: 2009-07-05 05:01:44 -0700 (Sun, 05 Jul 2009) $
+ Last modified: $Date: 2009-07-05 20:01:44 +0800 (日, 05 7月 2009) $
</address>
</body>
diff --git a/docs/GarbageCollection.html b/docs/GarbageCollection.html
index ab43f6e..b93d845 100644
--- a/docs/GarbageCollection.html
+++ b/docs/GarbageCollection.html
@@ -1380,7 +1380,7 @@ Fergus Henderson. International Symposium on Memory Management 2002.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-08-05 08:42:44 -0700 (Wed, 05 Aug 2009) $
+ Last modified: $Date: 2009-08-05 23:42:44 +0800 (三, 05 8月 2009) $
</address>
</body>
diff --git a/docs/GetElementPtr.html b/docs/GetElementPtr.html
index 32c1bce..37dcd78 100644
--- a/docs/GetElementPtr.html
+++ b/docs/GetElementPtr.html
@@ -17,7 +17,7 @@
<ol>
<li><a href="#intro">Introduction</a></li>
- <li><a href="#questions">The Questions</a>
+ <li><a href="#addresses">Address Computation</a>
<ol>
<li><a href="#extra_index">Why is the extra 0 index required?</a></li>
<li><a href="#deref">What is dereferenced by GEP?</a></li>
@@ -25,6 +25,30 @@
subsequent ones?</a></li>
<li><a href="#lead0">Why don't GEP x,0,0,1 and GEP x,1 alias? </a></li>
<li><a href="#trail0">Why do GEP x,1,0,0 and GEP x,1 alias? </a></li>
+ <li><a href="#vectors">Can GEP index into vector elements?</a>
+ <li><a href="#unions">Can GEP index into unions?</a>
+ <li><a href="#addrspace">What effect do address spaces have on GEPs?</a>
+ <li><a href="#int">How is GEP different from ptrtoint, arithmetic, and inttoptr?</a></li>
+ <li><a href="#be">I'm writing a backend for a target which needs custom lowering for GEP. How do I do this?</a>
+ <li><a href="#vla">How does VLA addressing work with GEPs?</a>
+ </ol></li>
+ <li><a href="#rules">Rules</a>
+ <ol>
+ <li><a href="#bounds">What happens if an array index is out of bounds?</a>
+ <li><a href="#negative">Can array indices be negative?</a>
+ <li><a href="#compare">Can I compare two values computed with GEPs?</a>
+ <li><a href="#types">Can I do GEP with a different pointer type than the type of the underlying object?</a>
+ <li><a href="#null">Can I cast an object's address to integer and add it to null?</a>
+ <li><a href="#ptrdiff">Can I compute the distance between two objects, and add that value to one address to compute the other address?</a>
+ <li><a href="#tbaa">Can I do type-based alias analysis on LLVM IR?</a>
+ <li><a href="#overflow">What happens if a GEP computation overflows?</a>
+ <li><a href="#check">How can I tell if my front-end is following the rules?</a>
+ </ol></li>
+ <li><a href="#rationale">Rationale</a>
+ <ol>
+ <li><a href="#goals">Why is GEP designed this way?</a></li>
+ <li><a href="#i32">Why do struct member indices always use i32?</a></li>
+ <li><a href="#uglygep">What's an uglygep?</a>
</ol></li>
<li><a href="#summary">Summary</a></li>
</ol>
@@ -37,9 +61,10 @@
<!-- *********************************************************************** -->
<div class="doc_section"><a name="intro"><b>Introduction</b></a></div>
<!-- *********************************************************************** -->
+
<div class="doc_text">
<p>This document seeks to dispel the mystery and confusion surrounding LLVM's
- GetElementPtr (GEP) instruction. Questions about the wiley GEP instruction are
+ GetElementPtr (GEP) instruction. Questions about the wily GEP instruction are
probably the most frequently occurring questions once a developer gets down to
coding with LLVM. Here we lay out the sources of confusion and show that the
GEP instruction is really quite simple.
@@ -47,22 +72,14 @@
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="questions"><b>The Questions</b></a></div>
+<div class="doc_section"><a name="addresses"><b>Address Computation</b></a></div>
<!-- *********************************************************************** -->
<div class="doc_text">
<p>When people are first confronted with the GEP instruction, they tend to
relate it to known concepts from other programming paradigms, most notably C
- array indexing and field selection. However, GEP is a little different and
- this leads to the following questions; all of which are answered in the
- following sections.</p>
- <ol>
- <li><a href="#firstptr">What is the first index of the GEP instruction?</a>
- </li>
- <li><a href="#extra_index">Why is the extra 0 index required?</a></li>
- <li><a href="#deref">What is dereferenced by GEP?</a></li>
- <li><a href="#lead0">Why don't GEP x,0,0,1 and GEP x,1 alias? </a></li>
- <li><a href="#trail0">Why do GEP x,1,0,0 and GEP x,1 alias? </a></li>
- </ol>
+ array indexing and field selection. GEP closely resembles C array indexing
+ and field selection, however it's is a little different and this leads to
+ the following questions.</p>
</div>
<!-- *********************************************************************** -->
@@ -85,7 +102,7 @@ X = &amp;Foo-&gt;F;
<p>it is natural to think that there is only one index, the selection of the
field <tt>F</tt>. However, in this example, <tt>Foo</tt> is a pointer. That
- pointer must be indexed explicitly in LLVM. C, on the other hand, indexs
+ pointer must be indexed explicitly in LLVM. C, on the other hand, indices
through it transparently. To arrive at the same address location as the C
code, you would provide the GEP instruction with two index operands. The
first operand indexes through the pointer; the second operand indexes the
@@ -155,7 +172,7 @@ entry:
<div class="doc_code">
<pre>
-%MyVar = unintialized global i32
+%MyVar = uninitialized global i32
...
%idx1 = getelementptr i32* %MyVar, i64 0
%idx2 = getelementptr i32* %MyVar, i64 1
@@ -210,7 +227,7 @@ idx3 = (char*) &amp;MyVar + 8
field of the structure <tt>%MyStruct</tt>. When people first look at it, they
wonder why the <tt>i64 0</tt> index is needed. However, a closer inspection
of how globals and GEPs work reveals the need. Becoming aware of the following
- facts will dispell the confusion:</p>
+ facts will dispel the confusion:</p>
<ol>
<li>The type of <tt>%MyStruct</tt> is <i>not</i> <tt>{ float*, i32 }</tt>
but rather <tt>{ float*, i32 }*</tt>. That is, <tt>%MyStruct</tt> is a
@@ -297,8 +314,8 @@ idx3 = (char*) &amp;MyVar + 8
<div class="doc_code">
<pre>
%MyVar = global { [10 x i32 ] }
-%idx1 = getlementptr { [10 x i32 ] }* %MyVar, i64 0, i32 0, i64 1
-%idx2 = getlementptr { [10 x i32 ] }* %MyVar, i64 1
+%idx1 = getelementptr { [10 x i32 ] }* %MyVar, i64 0, i32 0, i64 1
+%idx2 = getelementptr { [10 x i32 ] }* %MyVar, i64 1
</pre>
</div>
@@ -326,8 +343,8 @@ idx3 = (char*) &amp;MyVar + 8
<div class="doc_code">
<pre>
%MyVar = global { [10 x i32 ] }
-%idx1 = getlementptr { [10 x i32 ] }* %MyVar, i64 1, i32 0, i64 0
-%idx2 = getlementptr { [10 x i32 ] }* %MyVar, i64 1
+%idx1 = getelementptr { [10 x i32 ] }* %MyVar, i64 1, i32 0, i64 0
+%idx2 = getelementptr { [10 x i32 ] }* %MyVar, i64 1
</pre>
</div>
@@ -337,6 +354,352 @@ idx3 = (char*) &amp;MyVar + 8
</div>
<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="vectors"><b>Can GEP index into vector elements?</b></a>
+</div>
+<div class="doc_text">
+ <p>This hasn't always been forcefully disallowed, though it's not recommended.
+ It leads to awkward special cases in the optimizers, and fundamental
+ inconsistency in the IR. In the future, it will probably be outright
+ disallowed.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="unions"><b>Can GEP index into unions?</b></a>
+</div>
+<div class="doc_text">
+ <p>Unknown.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="addrspace"><b>What effect do address spaces have on GEPs?</b></a>
+</div>
+<div class="doc_text">
+ <p>None, except that the address space qualifier on the first operand pointer
+ type always matches the address space qualifier on the result type.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="int"><b>How is GEP different from ptrtoint, arithmetic,
+ and inttoptr?</b></a>
+</div>
+<div class="doc_text">
+ <p>It's very similar; there are only subtle differences.</p>
+
+ <p>With ptrtoint, you have to pick an integer type. One approach is to pick i64;
+ this is safe on everything LLVM supports (LLVM internally assumes pointers
+ are never wider than 64 bits in many places), and the optimizer will actually
+ narrow the i64 arithmetic down to the actual pointer size on targets which
+ don't support 64-bit arithmetic in most cases. However, there are some cases
+ where it doesn't do this. With GEP you can avoid this problem.
+
+ <p>Also, GEP carries additional pointer aliasing rules. It's invalid to take a
+ GEP from one object, address into a different separately allocated
+ object, and dereference it. IR producers (front-ends) must follow this rule,
+ and consumers (optimizers, specifically alias analysis) benefit from being
+ able to rely on it. See the <a href="#rules">Rules</a> section for more
+ information.</p>
+
+ <p>And, GEP is more concise in common cases.</p>
+
+ <p>However, for the underlying integer computation implied, there
+ is no difference.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="be"><b>I'm writing a backend for a target which needs custom
+ lowering for GEP. How do I do this?</b></a>
+</div>
+<div class="doc_text">
+ <p>You don't. The integer computation implied by a GEP is target-independent.
+ Typically what you'll need to do is make your backend pattern-match
+ expressions trees involving ADD, MUL, etc., which are what GEP is lowered
+ into. This has the advantage of letting your code work correctly in more
+ cases.</p>
+
+ <p>GEP does use target-dependent parameters for the size and layout of data
+ types, which targets can customize.</p>
+
+ <p>If you require support for addressing units which are not 8 bits, you'll
+ need to fix a lot of code in the backend, with GEP lowering being only a
+ small piece of the overall picture.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="vla"><b>How does VLA addressing work with GEPs?</b></a>
+</div>
+<div class="doc_text">
+ <p>GEPs don't natively support VLAs. LLVM's type system is entirely static,
+ and GEP address computations are guided by an LLVM type.</p>
+
+ <p>VLA indices can be implemented as linearized indices. For example, an
+ expression like X[a][b][c], must be effectively lowered into a form
+ like X[a*m+b*n+c], so that it appears to the GEP as a single-dimensional
+ array reference.</p>
+
+ <p>This means if you want to write an analysis which understands array
+ indices and you want to support VLAs, your code will have to be
+ prepared to reverse-engineer the linearization. One way to solve this
+ problem is to use the ScalarEvolution library, which always presents
+ VLA and non-VLA indexing in the same manner.</p>
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_section"><a name="rules"><b>Rules</b></a></div>
+<!-- *********************************************************************** -->
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="bounds"><b>What happens if an array index is out of bounds?</b></a>
+</div>
+<div class="doc_text">
+ <p>There are two senses in which an array index can be out of bounds.</p>
+
+ <p>First, there's the array type which comes from the (static) type of
+ the first operand to the GEP. Indices greater than the number of elements
+ in the corresponding static array type are valid. There is no problem with
+ out of bounds indices in this sense. Indexing into an array only depends
+ on the size of the array element, not the number of elements.</p>
+
+ <p>A common example of how this is used is arrays where the size is not known.
+ It's common to use array types with zero length to represent these. The
+ fact that the static type says there are zero elements is irrelevant; it's
+ perfectly valid to compute arbitrary element indices, as the computation
+ only depends on the size of the array element, not the number of
+ elements. Note that zero-sized arrays are not a special case here.</p>
+
+ <p>This sense is unconnected with <tt>inbounds</tt> keyword. The
+ <tt>inbounds</tt> keyword is designed to describe low-level pointer
+ arithmetic overflow conditions, rather than high-level array
+ indexing rules.
+
+ <p>Analysis passes which wish to understand array indexing should not
+ assume that the static array type bounds are respected.</p>
+
+ <p>The second sense of being out of bounds is computing an address that's
+ beyond the actual underlying allocated object.</p>
+
+ <p>With the <tt>inbounds</tt> keyword, the result value of the GEP is
+ undefined if the address is outside the actual underlying allocated
+ object and not the address one-past-the-end.</p>
+
+ <p>Without the <tt>inbounds</tt> keyword, there are no restrictions
+ on computing out-of-bounds addresses. Obviously, performing a load or
+ a store requires an address of allocated and sufficiently aligned
+ memory. But the GEP itself is only concerned with computing addresses.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_subsection">
+ <a name="negative"><b>Can array indices be negative?</b></a>
+</div>
+<div class="doc_text">
+ <p>Yes. This is basically a special case of array indices being out
+ of bounds.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_subsection">
+ <a name="compare"><b>Can I compare two values computed with GEPs?</b></a>
+</div>
+<div class="doc_text">
+ <p>Yes. If both addresses are within the same allocated object, or
+ one-past-the-end, you'll get the comparison result you expect. If either
+ is outside of it, integer arithmetic wrapping may occur, so the
+ comparison may not be meaningful.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_subsection">
+ <a name="types"><b>Can I do GEP with a different pointer type than the type of
+ the underlying object?</b></a>
+</div>
+<div class="doc_text">
+ <p>Yes. There are no restrictions on bitcasting a pointer value to an arbitrary
+ pointer type. The types in a GEP serve only to define the parameters for the
+ underlying integer computation. They need not correspond with the actual
+ type of the underlying object.</p>
+
+ <p>Furthermore, loads and stores don't have to use the same types as the type
+ of the underlying object. Types in this context serve only to specify
+ memory size and alignment. Beyond that there are merely a hint to the
+ optimizer indicating how the value will likely be used.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_subsection">
+ <a name="null"><b>Can I cast an object's address to integer and add it
+ to null?</b></a>
+</div>
+<div class="doc_text">
+ <p>You can compute an address that way, but if you use GEP to do the add,
+ you can't use that pointer to actually access the object, unless the
+ object is managed outside of LLVM.</p>
+
+ <p>The underlying integer computation is sufficiently defined; null has a
+ defined value -- zero -- and you can add whatever value you want to it.</p>
+
+ <p>However, it's invalid to access (load from or store to) an LLVM-aware
+ object with such a pointer. This includes GlobalVariables, Allocas, and
+ objects pointed to by noalias pointers.</p>
+
+ <p>If you really need this functionality, you can do the arithmetic with
+ explicit integer instructions, and use inttoptr to convert the result to
+ an address. Most of GEP's special aliasing rules do not apply to pointers
+ computed from ptrtoint, arithmetic, and inttoptr sequences.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_subsection">
+ <a name="ptrdiff"><b>Can I compute the distance between two objects, and add
+ that value to one address to compute the other address?</b></a>
+</div>
+<div class="doc_text">
+ <p>As with arithmetic on null, You can use GEP to compute an address that
+ way, but you can't use that pointer to actually access the object if you
+ do, unless the object is managed outside of LLVM.</p>
+
+ <p>Also as above, ptrtoint and inttoptr provide an alternative way to do this
+ which do not have this restriction.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_subsection">
+ <a name="tbaa"><b>Can I do type-based alias analysis on LLVM IR?</b></a>
+</div>
+<div class="doc_text">
+ <p>You can't do type-based alias analysis using LLVM's built-in type system,
+ because LLVM has no restrictions on mixing types in addressing, loads or
+ stores.</p>
+
+ <p>It would be possible to add special annotations to the IR, probably using
+ metadata, to describe a different type system (such as the C type system),
+ and do type-based aliasing on top of that. This is a much bigger
+ undertaking though.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="overflow"><b>What happens if a GEP computation overflows?</b></a>
+</div>
+<div class="doc_text">
+ <p>If the GEP has the <tt>inbounds</tt> keyword, the result value is
+ undefined.</p>
+
+ <p>Otherwise, the result value is the result from evaluating the implied
+ two's complement integer computation. However, since there's no
+ guarantee of where an object will be allocated in the address space,
+ such values have limited meaning.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="check"><b>How can I tell if my front-end is following the
+ rules?</b></a>
+</div>
+<div class="doc_text">
+ <p>There is currently no checker for the getelementptr rules. Currently,
+ the only way to do this is to manually check each place in your front-end
+ where GetElementPtr operators are created.</p>
+
+ <p>It's not possible to write a checker which could find all rule
+ violations statically. It would be possible to write a checker which
+ works by instrumenting the code with dynamic checks though. Alternatively,
+ it would be possible to write a static checker which catches a subset of
+ possible problems. However, no such checker exists today.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_section"><a name="rationale"><b>Rationale</b></a></div>
+<!-- *********************************************************************** -->
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="goals"><b>Why is GEP designed this way?</b></a>
+</div>
+<div class="doc_text">
+ <p>The design of GEP has the following goals, in rough unofficial
+ order of priority:</p>
+ <ul>
+ <li>Support C, C-like languages, and languages which can be
+ conceptually lowered into C (this covers a lot).</li>
+ <li>Support optimizations such as those that are common in
+ C compilers.</li>
+ <li>Provide a consistent method for computing addresses so that
+ address computations don't need to be a part of load and
+ store instructions in the IR.</li>
+ <li>Support non-C-like languages, to the extent that it doesn't
+ interfere with other goals.</li>
+ <li>Minimize target-specific information in the IR.</li>
+ </ul>
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_subsection">
+ <a name="i32"><b>Why do struct member indices always use i32?</b></a>
+</div>
+<div class="doc_text">
+ <p>The specific type i32 is probably just a historical artifact, however it's
+ wide enough for all practical purposes, so there's been no need to change it.
+ It doesn't necessarily imply i32 address arithmetic; it's just an identifier
+ which identifies a field in a struct. Requiring that all struct indices be
+ the same reduces the range of possibilities for cases where two GEPs are
+ effectively the same but have distinct operand types.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+
+<div class="doc_subsection">
+ <a name="uglygep"><b>What's an uglygep?</b></a>
+</div>
+<div class="doc_text">
+ <p>Some LLVM optimizers operate on GEPs by internally lowering them into
+ more primitive integer expressions, which allows them to be combined
+ with other integer expressions and/or split into multiple separate
+ integer expressions. If they've made non-trivial changes, translating
+ back into LLVM IR can involve reverse-engineering the structure of
+ the addressing in order to fit it into the static type of the original
+ first operand. It isn't always possibly to fully reconstruct this
+ structure; sometimes the underlying addressing doesn't correspond with
+ the static type at all. In such cases the optimizer instead will emit
+ a GEP with the base pointer casted to a simple address-unit pointer,
+ using the name "uglygep". This isn't pretty, but it's just as
+ valid, and it's sufficient to preserve the pointer aliasing guarantees
+ that GEP provides.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
<div class="doc_section"><a name="summary"><b>Summary</b></a></div>
<!-- *********************************************************************** -->
@@ -365,7 +728,7 @@ idx3 = (char*) &amp;MyVar + 8
<a href="http://validator.w3.org/check/referer"><img
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br/>
- Last modified: $Date: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2010-02-26 02:16:03 +0800 (五, 26 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/GettingStarted.html b/docs/GettingStarted.html
index 8d865d6..42005b2 100644
--- a/docs/GettingStarted.html
+++ b/docs/GettingStarted.html
@@ -256,13 +256,13 @@ software you will need.</p>
<td>Cygwin/Win32</td>
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_8">8</a>,
<a href="#pf_11">11</a></sup></td>
- <td>GCC 3.4.X, binutils 2.15</td>
+ <td>GCC 3.4.X, binutils 2.20</td>
</tr>
<tr>
<td>MinGW/Win32</td>
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_6">6</a>,
<a href="#pf_8">8</a>, <a href="#pf_10">10</a></sup></td>
- <td>GCC 3.4.X, binutils 2.15</td>
+ <td>GCC 3.4.X, binutils 2.20</td>
</tr>
</table>
@@ -318,12 +318,8 @@ up</a></li>
<li><a name="pf_5">The GCC-based C/C++ frontend does not build</a></li>
<li><a name="pf_6">The port is done using the MSYS shell.</a></li>
<li><a name="pf_7">Native code generation exists but is not complete.</a></li>
-<li><a name="pf_8">Binutils</a> up to post-2.17 has bug in bfd/cofflink.c
- preventing LLVM from building correctly. Several workarounds have been
- introduced into LLVM build system, but the bug can occur anytime in the
- future. We highly recommend that you rebuild your current binutils with the
- patch from <a href="http://sourceware.org/bugzilla/show_bug.cgi?id=2659">
- Binutils bugzilla</a>, if it wasn't already applied.</li>
+<li><a name="pf_8">Binutils 2.20 or later is required to build the assembler
+ generated by LLVM properly.</a></li>
<li><a name="pf_9">XCode 2.5 and gcc 4.0.1</a> (Apple Build 5370) will trip
internal LLVM assert messages when compiled for Release at optimization
levels greater than 0 (i.e., <i>"-O1"</i> and higher).
@@ -1197,10 +1193,16 @@ $ ./hello.bc
</div>
<p>
-This allows you to execute LLVM bitcode files directly. Thanks to Jack
-Cummings for pointing this out!
+This allows you to execute LLVM bitcode files directly. On Debian, you
+can also use this command instead of the 'echo' command above:</p>
</p>
+<div class="doc_code">
+<pre>
+$ sudo update-binfmts --install llvm /path/to/lli --magic 'BC'
+</pre>
+</div>
+
</div>
<!-- *********************************************************************** -->
@@ -1367,7 +1369,7 @@ end to compile.</p>
<p>The <b>tools</b> directory contains the executables built out of the
libraries above, which form the main part of the user interface. You can
-always get help for a tool by typing <tt>tool_name --help</tt>. The
+always get help for a tool by typing <tt>tool_name -help</tt>. The
following is a brief introduction to the most important tools. More detailed
information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
@@ -1438,7 +1440,7 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
<dt><tt><b>opt</b></tt></dt>
<dd><tt>opt</tt> reads LLVM bitcode, applies a series of LLVM to LLVM
transformations (which are specified on the command line), and then outputs
- the resultant bitcode. The '<tt>opt --help</tt>' command is a good way to
+ the resultant bitcode. The '<tt>opt -help</tt>' command is a good way to
get a list of the program transformations available in LLVM.<br>
<dd><tt>opt</tt> can also be used to run a specific analysis on an input
LLVM bitcode file and print out the results. It is primarily useful for
@@ -1671,7 +1673,7 @@ out:</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.x10sys.com/rspencer/">Reid Spencer</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-12-17 09:18:11 -0800 (Thu, 17 Dec 2009) $
+ Last modified: $Date: 2010-02-18 22:08:13 +0800 (四, 18 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/GettingStartedVS.html b/docs/GettingStartedVS.html
index 33ed206..07aed25 100644
--- a/docs/GettingStartedVS.html
+++ b/docs/GettingStartedVS.html
@@ -411,7 +411,7 @@ out:</p>
<a href="mailto:jeffc@jolt-lang.org">Jeff Cohen</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-08-05 08:42:44 -0700 (Wed, 05 Aug 2009) $
+ Last modified: $Date: 2009-08-05 23:42:44 +0800 (三, 05 8月 2009) $
</address>
</body>
</html>
diff --git a/docs/HowToReleaseLLVM.html b/docs/HowToReleaseLLVM.html
index f2c1b02..fed604f 100644
--- a/docs/HowToReleaseLLVM.html
+++ b/docs/HowToReleaseLLVM.html
@@ -518,7 +518,7 @@ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_XX \
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
- Last modified: $Date: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2009-10-12 22:46:08 +0800 (一, 12 10月 2009) $
</address>
</body>
</html>
diff --git a/docs/HowToSubmitABug.html b/docs/HowToSubmitABug.html
index 7923956..97568f2 100644
--- a/docs/HowToSubmitABug.html
+++ b/docs/HowToSubmitABug.html
@@ -348,7 +348,7 @@ the following:</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: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2009-10-12 22:46:08 +0800 (一, 12 10月 2009) $
</address>
</body>
diff --git a/docs/LangRef.html b/docs/LangRef.html
index eea369d..6a965ce 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -66,12 +66,17 @@
</li>
<li><a href="#t_derived">Derived Types</a>
<ol>
- <li><a href="#t_array">Array Type</a></li>
+ <li><a href="#t_aggregate">Aggregate Types</a>
+ <ol>
+ <li><a href="#t_array">Array Type</a></li>
+ <li><a href="#t_struct">Structure Type</a></li>
+ <li><a href="#t_pstruct">Packed Structure Type</a></li>
+ <li><a href="#t_union">Union Type</a></li>
+ <li><a href="#t_vector">Vector Type</a></li>
+ </ol>
+ </li>
<li><a href="#t_function">Function Type</a></li>
<li><a href="#t_pointer">Pointer Type</a></li>
- <li><a href="#t_struct">Structure Type</a></li>
- <li><a href="#t_pstruct">Packed Structure Type</a></li>
- <li><a href="#t_vector">Vector Type</a></li>
<li><a href="#t_opaque">Opaque Type</a></li>
</ol>
</li>
@@ -843,7 +848,7 @@ define i32 @main() { <i>; i32()* </i>
<div class="doc_text">
-<p>LLVM function definitions consist of the "<tt>define</tt>" keyord, an
+<p>LLVM function definitions consist of the "<tt>define</tt>" keyword, an
optional <a href="#linkage">linkage type</a>, an optional
<a href="#visibility">visibility style</a>, an optional
<a href="#callingconv">calling convention</a>, a return type, an optional
@@ -1078,6 +1083,11 @@ define void @f() optsize { ... }
</div>
<dl>
+ <dt><tt><b>alignstack(&lt;<em>n</em>&gt;)</b></tt></dt>
+ <dd>This attribute indicates that, when emitting the prologue and epilogue,
+ the backend should forcibly align the stack pointer. Specify the
+ desired alignment, which must be a power of two, in parentheses.
+
<dt><tt><b>alwaysinline</b></tt></dt>
<dd>This attribute indicates that the inliner should attempt to inline this
function into callers whenever possible, ignoring any active inlining size
@@ -1267,7 +1277,7 @@ target datalayout = "<i>layout specification</i>"
<ul>
<li><tt>E</tt> - big endian</li>
- <li><tt>p:32:64:64</tt> - 32-bit pointers with 64-bit alignment</li>
+ <li><tt>p:64:64:64</tt> - 64-bit pointers with 64-bit alignment</li>
<li><tt>i1:8:8</tt> - i1 is 8-bit (byte) aligned</li>
<li><tt>i8:8:8</tt> - i8 is 8-bit (byte) aligned</li>
<li><tt>i16:16:16</tt> - i16 is 16-bit aligned</li>
@@ -1399,6 +1409,7 @@ Classifications</a> </div>
<a href="#t_pointer">pointer</a>,
<a href="#t_vector">vector</a>,
<a href="#t_struct">structure</a>,
+ <a href="#t_union">union</a>,
<a href="#t_array">array</a>,
<a href="#t_label">label</a>,
<a href="#t_metadata">metadata</a>.
@@ -1413,12 +1424,12 @@ Classifications</a> </div>
</tr>
<tr>
<td><a href="#t_derived">derived</a></td>
- <td><a href="#t_integer">integer</a>,
- <a href="#t_array">array</a>,
+ <td><a href="#t_array">array</a>,
<a href="#t_function">function</a>,
<a href="#t_pointer">pointer</a>,
<a href="#t_struct">structure</a>,
<a href="#t_pstruct">packed structure</a>,
+ <a href="#t_union">union</a>,
<a href="#t_vector">vector</a>,
<a href="#t_opaque">opaque</a>.
</td>
@@ -1556,6 +1567,21 @@ Classifications</a> </div>
possible to have a two dimensional array, using an array as the element type
of another array.</p>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"> <a name="t_aggregate">Aggregate Types</a> </div>
+
+<div class="doc_text">
+
+<p>Aggregate Types are a subset of derived types that can contain multiple
+ member types. <a href="#t_array">Arrays</a>,
+ <a href="#t_struct">structs</a>, <a href="#t_vector">vectors</a> and
+ <a href="#t_union">unions</a> are aggregate types.</p>
+
+</div>
+
</div>
<!-- _______________________________________________________________________ -->
@@ -1624,9 +1650,9 @@ Classifications</a> </div>
<h5>Overview:</h5>
<p>The function type can be thought of as a function signature. It consists of
a return type and a list of formal parameter types. The return type of a
- function type is a scalar type, a void type, or a struct type. If the return
- type is a struct type then all struct elements must be of first class types,
- and the struct must have at least one element.</p>
+ function type is a scalar type, a void type, a struct type, or a union
+ type. If the return type is a struct type then all struct elements must be
+ of first class types, and the struct must have at least one element.</p>
<h5>Syntax:</h5>
<pre>
@@ -1638,7 +1664,7 @@ Classifications</a> </div>
which indicates that the function takes a variable number of arguments.
Variable argument functions can access their arguments with
the <a href="#int_varargs">variable argument handling intrinsic</a>
- functions. '<tt>&lt;returntype&gt;</tt>' is a any type except
+ functions. '<tt>&lt;returntype&gt;</tt>' is any type except
<a href="#t_label">label</a>.</p>
<h5>Examples:</h5>
@@ -1648,12 +1674,11 @@ Classifications</a> </div>
<td class="left">function taking an <tt>i32</tt>, returning an <tt>i32</tt>
</td>
</tr><tr class="layout">
- <td class="left"><tt>float&nbsp;(i16&nbsp;signext,&nbsp;i32&nbsp;*)&nbsp;*
+ <td class="left"><tt>float&nbsp;(i16,&nbsp;i32&nbsp;*)&nbsp;*
</tt></td>
<td class="left"><a href="#t_pointer">Pointer</a> to a function that takes
- an <tt>i16</tt> that should be sign extended and a
- <a href="#t_pointer">pointer</a> to <tt>i32</tt>, returning
- <tt>float</tt>.
+ an <tt>i16</tt> and a <a href="#t_pointer">pointer</a> to <tt>i32</tt>,
+ returning <tt>float</tt>.
</td>
</tr><tr class="layout">
<td class="left"><tt>i32 (i8*, ...)</tt></td>
@@ -1749,15 +1774,65 @@ Classifications</a> </div>
</div>
<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"> <a name="t_union">Union Type</a> </div>
+
+<div class="doc_text">
+
+<h5>Overview:</h5>
+<p>A union type describes an object with size and alignment suitable for
+ an object of any one of a given set of types (also known as an "untagged"
+ union). It is similar in concept and usage to a
+ <a href="#t_struct">struct</a>, except that all members of the union
+ have an offset of zero. The elements of a union may be any type that has a
+ size. Unions must have at least one member - empty unions are not allowed.
+ </p>
+
+<p>The size of the union as a whole will be the size of its largest member,
+ and the alignment requirements of the union as a whole will be the largest
+ alignment requirement of any member.</p>
+
+<p>Union members are accessed using '<tt><a href="#i_load">load</a></tt> and
+ '<tt><a href="#i_store">store</a></tt>' by getting a pointer to a field with
+ the '<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
+ Since all members are at offset zero, the getelementptr instruction does
+ not affect the address, only the type of the resulting pointer.</p>
+
+<h5>Syntax:</h5>
+<pre>
+ union { &lt;type list&gt; }
+</pre>
+
+<h5>Examples:</h5>
+<table class="layout">
+ <tr class="layout">
+ <td class="left"><tt>union { i32, i32*, float }</tt></td>
+ <td class="left">A union of three types: an <tt>i32</tt>, a pointer to
+ an <tt>i32</tt>, and a <tt>float</tt>.</td>
+ </tr><tr class="layout">
+ <td class="left">
+ <tt>union {&nbsp;float,&nbsp;i32&nbsp;(i32)&nbsp;*&nbsp;}</tt></td>
+ <td class="left">A union, where the first element is a <tt>float</tt> and the
+ second element is a <a href="#t_pointer">pointer</a> to a
+ <a href="#t_function">function</a> that takes an <tt>i32</tt>, returning
+ an <tt>i32</tt>.</td>
+ </tr>
+</table>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection"> <a name="t_pointer">Pointer Type</a> </div>
<div class="doc_text">
<h5>Overview:</h5>
-<p>As in many languages, the pointer type represents a pointer or reference to
- another object, which must live in memory. Pointer types may have an optional
- address space attribute defining the target-specific numbered address space
- where the pointed-to object resides. The default address space is zero.</p>
+<p>The pointer type is used to specify memory locations.
+ Pointers are commonly used to reference objects in memory.</p>
+
+<p>Pointer types may have an optional address space attribute defining the
+ numbered address space where the pointed-to object resides. The default
+ address space is number zero. The semantics of non-zero address
+ spaces are target-specific.</p>
<p>Note that LLVM does not permit pointers to void (<tt>void*</tt>) nor does it
permit pointers to labels (<tt>label*</tt>). Use <tt>i8*</tt> instead.</p>
@@ -1986,6 +2061,14 @@ Classifications</a> </div>
the number and types of elements must match those specified by the
type.</dd>
+ <dt><b>Union constants</b></dt>
+ <dd>Union constants are represented with notation similar to a structure with
+ a single element - that is, a single typed element surrounded
+ by braces (<tt>{}</tt>)). For example: "<tt>{ i32 4 }</tt>". The
+ <a href="#t_union">union type</a> can be initialized with a single-element
+ struct as long as the type of the struct element matches the type of
+ one of the union members.</dd>
+
<dt><b>Array constants</b></dt>
<dd>Array constants are represented with notation similar to array type
definitions (a comma separated list of elements, surrounded by square
@@ -2004,7 +2087,8 @@ Classifications</a> </div>
<dt><b>Zero initialization</b></dt>
<dd>The string '<tt>zeroinitializer</tt>' can be used to zero initialize a
- value to zero of <em>any</em> type, including scalar and aggregate types.
+ value to zero of <em>any</em> type, including scalar and
+ <a href="#t_aggregate">aggregate</a> types.
This is often used to avoid having to print large zero initializers
(e.g. for large arrays) and is always exactly equivalent to using explicit
zero initializers.</dd>
@@ -2436,6 +2520,23 @@ call void asm alignstack "eieio", ""()
metadata nodes, which can be looked up in the module symbol table. For
example: "<tt>!foo = metadata !{!4, !3}</tt>".
+<p>Metadata can be used as function arguments. Here <tt>llvm.dbg.value</tt>
+ function is using two metadata arguments.
+
+ <div class="doc_code">
+ <pre>
+ call void @llvm.dbg.value(metadata !24, i64 0, metadata !25)
+ </pre>
+ </div></p>
+
+<p>Metadata can be attached with an instruction. Here metadata <tt>!21</tt> is
+ attached with <tt>add</tt> instruction using <tt>!dbg</tt> identifier.
+
+ <div class="doc_code">
+ <pre>
+ %indvar.next = add i64 %indvar, 1, !dbg !21
+ </pre>
+ </div></p>
</div>
@@ -2803,9 +2904,10 @@ IfUnequal:
function to be invoked. </li>
<li>'<tt>function args</tt>': argument list whose types match the function
- signature argument types. If the function signature indicates the
- function accepts a variable number of arguments, the extra arguments can
- be specified.</li>
+ signature argument types and parameter attributes. All arguments must be
+ of <a href="#t_firstclass">first class</a> type. If the function
+ signature indicates the function accepts a variable number of arguments,
+ the extra arguments can be specified.</li>
<li>'<tt>normal label</tt>': the label reached when the called function
executes a '<tt><a href="#i_ret">ret</a></tt>' instruction. </li>
@@ -3840,7 +3942,8 @@ Instruction</a> </div>
<div class="doc_text">
-<p>LLVM supports several instructions for working with aggregate values.</p>
+<p>LLVM supports several instructions for working with
+ <a href="#t_aggregate">aggregate</a> values.</p>
</div>
@@ -3857,14 +3960,14 @@ Instruction</a> </div>
</pre>
<h5>Overview:</h5>
-<p>The '<tt>extractvalue</tt>' instruction extracts the value of a struct field
- or array element from an aggregate value.</p>
+<p>The '<tt>extractvalue</tt>' instruction extracts the value of a member field
+ from an <a href="#t_aggregate">aggregate</a> value.</p>
<h5>Arguments:</h5>
<p>The first operand of an '<tt>extractvalue</tt>' instruction is a value
- of <a href="#t_struct">struct</a> or <a href="#t_array">array</a> type. The
- operands are constant indices to specify which value to extract in a similar
- manner as indices in a
+ of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
+ <a href="#t_array">array</a> type. The operands are constant indices to
+ specify which value to extract in a similar manner as indices in a
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.</p>
<h5>Semantics:</h5>
@@ -3891,16 +3994,15 @@ Instruction</a> </div>
</pre>
<h5>Overview:</h5>
-<p>The '<tt>insertvalue</tt>' instruction inserts a value into a struct field or
- array element in an aggregate.</p>
-
+<p>The '<tt>insertvalue</tt>' instruction inserts a value into a member field
+ in an <a href="#t_aggregate">aggregate</a> value.</p>
<h5>Arguments:</h5>
<p>The first operand of an '<tt>insertvalue</tt>' instruction is a value
- of <a href="#t_struct">struct</a> or <a href="#t_array">array</a> type. The
- second operand is a first-class value to insert. The following operands are
- constant indices indicating the position at which to insert the value in a
- similar manner as indices in a
+ of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
+ <a href="#t_array">array</a> type. The second operand is a first-class
+ value to insert. The following operands are constant indices indicating
+ the position at which to insert the value in a similar manner as indices in a
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction. The
value to insert must have the same type as the value identified by the
indices.</p>
@@ -3992,8 +4094,9 @@ Instruction</a> </div>
<h5>Syntax:</h5>
<pre>
- &lt;result&gt; = load &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;]
- &lt;result&gt; = volatile load &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;]
+ &lt;result&gt; = load &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;][, !nontemporal !&lt;index&gt;]
+ &lt;result&gt; = volatile load &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;][, !nontemporal !&lt;index&gt;]
+ !&lt;index&gt; = !{ i32 1 }
</pre>
<h5>Overview:</h5>
@@ -4006,16 +4109,24 @@ Instruction</a> </div>
marked as <tt>volatile</tt>, then the optimizer is not allowed to modify the
number or order of execution of this <tt>load</tt> with other
volatile <tt>load</tt> and <tt><a href="#i_store">store</a></tt>
- instructions. </p>
+ instructions.</p>
-<p>The optional constant "align" argument specifies the alignment of the
+<p>The optional constant <tt>align</tt> argument specifies the alignment of the
operation (that is, the alignment of the memory address). A value of 0 or an
- omitted "align" argument means that the operation has the preferential
+ omitted <tt>align</tt> argument means that the operation has the preferential
alignment for the target. It is the responsibility of the code emitter to
ensure that the alignment information is correct. Overestimating the
- alignment results in an undefined behavior. Underestimating the alignment may
+ alignment results in undefined behavior. Underestimating the alignment may
produce less efficient code. An alignment of 1 is always safe.</p>
+<p>The optional <tt>!nontemporal</tt> metadata must reference a single
+ metatadata name &lt;index&gt; corresponding to a metadata node with
+ one <tt>i32</tt> entry of value 1. The existence of
+ the <tt>!nontemporal</tt> metatadata on the instruction tells the optimizer
+ and code generator that this load is not expected to be reused in the cache.
+ The code generator may select special instructions to save cache bandwidth,
+ such as the <tt>MOVNT</tt> instruction on x86.</p>
+
<h5>Semantics:</h5>
<p>The location of memory pointed to is loaded. If the value being loaded is of
scalar type then the number of bytes read does not exceed the minimum number
@@ -4042,8 +4153,8 @@ Instruction</a> </div>
<h5>Syntax:</h5>
<pre>
- store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;] <i>; yields {void}</i>
- volatile store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;] <i>; yields {void}</i>
+ store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;][, !nontemporal !<index>] <i>; yields {void}</i>
+ volatile store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;][, !nontemporal !<index>] <i>; yields {void}</i>
</pre>
<h5>Overview:</h5>
@@ -4068,6 +4179,15 @@ Instruction</a> </div>
alignment results in an undefined behavior. Underestimating the alignment may
produce less efficient code. An alignment of 1 is always safe.</p>
+<p>The optional !nontemporal metadata must reference a single metatadata
+ name <index> corresponding to a metadata node with one i32 entry of
+ value 1. The existence of the !nontemporal metatadata on the
+ instruction tells the optimizer and code generator that this load is
+ not expected to be reused in the cache. The code generator may
+ select special instructions to save cache bandwidth, such as the
+ MOVNT instruction on x86.</p>
+
+
<h5>Semantics:</h5>
<p>The contents of memory are updated to contain '<tt>&lt;value&gt;</tt>' at the
location specified by the '<tt>&lt;pointer&gt;</tt>' operand. If
@@ -4102,8 +4222,8 @@ Instruction</a> </div>
<h5>Overview:</h5>
<p>The '<tt>getelementptr</tt>' instruction is used to get the address of a
- subelement of an aggregate data structure. It performs address calculation
- only and does not access memory.</p>
+ subelement of an <a href="#t_aggregate">aggregate</a> data structure.
+ It performs address calculation only and does not access memory.</p>
<h5>Arguments:</h5>
<p>The first argument is always a pointer, and forms the basis of the
@@ -4113,15 +4233,15 @@ Instruction</a> </div>
indexes the pointer value given as the first argument, the second index
indexes a value of the type pointed to (not necessarily the value directly
pointed to, since the first index can be non-zero), etc. The first type
- indexed into must be a pointer value, subsequent types can be arrays, vectors
- and structs. Note that subsequent types being indexed into can never be
- pointers, since that would require loading the pointer before continuing
- calculation.</p>
+ indexed into must be a pointer value, subsequent types can be arrays,
+ vectors, structs and unions. Note that subsequent types being indexed into
+ can never be pointers, since that would require loading the pointer before
+ continuing calculation.</p>
<p>The type of each index argument depends on the type it is indexing into.
- When indexing into a (optionally packed) structure, only <tt>i32</tt> integer
- <b>constants</b> are allowed. When indexing into an array, pointer or
- vector, integers of any width are allowed, and they are not required to be
+ When indexing into a (optionally packed) structure or union, only <tt>i32</tt>
+ integer <b>constants</b> are allowed. When indexing into an array, pointer
+ or vector, integers of any width are allowed, and they are not required to be
constant.</p>
<p>For example, let's consider a C code fragment and how it gets compiled to
@@ -4861,7 +4981,7 @@ entry:
<tt>op1</tt> is equal to <tt>op2</tt>.</li>
<li><tt>ogt</tt>: yields <tt>true</tt> if both operands are not a QNAN and
- <tt>op1</tt> is greather than <tt>op2</tt>.</li>
+ <tt>op1</tt> is greater than <tt>op2</tt>.</li>
<li><tt>oge</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<tt>op1</tt> is greater than or equal to <tt>op2</tt>.</li>
@@ -5037,7 +5157,7 @@ Loop: ; Infinite loop that counts from 0 on up...
<li>The call is in tail position (ret immediately follows call and ret
uses value of call or is void).</li>
<li>Option <tt>-tailcallopt</tt> is enabled,
- or <code>llvm::PerformTailCallOpt</code> is <code>true</code>.</li>
+ or <code>llvm::GuaranteedTailCallOpt</code> is <code>true</code>.</li>
<li><a href="CodeGenerator.html#tailcallopt">Platform specific
constraints are met.</a></li>
</ul>
@@ -5068,10 +5188,10 @@ Loop: ; Infinite loop that counts from 0 on up...
to function value.</li>
<li>'<tt>function args</tt>': argument list whose types match the function
- signature argument types. All arguments must be of
- <a href="#t_firstclass">first class</a> type. If the function signature
- indicates the function accepts a variable number of arguments, the extra
- arguments can be specified.</li>
+ signature argument types and parameter attributes. All arguments must be
+ of <a href="#t_firstclass">first class</a> type. If the function
+ signature indicates the function accepts a variable number of arguments,
+ the extra arguments can be specified.</li>
<li>The optional <a href="#fnattrs">function attributes</a> list. Only
'<tt>noreturn</tt>', '<tt>nounwind</tt>', '<tt>readonly</tt>' and
@@ -5106,7 +5226,7 @@ Loop: ; Infinite loop that counts from 0 on up...
standard C99 library as being the C99 library functions, and may perform
optimizations or generate code for them under that assumption. This is
something we'd like to change in the future to provide better support for
-freestanding environments and non-C-based langauges.</p>
+freestanding environments and non-C-based languages.</p>
</div>
@@ -5662,7 +5782,7 @@ LLVM</a>.</p>
<h5>Semantics:</h5>
<p>This intrinsic does not modify the behavior of the program. Backends that do
- not support this intrinisic may ignore it.</p>
+ not support this intrinsic may ignore it.</p>
</div>
@@ -5742,7 +5862,7 @@ LLVM</a>.</p>
number of bytes to copy, and the fourth argument is the alignment of the
source and destination locations.</p>
-<p>If the call to this intrinisic has an alignment value that is not 0 or 1,
+<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
then the caller guarantees that both the source and destination pointers are
aligned to that boundary.</p>
@@ -5792,7 +5912,7 @@ LLVM</a>.</p>
number of bytes to copy, and the fourth argument is the alignment of the
source and destination locations.</p>
-<p>If the call to this intrinisic has an alignment value that is not 0 or 1,
+<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
then the caller guarantees that the source and destination pointers are
aligned to that boundary.</p>
@@ -5840,7 +5960,7 @@ LLVM</a>.</p>
specifying the number of bytes to fill, and the fourth argument is the known
alignment of destination location.</p>
-<p>If the call to this intrinisic has an alignment value that is not 0 or 1,
+<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
then the caller guarantees that the destination pointer is aligned to that
boundary.</p>
@@ -6611,7 +6731,7 @@ LLVM</a>.</p>
<h5>Arguments:</h5>
<p>The <tt>llvm.memory.barrier</tt> intrinsic requires five boolean arguments.
The first four arguments enables a specific barrier as listed below. The
- fith argument specifies that the barrier applies to io or device or uncached
+ fifth argument specifies that the barrier applies to io or device or uncached
memory.</p>
<ul>
@@ -7350,7 +7470,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-02-05 17:16:28 -0800 (Fri, 05 Feb 2010) $
+ Last modified: $Date: 2010-03-05 07:44:48 +0800 (五, 05 3月 2010) $
</address>
</body>
diff --git a/docs/Lexicon.html b/docs/Lexicon.html
index 398be76..d8c0ba5 100644
--- a/docs/Lexicon.html
+++ b/docs/Lexicon.html
@@ -255,7 +255,7 @@ href="http://www.program-transformation.org/Transform/BURG">BURG</a> tool.</dd>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a><a
href="http://llvm.org/">The LLVM Team</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
-Last modified: $Date: 2008-12-14 00:01:51 -0800 (Sun, 14 Dec 2008) $
+Last modified: $Date: 2008-12-14 16:01:51 +0800 (日, 14 12月 2008) $
</address>
<!-- vim: sw=2
-->
diff --git a/docs/LinkTimeOptimization.html b/docs/LinkTimeOptimization.html
index 90460d0..7c2f986 100644
--- a/docs/LinkTimeOptimization.html
+++ b/docs/LinkTimeOptimization.html
@@ -382,7 +382,7 @@ of the native object files.</p>
Devang Patel and Nick Kledzik<br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2009-10-12 22:46:08 +0800 (一, 12 10月 2009) $
</address>
</body>
diff --git a/docs/Makefile b/docs/Makefile
index 5bfa6c3..8f7d617 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -48,11 +48,11 @@ generated:: doxygen ocamldoc
install-html: $(PROJ_OBJ_DIR)/html.tar.gz
$(Echo) Installing HTML documentation
- $(Verb) $(MKDIR) $(PROJ_docsdir)/html
- $(Verb) $(MKDIR) $(PROJ_docsdir)/html/img
- $(Verb) $(DataInstall) $(HTML) $(PROJ_docsdir)/html
- $(Verb) $(DataInstall) $(IMAGES) $(PROJ_docsdir)/html/img
- $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(PROJ_docsdir)
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/img
+ $(Verb) $(DataInstall) $(HTML) $(DESTDIR)$(PROJ_docsdir)/html
+ $(Verb) $(DataInstall) $(IMAGES) $(DESTDIR)$(PROJ_docsdir)/html/img
+ $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(DESTDIR)$(PROJ_docsdir)
$(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
$(Echo) Packaging HTML documentation
@@ -63,11 +63,11 @@ $(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
install-doxygen: doxygen
$(Echo) Installing doxygen documentation
- $(Verb) $(MKDIR) $(PROJ_docsdir)/html/doxygen
- $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(PROJ_docsdir)
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/doxygen
+ $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(DESTDIR)$(PROJ_docsdir)
$(Verb) cd $(PROJ_OBJ_DIR)/doxygen && \
$(FIND) . -type f -exec \
- $(DataInstall) {} $(PROJ_docsdir)/html/doxygen \;
+ $(DataInstall) {} $(DESTDIR)$(PROJ_docsdir)/html/doxygen \;
doxygen: regendoc $(PROJ_OBJ_DIR)/doxygen.tar.gz
@@ -94,11 +94,11 @@ $(LLVM_SRC_ROOT)/docs/userloc.html:
install-ocamldoc: ocamldoc
$(Echo) Installing ocamldoc documentation
- $(Verb) $(MKDIR) $(PROJ_docsdir)/ocamldoc/html
- $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/ocamldoc.tar.gz $(PROJ_docsdir)
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/ocamldoc/html
+ $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/ocamldoc.tar.gz $(DESTDIR)$(PROJ_docsdir)
$(Verb) cd $(PROJ_OBJ_DIR)/ocamldoc && \
$(FIND) . -type f -exec \
- $(DataInstall) {} $(PROJ_docsdir)/ocamldoc/html \;
+ $(DataInstall) {} $(DESTDIR)$(PROJ_docsdir)/ocamldoc/html \;
ocamldoc: regen-ocamldoc
$(Echo) Packaging ocamldoc documentation
@@ -120,4 +120,4 @@ regen-ocamldoc:
uninstall-local::
$(Echo) Uninstalling Documentation
- $(Verb) $(RM) -rf $(PROJ_docsdir)
+ $(Verb) $(RM) -rf $(DESTDIR)$(PROJ_docsdir)
diff --git a/docs/MakefileGuide.html b/docs/MakefileGuide.html
index 6c06c9f..37b0d01 100644
--- a/docs/MakefileGuide.html
+++ b/docs/MakefileGuide.html
@@ -818,6 +818,10 @@
<tt>mklib</tt> by the <tt>configure</tt> script and always located in the
<dt><a name="LLVMAS"><tt>LLVMAS</tt></a><small>(defaulted)</small></dt>
<dd>Specifies the path to the <tt>llvm-as</tt> tool.</dd>
+ <dt><a name="LLVMCC"><tt>LLVMCC</tt></a></dt>
+ <dd>Specifies the path to the LLVM capable compiler.</dd>
+ <dt><a name="LLVMCXX"><tt>LLVMCXX</tt></a></dt>
+ <dd>Specifies the path to the LLVM C++ capable compiler.</dd>
<dt><a name="LLVMGCC"><tt>LLVMGCC</tt></a><small>(defaulted)</small></dt>
<dd>Specifies the path to the LLVM version of the GCC 'C' Compiler</dd>
<dt><a name="LLVMGXX"><tt>LLVMGXX</tt></a><small>(defaulted)</small></dt>
@@ -1021,7 +1025,7 @@
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2010-02-23 18:00:53 +0800 (二, 23 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/Packaging.html b/docs/Packaging.html
new file mode 100644
index 0000000..883e755
--- /dev/null
+++ b/docs/Packaging.html
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+ <title>Advice on Packaging LLVM</title>
+ <link rel="stylesheet" href="llvm.css" type="text/css">
+</head>
+<body>
+
+<div class="doc_title">Advice on Packaging LLVM</div>
+<ol>
+ <li><a href="#overview">Overview</a></li>
+ <li><a href="#compilation">Compile Flags</a></li>
+ <li><a href="#cxx-features">C++ Features</a></li>
+ <li><a href="#shared-library">Shared Library</a></li>
+ <li><a href="#deps">Dependencies</a></li>
+</ol>
+
+<!--=========================================================================-->
+<div class="doc_section"><a name="overview">Overview</a></div>
+<!--=========================================================================-->
+<div class="doc_text">
+
+<p>LLVM sets certain default configure options to make sure our developers don't
+break things for constrained platforms. These settings are not optimal for most
+desktop systems, and we hope that packagers (e.g., Redhat, Debian, MacPorts,
+etc.) will tweak them. This document lists settings we suggest you tweak.
+</p>
+
+<p>LLVM's API changes with each release, so users are likely to want, for
+example, both LLVM-2.6 and LLVM-2.7 installed at the same time to support apps
+developed against each.
+</p>
+</div>
+
+<!--=========================================================================-->
+<div class="doc_section"><a name="compilation">Compile Flags</a></div>
+<!--=========================================================================-->
+<div class="doc_text">
+
+<p>LLVM runs much more quickly when it's optimized and assertions are removed.
+However, such a build is currently incompatible with users who build without
+defining NDEBUG, and the lack of assertions makes it hard to debug problems in
+user code. We recommend allowing users to install both optimized and debug
+versions of LLVM in parallel. The following configure flags are relevant:
+</p>
+
+<dl>
+ <dt><tt>--disable-assertions</tt></dt><dd>Builds LLVM with <tt>NDEBUG</tt>
+ defined. Changes the LLVM ABI. Also available by setting
+ <tt>DISABLE_ASSERTIONS=0|1</tt> in <tt>make</tt>'s environment. This defaults
+ to enabled regardless of the optimization setting, but it slows things
+ down.</dd>
+
+ <dt><tt>--enable-debug-symbols</tt></dt><dd>Builds LLVM with <tt>-g</tt>.
+ Also available by setting <tt>DEBUG_SYMBOLS=0|1</tt> in <tt>make</tt>'s
+ environment. This defaults to disabled when optimizing, so you should turn it
+ back on to let users debug their programs.</dd>
+
+ <dt><tt>--enable-optimized</tt></dt><dd>(For svn checkouts) Builds LLVM with
+ <tt>-O2</tt> and, by default, turns off debug symbols. Also available by
+ setting <tt>ENABLE_OPTIMIZED=0|1</tt> in <tt>make</tt>'s environment. This
+ defaults to enabled when not in a checkout.</dd>
+</dl>
+</div>
+
+<!--=========================================================================-->
+<div class="doc_section"><a name="cxx-features">C++ Features</a></div>
+<!--=========================================================================-->
+<div class="doc_text">
+
+<dl>
+ <dt>RTTI</dt><dd>LLVM disables RTTI by default. Add <tt>REQUIRES_RTTI=1</tt>
+ to your environment while running <tt>make</tt> to re-enable it. This will
+ allow users to build with RTTI enabled and still inherit from LLVM
+ classes.</dd>
+</dl>
+</div>
+
+<!--=========================================================================-->
+<div class="doc_section"><a name="shared-library">Shared Library</a></div>
+<!--=========================================================================-->
+<div class="doc_text">
+
+<p>Configure with <tt>--enable-shared</tt> to build
+<tt>libLLVM-<var>major</var>.<var>minor</var>.(so|dylib)</tt> and link the tools
+against it. This saves lots of binary size at the cost of some startup time.
+</p>
+</div>
+
+<!--=========================================================================-->
+<div class="doc_section"><a name="deps">Dependencies</a></div>
+<!--=========================================================================-->
+<div class="doc_text">
+
+<dl>
+<dt><tt>--enable-libffi</tt></dt><dd>Depend on <a
+href="http://sources.redhat.com/libffi/">libffi</a> to allow the LLVM
+interpreter to call external functions.</dd>
+<dt><tt>--with-oprofile</tt></dt><dd>Depend on <a
+href="http://oprofile.sourceforge.net/doc/devel/index.html">libopagent</a>
+(>=version 0.9.4) to let the LLVM JIT tell oprofile about function addresses and
+line numbers.</dd>
+</dl>
+</div>
+
+<!-- *********************************************************************** -->
+<hr>
+<address>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
+ src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
+ <a href="http://validator.w3.org/check/referer"><img
+ src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
+ <a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
+ Last modified: $Date: 2010-02-27 06:25:06 +0800 (六, 27 2月 2010) $
+</address>
+</body>
+</html>
diff --git a/docs/Passes.html b/docs/Passes.html
index c366808..a0b2337 100644
--- a/docs/Passes.html
+++ b/docs/Passes.html
@@ -75,7 +75,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
<tr><th colspan="2"><b>ANALYSIS PASSES</b></th></tr>
<tr><th>Option</th><th>Name</th></tr>
<tr><td><a href="#aa-eval">-aa-eval</a></td><td>Exhaustive Alias Analysis Precision Evaluator</td></tr>
-<tr><td><a href="#anders-aa">-anders-aa</a></td><td>Andersen's Interprocedural Alias Analysis</td></tr>
<tr><td><a href="#basicaa">-basicaa</a></td><td>Basic Alias Analysis (default AA impl)</td></tr>
<tr><td><a href="#basiccg">-basiccg</a></td><td>Basic CallGraph Construction</td></tr>
<tr><td><a href="#codegenprepare">-codegenprepare</a></td><td>Optimize for code generation</td></tr>
@@ -204,80 +203,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
<!-------------------------------------------------------------------------- -->
<div class="doc_subsection">
- <a name="anders-aa">Andersen's Interprocedural Alias Analysis</a>
-</div>
-<div class="doc_text">
- <p>
- This is an implementation of Andersen's interprocedural alias
- analysis
- </p>
-
- <p>
- In pointer analysis terms, this is a subset-based, flow-insensitive,
- field-sensitive, and context-insensitive algorithm pointer algorithm.
- </p>
-
- <p>
- This algorithm is implemented as three stages:
- </p>
-
- <ol>
- <li>Object identification.</li>
- <li>Inclusion constraint identification.</li>
- <li>Offline constraint graph optimization.</li>
- <li>Inclusion constraint solving.</li>
- </ol>
-
- <p>
- The object identification stage identifies all of the memory objects in the
- program, which includes globals, heap allocated objects, and stack allocated
- objects.
- </p>
-
- <p>
- The inclusion constraint identification stage finds all inclusion constraints
- in the program by scanning the program, looking for pointer assignments and
- other statements that effect the points-to graph. For a statement like
- <code><var>A</var> = <var>B</var></code>, this statement is processed to
- indicate that <var>A</var> can point to anything that <var>B</var> can point
- to. Constraints can handle copies, loads, and stores, and address taking.
- </p>
-
- <p>
- The offline constraint graph optimization portion includes offline variable
- substitution algorithms intended to computer pointer and location
- equivalences. Pointer equivalences are those pointers that will have the
- same points-to sets, and location equivalences are those variables that
- always appear together in points-to sets.
- </p>
-
- <p>
- The inclusion constraint solving phase iteratively propagates the inclusion
- constraints until a fixed point is reached. This is an O(<var>n</var>³)
- algorithm.
- </p>
-
- <p>
- Function constraints are handled as if they were structs with <var>X</var>
- fields. Thus, an access to argument <var>X</var> of function <var>Y</var> is
- an access to node index <code>getNode(<var>Y</var>) + <var>X</var></code>.
- This representation allows handling of indirect calls without any issues. To
- wit, an indirect call <code><var>Y</var>(<var>a</var>,<var>b</var>)</code> is
- equivalent to <code>*(<var>Y</var> + 1) = <var>a</var>, *(<var>Y</var> + 2) =
- <var>b</var></code>. The return node for a function <var>F</var> is always
- located at <code>getNode(<var>F</var>) + CallReturnPos</code>. The arguments
- start at <code>getNode(<var>F</var>) + CallArgPos</code>.
- </p>
-
- <p>
- Please keep in mind that the current andersen's pass has many known
- problems and bugs. It should be considered "research quality".
- </p>
-
-</div>
-
-<!-------------------------------------------------------------------------- -->
-<div class="doc_subsection">
<a name="basicaa">Basic Alias Analysis (default AA impl)</a>
</div>
<div class="doc_text">
@@ -1848,7 +1773,7 @@ if (X &lt; 3) {</pre>
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-27 21:47:06 -0700 (Tue, 27 Oct 2009) $
+ Last modified: $Date: 2010-03-02 03:24:17 +0800 (二, 02 3月 2010) $
</address>
</body>
diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html
index ec38855..48e14b6 100644
--- a/docs/ProgrammersManual.html
+++ b/docs/ProgrammersManual.html
@@ -525,7 +525,7 @@ lightweight <a href="http://en.wikipedia.org/wiki/Rope_(computer_science)">rope<
which points to temporary (stack allocated) objects. Twines can be implicitly
constructed as the result of the plus operator applied to strings (i.e., a C
strings, an <tt>std::string</tt>, or a <tt>StringRef</tt>). The twine delays the
-actual concatentation of strings until it is actually required, at which point
+actual concatenation of strings until it is actually required, at which point
it can be efficiently rendered directly into a character array. This avoids
unnecessary heap allocation involved in constructing the temporary results of
string concatenation. See
@@ -1098,7 +1098,7 @@ in the default manner.</p>
</div>
<div class="doc_text">
-<p><tt>ilist</tt>s have another speciality that must be considered. To be a good
+<p><tt>ilist</tt>s have another specialty that must be considered. To be a good
citizen in the C++ ecosystem, it needs to support the standard container
operations, such as <tt>begin</tt> and <tt>end</tt> iterators, etc. Also, the
<tt>operator--</tt> must work correctly on the <tt>end</tt> iterator in the
@@ -2999,9 +2999,9 @@ the <tt>lib/VMCore</tt> directory.</p>
<div class="doc_text">
<ul>
- <li><tt>bool isInteger() const</tt>: Returns true for any integer type.</li>
+ <li><tt>bool isIntegerTy() const</tt>: Returns true for any integer type.</li>
- <li><tt>bool isFloatingPoint()</tt>: Return true if this is one of the two
+ <li><tt>bool isFloatingPointTy()</tt>: Return true if this is one of the five
floating point types.</li>
<li><tt>bool isAbstract()</tt>: Return true if the type is abstract (contains
@@ -3921,7 +3921,7 @@ arguments. An argument has a pointer to the parent Function.</p>
<a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
<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-29 11:10:38 -0800 (Fri, 29 Jan 2010) $
+ Last modified: $Date: 2010-02-26 07:51:27 +0800 (五, 26 2月 2010) $
</address>
</body>
diff --git a/docs/Projects.html b/docs/Projects.html
index a42f3bf..f9b6b07 100644
--- a/docs/Projects.html
+++ b/docs/Projects.html
@@ -453,7 +453,7 @@ Mailing List</a>.</p>
<a href="mailto:criswell@uiuc.edu">John Criswell</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a>
<br>
- Last modified: $Date: 2009-08-13 13:08:52 -0700 (Thu, 13 Aug 2009) $
+ Last modified: $Date: 2009-08-14 04:08:52 +0800 (五, 14 8月 2009) $
</address>
</body>
diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html
index b750011..a604da4 100644
--- a/docs/ReleaseNotes.html
+++ b/docs/ReleaseNotes.html
@@ -451,6 +451,8 @@ release includes a few major enhancements and additions to the optimizers:</p>
</ul>
+<p>Also, -anders-aa was removed</p>
+
</div>
@@ -467,6 +469,10 @@ href="http://llvm.org/viewvc/llvm-project?view=rev&revision=85295">defaults
to compiling eagerly</a> to avoid a race condition in the lazy JIT.
Clients that still want the lazy JIT can switch it on by calling
<tt>ExecutionEngine::DisableLazyCompilation(false)</tt>.</li>
+<li>It is now possible to create more than one JIT instance in the same process.
+These JITs can generate machine code in parallel,
+although <a href="http://llvm.org/docs/ProgrammersManual.html#jitthreading">you
+still have to obey the other threading restrictions</a>.</li>
</ul>
</div>
@@ -637,6 +643,13 @@ Clients must replace calls to
<li>FIXME: Debug info has been totally redone. Add pointers to new APIs. Substantial caveats about compatibility of .ll and .bc files.</li>
+<li>The <tt>llvm/Support/DataTypes.h</tt> header has moved
+to <tt>llvm/System/DataTypes.h</tt>.</li>
+
+<li>The <tt>isInteger</tt>, <tt>isIntOrIntVector</tt>, <tt>isFloatingPoint</tt>,
+<tt>isFPOrFPVector</tt> and <tt>isFPOrFPVector</tt> methods have been renamed
+<tt>isIntegerTy</tt>, <tt>isIntOrIntVectorTy</tt>, <tt>isFloatingPointTy</tt>,
+<tt>isFPOrFPVectorTy</tt> and <tt>isFPOrFPVectorTy</tt> respectively.</li>
</ul>
</div>
@@ -722,7 +735,6 @@ href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p>
experimental.</li>
<li>The <tt>llc</tt> "<tt>-filetype=asm</tt>" (the default) is the only
supported value for this option. The ELF writer is experimental.</li>
-<li>The implementation of Andersen's Alias Analysis has many known bugs.</li>
</ul>
</div>
@@ -985,7 +997,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-02-09 20:09:52 -0800 (Tue, 09 Feb 2010) $
+ Last modified: $Date: 2010-03-02 03:29:17 +0800 (二, 02 3月 2010) $
</address>
</body>
diff --git a/docs/SourceLevelDebugging.html b/docs/SourceLevelDebugging.html
index e1c78a9..231ce54 100644
--- a/docs/SourceLevelDebugging.html
+++ b/docs/SourceLevelDebugging.html
@@ -1738,7 +1738,7 @@ enum Trees {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-11 14:53:48 -0800 (Mon, 11 Jan 2010) $
+ Last modified: $Date: 2010-01-12 06:53:48 +0800 (二, 12 1月 2010) $
</address>
</body>
diff --git a/docs/SystemLibrary.html b/docs/SystemLibrary.html
index c438ee7..52d9b21 100644
--- a/docs/SystemLibrary.html
+++ b/docs/SystemLibrary.html
@@ -313,7 +313,7 @@
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-07-17 14:11:24 -0700 (Fri, 17 Jul 2009) $
+ Last modified: $Date: 2009-07-18 05:11:24 +0800 (六, 18 7月 2009) $
</address>
</body>
</html>
diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html
index 05d5199..fd93fc3 100644
--- a/docs/TableGenFundamentals.html
+++ b/docs/TableGenFundamentals.html
@@ -155,7 +155,6 @@ file prints this (at the time of this writing):</p>
<b>bit</b> hasCtrlDep = 0;
<b>bit</b> isNotDuplicable = 0;
<b>bit</b> hasSideEffects = 0;
- <b>bit</b> mayHaveSideEffects = 0;
<b>bit</b> neverHasSideEffects = 0;
InstrItinClass Itinerary = NoItinerary;
<b>string</b> Constraints = "";
@@ -189,7 +188,7 @@ backend, and is only shown as an example.</p>
<p>As you can see, a lot of information is needed for every instruction
supported by the code generator, and specifying it all manually would be
-unmaintainble, prone to bugs, and tiring to do in the first place. Because we
+unmaintainable, prone to bugs, and tiring to do in the first place. Because we
are using TableGen, all of the information was derived from the following
definition:</p>
@@ -798,7 +797,7 @@ This should highlight the APIs in <tt>TableGen/Record.h</tt>.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-05 11:11:42 -0800 (Tue, 05 Jan 2010) $
+ Last modified: $Date: 2010-02-28 07:47:46 +0800 (日, 28 2月 2010) $
</address>
</body>
diff --git a/docs/TestingGuide.html b/docs/TestingGuide.html
index d776afe..f1584c3 100644
--- a/docs/TestingGuide.html
+++ b/docs/TestingGuide.html
@@ -693,8 +693,6 @@ that FileCheck is not actually line-oriented when it matches, this allows you to
define two separate CHECK lines that match on the same line.
</p>
-
-
</div>
<!-- _______________________________________________________________________ -->
@@ -761,12 +759,6 @@ substitutions</a></div>
<dd>The full path to the <tt>llvm-gxx</tt> executable as specified in the
configured LLVM environment</dd>
- <dt><b>llvmgcc_version</b> (%llvmgcc_version)</dt>
- <dd>The full version number of the <tt>llvm-gcc</tt> executable.</dd>
-
- <dt><b>llvmgccmajvers</b> (%llvmgccmajvers)</dt>
- <dd>The major version number of the <tt>llvm-gcc</tt> executable.</dd>
-
<dt><b>gccpath</b></dt>
<dd>The full path to the C compiler used to <i>build </i> LLVM. Note that
this might not be gcc.</dd>
@@ -824,22 +816,20 @@ substitutions</a></div>
</dl>
<p>Sometimes it is necessary to mark a test case as "expected fail" or XFAIL.
- You can easily mark a test as XFAIL just by including <tt>XFAIL: </tt> on a
+ You can easily mark a test as XFAIL just by including <tt>XFAIL: </tt> on a
line near the top of the file. This signals that the test case should succeed
if the test fails. Such test cases are counted separately by DejaGnu. To
specify an expected fail, use the XFAIL keyword in the comments of the test
program followed by a colon and one or more regular expressions (separated by
- a comma). The regular expressions allow you to XFAIL the test conditionally
- by host platform. The regular expressions following the : are matched against
- the target triplet or llvmgcc version number for the host machine. If there is
- a match, the test is expected to fail. If not, the test is expected to
- succeed. To XFAIL everywhere just specify <tt>XFAIL: *</tt>. When matching
- the llvm-gcc version, you can specify the major (e.g. 3) or full version
- (i.e. 3.4) number. Here is an example of an <tt>XFAIL</tt> line:</p>
+ a comma). The regular expressions allow you to XFAIL the test conditionally by
+ host platform. The regular expressions following the : are matched against the
+ target triplet for the host machine. If there is a match, the test is expected
+ to fail. If not, the test is expected to succeed. To XFAIL everywhere just
+ specify <tt>XFAIL: *</tt>. Here is an example of an <tt>XFAIL</tt> line:</p>
<div class="doc_code">
<pre>
-; XFAIL: darwin,sun,llvmgcc4
+; XFAIL: darwin,sun
</pre>
</div>
@@ -1145,7 +1135,6 @@ example reports that can do fancy stuff.</p>
</div>
-
<!--=========================================================================-->
<div class="doc_section"><a name="nightly">Running the nightly tester</a></div>
<!--=========================================================================-->
@@ -1217,7 +1206,7 @@ know. Thanks!</p>
John T. Criswell, Reid Spencer, and Tanya Lattner<br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-09-27 01:01:44 -0700 (Sun, 27 Sep 2009) $
+ Last modified: $Date: 2010-02-27 05:23:59 +0800 (六, 27 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/UsingLibraries.html b/docs/UsingLibraries.html
index cf5333c..47e459c 100644
--- a/docs/UsingLibraries.html
+++ b/docs/UsingLibraries.html
@@ -432,7 +432,7 @@
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a>
</address>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a>
-<br>Last modified: $Date: 2009-07-23 17:30:09 -0700 (Thu, 23 Jul 2009) $ </div>
+<br>Last modified: $Date: 2009-07-24 08:30:09 +0800 (五, 24 7月 2009) $ </div>
</body>
</html>
<!-- vim: sw=2 ts=2 ai
diff --git a/docs/WritingAnLLVMBackend.html b/docs/WritingAnLLVMBackend.html
index 6731e30..151edae 100644
--- a/docs/WritingAnLLVMBackend.html
+++ b/docs/WritingAnLLVMBackend.html
@@ -2555,7 +2555,7 @@ with assembler.
<a href="http://www.woo.com">Mason Woo</a> and <a href="http://misha.brukman.net">Misha Brukman</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a>
<br>
- Last modified: $Date: 2010-02-02 10:44:12 -0800 (Tue, 02 Feb 2010) $
+ Last modified: $Date: 2010-02-03 02:44:12 +0800 (三, 03 2月 2010) $
</address>
</body>
diff --git a/docs/WritingAnLLVMPass.html b/docs/WritingAnLLVMPass.html
index 9a57fd5..c53bc8d 100644
--- a/docs/WritingAnLLVMPass.html
+++ b/docs/WritingAnLLVMPass.html
@@ -377,10 +377,10 @@ interesting way, we just throw away the result of <tt>opt</tt> (sending it to
<tt>/dev/null</tt>).</p>
<p>To see what happened to the other string you registered, try running
-<tt>opt</tt> with the <tt>--help</tt> option:</p>
+<tt>opt</tt> with the <tt>-help</tt> option:</p>
<div class="doc_code"><pre>
-$ opt -load ../../../Debug/lib/Hello.so --help
+$ opt -load ../../../Debug/lib/Hello.so -help
OVERVIEW: llvm .bc -&gt; .bc modular optimizer
USAGE: opt [options] &lt;input bitcode&gt;
@@ -970,7 +970,7 @@ template, which requires you to pass at least two
parameters. The first parameter is the name of the pass that is to be used on
the command line to specify that the pass should be added to a program (for
example, with <tt>opt</tt> or <tt>bugpoint</tt>). The second argument is the
-name of the pass, which is to be used for the <tt>--help</tt> output of
+name of the pass, which is to be used for the <tt>-help</tt> output of
programs, as
well as for debug output generated by the <tt>--debug-pass</tt> option.</p>
@@ -1410,7 +1410,7 @@ allowing any analysis results to live across the execution of your pass.</p>
options that is useful for debugging pass execution, seeing how things work, and
diagnosing when you should be preserving more analyses than you currently are
(To get information about all of the variants of the <tt>--debug-pass</tt>
-option, just type '<tt>opt --help-hidden</tt>').</p>
+option, just type '<tt>opt -help-hidden</tt>').</p>
<p>By using the <tt>--debug-pass=Structure</tt> option, for example, we can see
how our <a href="#basiccode">Hello World</a> pass interacts with other passes.
@@ -1625,12 +1625,12 @@ form; </p>
</pre></div>
<p>Note the two spaces prior to the help string produces a tidy result on the
---help query.</p>
+-help query.</p>
<div class="doc_code"><pre>
-$ llc --help
+$ llc -help
...
- -regalloc - Register allocator to use: (default = linearscan)
+ -regalloc - Register allocator to use (default=linearscan)
=linearscan - linear scan register allocator
=local - local register allocator
=simple - simple register allocator
@@ -1829,7 +1829,7 @@ Despite that, we have kept the LLVM passes SMP ready, and you should too.</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: 2009-10-12 07:46:08 -0700 (Mon, 12 Oct 2009) $
+ Last modified: $Date: 2010-02-18 22:37:52 +0800 (四, 18 2月 2010) $
</address>
</body>
diff --git a/docs/index.html b/docs/index.html
index 0de651f..5c85ec2 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -93,7 +93,6 @@ Current tools:
<a href="/cmds/llvmc.html">llvmc</a>
<a href="/cmds/llvmgcc.html">llvm-gcc</a>,
<a href="/cmds/llvmgxx.html">llvm-g++</a>,
- <a href="/cmds/stkrc.html">stkrc</a>,
<a href="/cmds/bugpoint.html">bugpoint</a>,
<a href="/cmds/llvm-bcanalyzer.html">llvm-bcanalyzer</a>,
</li>
@@ -117,6 +116,9 @@ manual for using the LLVM testing infrastructure.</li>
<li><a href="GCCFEBuildInstrs.html">How to build the Ada/C/C++/Fortran front-ends</a> -
Instructions for building gcc front-ends from source.</li>
+<li><a href="Packaging.html">Packaging guide</a> - Advice on packaging
+LLVM into a distribution.</li>
+
<li><a href="Lexicon.html">The LLVM Lexicon</a> - Definition of acronyms, terms
and concepts used in LLVM.</li>
@@ -285,7 +287,7 @@ times each day, making it a high volume list.</li>
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-02-03 10:49:55 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-26 08:54:42 +0800 (五, 26 2月 2010) $
</address>
</body></html>
diff --git a/docs/tutorial/LangImpl1.html b/docs/tutorial/LangImpl1.html
index fddb40f..0779bf1 100644
--- a/docs/tutorial/LangImpl1.html
+++ b/docs/tutorial/LangImpl1.html
@@ -342,7 +342,7 @@ so that you can use the lexer and parser together.
<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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-04 01:27:31 +0800 (四, 04 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl2.html b/docs/tutorial/LangImpl2.html
index fb9f8e1..64f2747 100644
--- a/docs/tutorial/LangImpl2.html
+++ b/docs/tutorial/LangImpl2.html
@@ -1227,7 +1227,7 @@ int main() {
<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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-04 01:27:31 +0800 (四, 04 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl3.html b/docs/tutorial/LangImpl3.html
index aab7faa..831c7c1 100644
--- a/docs/tutorial/LangImpl3.html
+++ b/docs/tutorial/LangImpl3.html
@@ -170,7 +170,7 @@ internally (<tt>APFloat</tt> has the capability of holding floating point
constants of <em>A</em>rbitrary <em>P</em>recision). This code basically just
creates and returns a <tt>ConstantFP</tt>. Note that in the LLVM IR
that constants are all uniqued together and shared. For this reason, the API
-uses "the Context.get..." idiom instead of "new foo(..)" or "foo::Create(..)".</p>
+uses the "foo::get(...)" idiom instead of "new foo(..)" or "foo::Create(..)".</p>
<div class="doc_code">
<pre>
@@ -323,10 +323,10 @@ really talks about the external interface for a function (not the value computed
by an expression), it makes sense for it to return the LLVM Function it
corresponds to when codegen'd.</p>
-<p>The call to <tt>Context.get</tt> creates
+<p>The call to <tt>FunctionType::get</tt> creates
the <tt>FunctionType</tt> that should be used for a given Prototype. Since all
function arguments in Kaleidoscope are of type double, the first line creates
-a vector of "N" LLVM double types. It then uses the <tt>Context.get</tt>
+a vector of "N" LLVM double types. It then uses the <tt>Functiontype::get</tt>
method to create a function type that takes "N" doubles as arguments, returns
one double as a result, and that is not vararg (the false parameter indicates
this). Note that Types in LLVM are uniqued just like Constants are, so you
@@ -535,8 +535,7 @@ ready> <b>4+5</b>;
Read top-level expression:
define double @""() {
entry:
- %addtmp = add double 4.000000e+00, 5.000000e+00
- ret double %addtmp
+ ret double 9.000000e+00
}
</pre>
</div>
@@ -544,7 +543,8 @@ entry:
<p>Note how the parser turns the top-level expression into anonymous functions
for us. This will be handy when we add <a href="LangImpl4.html#jit">JIT
support</a> in the next chapter. Also note that the code is very literally
-transcribed, no optimizations are being performed. We will
+transcribed, no optimizations are being performed except simple constant
+folding done by IRBuilder. We will
<a href="LangImpl4.html#trivialconstfold">add optimizations</a> explicitly in
the next chapter.</p>
@@ -554,12 +554,12 @@ ready&gt; <b>def foo(a b) a*a + 2*a*b + b*b;</b>
Read function definition:
define double @foo(double %a, double %b) {
entry:
- %multmp = mul double %a, %a
- %multmp1 = mul double 2.000000e+00, %a
- %multmp2 = mul double %multmp1, %b
- %addtmp = add double %multmp, %multmp2
- %multmp3 = mul double %b, %b
- %addtmp4 = add double %addtmp, %multmp3
+ %multmp = fmul double %a, %a
+ %multmp1 = fmul double 2.000000e+00, %a
+ %multmp2 = fmul double %multmp1, %b
+ %addtmp = fadd double %multmp, %multmp2
+ %multmp3 = fmul double %b, %b
+ %addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
</pre>
@@ -576,7 +576,7 @@ define double @bar(double %a) {
entry:
%calltmp = call double @foo( double %a, double 4.000000e+00 )
%calltmp1 = call double @bar( double 3.133700e+04 )
- %addtmp = add double %calltmp, %calltmp1
+ %addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
</pre>
@@ -612,18 +612,18 @@ ready&gt; <b>^D</b>
define double @""() {
entry:
- %addtmp = add double 4.000000e+00, 5.000000e+00
+ %addtmp = fadd double 4.000000e+00, 5.000000e+00
ret double %addtmp
}
define double @foo(double %a, double %b) {
entry:
- %multmp = mul double %a, %a
- %multmp1 = mul double 2.000000e+00, %a
- %multmp2 = mul double %multmp1, %b
- %addtmp = add double %multmp, %multmp2
- %multmp3 = mul double %b, %b
- %addtmp4 = add double %addtmp, %multmp3
+ %multmp = fmul double %a, %a
+ %multmp1 = fmul double 2.000000e+00, %a
+ %multmp2 = fmul double %multmp1, %b
+ %addtmp = fadd double %multmp, %multmp2
+ %multmp3 = fmul double %b, %b
+ %addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
@@ -631,7 +631,7 @@ define double @bar(double %a) {
entry:
%calltmp = call double @foo( double %a, double 4.000000e+00 )
%calltmp1 = call double @bar( double 3.133700e+04 )
- %addtmp = add double %calltmp, %calltmp1
+ %addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
@@ -1263,7 +1263,7 @@ int main() {
<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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl4.html b/docs/tutorial/LangImpl4.html
index 38ed25d..992fe36 100644
--- a/docs/tutorial/LangImpl4.html
+++ b/docs/tutorial/LangImpl4.html
@@ -65,7 +65,7 @@ ready&gt; <b>def test(x) 1+2+x;</b>
Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double 3.000000e+00, %x
+ %addtmp = fadd double 3.000000e+00, %x
ret double %addtmp
}
</pre>
@@ -80,8 +80,8 @@ ready&gt; <b>def test(x) 1+2+x;</b>
Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double 2.000000e+00, 1.000000e+00
- %addtmp1 = add double %addtmp, %x
+ %addtmp = fadd double 2.000000e+00, 1.000000e+00
+ %addtmp1 = fadd double %addtmp, %x
ret double %addtmp1
}
</pre>
@@ -113,9 +113,9 @@ ready&gt; <b>def test(x) (1+2+x)*(x+(1+2));</b>
ready> Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double 3.000000e+00, %x
- %addtmp1 = add double %x, 3.000000e+00
- %multmp = mul double %addtmp, %addtmp1
+ %addtmp = fadd double 3.000000e+00, %x
+ %addtmp1 = fadd double %x, 3.000000e+00
+ %multmp = fmul double %addtmp, %addtmp1
ret double %multmp
}
</pre>
@@ -240,8 +240,8 @@ ready&gt; <b>def test(x) (1+2+x)*(x+(1+2));</b>
ready> Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double %x, 3.000000e+00
- %multmp = mul double %addtmp, %addtmp
+ %addtmp = fadd double %x, 3.000000e+00
+ %multmp = fmul double %addtmp, %addtmp
ret double %multmp
}
</pre>
@@ -363,8 +363,8 @@ ready&gt; <b>def testfunc(x y) x + y*2; </b>
Read function definition:
define double @testfunc(double %x, double %y) {
entry:
- %multmp = mul double %y, 2.000000e+00
- %addtmp = add double %multmp, %x
+ %multmp = fmul double %y, 2.000000e+00
+ %addtmp = fadd double %multmp, %x
ret double %addtmp
}
@@ -411,10 +411,10 @@ Read function definition:
define double @foo(double %x) {
entry:
%calltmp = call double @sin( double %x )
- %multmp = mul double %calltmp, %calltmp
+ %multmp = fmul double %calltmp, %calltmp
%calltmp2 = call double @cos( double %x )
- %multmp4 = mul double %calltmp2, %calltmp2
- %addtmp = add double %multmp, %multmp4
+ %multmp4 = fmul double %calltmp2, %calltmp2
+ %addtmp = fadd double %multmp, %multmp4
ret double %addtmp
}
@@ -485,7 +485,7 @@ LLVM JIT and optimizer. To build this example, use:
<div class="doc_code">
<pre>
# Compile
- g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit interpreter native` -O3 -o toy
+ g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
@@ -502,7 +502,6 @@ at runtime.</p>
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -1075,7 +1074,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
@@ -1122,7 +1126,7 @@ int main() {
<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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl5.html b/docs/tutorial/LangImpl5.html
index bd175c0..a663e9c 100644
--- a/docs/tutorial/LangImpl5.html
+++ b/docs/tutorial/LangImpl5.html
@@ -678,7 +678,7 @@ loop: ; preds = %loop, %entry
; body
%calltmp = call double @putchard( double 4.200000e+01 )
; increment
- %nextvar = add double %i, 1.000000e+00
+ %nextvar = fadd double %i, 1.000000e+00
; termination test
%cmptmp = fcmp ult double %i, %n
@@ -902,7 +902,6 @@ if/then/else and for expressions.. To build this example, use:
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -1720,7 +1719,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
@@ -1767,7 +1771,7 @@ int main() {
<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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl6.html b/docs/tutorial/LangImpl6.html
index 0c93224..5986849 100644
--- a/docs/tutorial/LangImpl6.html
+++ b/docs/tutorial/LangImpl6.html
@@ -821,7 +821,6 @@ if/then/else and for expressions.. To build this example, use:
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -1757,7 +1756,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
@@ -1804,7 +1808,7 @@ int main() {
<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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-12 03:15:20 +0800 (五, 12 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl7.html b/docs/tutorial/LangImpl7.html
index 30342c3..9d67e6b 100644
--- a/docs/tutorial/LangImpl7.html
+++ b/docs/tutorial/LangImpl7.html
@@ -557,12 +557,12 @@ then: ; preds = %entry
else: ; preds = %entry
<b>%x3 = load double* %x1</b>
- %subtmp = sub double %x3, 1.000000e+00
+ %subtmp = fsub double %x3, 1.000000e+00
%calltmp = call double @fib( double %subtmp )
<b>%x4 = load double* %x1</b>
- %subtmp5 = sub double %x4, 2.000000e+00
+ %subtmp5 = fsub double %x4, 2.000000e+00
%calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
@@ -595,11 +595,11 @@ then:
br label %ifcont
else:
- %subtmp = sub double <b>%x</b>, 1.000000e+00
+ %subtmp = fsub double <b>%x</b>, 1.000000e+00
%calltmp = call double @fib( double %subtmp )
- %subtmp5 = sub double <b>%x</b>, 2.000000e+00
+ %subtmp5 = fsub double <b>%x</b>, 2.000000e+00
%calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
@@ -625,11 +625,11 @@ entry:
br i1 %ifcond, label %else, label %ifcont
else:
- %subtmp = sub double %x, 1.000000e+00
+ %subtmp = fsub double %x, 1.000000e+00
%calltmp = call double @fib( double %subtmp )
- %subtmp5 = sub double %x, 2.000000e+00
+ %subtmp5 = fsub double %x, 2.000000e+00
%calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %addtmp = fadd double %calltmp, %calltmp6
ret double %addtmp
ifcont:
@@ -1004,7 +1004,6 @@ variables and var/in support. To build this example, use:
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -2105,7 +2104,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
@@ -2154,7 +2158,7 @@ int main() {
<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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl8.html b/docs/tutorial/LangImpl8.html
index b5d4f67..bd26cc4 100644
--- a/docs/tutorial/LangImpl8.html
+++ b/docs/tutorial/LangImpl8.html
@@ -359,7 +359,7 @@ Passing Style</a> and the use of tail calls (which LLVM also supports).</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-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-04 01:27:31 +0800 (四, 04 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/Makefile b/docs/tutorial/Makefile
index 6169bb8..9082ad4 100644
--- a/docs/tutorial/Makefile
+++ b/docs/tutorial/Makefile
@@ -12,7 +12,7 @@ include $(LEVEL)/Makefile.common
HTML := $(wildcard $(PROJ_SRC_DIR)/*.html)
EXTRA_DIST := $(HTML) index.html
-HTML_DIR := $(PROJ_docsdir)/html/tutorial
+HTML_DIR := $(DESTDIR)$(PROJ_docsdir)/html/tutorial
install-local:: $(HTML)
$(Echo) Installing HTML Tutorial Documentation
diff --git a/docs/tutorial/OCamlLangImpl1.html b/docs/tutorial/OCamlLangImpl1.html
index c9bb13d..64ba926 100644
--- a/docs/tutorial/OCamlLangImpl1.html
+++ b/docs/tutorial/OCamlLangImpl1.html
@@ -359,7 +359,7 @@ include a driver so that you can use the lexer and parser together.
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-04 01:27:31 +0800 (四, 04 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl2.html b/docs/tutorial/OCamlLangImpl2.html
index f354223..db03134 100644
--- a/docs/tutorial/OCamlLangImpl2.html
+++ b/docs/tutorial/OCamlLangImpl2.html
@@ -1039,7 +1039,7 @@ main ()
<a href="mailto:sabre@nondot.org">Chris Lattner</a>
<a href="mailto:erickt@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-04 01:27:31 +0800 (四, 04 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl3.html b/docs/tutorial/OCamlLangImpl3.html
index 1802eff..4d2c0f8 100644
--- a/docs/tutorial/OCamlLangImpl3.html
+++ b/docs/tutorial/OCamlLangImpl3.html
@@ -484,7 +484,7 @@ ready&gt; <b>4+5</b>;
Read top-level expression:
define double @""() {
entry:
- %addtmp = add double 4.000000e+00, 5.000000e+00
+ %addtmp = fadd double 4.000000e+00, 5.000000e+00
ret double %addtmp
}
</pre>
@@ -503,12 +503,12 @@ ready&gt; <b>def foo(a b) a*a + 2*a*b + b*b;</b>
Read function definition:
define double @foo(double %a, double %b) {
entry:
- %multmp = mul double %a, %a
- %multmp1 = mul double 2.000000e+00, %a
- %multmp2 = mul double %multmp1, %b
- %addtmp = add double %multmp, %multmp2
- %multmp3 = mul double %b, %b
- %addtmp4 = add double %addtmp, %multmp3
+ %multmp = fmul double %a, %a
+ %multmp1 = fmul double 2.000000e+00, %a
+ %multmp2 = fmul double %multmp1, %b
+ %addtmp = fadd double %multmp, %multmp2
+ %multmp3 = fmul double %b, %b
+ %addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
</pre>
@@ -525,7 +525,7 @@ define double @bar(double %a) {
entry:
%calltmp = call double @foo( double %a, double 4.000000e+00 )
%calltmp1 = call double @bar( double 3.133700e+04 )
- %addtmp = add double %calltmp, %calltmp1
+ %addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
</pre>
@@ -561,18 +561,18 @@ ready&gt; <b>^D</b>
define double @""() {
entry:
- %addtmp = add double 4.000000e+00, 5.000000e+00
+ %addtmp = fadd double 4.000000e+00, 5.000000e+00
ret double %addtmp
}
define double @foo(double %a, double %b) {
entry:
- %multmp = mul double %a, %a
- %multmp1 = mul double 2.000000e+00, %a
- %multmp2 = mul double %multmp1, %b
- %addtmp = add double %multmp, %multmp2
- %multmp3 = mul double %b, %b
- %addtmp4 = add double %addtmp, %multmp3
+ %multmp = fmul double %a, %a
+ %multmp1 = fmul double 2.000000e+00, %a
+ %multmp2 = fmul double %multmp1, %b
+ %addtmp = fadd double %multmp, %multmp2
+ %multmp3 = fmul double %b, %b
+ %addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
@@ -580,7 +580,7 @@ define double @bar(double %a) {
entry:
%calltmp = call double @foo( double %a, double 4.000000e+00 )
%calltmp1 = call double @bar( double 3.133700e+04 )
- %addtmp = add double %calltmp, %calltmp1
+ %addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
@@ -1085,7 +1085,7 @@ main ()
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl4.html b/docs/tutorial/OCamlLangImpl4.html
index f3b9ff0..1e91330 100644
--- a/docs/tutorial/OCamlLangImpl4.html
+++ b/docs/tutorial/OCamlLangImpl4.html
@@ -72,8 +72,8 @@ ready&gt; <b>def test(x) 1+2+x;</b>
Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double 1.000000e+00, 2.000000e+00
- %addtmp1 = add double %addtmp, %x
+ %addtmp = fadd double 1.000000e+00, 2.000000e+00
+ %addtmp1 = fadd double %addtmp, %x
ret double %addtmp1
}
</pre>
@@ -104,7 +104,7 @@ ready&gt; <b>def test(x) 1+2+x;</b>
Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double 3.000000e+00, %x
+ %addtmp = fadd double 3.000000e+00, %x
ret double %addtmp
}
</pre>
@@ -127,9 +127,9 @@ ready&gt; <b>def test(x) (1+2+x)*(x+(1+2));</b>
ready&gt; Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double 3.000000e+00, %x
- %addtmp1 = add double %x, 3.000000e+00
- %multmp = mul double %addtmp, %addtmp1
+ %addtmp = fadd double 3.000000e+00, %x
+ %addtmp1 = fadd double %x, 3.000000e+00
+ %multmp = fmul double %addtmp, %addtmp1
ret double %multmp
}
</pre>
@@ -267,8 +267,8 @@ ready&gt; <b>def test(x) (1+2+x)*(x+(1+2));</b>
ready&gt; Read function definition:
define double @test(double %x) {
entry:
- %addtmp = add double %x, 3.000000e+00
- %multmp = mul double %addtmp, %addtmp
+ %addtmp = fadd double %x, 3.000000e+00
+ %multmp = fmul double %addtmp, %addtmp
ret double %multmp
}
</pre>
@@ -388,8 +388,8 @@ ready&gt; <b>def testfunc(x y) x + y*2; </b>
Read function definition:
define double @testfunc(double %x, double %y) {
entry:
- %multmp = mul double %y, 2.000000e+00
- %addtmp = add double %multmp, %x
+ %multmp = fmul double %y, 2.000000e+00
+ %addtmp = fadd double %multmp, %x
ret double %addtmp
}
@@ -436,10 +436,10 @@ Read function definition:
define double @foo(double %x) {
entry:
%calltmp = call double @sin( double %x )
- %multmp = mul double %calltmp, %calltmp
+ %multmp = fmul double %calltmp, %calltmp
%calltmp2 = call double @cos( double %x )
- %multmp4 = mul double %calltmp2, %calltmp2
- %addtmp = add double %multmp, %multmp4
+ %multmp4 = fmul double %calltmp2, %calltmp2
+ %addtmp = fadd double %multmp, %multmp4
ret double %addtmp
}
@@ -1032,7 +1032,7 @@ extern double putchard(double X) {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl5.html b/docs/tutorial/OCamlLangImpl5.html
index 93d7146..5848457 100644
--- a/docs/tutorial/OCamlLangImpl5.html
+++ b/docs/tutorial/OCamlLangImpl5.html
@@ -653,7 +653,7 @@ loop: ; preds = %loop, %entry
; body
%calltmp = call double @putchard( double 4.200000e+01 )
; increment
- %nextvar = add double %i, 1.000000e+00
+ %nextvar = fadd double %i, 1.000000e+00
; termination test
%cmptmp = fcmp ult double %i, %n
@@ -1563,7 +1563,7 @@ operators</a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl6.html b/docs/tutorial/OCamlLangImpl6.html
index cf153c4..218c9d1 100644
--- a/docs/tutorial/OCamlLangImpl6.html
+++ b/docs/tutorial/OCamlLangImpl6.html
@@ -1568,7 +1568,7 @@ SSA construction</a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-02-04 01:27:31 +0800 (四, 04 2月 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl7.html b/docs/tutorial/OCamlLangImpl7.html
index 9e0f3bd..78d42f8 100644
--- a/docs/tutorial/OCamlLangImpl7.html
+++ b/docs/tutorial/OCamlLangImpl7.html
@@ -581,12 +581,12 @@ then: ; preds = %entry
else: ; preds = %entry
<b>%x3 = load double* %x1</b>
- %subtmp = sub double %x3, 1.000000e+00
+ %subtmp = fsub double %x3, 1.000000e+00
%calltmp = call double @fib( double %subtmp )
<b>%x4 = load double* %x1</b>
- %subtmp5 = sub double %x4, 2.000000e+00
+ %subtmp5 = fsub double %x4, 2.000000e+00
%calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
@@ -619,11 +619,11 @@ then:
br label %ifcont
else:
- %subtmp = sub double <b>%x</b>, 1.000000e+00
+ %subtmp = fsub double <b>%x</b>, 1.000000e+00
%calltmp = call double @fib( double %subtmp )
- %subtmp5 = sub double <b>%x</b>, 2.000000e+00
+ %subtmp5 = fsub double <b>%x</b>, 2.000000e+00
%calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
@@ -649,11 +649,11 @@ entry:
br i1 %ifcond, label %else, label %ifcont
else:
- %subtmp = sub double %x, 1.000000e+00
+ %subtmp = fsub double %x, 1.000000e+00
%calltmp = call double @fib( double %subtmp )
- %subtmp5 = sub double %x, 2.000000e+00
+ %subtmp5 = fsub double %x, 2.000000e+00
%calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %addtmp = fadd double %calltmp, %calltmp6
ret double %addtmp
ifcont:
@@ -1901,7 +1901,7 @@ extern double printd(double X) {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
- Last modified: $Date: 2010-02-03 09:27:31 -0800 (Wed, 03 Feb 2010) $
+ Last modified: $Date: 2010-03-02 09:11:08 +0800 (二, 02 3月 2010) $
</address>
</body>
</html>
diff --git a/examples/Kaleidoscope/Chapter4/Makefile b/examples/Kaleidoscope/Chapter4/Makefile
index 7bc742f..30162d9 100644
--- a/examples/Kaleidoscope/Chapter4/Makefile
+++ b/examples/Kaleidoscope/Chapter4/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch4
EXAMPLE_TOOL = 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp
index cdc9d74..a2ddda2 100644
--- a/examples/Kaleidoscope/Chapter4/toy.cpp
+++ b/examples/Kaleidoscope/Chapter4/toy.cpp
@@ -1,6 +1,5 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -573,7 +572,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
diff --git a/examples/Kaleidoscope/Chapter5/Makefile b/examples/Kaleidoscope/Chapter5/Makefile
index 5a8355d..d1f5e20 100644
--- a/examples/Kaleidoscope/Chapter5/Makefile
+++ b/examples/Kaleidoscope/Chapter5/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch5
EXAMPLE_TOOL = 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp
index 24f551f..da64b7e 100644
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -1,6 +1,5 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -818,7 +817,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
diff --git a/examples/Kaleidoscope/Chapter6/Makefile b/examples/Kaleidoscope/Chapter6/Makefile
index de2d758..a5fbcbd 100644
--- a/examples/Kaleidoscope/Chapter6/Makefile
+++ b/examples/Kaleidoscope/Chapter6/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch6
EXAMPLE_TOOL = 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp
index f4b5b8c..4e719e3 100644
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -1,6 +1,5 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -936,7 +935,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
diff --git a/examples/Kaleidoscope/Chapter7/Makefile b/examples/Kaleidoscope/Chapter7/Makefile
index 8911d52..6cec323 100644
--- a/examples/Kaleidoscope/Chapter7/Makefile
+++ b/examples/Kaleidoscope/Chapter7/Makefile
@@ -11,6 +11,6 @@ TOOLNAME = Kaleidoscope-Ch7
EXAMPLE_TOOL = 1
REQUIRES_RTTI := 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp
index 951dfd8..7dd9eae 100644
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -1,6 +1,5 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -1100,7 +1099,12 @@ int main() {
TheModule = new Module("my cool jit", Context);
// Create the JIT. This takes ownership of the module.
- TheExecutionEngine = EngineBuilder(TheModule).create();
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
FunctionPassManager OurFPM(TheModule);
diff --git a/examples/Makefile b/examples/Makefile
index fc3a7d4..0737eaf 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -17,7 +17,12 @@ PARALLEL_DIRS += ParallelJIT
endif
ifeq ($(LLVM_ON_UNIX),1)
-PARALLEL_DIRS += ExceptionDemo
+ ifeq ($(ARCH),x86)
+ PARALLEL_DIRS += ExceptionDemo
+ endif
+ ifeq ($(ARCH),x86_64)
+ PARALLEL_DIRS += ExceptionDemo
+ endif
endif
include $(LEVEL)/Makefile.common
diff --git a/host/include/llvm/Config/AsmParsers.def b/host/include/llvm/Config/AsmParsers.def
new file mode 100644
index 0000000..dd5c70c
--- /dev/null
+++ b/host/include/llvm/Config/AsmParsers.def
@@ -0,0 +1,29 @@
+//===- llvm/Config/AsmParsers.def - LLVM Assembly Parsers -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language parsers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PARSER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly parsers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASM_PARSER
+# error Please define the macro LLVM_ASM_PARSER(TargetName)
+#endif
+
+LLVM_ASM_PARSER(X86) LLVM_ASM_PARSER(X86)
+
+#undef LLVM_ASM_PARSER
diff --git a/host/include/llvm/Config/AsmPrinters.def b/host/include/llvm/Config/AsmPrinters.def
new file mode 100644
index 0000000..3cec2c5
--- /dev/null
+++ b/host/include/llvm/Config/AsmPrinters.def
@@ -0,0 +1,29 @@
+//===- llvm/Config/AsmPrinters.def - LLVM Assembly Printers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language printers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PRINTER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly printers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASM_PRINTER
+# error Please define the macro LLVM_ASM_PRINTER(TargetName)
+#endif
+
+LLVM_ASM_PRINTER(X86) LLVM_ASM_PRINTER(X86)
+
+#undef LLVM_ASM_PRINTER
diff --git a/host/include/llvm/Config/Disassemblers.def b/host/include/llvm/Config/Disassemblers.def
new file mode 100644
index 0000000..fdb8499
--- /dev/null
+++ b/host/include/llvm/Config/Disassemblers.def
@@ -0,0 +1,29 @@
+//===- llvm/Config/Disassemblers.def - LLVM Assembly Parsers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language parsers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PARSER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly parsers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DISASSEMBLER
+# error Please define the macro LLVM_DISASSEMBLER(TargetName)
+#endif
+
+LLVM_DISASSEMBLER(X86) LLVM_DISASSEMBLER(X86)
+
+#undef LLVM_DISASSEMBLER
diff --git a/host/include/llvm/Config/Targets.def b/host/include/llvm/Config/Targets.def
new file mode 100644
index 0000000..dbc8dd6
--- /dev/null
+++ b/host/include/llvm/Config/Targets.def
@@ -0,0 +1,28 @@
+/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file enumerates all of the target architectures supported by *|
+|* this build of LLVM. Clients of this file should define the *|
+|* LLVM_TARGET macro to be a function-like macro with a single *|
+|* parameter (the name of the target); including this file will then *|
+|* enumerate all of the targets. *|
+|* *|
+|* The set of targets supported by LLVM is generated at configuration *|
+|* time, at which point this header is generated. Do not modify this *|
+|* header directly. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_TARGET
+# error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+LLVM_TARGET(X86) LLVM_TARGET(X86)
+
+#undef LLVM_TARGET
diff --git a/host/include/llvm/Config/config.h b/host/include/llvm/Config/config.h
new file mode 100644
index 0000000..773ac9a
--- /dev/null
+++ b/host/include/llvm/Config/config.h
@@ -0,0 +1,583 @@
+/* include/llvm/Config/config.h. Generated from config.h.in by configure. */
+/* include/llvm/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */
+
+/* 32 bit multilib directory. */
+#define CXX_INCLUDE_32BIT_DIR ""
+
+/* 64 bit multilib directory. */
+#define CXX_INCLUDE_64BIT_DIR ""
+
+/* Arch the libstdc++ headers. */
+#define CXX_INCLUDE_ARCH ""
+
+/* Directory with the libstdc++ headers. */
+#define CXX_INCLUDE_ROOT ""
+
+/* Directories clang will search for headers */
+#define C_INCLUDE_DIRS ""
+
+/* Define if CBE is enabled for printf %a output */
+#define ENABLE_CBE_PRINTF_A 1
+
+/* Define if position independent code is enabled */
+#define ENABLE_PIC 1
+
+/* Define if threads enabled */
+#define ENABLE_THREADS 1
+
+/* Define to 1 if you have the `argz_append' function. */
+/* #undef HAVE_ARGZ_APPEND */
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+/* #undef HAVE_ARGZ_CREATE_SEP */
+
+/* Define to 1 if you have the <argz.h> header file. */
+/* #undef HAVE_ARGZ_H */
+
+/* Define to 1 if you have the `argz_insert' function. */
+/* #undef HAVE_ARGZ_INSERT */
+
+/* Define to 1 if you have the `argz_next' function. */
+/* #undef HAVE_ARGZ_NEXT */
+
+/* Define to 1 if you have the `argz_stringify' function. */
+/* #undef HAVE_ARGZ_STRINGIFY */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bcopy' function. */
+/* #undef HAVE_BCOPY */
+
+/* Define to 1 if you have the `ceilf' function. */
+#define HAVE_CEILF 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_CIRCO */
+
+/* Define to 1 if you have the `closedir' function. */
+#define HAVE_CLOSEDIR 1
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the GNU dld library. */
+/* #undef HAVE_DLD */
+
+/* Define to 1 if you have the <dld.h> header file. */
+/* #undef HAVE_DLD_H */
+
+/* Define to 1 if you have the `dlerror' function. */
+#define HAVE_DLERROR 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define if dlopen() is available on this platform. */
+#define HAVE_DLOPEN 1
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define if the dot program is available */
+/* #undef HAVE_DOT */
+
+/* Define if the dotty program is available */
+/* #undef HAVE_DOTTY */
+
+/* Define if you have the _dyld_func_lookup function. */
+/* #undef HAVE_DYLD */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if the system has the type `error_t'. */
+/* #undef HAVE_ERROR_T */
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#define HAVE_EXECINFO_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_FDP */
+
+/* Define if libffi is available on this platform. */
+/* #undef HAVE_FFI_CALL */
+
+/* Define to 1 if you have the <ffi/ffi.h> header file. */
+/* #undef HAVE_FFI_FFI_H */
+
+/* Define to 1 if you have the <ffi.h> header file. */
+/* #undef HAVE_FFI_H */
+
+/* Set to 1 if the finite function is found in <ieeefp.h> */
+/* #undef HAVE_FINITE_IN_IEEEFP_H */
+
+/* Define to 1 if you have the `floorf' function. */
+#define HAVE_FLOORF 1
+
+/* Define to 1 if you have the `fmodf' function. */
+#define HAVE_FMODF 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the `getrusage' function. */
+#define HAVE_GETRUSAGE 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if the Graphviz program is available */
+/* #undef HAVE_GRAPHVIZ */
+
+/* Define if the gv program is available */
+/* #undef HAVE_GV */
+
+/* Define to 1 if you have the `index' function. */
+/* #undef HAVE_INDEX */
+
+/* Define to 1 if the system has the type `int64_t'. */
+#define HAVE_INT64_T 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `isatty' function. */
+#define HAVE_ISATTY 1
+
+/* Set to 1 if the isinf function is found in <cmath> */
+/* #undef HAVE_ISINF_IN_CMATH */
+
+/* Set to 1 if the isinf function is found in <math.h> */
+#define HAVE_ISINF_IN_MATH_H 1
+
+/* Set to 1 if the isnan function is found in <cmath> */
+/* #undef HAVE_ISNAN_IN_CMATH */
+
+/* Set to 1 if the isnan function is found in <math.h> */
+#define HAVE_ISNAN_IN_MATH_H 1
+
+/* Define if you have the libdl library or equivalent. */
+#define HAVE_LIBDL 1
+
+/* Define to 1 if you have the `imagehlp' library (-limagehlp). */
+/* #undef HAVE_LIBIMAGEHLP */
+
+/* Define to 1 if you have the `m' library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define to 1 if you have the `psapi' library (-lpsapi). */
+/* #undef HAVE_LIBPSAPI */
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define to 1 if you have the `udis86' library (-ludis86). */
+/* #undef HAVE_LIBUDIS86 */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you can use -Wl,-export-dynamic. */
+/* #undef HAVE_LINK_EXPORT_DYNAMIC */
+
+/* Define to 1 if you have the <link.h> header file. */
+/* #undef HAVE_LINK_H */
+
+/* Define if you can use -Wl,-R. to pass -R. to the linker, in order to add
+ the current directory to the dynamic linker search path. */
+/* #undef HAVE_LINK_R */
+
+/* Define to 1 if you have the `longjmp' function. */
+#define HAVE_LONGJMP 1
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+/* #undef HAVE_MACH_MACH_H */
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+/* #undef HAVE_MACH_O_DYLD_H */
+
+/* Define if mallinfo() is available on this platform. */
+/* #undef HAVE_MALLINFO */
+
+/* Define to 1 if you have the <malloc/malloc.h> header file. */
+/* #undef HAVE_MALLOC_MALLOC_H */
+
+/* Define to 1 if you have the `malloc_zone_statistics' function. */
+/* #undef HAVE_MALLOC_ZONE_STATISTICS */
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkdtemp' function. */
+#define HAVE_MKDTEMP 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the `mktemp' function. */
+#define HAVE_MKTEMP 1
+
+/* Define to 1 if you have a working `mmap' system call. */
+#define HAVE_MMAP 1
+
+/* Define if mmap() uses MAP_ANONYMOUS to map anonymous pages, or undefine if
+ it uses MAP_ANON */
+/* #undef HAVE_MMAP_ANONYMOUS */
+
+/* Define if mmap() can map files into memory */
+#define HAVE_MMAP_FILE
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the `nearbyintf' function. */
+#define HAVE_NEARBYINTF 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_NEATO */
+
+/* Define to 1 if you have the `opendir' function. */
+#define HAVE_OPENDIR 1
+
+/* Define to 1 if you have the `powf' function. */
+#define HAVE_POWF 1
+
+/* Define if libtool can extract symbol lists from object files. */
+#define HAVE_PRELOADED_SYMBOLS 1
+
+/* Define to have the %a format string */
+#define HAVE_PRINTF_A 1
+
+/* Have pthread_getspecific */
+#define HAVE_PTHREAD_GETSPECIFIC 1
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#define HAVE_PTHREAD_H 1
+
+/* Have pthread_mutex_lock */
+#define HAVE_PTHREAD_MUTEX_LOCK 1
+
+/* Have pthread_rwlock_init */
+#define HAVE_PTHREAD_RWLOCK_INIT 1
+
+/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
+#define HAVE_RAND48 1
+
+/* Define to 1 if you have the `readdir' function. */
+#define HAVE_READDIR 1
+
+/* Define to 1 if you have the `realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define to 1 if you have the `rindex' function. */
+/* #undef HAVE_RINDEX */
+
+/* Define to 1 if you have the `rintf' function. */
+#define HAVE_RINTF 1
+
+/* Define to 1 if you have the `round' function. */
+#define HAVE_ROUND 1
+
+/* Define to 1 if you have the `roundf' function. */
+#define HAVE_ROUNDF 1
+
+/* Define to 1 if you have the `sbrk' function. */
+#define HAVE_SBRK 1
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `setjmp' function. */
+#define HAVE_SETJMP 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define if you have the shl_load function. */
+/* #undef HAVE_SHL_LOAD */
+
+/* Define to 1 if you have the `siglongjmp' function. */
+#define HAVE_SIGLONGJMP 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the `sigsetjmp' function. */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Set to 1 if the std::isinf function is found in <cmath> */
+/* #undef HAVE_STD_ISINF_IN_CMATH */
+
+/* Set to 1 if the std::isnan function is found in <cmath> */
+#define HAVE_STD_ISNAN_IN_CMATH 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strcmp' function. */
+#define HAVE_STRCMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `strerror_s' function. */
+/* #undef HAVE_STRERROR_S */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the `strtof' function. */
+#define HAVE_STRTOF 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoq' function. */
+#define HAVE_STRTOQ 1
+
+/* Define to 1 if you have the `sysconf' function. */
+#define HAVE_SYSCONF 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/dl.h> header file. */
+/* #undef HAVE_SYS_DL_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_TWOPI */
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#define HAVE_UINT64_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if the system has the type `u_int64_t'. */
+/* #undef HAVE_U_INT64_T */
+
+/* Define to 1 if you have the <windows.h> header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the `__dso_handle' function. */
+#define HAVE___DSO_HANDLE 1
+
+/* Installation directory for binary executables */
+#define LLVM_BINDIR "/usr/local/google/llvm/bin"
+
+/* Time at which LLVM was configured */
+#define LLVM_CONFIGTIME "Fri Feb 26 12:17:10 CST 2010"
+
+/* Installation directory for data files */
+#define LLVM_DATADIR "/usr/local/google/llvm/share/llvm"
+
+/* Installation directory for documentation */
+#define LLVM_DOCSDIR "/usr/local/google/llvm/docs/llvm"
+
+/* Installation directory for config files */
+#define LLVM_ETCDIR "/usr/local/google/llvm/etc/llvm"
+
+/* Host triple we were built on */
+#define LLVM_HOSTTRIPLE "i386-unknown-linux"
+
+/* Installation directory for include files */
+#define LLVM_INCLUDEDIR "/usr/local/google/llvm/include"
+
+/* Installation directory for .info files */
+#define LLVM_INFODIR "/usr/local/google/llvm/info"
+
+/* Installation directory for libraries */
+#define LLVM_LIBDIR "/usr/local/google/llvm/lib"
+
+/* Installation directory for man pages */
+#define LLVM_MANDIR "/usr/local/google/llvm/man"
+
+/* Build multithreading support into LLVM */
+#define LLVM_MULTITHREADED 0
+
+/* LLVM architecture name for the native architecture, if available */
+#define LLVM_NATIVE_ARCH X86Target
+
+/* Define if this is Unixish platform */
+#define LLVM_ON_UNIX 1
+
+/* Define if this is Win32ish platform */
+/* #undef LLVM_ON_WIN32 */
+
+/* Define to path to circo program if found or 'echo circo' otherwise */
+/* #undef LLVM_PATH_CIRCO */
+
+/* Define to path to dot program if found or 'echo dot' otherwise */
+/* #undef LLVM_PATH_DOT */
+
+/* Define to path to dotty program if found or 'echo dotty' otherwise */
+/* #undef LLVM_PATH_DOTTY */
+
+/* Define to path to fdp program if found or 'echo fdp' otherwise */
+/* #undef LLVM_PATH_FDP */
+
+/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
+/* #undef LLVM_PATH_GRAPHVIZ */
+
+/* Define to path to gv program if found or 'echo gv' otherwise */
+/* #undef LLVM_PATH_GV */
+
+/* Define to path to neato program if found or 'echo neato' otherwise */
+/* #undef LLVM_PATH_NEATO */
+
+/* Define to path to twopi program if found or 'echo twopi' otherwise */
+/* #undef LLVM_PATH_TWOPI */
+
+/* Installation prefix directory */
+#define LLVM_PREFIX "/usr/local/google/llvm"
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+/* #undef LTDL_DLOPEN_DEPLIBS */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LTDL_OBJDIR ".libs/"
+
+/* Define to the name of the environment variable that determines the dynamic
+ library search path. */
+#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH"
+
+/* Define to the extension used for shared libraries, say, ".so". */
+#define LTDL_SHLIB_EXT ".so"
+
+/* Define to the system default library search path. */
+#define LTDL_SYSSEARCHPATH "/lib:/usr/lib:/usr/local/lib:/lib:/usr/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib32:/usr/lib32:/usr/local/lib32:/usr/x86_64-pc-linux-gnu/lib:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/32:/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2:/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/32"
+
+/* Define if /dev/zero should be used when mapping RWX memory, or undefine if
+ its not necessary */
+/* #undef NEED_DEV_ZERO_FOR_MMAP */
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+/* #undef NEED_USCORE */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "llvm"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "llvm 2.7svn"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "-llvm-"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.7svn"
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define if we have the oprofile JIT-support library */
+#define USE_OPROFILE 0
+
+/* Define if use udis86 library */
+#define USE_UDIS86 0
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to a type to use for `error_t' if it is not otherwise available. */
+/* #undef error_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/include/llvm-c/BitReader.h b/include/llvm-c/BitReader.h
index 59269ce..6db6607 100644
--- a/include/llvm-c/BitReader.h
+++ b/include/llvm-c/BitReader.h
@@ -36,18 +36,28 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
LLVMMemoryBufferRef MemBuf,
LLVMModuleRef *OutModule, char **OutMessage);
-/* Reads a module from the specified path, returning via the OutMP parameter
- a module provider which performs lazy deserialization. Returns 0 on success.
- Optionally returns a human-readable error message via OutMessage. */
-LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
- LLVMModuleProviderRef *OutMP,
- char **OutMessage);
+/** Reads a module from the specified path, returning via the OutMP parameter
+ a module provider which performs lazy deserialization. Returns 0 on success.
+ Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutM,
+ char **OutMessage);
+
+LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+ char **OutMessage);
+
+/** Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
LLVMMemoryBufferRef MemBuf,
LLVMModuleProviderRef *OutMP,
char **OutMessage);
+/** Deprecated: Use LLVMGetBitcodeModule instead. */
+LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
+ LLVMModuleProviderRef *OutMP,
+ char **OutMessage);
#ifdef __cplusplus
}
diff --git a/include/llvm-c/BitWriter.h b/include/llvm-c/BitWriter.h
index 008ff9f..bcbfb11 100644
--- a/include/llvm-c/BitWriter.h
+++ b/include/llvm-c/BitWriter.h
@@ -28,13 +28,16 @@ extern "C" {
/*===-- Operations on modules ---------------------------------------------===*/
-/* Writes a module to an open file descriptor. Returns 0 on success.
- Closes the Handle. Use dup first if this is not what you want. */
-int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
-
-/* Writes a module to the specified path. Returns 0 on success. */
+/** Writes a module to the specified path. Returns 0 on success. */
int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path);
+/** Writes a module to an open file descriptor. Returns 0 on success. */
+int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
+ int Unbuffered);
+
+/** Deprecated for LLVMWriteBitcodeToFD. Writes a module to an open file
+ descriptor. Returns 0 on success. Closes the Handle. */
+int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
#ifdef __cplusplus
}
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 98358fe..733b92c 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -92,11 +92,8 @@ typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
/** See the llvm::PassManagerBase class. */
typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
-/**
- * Used to iterate through the uses of a Value, allowing access to all Values
- * that use this Value. See the llvm::Use and llvm::value_use_iterator classes.
- */
-typedef struct LLVMOpaqueUseIterator *LLVMUseIteratorRef;
+/** Used to get the users and usees of a Value. See the llvm::Use class. */
+typedef struct LLVMOpaqueUse *LLVMUseRef;
typedef enum {
LLVMZExtAttribute = 1<<0,
@@ -115,67 +112,81 @@ typedef enum {
LLVMOptimizeForSizeAttribute = 1<<13,
LLVMStackProtectAttribute = 1<<14,
LLVMStackProtectReqAttribute = 1<<15,
+ LLVMAlignment = 31<<16,
LLVMNoCaptureAttribute = 1<<21,
LLVMNoRedZoneAttribute = 1<<22,
LLVMNoImplicitFloatAttribute = 1<<23,
LLVMNakedAttribute = 1<<24,
- LLVMInlineHintAttribute = 1<<25
+ LLVMInlineHintAttribute = 1<<25,
+ LLVMStackAlignment = 7<<26
} LLVMAttribute;
typedef enum {
+ /* Terminator Instructions */
LLVMRet = 1,
LLVMBr = 2,
LLVMSwitch = 3,
- LLVMInvoke = 4,
- LLVMUnwind = 5,
- LLVMUnreachable = 6,
- LLVMAdd = 7,
- LLVMFAdd = 8,
- LLVMSub = 9,
- LLVMFSub = 10,
- LLVMMul = 11,
- LLVMFMul = 12,
- LLVMUDiv = 13,
- LLVMSDiv = 14,
- LLVMFDiv = 15,
- LLVMURem = 16,
- LLVMSRem = 17,
- LLVMFRem = 18,
- LLVMShl = 19,
- LLVMLShr = 20,
- LLVMAShr = 21,
- LLVMAnd = 22,
- LLVMOr = 23,
- LLVMXor = 24,
- LLVMMalloc = 25,
- LLVMFree = 26,
- LLVMAlloca = 27,
- LLVMLoad = 28,
- LLVMStore = 29,
- LLVMGetElementPtr = 30,
- LLVMTrunk = 31,
- LLVMZExt = 32,
- LLVMSExt = 33,
- LLVMFPToUI = 34,
- LLVMFPToSI = 35,
- LLVMUIToFP = 36,
- LLVMSIToFP = 37,
- LLVMFPTrunc = 38,
- LLVMFPExt = 39,
- LLVMPtrToInt = 40,
- LLVMIntToPtr = 41,
- LLVMBitCast = 42,
- LLVMICmp = 43,
- LLVMFCmp = 44,
- LLVMPHI = 45,
- LLVMCall = 46,
- LLVMSelect = 47,
- LLVMVAArg = 50,
- LLVMExtractElement = 51,
- LLVMInsertElement = 52,
- LLVMShuffleVector = 53,
- LLVMExtractValue = 54,
- LLVMInsertValue = 55
+ LLVMIndirectBr = 4,
+ LLVMInvoke = 5,
+ LLVMUnwind = 6,
+ LLVMUnreachable = 7,
+
+ /* Standard Binary Operators */
+ LLVMAdd = 8,
+ LLVMFAdd = 9,
+ LLVMSub = 10,
+ LLVMFSub = 11,
+ LLVMMul = 12,
+ LLVMFMul = 13,
+ LLVMUDiv = 14,
+ LLVMSDiv = 15,
+ LLVMFDiv = 16,
+ LLVMURem = 17,
+ LLVMSRem = 18,
+ LLVMFRem = 19,
+
+ /* Logical Operators */
+ LLVMShl = 20,
+ LLVMLShr = 21,
+ LLVMAShr = 22,
+ LLVMAnd = 23,
+ LLVMOr = 24,
+ LLVMXor = 25,
+
+ /* Memory Operators */
+ LLVMAlloca = 26,
+ LLVMLoad = 27,
+ LLVMStore = 28,
+ LLVMGetElementPtr = 29,
+
+ /* Cast Operators */
+ LLVMTrunc = 30,
+ LLVMZExt = 31,
+ LLVMSExt = 32,
+ LLVMFPToUI = 33,
+ LLVMFPToSI = 34,
+ LLVMUIToFP = 35,
+ LLVMSIToFP = 36,
+ LLVMFPTrunc = 37,
+ LLVMFPExt = 38,
+ LLVMPtrToInt = 39,
+ LLVMIntToPtr = 40,
+ LLVMBitCast = 41,
+
+ /* Other Operators */
+ LLVMICmp = 42,
+ LLVMFCmp = 43,
+ LLVMPHI = 44,
+ LLVMCall = 45,
+ LLVMSelect = 46,
+ /* UserOp1 */
+ /* UserOp2 */
+ LLVMVAArg = 49,
+ LLVMExtractElement = 50,
+ LLVMInsertElement = 51,
+ LLVMShuffleVector = 52,
+ LLVMExtractValue = 53,
+ LLVMInsertValue = 54
} LLVMOpcode;
typedef enum {
@@ -193,7 +204,8 @@ typedef enum {
LLVMPointerTypeKind, /**< Pointers */
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
- LLVMMetadataTypeKind /**< Metadata */
+ LLVMMetadataTypeKind, /**< Metadata */
+ LLVMUnionTypeKind /**< Unions */
} LLVMTypeKind;
typedef enum {
@@ -269,13 +281,19 @@ typedef enum {
void LLVMDisposeMessage(char *Message);
-/*===-- Modules -----------------------------------------------------------===*/
+/*===-- Contexts ----------------------------------------------------------===*/
/* Create and destroy contexts. */
LLVMContextRef LLVMContextCreate(void);
LLVMContextRef LLVMGetGlobalContext(void);
void LLVMContextDispose(LLVMContextRef C);
+unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name,
+ unsigned SLen);
+unsigned LLVMGetMDKindID(const char* Name, unsigned SLen);
+
+/*===-- Modules -----------------------------------------------------------===*/
+
/* Create and destroy modules. */
/** See llvm::Module::Module. */
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
@@ -372,6 +390,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
+/* Operations on union types */
+LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
+ unsigned ElementCount);
+LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount);
+unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy);
+void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest);
+
/* Operations on array, pointer, and vector types (sequence types) */
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
@@ -477,6 +502,9 @@ const char *LLVMGetValueName(LLVMValueRef Val);
void LLVMSetValueName(LLVMValueRef Val, const char *Name);
void LLVMDumpValue(LLVMValueRef Val);
void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal);
+int LLVMHasMetadata(LLVMValueRef Val);
+LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID);
+void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node);
/* Conversion functions. Return the input value if it is an instance of the
specified class, otherwise NULL. See llvm::dyn_cast_or_null<>. */
@@ -485,10 +513,10 @@ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal);
LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST)
/* Operations on Uses */
-LLVMUseIteratorRef LLVMGetFirstUse(LLVMValueRef Val);
-LLVMUseIteratorRef LLVMGetNextUse(LLVMUseIteratorRef U);
-LLVMValueRef LLVMGetUser(LLVMUseIteratorRef U);
-LLVMValueRef LLVMGetUsedValue(LLVMUseIteratorRef U);
+LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val);
+LLVMUseRef LLVMGetNextUse(LLVMUseRef U);
+LLVMValueRef LLVMGetUser(LLVMUseRef U);
+LLVMValueRef LLVMGetUsedValue(LLVMUseRef U);
/* Operations on Users */
LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index);
@@ -502,6 +530,14 @@ LLVMBool LLVMIsNull(LLVMValueRef Val);
LLVMBool LLVMIsUndef(LLVMValueRef Val);
LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty);
+/* Operations on metadata */
+LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
+ unsigned SLen);
+LLVMValueRef LLVMMDString(const char *Str, unsigned SLen);
+LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
+ unsigned Count);
+LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
+
/* Operations on scalar constants */
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
LLVMBool SignExtend);
@@ -531,20 +567,28 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
LLVMBool Packed);
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
+LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val);
/* Constant expressions */
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal);
LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty);
LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty);
LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal);
LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal);
LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal);
LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
@@ -610,6 +654,7 @@ LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty,
const char *AsmString, const char *Constraints,
LLVMBool HasSideEffects, LLVMBool IsAlignStack);
+LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB);
/* Operations on global variables, functions, and aliases (globals) */
LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global);
@@ -625,6 +670,9 @@ void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes);
/* Operations on global variables */
LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
+ const char *Name,
+ unsigned AddressSpace);
LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name);
LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M);
LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M);
@@ -745,6 +793,11 @@ void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr,
const char *Name);
void LLVMDisposeBuilder(LLVMBuilderRef Builder);
+/* Metadata */
+void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L);
+LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder);
+void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst);
+
/* Terminators */
LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef);
LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V);
@@ -755,6 +808,8 @@ LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Else);
LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V,
LLVMBasicBlockRef Else, unsigned NumCases);
+LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
+ unsigned NumDests);
LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
@@ -766,19 +821,32 @@ LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
LLVMBasicBlockRef Dest);
+/* Add a destination to the indirectbr instruction */
+void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
+
/* Arithmetic */
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
+LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
+LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
LLVMValueRef LLVMBuildFSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
+LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
LLVMValueRef LLVMBuildFMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
@@ -807,7 +875,14 @@ LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
+LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op,
+ LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
+ const char *Name);
+LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
+ const char *Name);
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
@@ -866,6 +941,8 @@ LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name);
LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name);
LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/
@@ -947,6 +1024,9 @@ LLVMPassManagerRef LLVMCreatePassManager(void);
provider. It does not take ownership of the module provider. This type of
pipeline is suitable for code generation and JIT compilation tasks.
See llvm::FunctionPassManager::FunctionPassManager. */
+LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M);
+
+/** Deprecated: Use LLVMCreateFunctionPassManagerForModule instead. */
LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP);
/** Initializes, executes on the provided module, and finalizes all of the
@@ -1018,7 +1098,7 @@ namespace llvm {
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseIteratorRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef )
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
/* LLVMModuleProviderRef exists for historical reasons, but now just holds a
* Module.
diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h
index 151c935..5a98a77 100644
--- a/include/llvm-c/ExecutionEngine.h
+++ b/include/llvm-c/ExecutionEngine.h
@@ -55,14 +55,30 @@ void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal);
/*===-- Operations on execution engines -----------------------------------===*/
+LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
+ LLVMModuleRef M,
+ char **OutError);
+
+LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
+ LLVMModuleRef M,
+ char **OutError);
+
+LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
+ LLVMModuleRef M,
+ unsigned OptLevel,
+ char **OutError);
+
+/** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */
LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
LLVMModuleProviderRef MP,
char **OutError);
+/** Deprecated: Use LLVMCreateInterpreterForModule instead. */
LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
LLVMModuleProviderRef MP,
char **OutError);
+/** Deprecated: Use LLVMCreateJITCompilerForModule instead. */
LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
LLVMModuleProviderRef MP,
unsigned OptLevel,
@@ -84,8 +100,15 @@ LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F);
+void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M);
+
+/** Deprecated: Use LLVMAddModule instead. */
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP);
+LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
+ LLVMModuleRef *OutMod, char **OutError);
+
+/** Deprecated: Use LLVMRemoveModule instead. */
LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
LLVMModuleProviderRef MP,
LLVMModuleRef *OutMod, char **OutError);
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index f81109a..3cccc81 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -173,11 +173,16 @@ namespace llvm {
fcZero
};
+ enum uninitializedTag {
+ uninitialized
+ };
+
// Constructors.
APFloat(const fltSemantics &); // Default construct to 0.0
APFloat(const fltSemantics &, const StringRef &);
APFloat(const fltSemantics &, integerPart);
- APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0);
+ APFloat(const fltSemantics &, fltCategory, bool negative);
+ APFloat(const fltSemantics &, uninitializedTag);
explicit APFloat(double d);
explicit APFloat(float f);
explicit APFloat(const APInt &, bool isIEEE = false);
@@ -199,7 +204,26 @@ namespace llvm {
/// default. The value is truncated as necessary.
static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
unsigned type = 0) {
- return APFloat(Sem, fcNaN, Negative, type);
+ if (type) {
+ APInt fill(64, type);
+ return getQNaN(Sem, Negative, &fill);
+ } else {
+ return getQNaN(Sem, Negative, 0);
+ }
+ }
+
+ /// getQNan - Factory for QNaN values.
+ static APFloat getQNaN(const fltSemantics &Sem,
+ bool Negative = false,
+ const APInt *payload = 0) {
+ return makeNaN(Sem, false, Negative, payload);
+ }
+
+ /// getSNan - Factory for SNaN values.
+ static APFloat getSNaN(const fltSemantics &Sem,
+ bool Negative = false,
+ const APInt *payload = 0) {
+ return makeNaN(Sem, true, Negative, payload);
}
/// getLargest - Returns the largest finite number in the given
@@ -320,7 +344,7 @@ namespace llvm {
/// 1.01E-2 4 1 1.01E-2
void toString(SmallVectorImpl<char> &Str,
unsigned FormatPrecision = 0,
- unsigned FormatMaxPadding = 3);
+ unsigned FormatMaxPadding = 3) const;
private:
@@ -350,7 +374,9 @@ namespace llvm {
opStatus modSpecials(const APFloat &);
/* Miscellany. */
- void makeNaN(unsigned = 0);
+ static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
+ const APInt *fill);
+ void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0);
opStatus normalize(roundingMode, lostFraction);
opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
cmpResult compareAbsoluteValue(const APFloat &) const;
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 88aa995..3f67ffb 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -150,7 +150,17 @@ class APInt {
return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
}
+ /// Converts a string into a number. The string must be non-empty
+ /// and well-formed as a number of the given base. The bit-width
+ /// must be sufficient to hold the result.
+ ///
/// This is used by the constructors that take string arguments.
+ ///
+ /// StringRef::getAsInteger is superficially similar but (1) does
+ /// not assume that the string is well-formed and (2) grows the
+ /// result to hold the input.
+ ///
+ /// @param radix 2, 8, 10, or 16
/// @brief Convert a char array into an APInt
void fromString(unsigned numBits, const StringRef &str, uint8_t radix);
@@ -571,6 +581,21 @@ public:
/// @brief Bitwise OR assignment operator.
APInt& operator|=(const APInt& RHS);
+ /// Performs a bitwise OR operation on this APInt and RHS. RHS is
+ /// logically zero-extended or truncated to match the bit-width of
+ /// the LHS.
+ ///
+ /// @brief Bitwise OR assignment operator.
+ APInt& operator|=(uint64_t RHS) {
+ if (isSingleWord()) {
+ VAL |= RHS;
+ clearUnusedBits();
+ } else {
+ pVal[0] |= RHS;
+ }
+ return *this;
+ }
+
/// Performs a bitwise XOR operation on this APInt and RHS. The result is
/// assigned to *this.
/// @returns *this after XORing with RHS.
@@ -1308,6 +1333,9 @@ public:
/// Set the given bit of a bignum. Zero-based.
static void tcSetBit(integerPart *, unsigned int bit);
+ /// Clear the given bit of a bignum. Zero-based.
+ static void tcClearBit(integerPart *, unsigned int bit);
+
/// Returns the bit number of the least or most significant set bit
/// of a number. If the input number has no bits set -1U is
/// returned.
diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h
index 1facfa0..45ba198 100644
--- a/include/llvm/ADT/DeltaAlgorithm.h
+++ b/include/llvm/ADT/DeltaAlgorithm.h
@@ -52,7 +52,7 @@ private:
/// \return - The test result.
bool GetTestResult(const changeset_ty &Changes);
- /// Split - Partition a set of changes \arg Sinto one or two subsets.
+ /// Split - Partition a set of changes \arg S into one or two subsets.
void Split(const changeset_ty &S, changesetlist_ty &Res);
/// Delta - Minimize a set of \arg Changes which has been partioned into
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
index f5f3d49..d9d6f73 100644
--- a/include/llvm/ADT/EquivalenceClasses.h
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -203,7 +203,7 @@ public:
return member_iterator(I->getLeader());
}
member_iterator findLeader(const ElemTy &V) const {
- return findLeader(TheMapping.find(V));
+ return findLeader(TheMapping.find(ECValue(V)));
}
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
index d538295..b5ca374 100644
--- a/include/llvm/ADT/ScopedHashTable.h
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -36,10 +36,10 @@
namespace llvm {
-template <typename K, typename V>
+template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
class ScopedHashTable;
-template <typename K, typename V>
+template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
class ScopedHashTableVal {
ScopedHashTableVal *NextInScope;
ScopedHashTableVal *NextForKey;
@@ -61,35 +61,39 @@ public:
ScopedHashTableVal *getNextInScope() { return NextInScope; }
};
-template <typename K, typename V>
+template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
class ScopedHashTableScope {
/// HT - The hashtable that we are active for.
- ScopedHashTable<K, V> &HT;
+ ScopedHashTable<K, V, KInfo> &HT;
/// PrevScope - This is the scope that we are shadowing in HT.
ScopedHashTableScope *PrevScope;
/// LastValInScope - This is the last value that was inserted for this scope
/// or null if none have been inserted yet.
- ScopedHashTableVal<K,V> *LastValInScope;
+ ScopedHashTableVal<K, V, KInfo> *LastValInScope;
void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
public:
- ScopedHashTableScope(ScopedHashTable<K, V> &HT);
+ ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &HT);
~ScopedHashTableScope();
private:
- friend class ScopedHashTable<K, V>;
- ScopedHashTableVal<K, V> *getLastValInScope() { return LastValInScope; }
- void setLastValInScope(ScopedHashTableVal<K,V> *Val) { LastValInScope = Val; }
+ friend class ScopedHashTable<K, V, KInfo>;
+ ScopedHashTableVal<K, V, KInfo> *getLastValInScope() {
+ return LastValInScope;
+ }
+ void setLastValInScope(ScopedHashTableVal<K, V, KInfo> *Val) {
+ LastValInScope = Val;
+ }
};
-template <typename K, typename V>
+template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
class ScopedHashTableIterator {
- ScopedHashTableVal<K,V> *Node;
+ ScopedHashTableVal<K, V, KInfo> *Node;
public:
- ScopedHashTableIterator(ScopedHashTableVal<K,V> *node) : Node(node){}
+ ScopedHashTableIterator(ScopedHashTableVal<K, V, KInfo> *node) : Node(node) {}
V &operator*() const {
assert(Node && "Dereference end()");
@@ -117,35 +121,43 @@ public:
};
-template <typename K, typename V>
+template <typename K, typename V, typename KInfo>
class ScopedHashTable {
- DenseMap<K, ScopedHashTableVal<K,V>*> TopLevelMap;
- ScopedHashTableScope<K, V> *CurScope;
+ DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo> TopLevelMap;
+ ScopedHashTableScope<K, V, KInfo> *CurScope;
ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED
- friend class ScopedHashTableScope<K, V>;
+ friend class ScopedHashTableScope<K, V, KInfo>;
public:
ScopedHashTable() : CurScope(0) {}
~ScopedHashTable() {
assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
}
+ bool count(const K &Key) const {
+ return TopLevelMap.count(Key);
+ }
+
+ V lookup(const K &Key) {
+ return TopLevelMap[Key]->getValue();
+ }
+
void insert(const K &Key, const V &Val) {
assert(CurScope && "No scope active!");
- ScopedHashTableVal<K,V> *&KeyEntry = TopLevelMap[Key];
+ ScopedHashTableVal<K, V, KInfo> *&KeyEntry = TopLevelMap[Key];
- KeyEntry = new ScopedHashTableVal<K,V>(CurScope->getLastValInScope(),
- KeyEntry, Key, Val);
+ KeyEntry= new ScopedHashTableVal<K, V, KInfo>(CurScope->getLastValInScope(),
+ KeyEntry, Key, Val);
CurScope->setLastValInScope(KeyEntry);
}
- typedef ScopedHashTableIterator<K, V> iterator;
+ typedef ScopedHashTableIterator<K, V, KInfo> iterator;
iterator end() { return iterator(0); }
iterator begin(const K &Key) {
- typename DenseMap<K, ScopedHashTableVal<K,V>*>::iterator I =
+ typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator I =
TopLevelMap.find(Key);
if (I == TopLevelMap.end()) return end();
return iterator(I->second);
@@ -154,28 +166,29 @@ public:
/// ScopedHashTableScope ctor - Install this as the current scope for the hash
/// table.
-template <typename K, typename V>
-ScopedHashTableScope<K, V>::ScopedHashTableScope(ScopedHashTable<K, V> &ht)
- : HT(ht) {
+template <typename K, typename V, typename KInfo>
+ScopedHashTableScope<K, V, KInfo>::
+ ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &ht) : HT(ht) {
PrevScope = HT.CurScope;
HT.CurScope = this;
LastValInScope = 0;
}
-template <typename K, typename V>
-ScopedHashTableScope<K, V>::~ScopedHashTableScope() {
+template <typename K, typename V, typename KInfo>
+ScopedHashTableScope<K, V, KInfo>::~ScopedHashTableScope() {
assert(HT.CurScope == this && "Scope imbalance!");
HT.CurScope = PrevScope;
// Pop and delete all values corresponding to this scope.
- while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) {
+ while (ScopedHashTableVal<K, V, KInfo> *ThisEntry = LastValInScope) {
// Pop this value out of the TopLevelMap.
if (ThisEntry->getNextForKey() == 0) {
assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry &&
"Scope imbalance!");
HT.TopLevelMap.erase(ThisEntry->getKey());
} else {
- ScopedHashTableVal<K,V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()];
+ ScopedHashTableVal<K, V, KInfo> *&KeyEntry =
+ HT.TopLevelMap[ThisEntry->getKey()];
assert(KeyEntry == ThisEntry && "Scope imbalance!");
KeyEntry = ThisEntry->getNextForKey();
}
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index c29fc9f..ef08125 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -225,7 +225,7 @@ struct NextPowerOfTwo {
};
-/// SmallPtrSet - This class implements a set which is optimizer for holding
+/// SmallPtrSet - This class implements a set which is optimized for holding
/// SmallSize or less elements. This internally rounds up SmallSize to the next
/// power of two if it is not already a power of two. See the comments above
/// SmallPtrSetImpl for details of the algorithm.
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index 3064af3..9257770 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -18,6 +18,7 @@
namespace llvm {
template<typename T>
class SmallVectorImpl;
+ class APInt;
/// StringRef - Represent a constant reference to a string, i.e. a character
/// array and a length, which need not be null terminated.
@@ -273,6 +274,19 @@ namespace llvm {
// TODO: Provide overloads for int/unsigned that check for overflow.
+ /// getAsInteger - Parse the current string as an integer of the
+ /// specified radix, or of an autosensed radix if the radix given
+ /// is 0. The current value in Result is discarded, and the
+ /// storage is changed to be wide enough to store the parsed
+ /// integer.
+ ///
+ /// Returns true if the string does not solely consist of a valid
+ /// non-empty number in the appropriate base.
+ ///
+ /// APInt::fromString is superficially similar but assumes the
+ /// string is well-formed in the given radix.
+ bool getAsInteger(unsigned Radix, APInt &Result) const;
+
/// @}
/// @name Substring Operations
/// @{
@@ -355,7 +369,7 @@ namespace llvm {
/// \param A - Where to put the substrings.
/// \param Separator - The string to split on.
/// \param MaxSplit - The maximum number of times the string is split.
- /// \parm KeepEmpty - True if empty substring should be added.
+ /// \param KeepEmpty - True if empty substring should be added.
void split(SmallVectorImpl<StringRef> &A,
StringRef Separator, int MaxSplit = -1,
bool KeepEmpty = true) const;
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 8798b0e..be31ea0 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -73,6 +73,7 @@ public:
x86, // X86: i[3-9]86
x86_64, // X86-64: amd64, x86_64
xcore, // XCore: xcore
+ mblaze, // MBlaze: mblaze
InvalidArch
};
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index ccf0105..f105c20 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -459,9 +459,11 @@ namespace llvm {
if (DbgNode && !isLexicalBlock())
DbgNode = 0;
}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getDirectory() const { return getContext().getDirectory(); }
- StringRef getFilename() const { return getContext().getFilename(); }
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getDirectory() const { return getContext().getDirectory(); }
+ StringRef getFilename() const { return getContext().getFilename(); }
+ unsigned getLineNumber() const { return getUnsignedField(2); }
+ unsigned getColumnNumber() const { return getUnsignedField(3); }
};
/// DINameSpace - A wrapper for a C++ style name space.
@@ -636,7 +638,8 @@ namespace llvm {
/// CreateLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.
- DILexicalBlock CreateLexicalBlock(DIDescriptor Context);
+ DILexicalBlock CreateLexicalBlock(DIDescriptor Context, unsigned Line = 0,
+ unsigned Col = 0);
/// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context.
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index 31c19c4..1e94f30 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -52,7 +52,7 @@ protected:
Roots(), IsPostDominators(isPostDom) {}
public:
- /// getRoots - Return the root blocks of the current CFG. This may include
+ /// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
@@ -225,7 +225,7 @@ protected:
DenseMap<NodeT*, InfoRec> Info;
void reset() {
- for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
+ for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
E = DomTreeNodes.end(); I != E; ++I)
delete I->second;
DomTreeNodes.clear();
@@ -248,7 +248,7 @@ protected:
for (typename GraphTraits<Inverse<N> >::ChildIteratorType PI =
GraphTraits<Inverse<N> >::child_begin(NewBB),
PE = GraphTraits<Inverse<N> >::child_end(NewBB); PI != PE; ++PI)
- PredBlocks.push_back(*PI);
+ PredBlocks.push_back(*PI);
assert(!PredBlocks.empty() && "No predblocks??");
@@ -310,7 +310,7 @@ public:
if (DomTreeNodes.size() != OtherDomTreeNodes.size())
return true;
- for (typename DomTreeNodeMapType::const_iterator
+ for (typename DomTreeNodeMapType::const_iterator
I = this->DomTreeNodes.begin(),
E = this->DomTreeNodes.end(); I != E; ++I) {
NodeT *BB = I->first;
@@ -361,7 +361,7 @@ public:
return properlyDominates(getNode(A), getNode(B));
}
- bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
+ bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const {
const DomTreeNodeBase<NodeT> *IDom;
if (A == 0 || B == 0) return false;
@@ -374,7 +374,7 @@ public:
/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
bool isReachableFromEntry(NodeT* A) {
- assert (!this->isPostDominator()
+ assert (!this->isPostDominator()
&& "This is not implemented for post dominators");
return dominates(&A->getParent()->front(), A);
}
@@ -384,7 +384,7 @@ public:
///
inline bool dominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) {
- if (B == A)
+ if (B == A)
return true; // A node trivially dominates itself.
if (A == 0 || B == 0)
@@ -412,7 +412,7 @@ public:
}
inline bool dominates(const NodeT *A, const NodeT *B) {
- if (A == B)
+ if (A == B)
return true;
// Cast away the const qualifiers here. This is ok since
@@ -431,9 +431,9 @@ public:
/// for basic block A and B. If there is no such block then return NULL.
NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
- assert (!this->isPostDominator()
+ assert (!this->isPostDominator()
&& "This is not implemented for post dominators");
- assert (A->getParent() == B->getParent()
+ assert (A->getParent() == B->getParent()
&& "Two blocks are not in same function");
// If either A or B is a entry block then it is nearest common dominator.
@@ -478,14 +478,14 @@ public:
// the CFG...
/// addNewBlock - Add a new node to the dominator tree information. This
- /// creates a new node as a child of DomBB dominator node,linking it into
+ /// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
assert(getNode(BB) == 0 && "Block already in dominator tree!");
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
assert(IDomNode && "Not immediate dominator specified for block!");
DFSInfoValid = false;
- return DomTreeNodes[BB] =
+ return DomTreeNodes[BB] =
IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
}
@@ -503,7 +503,7 @@ public:
changeImmediateDominator(getNode(BB), getNode(NewBB));
}
- /// eraseNode - Removes a node from the dominator tree. Block must not
+ /// eraseNode - Removes a node from the dominator tree. Block must not
/// domiante any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
void eraseNode(NodeT *BB) {
@@ -708,7 +708,7 @@ public:
DominatorTreeBase<BasicBlock>& getBase() { return *DT; }
- /// getRoots - Return the root blocks of the current CFG. This may include
+ /// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
@@ -785,7 +785,7 @@ public:
}
/// addNewBlock - Add a new node to the dominator tree information. This
- /// creates a new node as a child of DomBB dominator node,linking it into
+ /// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
inline DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) {
return DT->addNewBlock(BB, DomBB);
@@ -802,7 +802,7 @@ public:
DT->changeImmediateDominator(N, NewIDom);
}
- /// eraseNode - Removes a node from the dominator tree. Block must not
+ /// eraseNode - Removes a node from the dominator tree. Block must not
/// domiante any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
inline void eraseNode(BasicBlock *BB) {
@@ -820,7 +820,7 @@ public:
}
- virtual void releaseMemory() {
+ virtual void releaseMemory() {
DT->releaseMemory();
}
@@ -886,10 +886,10 @@ protected:
const bool IsPostDominators;
public:
- DominanceFrontierBase(void *ID, bool isPostDom)
+ DominanceFrontierBase(void *ID, bool isPostDom)
: FunctionPass(ID), IsPostDominators(isPostDom) {}
- /// getRoots - Return the root blocks of the current CFG. This may include
+ /// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
@@ -940,7 +940,7 @@ public:
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
std::set<BasicBlock *> tmpSet;
for (DomSetType::const_iterator I = DS2.begin(),
- E = DS2.end(); I != E; ++I)
+ E = DS2.end(); I != E; ++I)
tmpSet.insert(*I);
for (DomSetType::const_iterator I = DS1.begin(),
@@ -965,14 +965,14 @@ public:
bool compare(DominanceFrontierBase &Other) const {
DomSetMapType tmpFrontiers;
for (DomSetMapType::const_iterator I = Other.begin(),
- E = Other.end(); I != E; ++I)
+ E = Other.end(); I != E; ++I)
tmpFrontiers.insert(std::make_pair(I->first, I->second));
for (DomSetMapType::iterator I = tmpFrontiers.begin(),
E = tmpFrontiers.end(); I != E; ) {
BasicBlock *Node = I->first;
const_iterator DFI = find(Node);
- if (DFI == end())
+ if (DFI == end())
return true;
if (compareDomSet(I->second, DFI->second))
@@ -1001,7 +1001,7 @@ public:
class DominanceFrontier : public DominanceFrontierBase {
public:
static char ID; // Pass ID, replacement for typeid
- DominanceFrontier() :
+ DominanceFrontier() :
DominanceFrontierBase(&ID, false) {}
BasicBlock *getRoot() const {
@@ -1033,7 +1033,7 @@ public:
/// to reflect this change.
void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB,
DominatorTree *DT) {
- // NewBB is now dominating BB. Which means BB's dominance
+ // NewBB is now dominating BB. Which means BB's dominance
// frontier is now part of NewBB's dominance frontier. However, BB
// itself is not member of NewBB's dominance frontier.
DominanceFrontier::iterator NewDFI = find(NewBB);
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index b69bda8..dc616ca 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -16,29 +16,27 @@
#define LLVM_ANALYSIS_IVUSERS_H
#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/ADT/SmallVector.h"
-#include <map>
+#include "llvm/Support/ValueHandle.h"
namespace llvm {
class DominatorTree;
class Instruction;
class Value;
-struct IVUsersOfOneStride;
-
-/// IVStrideUse - Keep track of one use of a strided induction variable, where
-/// the stride is stored externally. The Offset member keeps track of the
-/// offset from the IV, User is the actual user of the operand, and
-/// 'OperandValToReplace' is the operand of the User that is the use.
+class IVUsers;
+class ScalarEvolution;
+class SCEV;
+
+/// IVStrideUse - Keep track of one use of a strided induction variable.
+/// The Expr member keeps track of the expression, User is the actual user
+/// instruction of the operand, and 'OperandValToReplace' is the operand of
+/// the User that is the use.
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
public:
- IVStrideUse(IVUsersOfOneStride *parent,
- const SCEV *offset,
+ IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off,
Instruction* U, Value *O)
- : CallbackVH(U), Parent(parent), Offset(offset),
- OperandValToReplace(O),
- IsUseOfPostIncrementedValue(false) {
+ : CallbackVH(U), Parent(P), Stride(S), Offset(Off),
+ OperandValToReplace(O), IsUseOfPostIncrementedValue(false) {
}
/// getUser - Return the user instruction for this use.
@@ -51,11 +49,19 @@ public:
setValPtr(NewUser);
}
- /// getParent - Return a pointer to the IVUsersOfOneStride that owns
+ /// getParent - Return a pointer to the IVUsers that owns
/// this IVStrideUse.
- IVUsersOfOneStride *getParent() const { return Parent; }
+ IVUsers *getParent() const { return Parent; }
+
+ /// getStride - Return the expression for the stride for the use.
+ const SCEV *getStride() const { return Stride; }
+
+ /// setStride - Assign a new stride to this use.
+ void setStride(const SCEV *Val) {
+ Stride = Val;
+ }
- /// getOffset - Return the offset to add to a theoeretical induction
+ /// getOffset - Return the offset to add to a theoretical induction
/// variable that starts at zero and counts up by the stride to compute
/// the value for the use. This always has the same type as the stride.
const SCEV *getOffset() const { return Offset; }
@@ -92,8 +98,11 @@ public:
}
private:
- /// Parent - a pointer to the IVUsersOfOneStride that owns this IVStrideUse.
- IVUsersOfOneStride *Parent;
+ /// Parent - a pointer to the IVUsers that owns this IVStrideUse.
+ IVUsers *Parent;
+
+ /// Stride - The stride for this use.
+ const SCEV *Stride;
/// Offset - The offset to add to the base induction expression.
const SCEV *Offset;
@@ -107,7 +116,7 @@ private:
bool IsUseOfPostIncrementedValue;
/// Deleted - Implementation of CallbackVH virtual function to
- /// recieve notification when the User is deleted.
+ /// receive notification when the User is deleted.
virtual void deleted();
};
@@ -138,42 +147,8 @@ private:
mutable ilist_node<IVStrideUse> Sentinel;
};
-/// IVUsersOfOneStride - This structure keeps track of all instructions that
-/// have an operand that is based on the trip count multiplied by some stride.
-struct IVUsersOfOneStride : public ilist_node<IVUsersOfOneStride> {
-private:
- IVUsersOfOneStride(const IVUsersOfOneStride &I); // do not implement
- void operator=(const IVUsersOfOneStride &I); // do not implement
-
-public:
- IVUsersOfOneStride() : Stride(0) {}
-
- explicit IVUsersOfOneStride(const SCEV *stride) : Stride(stride) {}
-
- /// Stride - The stride for all the contained IVStrideUses. This is
- /// a constant for affine strides.
- const SCEV *Stride;
-
- /// Users - Keep track of all of the users of this stride as well as the
- /// initial value and the operand that uses the IV.
- ilist<IVStrideUse> Users;
-
- void addUser(const SCEV *Offset, Instruction *User, Value *Operand) {
- Users.push_back(new IVStrideUse(this, Offset, User, Operand));
- }
-
- void removeUser(IVStrideUse *User) {
- Users.erase(User);
- }
-
- void print(raw_ostream &OS) const;
-
- /// dump - This method is used for debugging.
- void dump() const;
-};
-
class IVUsers : public LoopPass {
- friend class IVStrideUserVH;
+ friend class IVStrideUse;
Loop *L;
LoopInfo *LI;
DominatorTree *DT;
@@ -182,19 +157,8 @@ class IVUsers : public LoopPass {
/// IVUses - A list of all tracked IV uses of induction variable expressions
/// we are interested in.
- ilist<IVUsersOfOneStride> IVUses;
-
-public:
- /// IVUsesByStride - A mapping from the strides in StrideOrder to the
- /// uses in IVUses.
- std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride;
+ ilist<IVStrideUse> IVUses;
- /// StrideOrder - An ordering of the keys in IVUsesByStride that is stable:
- /// We use this to iterate over the IVUsesByStride collection without being
- /// dependent on random ordering of pointers in the process.
- SmallVector<const SCEV *, 16> StrideOrder;
-
-private:
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
@@ -210,8 +174,8 @@ public:
/// return true. Otherwise, return false.
bool AddUsersIfInteresting(Instruction *I);
- void AddUser(const SCEV *Stride, const SCEV *Offset,
- Instruction *User, Value *Operand);
+ IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset,
+ Instruction *User, Value *Operand);
/// getReplacementExpr - Return a SCEV expression which computes the
/// value of the OperandValToReplace of the given IVStrideUse.
@@ -222,6 +186,14 @@ public:
/// isUseOfPostIncrementedValue flag.
const SCEV *getCanonicalExpr(const IVStrideUse &U) const;
+ typedef ilist<IVStrideUse>::iterator iterator;
+ typedef ilist<IVStrideUse>::const_iterator const_iterator;
+ iterator begin() { return IVUses.begin(); }
+ iterator end() { return IVUses.end(); }
+ const_iterator begin() const { return IVUses.begin(); }
+ const_iterator end() const { return IVUses.end(); }
+ bool empty() const { return IVUses.empty(); }
+
void print(raw_ostream &OS, const Module* = 0) const;
/// dump - This method is used for debugging.
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index d5e4d51..f792a7f 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -835,7 +835,7 @@ public:
} else if (BlockLoop != Child) {
LoopT *SubLoop = BlockLoop;
// Reparent all of the blocks which used to belong to BlockLoops
- for (unsigned j = 0, e = SubLoop->Blocks.size(); j != e; ++j)
+ for (unsigned j = 0, f = SubLoop->Blocks.size(); j != f; ++j)
ContainingLoops[SubLoop->Blocks[j]] = Child;
// There is already a loop which contains this block, that means
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index f83cc4f..f6aab03 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -249,7 +249,7 @@ namespace llvm {
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
ReverseDepMapType ReverseLocalDeps;
- // A reverse mapping form dependencies to the non-local dependees.
+ // A reverse mapping from dependencies to the non-local dependees.
ReverseDepMapType ReverseNonLocalDeps;
/// Current AA implementation, just a cache.
@@ -312,6 +312,11 @@ namespace llvm {
/// value and replaces the other value with ptr. This can make Ptr available
/// in more places that cached info does not necessarily keep.
void invalidateCachedPointerInfo(Value *Ptr);
+
+ /// invalidateCachedPredecessors - Clear the PredIteratorCache info.
+ /// This needs to be done when the CFG changes, e.g., due to splitting
+ /// critical edges.
+ void invalidateCachedPredecessors();
private:
MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
index b612316..033efba 100644
--- a/include/llvm/Analysis/PHITransAddr.h
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -66,9 +66,11 @@ public:
bool IsPotentiallyPHITranslatable() const;
/// PHITranslateValue - PHI translate the current address up the CFG from
- /// CurBB to Pred, updating our state the reflect any needed changes. This
- /// returns true on failure and sets Addr to null.
- bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB);
+ /// CurBB to Pred, updating our state to reflect any needed changes. If the
+ /// dominator tree DT is non-null, the translated value must dominate
+ /// PredBB. This returns true on failure and sets Addr to null.
+ bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
+ const DominatorTree *DT);
/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
@@ -88,14 +90,8 @@ public:
/// returns false.
bool Verify() const;
private:
- Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB);
-
-
- /// GetAvailablePHITranslatedSubExpr - Return the value computed by
- /// PHITranslateSubExpr if it dominates PredBB, otherwise return null.
- Value *GetAvailablePHITranslatedSubExpr(Value *V,
- BasicBlock *CurBB, BasicBlock *PredBB,
- const DominatorTree &DT) const;
+ Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB,
+ const DominatorTree *DT);
/// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index 2f39c6a..1a5cbb2 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -81,13 +81,6 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
- // createAndersensPass - This pass implements Andersen's interprocedural alias
- // analysis.
- //
- ModulePass *createAndersensPass();
-
- //===--------------------------------------------------------------------===//
- //
// createProfileLoaderPass - This pass loads information from a profile dump
// file.
//
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
index 3681cc0..5552017 100644
--- a/include/llvm/Analysis/PostDominators.h
+++ b/include/llvm/Analysis/PostDominators.h
@@ -69,6 +69,10 @@ struct PostDominatorTree : public FunctionPass {
return DT->properlyDominates(A, B);
}
+ inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
+ return DT->findNearestCommonDominator(A, B);
+ }
+
virtual void releaseMemory() {
DT->releaseMemory();
}
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 383ee88..96d29ba 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// The ScalarEvolution class is an LLVM pass which can be used to analyze and
-// catagorize scalar expressions in loops. It specializes in recognizing
+// categorize scalar expressions in loops. It specializes in recognizing
// general induction variables, representing them with the abstract and opaque
// SCEV class. Given this analysis, trip counts of loops and other important
// properties can be obtained.
@@ -55,7 +55,7 @@ namespace llvm {
protected:
/// SubclassData - This field is initialized to zero and may be used in
- /// subclasses to store miscelaneous information.
+ /// subclasses to store miscellaneous information.
unsigned short SubclassData;
private:
@@ -177,7 +177,7 @@ namespace llvm {
///
LoopInfo *LI;
- /// TD - The target data information for the target we are targetting.
+ /// TD - The target data information for the target we are targeting.
///
TargetData *TD;
@@ -194,7 +194,7 @@ namespace llvm {
std::map<SCEVCallbackVH, const SCEV *> Scalars;
/// BackedgeTakenInfo - Information about the backedge-taken count
- /// of a loop. This currently inclues an exact count and a maximum count.
+ /// of a loop. This currently includes an exact count and a maximum count.
///
struct BackedgeTakenInfo {
/// Exact - An expression indicating the exact backedge-taken count of
@@ -305,7 +305,7 @@ namespace llvm {
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition
/// of 'icmp op load X, cst', try to see if we can compute the
/// backedge-taken count.
- const SCEV *
+ BackedgeTakenInfo
ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI,
Constant *RHS,
const Loop *L,
@@ -323,12 +323,12 @@ namespace llvm {
/// HowFarToZero - Return the number of times a backedge comparing the
/// specified value to zero will execute. If not computable, return
/// CouldNotCompute.
- const SCEV *HowFarToZero(const SCEV *V, const Loop *L);
+ BackedgeTakenInfo HowFarToZero(const SCEV *V, const Loop *L);
/// HowFarToNonZero - Return the number of times a backedge checking the
/// specified value for nonzero will execute. If not computable, return
/// CouldNotCompute.
- const SCEV *HowFarToNonZero(const SCEV *V, const Loop *L);
+ BackedgeTakenInfo HowFarToNonZero(const SCEV *V, const Loop *L);
/// HowManyLessThans - Return the number of times a backedge containing the
/// specified less-than comparison will execute. If not computable, return
@@ -353,14 +353,14 @@ namespace llvm {
bool Inverse);
/// isImpliedCondOperands - Test whether the condition described by Pred,
- /// LHS, and RHS is true whenever the condition desribed by Pred, FoundLHS,
+ /// LHS, and RHS is true whenever the condition described by Pred, FoundLHS,
/// and FoundRHS is true.
bool isImpliedCondOperands(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
const SCEV *FoundLHS, const SCEV *FoundRHS);
/// isImpliedCondOperandsHelper - Test whether the condition described by
- /// Pred, LHS, and RHS is true whenever the condition desribed by Pred,
+ /// Pred, LHS, and RHS is true whenever the condition described by Pred,
/// FoundLHS, and FoundRHS is true.
bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
@@ -586,6 +586,11 @@ namespace llvm {
/// compute a trip count, or if the loop is deleted.
void forgetLoop(const Loop *L);
+ /// forgetValue - This method should be called by the client when it has
+ /// changed a value in a way that may effect its value, or which may
+ /// disconnect it from a def-use chain linking it to a loop.
+ void forgetValue(Value *V);
+
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S
/// is guaranteed to end in (at every loop iteration). It is, at the same
/// time, the minimum number of times S is divisible by 2. For example,
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 796b168..26dc0c4 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -27,10 +27,7 @@ namespace llvm {
/// and destroy it when finished to allow the release of the associated
/// memory.
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
- public:
ScalarEvolution &SE;
-
- private:
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
InsertedExpressions;
std::set<Value*> InsertedValues;
@@ -57,11 +54,11 @@ namespace llvm {
/// 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)
@@ -171,9 +168,9 @@ namespace llvm {
return S->getValue();
}
- void rememberInstruction(Value *I) {
- if (!PostIncLoop) InsertedValues.insert(I);
- }
+ void rememberInstruction(Value *I);
+
+ void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 3645a5b..0ab3b3f 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -417,6 +417,10 @@ namespace llvm {
virtual bool isLoopInvariant(const Loop *QueryLoop) const;
+ bool dominates(BasicBlock *BB, DominatorTree *DT) const;
+
+ bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
+
/// isAffine - Return true if this is an affine AddRec (i.e., it represents
/// an expressions A+B*x where A and B are loop invariant values.
bool isAffine() const {
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index 7c673c3..0791b7b 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -124,6 +124,10 @@ namespace llvm {
/// character is included in the result string.
bool GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset = 0,
bool StopAtNul = true);
+
+ /// GetStringLength - If we can compute the length of the string pointed to by
+ /// the specified pointer, return 'len+1'. If we can't, return 0.
+ uint64_t GetStringLength(Value *V);
} // end namespace llvm
#endif
diff --git a/include/llvm/Assembly/AsmAnnotationWriter.h b/include/llvm/Assembly/AsmAnnotationWriter.h
index 6c3ddaf..6d75720 100644
--- a/include/llvm/Assembly/AsmAnnotationWriter.h
+++ b/include/llvm/Assembly/AsmAnnotationWriter.h
@@ -23,29 +23,34 @@ class Function;
class BasicBlock;
class Instruction;
class raw_ostream;
+class formatted_raw_ostream;
class AssemblyAnnotationWriter {
public:
virtual ~AssemblyAnnotationWriter();
- // emitFunctionAnnot - This may be implemented to emit a string right before
- // the start of a function.
+ /// emitFunctionAnnot - This may be implemented to emit a string right before
+ /// the start of a function.
virtual void emitFunctionAnnot(const Function *F, raw_ostream &OS) {}
- // emitBasicBlockStartAnnot - This may be implemented to emit a string right
- // after the basic block label, but before the first instruction in the block.
+ /// emitBasicBlockStartAnnot - This may be implemented to emit a string right
+ /// after the basic block label, but before the first instruction in the block.
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, raw_ostream &OS){
}
- // emitBasicBlockEndAnnot - This may be implemented to emit a string right
- // after the basic block.
+ /// emitBasicBlockEndAnnot - This may be implemented to emit a string right
+ /// after the basic block.
virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, raw_ostream &OS){
}
- // emitInstructionAnnot - This may be implemented to emit a string right
- // before an instruction is emitted.
+ /// emitInstructionAnnot - This may be implemented to emit a string right
+ /// before an instruction is emitted.
virtual void emitInstructionAnnot(const Instruction *I, raw_ostream &OS) {}
+
+ /// printInfoComment - This may be implemented to emit a comment to the
+ /// right of an instruction or global value.
+ virtual void printInfoComment(const Value &V, formatted_raw_ostream &OS) {}
};
} // End llvm namespace
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index 068f81f..1296d67 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -60,6 +60,11 @@ const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
const Attributes Naked = 1<<24; ///< Naked function
const Attributes InlineHint = 1<<25; ///< source said inlining was
///desirable
+const Attributes StackAlignment = 7<<26; ///< Alignment of stack for
+ ///function (3 bits) stored as log2
+ ///of alignment with +1 bias
+ ///0 means unaligned (different from
+ ///alignstack(1))
/// @brief Attributes that only apply to function parameters.
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
@@ -68,7 +73,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 | InlineHint | StackAlignment;
/// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet;
@@ -105,6 +110,28 @@ inline unsigned getAlignmentFromAttrs(Attributes A) {
return 1U << ((Align >> 16) - 1);
}
+/// This turns an int stack alignment (which must be a power of 2) into
+/// the form used internally in Attributes.
+inline Attributes constructStackAlignmentFromInt(unsigned i) {
+ // Default alignment, allow the target to define how to align it.
+ if (i == 0)
+ return 0;
+
+ assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+ assert(i <= 0x100 && "Alignment too large.");
+ return (Log2_32(i)+1) << 26;
+}
+
+/// This returns the stack alignment field of an attribute as a byte alignment
+/// value.
+inline unsigned getStackAlignmentFromAttrs(Attributes A) {
+ Attributes StackAlign = A & Attribute::StackAlignment;
+ if (StackAlign == 0)
+ return 0;
+
+ return 1U << ((StackAlign >> 26) - 1);
+}
+
/// The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 9bb50d4..a980df8 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -94,7 +94,8 @@ namespace bitc {
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
- TYPE_CODE_METADATA = 16 // METADATA
+ TYPE_CODE_METADATA = 16, // METADATA
+ TYPE_CODE_UNION = 17 // UNION: [eltty x N]
};
// The type symbol table only has one code (TST_ENTRY_CODE).
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 3c4dcb5..8ade1bd 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -223,7 +223,7 @@ namespace llvm {
void EmitFunctionBody();
/// EmitInstruction - Targets should implement this to emit instructions.
- virtual void EmitInstruction(const MachineInstr *MI) {
+ virtual void EmitInstruction(const MachineInstr *) {
assert(0 && "EmitInstruction not implemented");
}
@@ -308,7 +308,7 @@ namespace llvm {
/// GetGlobalValueSymbol - Return the MCSymbol for the specified global
/// value.
- MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
+ virtual 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
@@ -356,6 +356,11 @@ namespace llvm {
/// printOffset - This is just convenient handler for printing offsets.
void printOffset(int64_t Offset) const;
+ /// isBlockOnlyReachableByFallthough - Return true if the basic block has
+ /// exactly one predecessor and the control transfer mechanism between
+ /// the predecessor and this block is a fall-through.
+ virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
+
private:
/// processDebugLoc - Processes the debug information of each machine
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h
deleted file mode 100644
index 4d50879..0000000
--- a/include/llvm/CodeGen/DAGISelHeader.h
+++ /dev/null
@@ -1,135 +0,0 @@
-//==-llvm/CodeGen/DAGISelHeader.h - Common DAG ISel definitions -*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides definitions of the common, target-independent methods and
-// data, which is used by SelectionDAG-based instruction selectors.
-//
-// *** NOTE: This file is #included into the middle of the target
-// instruction selector class. These functions are really methods.
-// This is a little awkward, but it allows this code to be shared
-// by all the targets while still being able to call into
-// target-specific code without using a virtual function call.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_DAGISEL_HEADER_H
-#define LLVM_CODEGEN_DAGISEL_HEADER_H
-
-/// ISelPosition - Node iterator marking the current position of
-/// instruction selection as it procedes through the topologically-sorted
-/// node list.
-SelectionDAG::allnodes_iterator ISelPosition;
-
-/// IsChainCompatible - Returns true if Chain is Op or Chain does
-/// not reach Op.
-static bool IsChainCompatible(SDNode *Chain, SDNode *Op) {
- if (Chain->getOpcode() == ISD::EntryToken)
- return true;
- if (Chain->getOpcode() == ISD::TokenFactor)
- return false;
- if (Chain->getNumOperands() > 0) {
- SDValue C0 = Chain->getOperand(0);
- if (C0.getValueType() == MVT::Other)
- return C0.getNode() != Op && IsChainCompatible(C0.getNode(), Op);
- }
- return true;
-}
-
-/// ISelUpdater - helper class to handle updates of the
-/// instruciton selection graph.
-class VISIBILITY_HIDDEN ISelUpdater : public SelectionDAG::DAGUpdateListener {
- SelectionDAG::allnodes_iterator &ISelPosition;
-public:
- explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
- : ISelPosition(isp) {}
-
- /// NodeDeleted - Handle nodes deleted from the graph. If the
- /// node being deleted is the current ISelPosition node, update
- /// ISelPosition.
- ///
- virtual void NodeDeleted(SDNode *N, SDNode *E) {
- if (ISelPosition == SelectionDAG::allnodes_iterator(N))
- ++ISelPosition;
- }
-
- /// NodeUpdated - Ignore updates for now.
- virtual void NodeUpdated(SDNode *N) {}
-};
-
-/// ReplaceUses - replace all uses of the old node F with the use
-/// of the new node T.
-DISABLE_INLINE void ReplaceUses(SDValue F, SDValue T) {
- ISelUpdater ISU(ISelPosition);
- CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
-}
-
-/// ReplaceUses - replace all uses of the old nodes F with the use
-/// of the new nodes T.
-DISABLE_INLINE void ReplaceUses(const SDValue *F, const SDValue *T,
- unsigned Num) {
- ISelUpdater ISU(ISelPosition);
- CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
-}
-
-/// ReplaceUses - replace all uses of the old node F with the use
-/// of the new node T.
-DISABLE_INLINE void ReplaceUses(SDNode *F, SDNode *T) {
- ISelUpdater ISU(ISelPosition);
- CurDAG->ReplaceAllUsesWith(F, T, &ISU);
-}
-
-/// SelectRoot - Top level entry to DAG instruction selector.
-/// Selects instructions starting at the root of the current DAG.
-void SelectRoot(SelectionDAG &DAG) {
- SelectRootInit();
-
- // Create a dummy node (which is not added to allnodes), that adds
- // a reference to the root node, preventing it from being deleted,
- // and tracking any changes of the root.
- HandleSDNode Dummy(CurDAG->getRoot());
- ISelPosition = llvm::next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()));
-
- // The AllNodes list is now topological-sorted. Visit the
- // nodes by starting at the end of the list (the root of the
- // graph) and preceding back toward the beginning (the entry
- // node).
- while (ISelPosition != CurDAG->allnodes_begin()) {
- SDNode *Node = --ISelPosition;
- // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes,
- // but there are currently some corner cases that it misses. Also, this
- // makes it theoretically possible to disable the DAGCombiner.
- if (Node->use_empty())
- continue;
-#if 0
- DAG.setSubgraphColor(Node, "red");
-#endif
- SDNode *ResNode = Select(Node);
- // If node should not be replaced, continue with the next one.
- if (ResNode == Node)
- continue;
- // Replace node.
- if (ResNode) {
-#if 0
- DAG.setSubgraphColor(ResNode, "yellow");
- DAG.setSubgraphColor(ResNode, "black");
-#endif
- ReplaceUses(Node, ResNode);
- }
- // If after the replacement this node is not used any more,
- // remove this dead node.
- if (Node->use_empty()) { // Don't delete EntryToken, etc.
- ISelUpdater ISU(ISelPosition);
- CurDAG->RemoveDeadNode(Node, &ISU);
- }
- }
-
- CurDAG->setRoot(Dummy.getValue());
-}
-
-#endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index 525ce47..0a1d4f4 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -146,7 +146,7 @@ public:
}
}
- /// emitAlignment - Move the CurBufferPtr pointer up the specified
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
/// alignment (saturated to BufferEnd of course).
void emitAlignment(unsigned Alignment) {
if (Alignment == 0) Alignment = 1;
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 3d6c9bc..eb5901c 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -320,7 +320,7 @@ namespace llvm {
/// advanceTo - Advance the specified iterator to point to the LiveRange
/// containing the specified position, or end() if the position is past the
/// end of the interval. If no LiveRange contains this position, but the
- /// position is in a hole, this method returns an iterator pointing the
+ /// position is in a hole, this method returns an iterator pointing to the
/// LiveRange immediately after the hole.
iterator advanceTo(iterator I, SlotIndex Pos) {
if (Pos >= endIndex())
@@ -569,6 +569,16 @@ namespace llvm {
///
unsigned getSize() const;
+ /// isSpillable - Can this interval be spilled?
+ bool isSpillable() const {
+ return weight != HUGE_VALF;
+ }
+
+ /// markNotSpillable - Mark interval as not spillable
+ void markNotSpillable() {
+ weight = HUGE_VALF;
+ }
+
/// ComputeJoinedWeight - Set the weight of a live interval after
/// Other has been merged into it.
void ComputeJoinedWeight(const LiveInterval &Other);
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index d7ff8da..e8856ac 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -70,8 +70,15 @@ namespace llvm {
static char ID; // Pass identification, replacement for typeid
LiveIntervals() : MachineFunctionPass(&ID) {}
- static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) {
- return (isDef + isUse) * powf(10.0F, (float)loopDepth);
+ // Calculate the spill weight to assign to a single instruction.
+ static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
+
+ // After summing the spill weights of all defs and uses, the final weight
+ // should be normalized, dividing the weight of the interval by its size.
+ // This encourages spilling of intervals that are large and have few uses,
+ // and discourages spilling of small intervals with many uses.
+ void normalizeSpillWeight(LiveInterval &li) {
+ li.weight /= getApproximateInstructionCount(li) + 25;
}
typedef Reg2IntervalMap::iterator iterator;
@@ -409,6 +416,9 @@ namespace llvm {
DenseMap<unsigned,unsigned> &MBBVRegsMap,
std::vector<LiveInterval*> &NewLIs);
+ // Normalize the spill weight of all the intervals in NewLIs.
+ void normalizeSpillWeights(std::vector<LiveInterval*> &NewLIs);
+
static LiveInterval* createInterval(unsigned Reg);
void printInstrs(raw_ostream &O) const;
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
index a7bf600..fc5ea6f 100644
--- a/include/llvm/CodeGen/LiveVariables.h
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -124,6 +124,11 @@ private:
///
std::vector<VarInfo> VirtRegInfo;
+ /// PHIJoins - list of virtual registers that are PHI joins. These registers
+ /// may have multiple definitions, and they require special handling when
+ /// building live intervals.
+ SparseBitVector<> PHIJoins;
+
/// ReservedRegisters - This vector keeps track of which registers
/// are reserved register which are not allocatable by the target machine.
/// We can not track liveness for values that are in this set.
@@ -295,6 +300,12 @@ public:
void addNewBlock(MachineBasicBlock *BB,
MachineBasicBlock *DomBB,
MachineBasicBlock *SuccBB);
+
+ /// isPHIJoin - Return true if Reg is a phi join register.
+ bool isPHIJoin(unsigned Reg) { return PHIJoins.test(Reg); }
+
+ /// setPHIJoin - Mark Reg as a phi join register.
+ void setPHIJoin(unsigned Reg) { PHIJoins.set(Reg); }
};
} // End llvm namespace
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index db82ba5..d92650b 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -285,11 +285,6 @@ public:
/// it returns end()
iterator getFirstTerminator();
- /// isOnlyReachableViaFallthough - Return true if this basic block has
- /// exactly one predecessor and the control transfer mechanism between
- /// the predecessor and this block is a fall-through.
- bool isOnlyReachableByFallthrough() const;
-
void pop_front() { Insts.pop_front(); }
void pop_back() { Insts.pop_back(); }
void push_back(MachineInstr *MI) { Insts.push_back(MI); }
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
index 115aecc..48b4082 100644
--- a/include/llvm/CodeGen/MachineCodeEmitter.h
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -155,7 +155,7 @@ public:
}
}
- /// emitAlignment - Move the CurBufferPtr pointer up the specified
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
/// alignment (saturated to BufferEnd of course).
void emitAlignment(unsigned Alignment) {
if (Alignment == 0) Alignment = 1;
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 968e4ea..043e97f 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -276,6 +276,7 @@ public:
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
+ MaxAlignment = std::max(MaxAlignment, Align);
}
/// getObjectOffset - Return the assigned stack offset of the specified object
@@ -328,19 +329,6 @@ public:
///
void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
- /// calculateMaxStackAlignment() - If there is a local object which requires
- /// greater alignment than the current max alignment, adjust accordingly.
- void calculateMaxStackAlignment() {
- for (int i = getObjectIndexBegin(),
- e = getObjectIndexEnd(); i != e; ++i) {
- if (isDeadObjectIndex(i))
- continue;
-
- unsigned Align = getObjectAlignment(i);
- MaxAlignment = std::max(MaxAlignment, Align);
- }
- }
-
/// hasCalls - Return true if the current function has no function calls.
/// This is only valid during or after prolog/epilog code emission.
///
@@ -402,6 +390,7 @@ public:
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS));
int Index = (int)Objects.size()-NumFixedObjects-1;
assert(Index >= 0 && "Bad frame index!");
+ MaxAlignment = std::max(MaxAlignment, Alignment);
return Index;
}
@@ -412,6 +401,7 @@ public:
int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
CreateStackObject(Size, Alignment, true);
int Index = (int)Objects.size()-NumFixedObjects-1;
+ MaxAlignment = std::max(MaxAlignment, Alignment);
return Index;
}
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 6e33fb3..d84f882 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -179,17 +179,16 @@ public:
return MemRefsEnd - MemRefs == 1;
}
+ enum MICheckType {
+ CheckDefs, // Check all operands for equality
+ IgnoreDefs, // Ignore all definitions
+ IgnoreVRegDefs // Ignore virtual register definitions
+ };
+
/// isIdenticalTo - Return true if this instruction is identical to (same
/// opcode and same operands as) the specified instruction.
- bool isIdenticalTo(const MachineInstr *Other) const {
- if (Other->getOpcode() != getOpcode() ||
- Other->getNumOperands() != getNumOperands())
- return false;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (!getOperand(i).isIdenticalTo(Other->getOperand(i)))
- return false;
- return true;
- }
+ bool isIdenticalTo(const MachineInstr *Other,
+ MICheckType Check = CheckDefs) const;
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, and returns it, but does not delete it.
@@ -331,13 +330,13 @@ public:
/// isSafeToMove - Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between
/// the instruction's location and its intended destination.
- bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore,
- AliasAnalysis *AA) const;
+ bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA,
+ bool &SawStore) const;
/// isSafeToReMat - Return true if it's safe to rematerialize the specified
/// instruction which defined the specified register instead of copying it.
- bool isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg,
- AliasAnalysis *AA) const;
+ bool isSafeToReMat(const TargetInstrInfo *TII, AliasAnalysis *AA,
+ unsigned DstReg) const;
/// hasVolatileMemoryRef - Return true if this instruction may have a
/// volatile memory reference, or if the information describing the
@@ -420,6 +419,30 @@ private:
void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo);
};
+/// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare
+/// MachineInstr* by *value* of the instruction rather than by pointer value.
+/// The hashing and equality testing functions ignore definitions so this is
+/// useful for CSE, etc.
+struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> {
+ static inline MachineInstr *getEmptyKey() {
+ return 0;
+ }
+
+ static inline MachineInstr *getTombstoneKey() {
+ return reinterpret_cast<MachineInstr*>(-1);
+ }
+
+ static unsigned getHashValue(const MachineInstr* const &MI);
+
+ static bool isEqual(const MachineInstr* const &LHS,
+ const MachineInstr* const &RHS) {
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
+ LHS == getEmptyKey() || LHS == getTombstoneKey())
+ return LHS == RHS;
+ return LHS->isIdenticalTo(RHS, MachineInstr::IgnoreVRegDefs);
+ }
+};
+
//===----------------------------------------------------------------------===//
// Debugging Support
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index a263a97..47f7cf7 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -127,7 +127,7 @@ public:
return *this;
}
- const MachineInstrBuilder &addMetadata(MDNode *MD) const {
+ const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
MI->addOperand(MachineOperand::CreateMetadata(MD));
return *this;
}
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
index 5dee199..7272aa5 100644
--- a/include/llvm/CodeGen/MachineMemOperand.h
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -46,7 +46,11 @@ public:
/// The memory access writes data.
MOStore = 2,
/// The memory access is volatile.
- MOVolatile = 4
+ MOVolatile = 4,
+ /// The memory access is non-temporal.
+ MONonTemporal = 8,
+ // This is the number of bits we need to represent flags.
+ MOMaxBits = 4
};
/// MachineMemOperand - Construct an MachineMemOperand object with the
@@ -64,7 +68,7 @@ public:
const Value *getValue() const { return V; }
/// getFlags - Return the raw flags of the source value, \see MemOperandFlags.
- unsigned int getFlags() const { return Flags & 7; }
+ unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); }
/// getOffset - For normal values, this is a byte offset added to the base
/// address. For PseudoSourceValue::FPRel values, this is the FrameIndex
@@ -80,11 +84,12 @@ public:
/// getBaseAlignment - Return the minimum known alignment in bytes of the
/// base address, without the offset.
- uint64_t getBaseAlignment() const { return (1u << (Flags >> 3)) >> 1; }
+ uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; }
bool isLoad() const { return Flags & MOLoad; }
bool isStore() const { return Flags & MOStore; }
bool isVolatile() const { return Flags & MOVolatile; }
+ bool isNonTemporal() const { return Flags & MONonTemporal; }
/// refineAlignment - Update this MachineMemOperand to reflect the alignment
/// of MMO, if it has a greater alignment. This must only be used when the
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 556ba7f..8eeac9f 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -50,6 +50,7 @@ namespace llvm {
//===----------------------------------------------------------------------===//
// Forward declarations.
class Constant;
+class MCSymbol;
class MDNode;
class GlobalVariable;
class MachineBasicBlock;
@@ -66,6 +67,12 @@ class StructType;
class MachineModuleInfoImpl {
public:
virtual ~MachineModuleInfoImpl();
+
+ typedef std::vector<std::pair<MCSymbol*, MCSymbol*> >
+ SymbolListTy;
+protected:
+ static SymbolListTy
+ GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map);
};
diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 6679990..89b8207 100644
--- a/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -19,7 +19,7 @@
namespace llvm {
class MCSymbol;
-
+
/// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation
/// for MachO targets.
class MachineModuleInfoMachO : public MachineModuleInfoImpl {
@@ -54,10 +54,8 @@ namespace llvm {
assert(Sym && "Key cannot be null");
return HiddenGVStubs[Sym];
}
-
+
/// Accessor methods to return the set of stubs in sorted order.
- typedef std::vector<std::pair<MCSymbol*, MCSymbol*> > SymbolListTy;
-
SymbolListTy GetFnStubList() const {
return GetSortedStubs(FnStubs);
}
@@ -67,12 +65,31 @@ namespace llvm {
SymbolListTy GetHiddenGVStubList() const {
return GetSortedStubs(HiddenGVStubs);
}
-
- private:
- static SymbolListTy
- GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map);
};
-
+
+ /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
+ /// for ELF targets.
+ class MachineModuleInfoELF : public MachineModuleInfoImpl {
+ /// GVStubs - These stubs are used to materialize global addresses in PIC
+ /// mode.
+ DenseMap<MCSymbol*, MCSymbol*> GVStubs;
+
+ virtual void Anchor(); // Out of line virtual method.
+ public:
+ MachineModuleInfoELF(const MachineModuleInfo &) {}
+
+ MCSymbol *&getGVStubEntry(MCSymbol *Sym) {
+ assert(Sym && "Key cannot be null");
+ return GVStubs[Sym];
+ }
+
+ /// Accessor methods to return the set of stubs in sorted order.
+
+ SymbolListTy GetGVStubList() const {
+ return GetSortedStubs(GVStubs);
+ }
+ };
+
} // end namespace llvm
#endif
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 0bb6d7d..0978057 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -19,14 +19,14 @@
namespace llvm {
-class ConstantFP;
class BlockAddress;
-class MachineBasicBlock;
+class ConstantFP;
class GlobalValue;
+class MachineBasicBlock;
class MachineInstr;
-class TargetMachine;
class MachineRegisterInfo;
class MDNode;
+class TargetMachine;
class raw_ostream;
/// MachineOperand class - Representation of each machine instruction operand.
@@ -100,7 +100,7 @@ private:
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
const ConstantFP *CFP; // For MO_FPImmediate.
int64_t ImmVal; // For MO_Immediate.
- MDNode *MD; // For MO_Metadata.
+ const MDNode *MD; // For MO_Metadata.
struct { // For MO_Register.
unsigned RegNo;
@@ -220,7 +220,6 @@ public:
bool isDebug() const {
assert(isReg() && "Wrong MachineOperand accessor");
- assert(!isDef() && "Wrong MachineOperand accessor");
return IsDebug;
}
@@ -468,7 +467,7 @@ public:
Op.setTargetFlags(TargetFlags);
return Op;
}
- static MachineOperand CreateMetadata(MDNode *Meta) {
+ static MachineOperand CreateMetadata(const MDNode *Meta) {
MachineOperand Op(MachineOperand::MO_Metadata);
Op.Contents.MD = Meta;
return Op;
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 01dc018..f2e5e10 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -115,6 +115,10 @@ public:
/// register.
bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
+ /// hasOneUse - Return true if there is exactly one instruction using the
+ /// specified register.
+ bool hasOneUse(unsigned RegNo) const;
+
/// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
/// specified register, skipping those marked as Debug.
typedef defusechain_iterator<true,false,true> use_nodbg_iterator;
@@ -129,6 +133,10 @@ public:
return use_nodbg_begin(RegNo) == use_nodbg_end();
}
+ /// hasOneNonDBGUse - Return true if there is exactly one non-Debug
+ /// instruction using the specified register.
+ bool hasOneNonDBGUse(unsigned RegNo) const;
+
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
/// except that it also changes any definitions of the register as well.
diff --git a/include/llvm/CodeGen/ObjectCodeEmitter.h b/include/llvm/CodeGen/ObjectCodeEmitter.h
index 3caa747..170c0c8 100644
--- a/include/llvm/CodeGen/ObjectCodeEmitter.h
+++ b/include/llvm/CodeGen/ObjectCodeEmitter.h
@@ -81,7 +81,7 @@ public:
/// written to the data stream in big-endian format.
void emitDWordBE(uint64_t W);
- /// emitAlignment - Move the CurBufferPtr pointer up the specified
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
/// alignment (saturated to BufferEnd of course).
void emitAlignment(unsigned Alignment = 0, uint8_t fill = 0);
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 7e0da3f..911be22 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -162,6 +162,10 @@ namespace llvm {
///
FunctionPass *createGCInfoPrinter(raw_ostream &OS);
+ /// createMachineCSEPass - This pass performs global CSE on machine
+ /// instructions.
+ FunctionPass *createMachineCSEPass();
+
/// createMachineLICMPass - This pass performs LICM on machine instructions.
///
FunctionPass *createMachineLICMPass();
@@ -174,6 +178,10 @@ namespace llvm {
/// optimization by increasing uses of extended values.
FunctionPass *createOptimizeExtsPass();
+ /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs
+ /// to take advantage of opportunities created during DAG legalization.
+ FunctionPass *createOptimizePHIsPass();
+
/// createStackSlotColoringPass - This pass performs stack slot coloring.
FunctionPass *createStackSlotColoringPass(bool);
@@ -183,7 +191,7 @@ namespace llvm {
/// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness.
///
- /// @param allowPhysDoubleDefs ignore double definitions of
+ /// @param allowDoubleDefs ignore double definitions of
/// registers. Useful before LiveVariables has run.
FunctionPass *createMachineVerifierPass(bool allowDoubleDefs);
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 60014f8..ad01e89 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -581,18 +581,18 @@ public:
/// determined by their operands, and they produce a value AND a token chain.
///
SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
- const Value *SV, int SVOffset, bool isVolatile=false,
- unsigned Alignment=0);
+ const Value *SV, int SVOffset, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment);
SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
- SDValue Chain, SDValue Ptr, const Value *SV,
- int SVOffset, EVT MemVT, bool isVolatile=false,
- unsigned Alignment=0);
+ SDValue Chain, SDValue Ptr, const Value *SV,
+ int SVOffset, EVT MemVT, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment);
SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
SDValue Offset, ISD::MemIndexedMode AM);
SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
const Value *SV, int SVOffset, EVT MemVT,
- bool isVolatile=false, unsigned Alignment=0);
+ bool isVolatile, bool isNonTemporal, unsigned Alignment);
SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
EVT MemVT, MachineMemOperand *MMO);
@@ -600,13 +600,14 @@ public:
/// getStore - Helper function to build ISD::STORE nodes.
///
SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
- const Value *SV, int SVOffset, bool isVolatile=false,
- unsigned Alignment=0);
+ const Value *SV, int SVOffset, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment);
SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
MachineMemOperand *MMO);
SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
- const Value *SV, int SVOffset, EVT TVT,
- bool isVolatile=false, unsigned Alignment=0);
+ const Value *SV, int SVOffset, EVT TVT,
+ bool isNonTemporal, bool isVolatile,
+ unsigned Alignment);
SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
EVT TVT, MachineMemOperand *MMO);
SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base,
@@ -667,27 +668,8 @@ public:
SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs,
const SDValue *Ops, unsigned NumOps);
- /// MorphNodeTo - These *mutate* the specified node to have the specified
+ /// MorphNodeTo - This *mutates* the specified node to have the specified
/// return type, opcode, and operands.
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT, SDValue Op1);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT,
- SDValue Op1, SDValue Op2);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT,
- SDValue Op1, SDValue Op2, SDValue Op3);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT,
- const SDValue *Ops, unsigned NumOps);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, EVT VT2);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
- EVT VT2, const SDValue *Ops, unsigned NumOps);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
- EVT VT2, EVT VT3, const SDValue *Ops, unsigned NumOps);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
- EVT VT2, SDValue Op1);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
- EVT VT2, SDValue Op1, SDValue Op2);
- SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
- EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs,
const SDValue *Ops, unsigned NumOps);
@@ -897,6 +879,15 @@ public:
/// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
bool isKnownNeverNaN(SDValue Op) const;
+ /// isKnownNeverZero - Test whether the given SDValue is known to never be
+ /// positive or negative Zero.
+ bool isKnownNeverZero(SDValue Op) const;
+
+ /// isEqualTo - Test whether two SDValues are known to compare equal. This
+ /// is true if they are the same value, or if one is negative zero and the
+ /// other positive zero.
+ bool isEqualTo(SDValue A, SDValue B) const;
+
/// isVerifiedDebugInfoDesc - Returns true if the specified SDValue has
/// been verified as a debug information descriptor.
bool isVerifiedDebugInfoDesc(SDValue Op) const;
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index b33b21d..d9c1374 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -68,12 +68,18 @@ public:
unsigned MakeReg(EVT VT);
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {}
- virtual void InstructionSelect() = 0;
- void SelectRootInit() {
- DAGSize = CurDAG->AssignTopologicalOrder();
- }
-
+ /// PreprocessISelDAG - This hook allows targets to hack on the graph before
+ /// instruction selection starts.
+ virtual void PreprocessISelDAG() {}
+
+ /// PostprocessISelDAG() - This hook allows the target to hack on the graph
+ /// right after selection.
+ virtual void PostprocessISelDAG() {}
+
+ /// Select - Main hook targets implement to select a node.
+ virtual SDNode *Select(SDNode *N) = 0;
+
/// SelectInlineAsmMemoryOperand - Select the specified address as a target
/// addressing mode, according to the specified constraint code. If this does
/// not match or is not implemented, return true. The resultant operands
@@ -85,39 +91,197 @@ public:
return true;
}
- /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
- /// U can be folded during instruction selection that starts at Root and
- /// folding N is profitable.
- virtual
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const;
+ /// IsProfitableToFold - Returns true if it's profitable to fold the specific
+ /// operand node N of U during instruction selection that starts at Root.
+ virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+ /// IsLegalToFold - Returns true if the specific operand node N of
+ /// U can be folded during instruction selection that starts at Root.
+ bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
+ bool IgnoreChains = false) const;
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
/// to use for this target when scheduling the DAG.
virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer();
+
+ // Opcodes used by the DAG state machine:
+ enum BuiltinOpcodes {
+ OPC_Scope,
+ OPC_RecordNode,
+ OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
+ OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7,
+ OPC_RecordMemRef,
+ OPC_CaptureFlagInput,
+ OPC_MoveChild,
+ OPC_MoveParent,
+ OPC_CheckSame,
+ OPC_CheckPatternPredicate,
+ OPC_CheckPredicate,
+ OPC_CheckOpcode,
+ OPC_SwitchOpcode,
+ OPC_CheckType,
+ OPC_SwitchType,
+ OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
+ OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
+ OPC_CheckChild6Type, OPC_CheckChild7Type,
+ OPC_CheckInteger,
+ OPC_CheckCondCode,
+ OPC_CheckValueType,
+ OPC_CheckComplexPat,
+ OPC_CheckAndImm, OPC_CheckOrImm,
+ OPC_CheckFoldableChainNode,
+
+ OPC_EmitInteger,
+ OPC_EmitRegister,
+ OPC_EmitConvertToTarget,
+ OPC_EmitMergeInputChains,
+ OPC_EmitCopyToReg,
+ OPC_EmitNodeXForm,
+ OPC_EmitNode,
+ OPC_MorphNodeTo,
+ OPC_MarkFlagResults,
+ OPC_CompleteMatch
+ };
+
+ enum {
+ OPFL_None = 0, // Node has no chain or flag input and isn't variadic.
+ OPFL_Chain = 1, // Node has a chain input.
+ OPFL_FlagInput = 2, // Node has a flag input.
+ OPFL_FlagOutput = 4, // Node has a flag output.
+ OPFL_MemRefs = 8, // Node gets accumulated MemRefs.
+ OPFL_Variadic0 = 1<<4, // Node is variadic, root has 0 fixed inputs.
+ OPFL_Variadic1 = 2<<4, // Node is variadic, root has 1 fixed inputs.
+ OPFL_Variadic2 = 3<<4, // Node is variadic, root has 2 fixed inputs.
+ OPFL_Variadic3 = 4<<4, // Node is variadic, root has 3 fixed inputs.
+ OPFL_Variadic4 = 5<<4, // Node is variadic, root has 4 fixed inputs.
+ OPFL_Variadic5 = 6<<4, // Node is variadic, root has 5 fixed inputs.
+ OPFL_Variadic6 = 7<<4, // Node is variadic, root has 6 fixed inputs.
+
+ OPFL_VariadicInfo = OPFL_Variadic6
+ };
+
+ /// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
+ /// number of fixed arity values that should be skipped when copying from the
+ /// root.
+ static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
+ return ((Flags&OPFL_VariadicInfo) >> 4)-1;
+ }
+
+
protected:
/// DAGSize - Size of DAG being instruction selected.
///
unsigned DAGSize;
+
+ /// ISelPosition - Node iterator marking the current position of
+ /// instruction selection as it procedes through the topologically-sorted
+ /// node list.
+ SelectionDAG::allnodes_iterator ISelPosition;
+
+
+ /// ISelUpdater - helper class to handle updates of the
+ /// instruction selection graph.
+ class ISelUpdater : public SelectionDAG::DAGUpdateListener {
+ SelectionDAG::allnodes_iterator &ISelPosition;
+ public:
+ explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
+ : ISelPosition(isp) {}
+
+ /// NodeDeleted - Handle nodes deleted from the graph. If the
+ /// node being deleted is the current ISelPosition node, update
+ /// ISelPosition.
+ ///
+ virtual void NodeDeleted(SDNode *N, SDNode *E) {
+ if (ISelPosition == SelectionDAG::allnodes_iterator(N))
+ ++ISelPosition;
+ }
+
+ /// NodeUpdated - Ignore updates for now.
+ virtual void NodeUpdated(SDNode *N) {}
+ };
+
+ /// ReplaceUses - replace all uses of the old node F with the use
+ /// of the new node T.
+ void ReplaceUses(SDValue F, SDValue T) {
+ ISelUpdater ISU(ISelPosition);
+ CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
+ }
+
+ /// ReplaceUses - replace all uses of the old nodes F with the use
+ /// of the new nodes T.
+ void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) {
+ ISelUpdater ISU(ISelPosition);
+ CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
+ }
+
+ /// ReplaceUses - replace all uses of the old node F with the use
+ /// of the new node T.
+ void ReplaceUses(SDNode *F, SDNode *T) {
+ ISelUpdater ISU(ISelPosition);
+ CurDAG->ReplaceAllUsesWith(F, T, &ISU);
+ }
+
/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
/// by tblgen. Others should not call it.
void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops);
+
+public:
// Calls to these predicates are generated by tblgen.
bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
int64_t DesiredMaskS) const;
bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
int64_t DesiredMaskS) const;
+
+ /// CheckPatternPredicate - This function is generated by tblgen in the
+ /// target. It runs the specified pattern predicate and returns true if it
+ /// succeeds or false if it fails. The number is a private implementation
+ /// detail to the code tblgen produces.
+ virtual bool CheckPatternPredicate(unsigned PredNo) const {
+ assert(0 && "Tblgen should generate the implementation of this!");
+ return 0;
+ }
+
+ /// CheckNodePredicate - This function is generated by tblgen in the target.
+ /// It runs node predicate number PredNo and returns true if it succeeds or
+ /// false if it fails. The number is a private implementation
+ /// detail to the code tblgen produces.
+ virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {
+ assert(0 && "Tblgen should generate the implementation of this!");
+ return 0;
+ }
+
+ virtual bool CheckComplexPattern(SDNode *Root, SDValue N, unsigned PatternNo,
+ SmallVectorImpl<SDValue> &Result) {
+ assert(0 && "Tblgen should generate the implementation of this!");
+ return false;
+ }
+
+ virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {
+ assert(0 && "Tblgen shoudl generate this!");
+ return SDValue();
+ }
+
+ SDNode *SelectCodeCommon(SDNode *NodeToMatch,
+ const unsigned char *MatcherTable,
+ unsigned TableSize);
+
+private:
+
// Calls to these functions are generated by tblgen.
SDNode *Select_INLINEASM(SDNode *N);
SDNode *Select_UNDEF(SDNode *N);
SDNode *Select_EH_LABEL(SDNode *N);
void CannotYetSelect(SDNode *N);
- void CannotYetSelectIntrinsic(SDNode *N);
private:
+ void DoInstructionSelection();
+ SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo);
+
void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
MachineModuleInfo *MMI,
DwarfWriter *DW,
@@ -143,6 +307,16 @@ private:
/// one preferred by the target.
///
ScheduleDAGSDNodes *CreateScheduler();
+
+ /// OpcodeOffset - This is a cache used to dispatch efficiently into isel
+ /// state machines that start with a OPC_SwitchOpcode node.
+ std::vector<unsigned> OpcodeOffset;
+
+ void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
+ const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+ SDValue InputFlag,const SmallVectorImpl<SDNode*> &F,
+ bool isMorphNodeTo);
+
};
}
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 45a9d40..21a0b98 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -609,7 +609,7 @@ namespace ISD {
/// which do not reference a specific memory location should be less than
/// this value. Those that do must not be less than this value, and can
/// be used with SelectionDAG::getMemIntrinsicNode.
- static const int FIRST_TARGET_MEMORY_OPCODE = 1 << 14;
+ static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+80;
/// Node predicates
@@ -821,6 +821,8 @@ public:
/// set the SDNode
void setNode(SDNode *N) { Node = N; }
+ inline SDNode *operator->() const { return Node; }
+
bool operator==(const SDValue &O) const {
return Node == O.Node && ResNo == O.ResNo;
}
@@ -1025,11 +1027,15 @@ private:
/// then they will be delete[]'d when the node is destroyed.
uint16_t OperandsNeedDelete : 1;
+ /// HasDebugValue - This tracks whether this node has one or more dbg_value
+ /// nodes corresponding to it.
+ uint16_t HasDebugValue : 1;
+
protected:
/// SubclassData - This member is defined by this class, but is not used for
/// anything. Subclasses can use it to hold whatever state they find useful.
/// This field is initialized to zero by the ctor.
- uint16_t SubclassData : 15;
+ uint16_t SubclassData : 14;
private:
/// NodeId - Unique id per SDNode in the DAG.
@@ -1092,6 +1098,12 @@ public:
return ~NodeType;
}
+ /// getHasDebugValue - get this bit.
+ bool getHasDebugValue() const { return HasDebugValue; }
+
+ /// setHasDebugValue - set this bit.
+ void setHasDebugValue(bool b) { HasDebugValue = b; }
+
/// use_empty - Return true if there are no uses of this node.
///
bool use_empty() const { return UseList == NULL; }
@@ -1355,8 +1367,8 @@ protected:
SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops,
unsigned NumOps)
- : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
- NodeId(-1),
+ : NodeType(Opc), OperandsNeedDelete(true), HasDebugValue(false),
+ SubclassData(0), NodeId(-1),
OperandList(NumOps ? new SDUse[NumOps] : 0),
ValueList(VTs.VTs), UseList(NULL),
NumOperands(NumOps), NumValues(VTs.NumVTs),
@@ -1593,7 +1605,10 @@ public:
return SubclassData;
}
+ // We access subclass data here so that we can check consistency
+ // with MachineMemOperand information.
bool isVolatile() const { return (SubclassData >> 5) & 1; }
+ bool isNonTemporal() const { return (SubclassData >> 6) & 1; }
/// Returns the SrcValue and offset that describes the location of the access
const Value *getSrcValue() const { return MMO->getValue(); }
@@ -1759,7 +1774,12 @@ public:
bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
int getSplatIndex() const {
assert(isSplat() && "Cannot get splat index for non-splat!");
- return Mask[0];
+ EVT VT = getValueType(0);
+ for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
+ if (Mask[i] != -1)
+ return Mask[i];
+ }
+ return -1;
}
static bool isSplatMask(const int *Mask, EVT VT);
@@ -1805,6 +1825,12 @@ public:
const APFloat& getValueAPF() const { return Value->getValueAPF(); }
const ConstantFP *getConstantFPValue() const { return Value; }
+ /// isZero - Return true if the value is positive or negative zero.
+ bool isZero() const { return Value->isZero(); }
+
+ /// isNaN - Return true if the value is a NaN.
+ bool isNaN() const { return Value->isNaN(); }
+
/// isExactlyValue - We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
new file mode 100644
index 0000000..3d99fa7
--- /dev/null
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -0,0 +1,207 @@
+//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object Info -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+
+namespace llvm {
+ class MachineModuleInfo;
+ class Mangler;
+ class MCAsmInfo;
+ class MCExpr;
+ class MCSection;
+ class MCSectionMachO;
+ class MCSymbol;
+ class MCContext;
+ class GlobalValue;
+ class TargetMachine;
+
+
+class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
+ mutable void *UniquingMap;
+protected:
+ /// TLSDataSection - Section directive for Thread Local data.
+ ///
+ const MCSection *TLSDataSection; // Defaults to ".tdata".
+
+ /// TLSBSSSection - Section directive for Thread Local uninitialized data.
+ /// Null if this target doesn't support a BSS section.
+ ///
+ const MCSection *TLSBSSSection; // Defaults to ".tbss".
+
+ const MCSection *DataRelSection;
+ const MCSection *DataRelLocalSection;
+ const MCSection *DataRelROSection;
+ const MCSection *DataRelROLocalSection;
+
+ const MCSection *MergeableConst4Section;
+ const MCSection *MergeableConst8Section;
+ const MCSection *MergeableConst16Section;
+
+protected:
+ const MCSection *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind Kind,
+ bool IsExplicit = false) const;
+public:
+ TargetLoweringObjectFileELF() : UniquingMap(0) {}
+ ~TargetLoweringObjectFileELF();
+
+ virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+ const MCSection *getDataRelSection() const { return DataRelSection; }
+
+ /// getSectionForConstant - Given a constant with the SectionKind, return a
+ /// section that it should be placed in.
+ virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference
+ /// to the specified global variable from exception handling information.
+ ///
+ virtual const MCExpr *
+ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const;
+};
+
+
+
+class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
+ mutable void *UniquingMap;
+
+ const MCSection *CStringSection;
+ const MCSection *UStringSection;
+ const MCSection *TextCoalSection;
+ const MCSection *ConstTextCoalSection;
+ const MCSection *ConstDataCoalSection;
+ const MCSection *ConstDataSection;
+ const MCSection *DataCoalSection;
+ const MCSection *DataCommonSection;
+ const MCSection *DataBSSSection;
+ const MCSection *FourByteConstantSection;
+ const MCSection *EightByteConstantSection;
+ const MCSection *SixteenByteConstantSection;
+
+ const MCSection *LazySymbolPointerSection;
+ const MCSection *NonLazySymbolPointerSection;
+public:
+ TargetLoweringObjectFileMachO() : UniquingMap(0) {}
+ ~TargetLoweringObjectFileMachO();
+
+ virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+
+ /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
+ /// decide not to emit the UsedDirective for some symbols in llvm.used.
+ /// FIXME: REMOVE this (rdar://7071300)
+ virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
+ Mangler *) const;
+
+ /// getMachOSection - Return the MCSection for the specified mach-o section.
+ /// This requires the operands to be valid.
+ const MCSectionMachO *getMachOSection(StringRef Segment,
+ StringRef Section,
+ unsigned TypeAndAttributes,
+ SectionKind K) const {
+ return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
+ }
+ const MCSectionMachO *getMachOSection(StringRef Segment,
+ StringRef Section,
+ unsigned TypeAndAttributes,
+ unsigned Reserved2,
+ SectionKind K) const;
+
+ /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak
+ /// text symbols into.
+ const MCSection *getTextCoalSection() const {
+ return TextCoalSection;
+ }
+
+ /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section
+ /// we put weak read-only symbols into.
+ const MCSection *getConstTextCoalSection() const {
+ return ConstTextCoalSection;
+ }
+
+ /// getLazySymbolPointerSection - Return the section corresponding to
+ /// the .lazy_symbol_pointer directive.
+ const MCSection *getLazySymbolPointerSection() const {
+ return LazySymbolPointerSection;
+ }
+
+ /// getNonLazySymbolPointerSection - Return the section corresponding to
+ /// the .non_lazy_symbol_pointer directive.
+ const MCSection *getNonLazySymbolPointerSection() const {
+ return NonLazySymbolPointerSection;
+ }
+
+ /// getSymbolForDwarfGlobalReference - The mach-o version of this method
+ /// defaults to returning a stub reference.
+ virtual const MCExpr *
+ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const;
+
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
+};
+
+
+
+class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
+ mutable void *UniquingMap;
+public:
+ TargetLoweringObjectFileCOFF() : UniquingMap(0) {}
+ ~TargetLoweringObjectFileCOFF();
+
+ virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ /// getCOFFSection - Return the MCSection for the specified COFF section.
+ /// FIXME: Switch this to a semantic view eventually.
+ const MCSection *getCOFFSection(StringRef Name, bool isDirective,
+ SectionKind K) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td
index 9c3e861..31a627d 100644
--- a/include/llvm/CompilerDriver/Common.td
+++ b/include/llvm/CompilerDriver/Common.td
@@ -20,9 +20,12 @@ class Tool<list<dag> l> {
def in_language;
def out_language;
def output_suffix;
-def cmd_line;
+def command;
+def out_file_option;
+def in_file_option;
def join;
def sink;
+def works_on_empty;
def actions;
// Possible option types.
@@ -42,10 +45,12 @@ def hidden;
def init;
def multi_val;
def one_or_more;
+def zero_or_more;
def optional;
def really_hidden;
def required;
def comma_separated;
+def forward_not_split;
// The 'case' construct.
def case;
@@ -81,6 +86,7 @@ def forward_as;
def forward_value;
def forward_transformed_value;
def stop_compilation;
+def no_out_file;
def unpack_values;
def warning;
def error;
diff --git a/include/llvm/CompilerDriver/Main.inc b/include/llvm/CompilerDriver/Main.inc
index fc8b503..71bb8cb 100644
--- a/include/llvm/CompilerDriver/Main.inc
+++ b/include/llvm/CompilerDriver/Main.inc
@@ -10,7 +10,7 @@
// This tool provides a single point of access to the LLVM
// compilation tools. It has many options. To discover the options
// supported please refer to the tools' manual page or run the tool
-// with the --help option.
+// with the -help option.
//
// This file provides the default entry point for the driver executable.
//
diff --git a/include/llvm/CompilerDriver/Tool.h b/include/llvm/CompilerDriver/Tool.h
index a982e2d..85d1690 100644
--- a/include/llvm/CompilerDriver/Tool.h
+++ b/include/llvm/CompilerDriver/Tool.h
@@ -20,15 +20,19 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/System/Path.h"
+#include <string>
#include <vector>
+#include <utility>
namespace llvmc {
class LanguageMap;
+ typedef std::vector<std::pair<unsigned, std::string> > ArgsVector;
typedef std::vector<llvm::sys::Path> PathVector;
+ typedef std::vector<std::string> StrVector;
typedef llvm::StringSet<> InputLanguagesSet;
- /// Tool - A class
+ /// Tool - Represents a single tool.
class Tool : public llvm::RefCountedBaseVPTR<Tool> {
public:
@@ -51,6 +55,7 @@ namespace llvmc {
virtual const char* OutputLanguage() const = 0;
virtual bool IsJoin() const = 0;
+ virtual bool WorksOnEmpty() const = 0;
protected:
/// OutFileName - Generate the output file name.
@@ -58,6 +63,8 @@ namespace llvmc {
const llvm::sys::Path& TempDir,
bool StopCompilation,
const char* OutputSuffix) const;
+
+ StrVector SortArgs(ArgsVector& Args) const;
};
/// JoinTool - A Tool that has an associated input file list.
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index ff1be05..1cebb20 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -33,6 +33,7 @@ namespace llvm {
class ArrayType;
class IntegerType;
class StructType;
+class UnionType;
class PointerType;
class VectorType;
@@ -275,6 +276,12 @@ public:
return Val.isZero() && Val.isNegative();
}
+ /// isZero - Return true if the value is positive or negative zero.
+ bool isZero() const { return Val.isZero(); }
+
+ /// isNaN - Return true if the value is a NaN.
+ bool isNaN() const { return Val.isNaN(); }
+
/// isExactlyValue - We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
@@ -453,6 +460,50 @@ struct OperandTraits<ConstantStruct> : public VariadicOperandTraits<> {
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant)
//===----------------------------------------------------------------------===//
+// ConstantUnion - Constant Union Declarations
+//
+class ConstantUnion : public Constant {
+ friend struct ConstantCreator<ConstantUnion, UnionType, Constant*>;
+ ConstantUnion(const ConstantUnion &); // DO NOT IMPLEMENT
+protected:
+ ConstantUnion(const UnionType *T, Constant* Val);
+public:
+ // ConstantUnion accessors
+ static Constant *get(const UnionType *T, Constant* V);
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+ /// getType() specialization - Reduce amount of casting...
+ ///
+ inline const UnionType *getType() const {
+ return reinterpret_cast<const UnionType*>(Value::getType());
+ }
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue. This always returns false because zero structs are always
+ /// created as ConstantAggregateZero objects.
+ virtual bool isNullValue() const {
+ return false;
+ }
+
+ virtual void destroyConstant();
+ virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantUnion *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantUnionVal;
+ }
+};
+
+template <>
+struct OperandTraits<ConstantUnion> : public FixedNumOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantUnion, Constant)
+
+//===----------------------------------------------------------------------===//
/// ConstantVector - Constant Vector Declarations
///
class ConstantVector : public Constant {
@@ -647,8 +698,9 @@ public:
/// independent way (Note: the return type is an i64).
static Constant *getAlignOf(const Type* Ty);
- /// getSizeOf constant expr - computes the size of a type in a target
- /// independent way (Note: the return type is an i64).
+ /// getSizeOf constant expr - computes the (alloc) size of a type (in
+ /// address-units, not bits) in a target independent way (Note: the return
+ /// type is an i64).
///
static Constant *getSizeOf(const Type* Ty);
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index c220608..912bb6d 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -27,6 +27,7 @@ template<class ValType, class TypeClass> class TypeMap;
class FunctionValType;
class ArrayValType;
class StructValType;
+class UnionValType;
class PointerValType;
class VectorValType;
class IntegerValType;
@@ -229,7 +230,8 @@ public:
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID ||
T->getTypeID() == PointerTyID ||
- T->getTypeID() == VectorTyID;
+ T->getTypeID() == VectorTyID ||
+ T->getTypeID() == UnionTyID;
}
};
@@ -301,6 +303,63 @@ public:
};
+/// UnionType - Class to represent union types. A union type is similar to
+/// a structure, except that all member fields begin at offset 0.
+///
+class UnionType : public CompositeType {
+ friend class TypeMap<UnionValType, UnionType>;
+ UnionType(const UnionType &); // Do not implement
+ const UnionType &operator=(const UnionType &); // Do not implement
+ UnionType(LLVMContext &C, const Type* const* Types, unsigned NumTypes);
+public:
+ /// UnionType::get - This static method is the primary way to create a
+ /// UnionType.
+ static UnionType *get(const Type* const* Types, unsigned NumTypes);
+
+ /// UnionType::get - This static method is a convenience method for
+ /// creating union types by specifying the elements as arguments.
+ static UnionType *get(const Type *type, ...) END_WITH_NULL;
+
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
+ /// Given an element type, return the member index of that type, or -1
+ /// if there is no such member type.
+ int getElementTypeIndex(const Type *ElemTy) const;
+
+ // Iterator access to the elements
+ typedef Type::subtype_iterator element_iterator;
+ element_iterator element_begin() const { return ContainedTys; }
+ element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
+
+ // Random access to the elements
+ unsigned getNumElements() const { return NumContainedTys; }
+ const Type *getElementType(unsigned N) const {
+ assert(N < NumContainedTys && "Element number out of range!");
+ return ContainedTys[N];
+ }
+
+ /// getTypeAtIndex - Given an index value into the type, return the type of
+ /// the element. For a union type, this must be a constant value...
+ ///
+ virtual const Type *getTypeAtIndex(const Value *V) const;
+ virtual const Type *getTypeAtIndex(unsigned Idx) const;
+ virtual bool indexValid(const Value *V) const;
+ virtual bool indexValid(unsigned Idx) const;
+
+ // Implement the AbstractTypeUser interface.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const UnionType *) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == UnionTyID;
+ }
+};
+
+
/// SequentialType - This is the superclass of the array, pointer and vector
/// type classes. All of these represent "arrays" in memory. The array type
/// represents a specifically sized array, pointer types are unsized/unknown
@@ -496,6 +555,7 @@ public:
/// OpaqueType - Class to represent abstract types
///
class OpaqueType : public DerivedType {
+ friend class LLVMContextImpl;
OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT
const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT
OpaqueType(LLVMContext &C);
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
index c15b555..658967d 100644
--- a/include/llvm/GlobalValue.h
+++ b/include/llvm/GlobalValue.h
@@ -110,36 +110,51 @@ public:
return ODR ? WeakODRLinkage : WeakAnyLinkage;
}
- bool hasExternalLinkage() const { return Linkage == ExternalLinkage; }
- bool hasAvailableExternallyLinkage() const {
+ static bool isExternalLinkage(LinkageTypes Linkage) {
+ return Linkage == ExternalLinkage;
+ }
+ static bool isAvailableExternallyLinkage(LinkageTypes Linkage) {
return Linkage == AvailableExternallyLinkage;
}
- bool hasLinkOnceLinkage() const {
+ static bool isLinkOnceLinkage(LinkageTypes Linkage) {
return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage;
}
- bool hasWeakLinkage() const {
+ static bool isWeakLinkage(LinkageTypes Linkage) {
return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage;
}
- bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; }
- bool hasInternalLinkage() const { return Linkage == InternalLinkage; }
- bool hasPrivateLinkage() const { return Linkage == PrivateLinkage; }
- bool hasLinkerPrivateLinkage() const { return Linkage==LinkerPrivateLinkage; }
- bool hasLocalLinkage() const {
- return hasInternalLinkage() || hasPrivateLinkage() ||
- hasLinkerPrivateLinkage();
+ static bool isAppendingLinkage(LinkageTypes Linkage) {
+ return Linkage == AppendingLinkage;
+ }
+ static bool isInternalLinkage(LinkageTypes Linkage) {
+ return Linkage == InternalLinkage;
+ }
+ static bool isPrivateLinkage(LinkageTypes Linkage) {
+ return Linkage == PrivateLinkage;
+ }
+ static bool isLinkerPrivateLinkage(LinkageTypes Linkage) {
+ return Linkage==LinkerPrivateLinkage;
+ }
+ static bool isLocalLinkage(LinkageTypes Linkage) {
+ return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) ||
+ isLinkerPrivateLinkage(Linkage);
+ }
+ static bool isDLLImportLinkage(LinkageTypes Linkage) {
+ return Linkage == DLLImportLinkage;
+ }
+ static bool isDLLExportLinkage(LinkageTypes Linkage) {
+ return Linkage == DLLExportLinkage;
+ }
+ static bool isExternalWeakLinkage(LinkageTypes Linkage) {
+ return Linkage == ExternalWeakLinkage;
+ }
+ static bool isCommonLinkage(LinkageTypes Linkage) {
+ return Linkage == CommonLinkage;
}
- bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; }
- bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; }
- bool hasExternalWeakLinkage() const { return Linkage == ExternalWeakLinkage; }
- bool hasCommonLinkage() const { return Linkage == CommonLinkage; }
-
- void setLinkage(LinkageTypes LT) { Linkage = LT; }
- LinkageTypes getLinkage() const { return Linkage; }
/// mayBeOverridden - Whether the definition of this global may be replaced
/// by something non-equivalent at link time. For example, if a function has
/// weak linkage then the code defining it may be replaced by different code.
- bool mayBeOverridden() const {
+ static bool mayBeOverridden(LinkageTypes Linkage) {
return (Linkage == WeakAnyLinkage ||
Linkage == LinkOnceAnyLinkage ||
Linkage == CommonLinkage ||
@@ -148,7 +163,7 @@ public:
/// isWeakForLinker - Whether the definition of this global may be replaced at
/// link time.
- bool isWeakForLinker() const {
+ static bool isWeakForLinker(LinkageTypes Linkage) {
return (Linkage == AvailableExternallyLinkage ||
Linkage == WeakAnyLinkage ||
Linkage == WeakODRLinkage ||
@@ -158,6 +173,33 @@ public:
Linkage == ExternalWeakLinkage);
}
+ bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
+ bool hasAvailableExternallyLinkage() const {
+ return isAvailableExternallyLinkage(Linkage);
+ }
+ bool hasLinkOnceLinkage() const {
+ return isLinkOnceLinkage(Linkage);
+ }
+ bool hasWeakLinkage() const {
+ return isWeakLinkage(Linkage);
+ }
+ bool hasAppendingLinkage() const { return isAppendingLinkage(Linkage); }
+ bool hasInternalLinkage() const { return isInternalLinkage(Linkage); }
+ bool hasPrivateLinkage() const { return isPrivateLinkage(Linkage); }
+ bool hasLinkerPrivateLinkage() const { return isLinkerPrivateLinkage(Linkage); }
+ bool hasLocalLinkage() const { return isLocalLinkage(Linkage); }
+ bool hasDLLImportLinkage() const { return isDLLImportLinkage(Linkage); }
+ bool hasDLLExportLinkage() const { return isDLLExportLinkage(Linkage); }
+ bool hasExternalWeakLinkage() const { return isExternalWeakLinkage(Linkage); }
+ bool hasCommonLinkage() const { return isCommonLinkage(Linkage); }
+
+ void setLinkage(LinkageTypes LT) { Linkage = LT; }
+ LinkageTypes getLinkage() const { return Linkage; }
+
+ bool mayBeOverridden() const { return mayBeOverridden(Linkage); }
+
+ bool isWeakForLinker() const { return isWeakForLinker(Linkage); }
+
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalValue) from the GlobalValue Src to this one.
virtual void copyAttributesFrom(const GlobalValue *Src);
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index 5ce1a9d..49cdd6a 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -696,36 +696,36 @@ public:
/// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
/// predicate values are not overlapping between the classes.
enum Predicate {
- // Opcode U L G E Intuitive operation
- FCMP_FALSE = 0, /// 0 0 0 0 Always false (always folded)
- FCMP_OEQ = 1, /// 0 0 0 1 True if ordered and equal
- FCMP_OGT = 2, /// 0 0 1 0 True if ordered and greater than
- FCMP_OGE = 3, /// 0 0 1 1 True if ordered and greater than or equal
- FCMP_OLT = 4, /// 0 1 0 0 True if ordered and less than
- FCMP_OLE = 5, /// 0 1 0 1 True if ordered and less than or equal
- FCMP_ONE = 6, /// 0 1 1 0 True if ordered and operands are unequal
- FCMP_ORD = 7, /// 0 1 1 1 True if ordered (no nans)
- FCMP_UNO = 8, /// 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
- FCMP_UEQ = 9, /// 1 0 0 1 True if unordered or equal
- FCMP_UGT = 10, /// 1 0 1 0 True if unordered or greater than
- FCMP_UGE = 11, /// 1 0 1 1 True if unordered, greater than, or equal
- FCMP_ULT = 12, /// 1 1 0 0 True if unordered or less than
- FCMP_ULE = 13, /// 1 1 0 1 True if unordered, less than, or equal
- FCMP_UNE = 14, /// 1 1 1 0 True if unordered or not equal
- FCMP_TRUE = 15, /// 1 1 1 1 Always true (always folded)
+ // Opcode U L G E Intuitive operation
+ FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
+ FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
+ FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
+ FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
+ FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
+ FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
+ FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
+ FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
+ FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
+ FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than
+ FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal
+ FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than
+ FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal
+ FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal
+ FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded)
FIRST_FCMP_PREDICATE = FCMP_FALSE,
LAST_FCMP_PREDICATE = FCMP_TRUE,
BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
- ICMP_EQ = 32, /// equal
- ICMP_NE = 33, /// not equal
- ICMP_UGT = 34, /// unsigned greater than
- ICMP_UGE = 35, /// unsigned greater or equal
- ICMP_ULT = 36, /// unsigned less than
- ICMP_ULE = 37, /// unsigned less or equal
- ICMP_SGT = 38, /// signed greater than
- ICMP_SGE = 39, /// signed greater or equal
- ICMP_SLT = 40, /// signed less than
- ICMP_SLE = 41, /// signed less or equal
+ ICMP_EQ = 32, ///< equal
+ ICMP_NE = 33, ///< not equal
+ ICMP_UGT = 34, ///< unsigned greater than
+ ICMP_UGE = 35, ///< unsigned greater or equal
+ ICMP_ULT = 36, ///< unsigned less than
+ ICMP_ULE = 37, ///< unsigned less or equal
+ ICMP_SGT = 38, ///< signed greater than
+ ICMP_SGE = 39, ///< signed greater or equal
+ ICMP_SLT = 40, ///< signed less than
+ ICMP_SLE = 41, ///< signed less or equal
FIRST_ICMP_PREDICATE = ICMP_EQ,
LAST_ICMP_PREDICATE = ICMP_SLE,
BAD_ICMP_PREDICATE = ICMP_SLE + 1
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index c6cdbd5..f07291c 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -590,8 +590,8 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
- isa<PointerType>(getOperand(0)->getType())) &&
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->isPointerTy()) &&
"Invalid operand types for ICmp instruction");
}
@@ -611,8 +611,8 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
- isa<PointerType>(getOperand(0)->getType())) &&
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->isPointerTy()) &&
"Invalid operand types for ICmp instruction");
}
@@ -630,8 +630,8 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
- isa<PointerType>(getOperand(0)->getType())) &&
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->isPointerTy()) &&
"Invalid operand types for ICmp instruction");
}
@@ -740,7 +740,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
@@ -759,7 +759,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
@@ -776,7 +776,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
@@ -1805,7 +1805,7 @@ public:
return i/2;
}
- /// getIncomingBlock - Return incoming basic block #i.
+ /// getIncomingBlock - Return incoming basic block number @p i.
///
BasicBlock *getIncomingBlock(unsigned i) const {
return cast<BasicBlock>(getOperand(i*2+1));
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index a7e2e05..ae53851 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -46,7 +46,6 @@ namespace {
(void) llvm::createAggressiveDCEPass();
(void) llvm::createAliasAnalysisCounterPass();
(void) llvm::createAliasDebugger();
- (void) llvm::createAndersensPass();
(void) llvm::createArgumentPromotionPass();
(void) llvm::createStructRetPromotionPass();
(void) llvm::createBasicAliasAnalysisPass();
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 55696b0..882929f 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -14,6 +14,7 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/Casting.h"
+#include "llvm/MC/MCFixup.h"
#include "llvm/System/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
@@ -22,10 +23,34 @@ class raw_ostream;
class MCAssembler;
class MCContext;
class MCExpr;
+class MCFragment;
class MCSection;
class MCSectionData;
class MCSymbol;
+/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
+/// which needs to be rewritten. This region will either be rewritten by the
+/// assembler or cause a relocation entry to be generated.
+struct MCAsmFixup {
+ /// Offset - The offset inside the fragment which needs to be rewritten.
+ uint64_t Offset;
+
+ /// Value - The expression to eventually write into the fragment.
+ const MCExpr *Value;
+
+ /// Kind - The fixup kind.
+ MCFixupKind Kind;
+
+ /// FixedValue - The value to replace the fix up by.
+ //
+ // FIXME: This should not be here.
+ uint64_t FixedValue;
+
+public:
+ MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
+ : Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {}
+};
+
class MCFragment : public ilist_node<MCFragment> {
MCFragment(const MCFragment&); // DO NOT IMPLEMENT
void operator=(const MCFragment&); // DO NOT IMPLEMENT
@@ -85,7 +110,7 @@ public:
uint64_t getAddress() const;
- uint64_t getFileSize() const {
+ uint64_t getFileSize() const {
assert(FileSize != ~UINT64_C(0) && "File size not set!");
return FileSize;
}
@@ -103,11 +128,20 @@ public:
/// @}
static bool classof(const MCFragment *O) { return true; }
+
+ virtual void dump();
};
class MCDataFragment : public MCFragment {
SmallString<32> Contents;
+ /// Fixups - The list of fixups in this fragment.
+ std::vector<MCAsmFixup> Fixups;
+
+public:
+ typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
+ typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
+
public:
MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
@@ -123,10 +157,28 @@ public:
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Data;
+ /// @name Fixup Access
+ /// @{
+
+ std::vector<MCAsmFixup> &getFixups() { return Fixups; }
+ const std::vector<MCAsmFixup> &getFixups() const { return Fixups; }
+
+ fixup_iterator fixup_begin() { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+
+ fixup_iterator fixup_end() {return Fixups.end();}
+ const_fixup_iterator fixup_end() const {return Fixups.end();}
+
+ size_t fixup_size() const { return Fixups.size(); }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Data;
}
static bool classof(const MCDataFragment *) { return true; }
+
+ virtual void dump();
};
class MCAlignFragment : public MCFragment {
@@ -143,12 +195,16 @@ class MCAlignFragment : public MCFragment {
/// cannot be satisfied in this width then this fragment is ignored.
unsigned MaxBytesToEmit;
+ /// EmitNops - true when aligning code and optimal nops to be used for filling
+ bool EmitNops;
+
public:
MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
- unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
+ unsigned _MaxBytesToEmit, bool _EmitNops,
+ MCSectionData *SD = 0)
: MCFragment(FT_Align, SD), Alignment(_Alignment),
Value(_Value),ValueSize(_ValueSize),
- MaxBytesToEmit(_MaxBytesToEmit) {}
+ MaxBytesToEmit(_MaxBytesToEmit), EmitNops(_EmitNops) {}
/// @name Accessors
/// @{
@@ -158,24 +214,28 @@ public:
}
unsigned getAlignment() const { return Alignment; }
-
+
int64_t getValue() const { return Value; }
unsigned getValueSize() const { return ValueSize; }
unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
+ unsigned getEmitNops() const { return EmitNops; }
+
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Align;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Align;
}
static bool classof(const MCAlignFragment *) { return true; }
+
+ virtual void dump();
};
class MCFillFragment : public MCFragment {
/// Value - Value to use for filling bytes.
- const MCExpr *Value;
+ int64_t Value;
/// ValueSize - The size (in bytes) of \arg Value to use when filling.
unsigned ValueSize;
@@ -184,10 +244,10 @@ class MCFillFragment : public MCFragment {
uint64_t Count;
public:
- MCFillFragment(const MCExpr &_Value, unsigned _ValueSize, uint64_t _Count,
- MCSectionData *SD = 0)
+ MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count,
+ MCSectionData *SD = 0)
: MCFragment(FT_Fill, SD),
- Value(&_Value), ValueSize(_ValueSize), Count(_Count) {}
+ Value(_Value), ValueSize(_ValueSize), Count(_Count) {}
/// @name Accessors
/// @{
@@ -196,25 +256,27 @@ public:
return ValueSize * Count;
}
- const MCExpr &getValue() const { return *Value; }
-
+ int64_t getValue() const { return Value; }
+
unsigned getValueSize() const { return ValueSize; }
uint64_t getCount() const { return Count; }
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Fill;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Fill;
}
static bool classof(const MCFillFragment *) { return true; }
+
+ virtual void dump();
};
class MCOrgFragment : public MCFragment {
/// Offset - The offset this fragment should start at.
const MCExpr *Offset;
- /// Value - Value to use for filling bytes.
+ /// Value - Value to use for filling bytes.
int8_t Value;
public:
@@ -231,15 +293,17 @@ public:
}
const MCExpr &getOffset() const { return *Offset; }
-
+
uint8_t getValue() const { return Value; }
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Org;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Org;
}
static bool classof(const MCOrgFragment *) { return true; }
+
+ virtual void dump();
};
/// MCZeroFillFragment - Represent data which has a fixed size and alignment,
@@ -265,15 +329,17 @@ public:
}
uint64_t getSize() const { return Size; }
-
+
unsigned getAlignment() const { return Alignment; }
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_ZeroFill;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_ZeroFill;
}
static bool classof(const MCZeroFillFragment *) { return true; }
+
+ virtual void dump();
};
// FIXME: Should this be a separate class, or just merged into MCSection? Since
@@ -284,41 +350,13 @@ class MCSectionData : public ilist_node<MCSectionData> {
void operator=(const MCSectionData&); // DO NOT IMPLEMENT
public:
- /// Fixup - Represent a fixed size region of bytes inside some fragment which
- /// needs to be rewritten. This region will either be rewritten by the
- /// assembler or cause a relocation entry to be generated.
- struct Fixup {
- /// Fragment - The fragment containing the fixup.
- MCFragment *Fragment;
-
- /// Offset - The offset inside the fragment which needs to be rewritten.
- uint64_t Offset;
-
- /// Value - The expression to eventually write into the fragment.
- const MCExpr *Value;
-
- /// Size - The fixup size.
- unsigned Size;
-
- /// FixedValue - The value to replace the fix up by.
- //
- // FIXME: This should not be here.
- uint64_t FixedValue;
-
- public:
- Fixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value,
- unsigned _Size)
- : Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size),
- FixedValue(0) {}
- };
-
typedef iplist<MCFragment> FragmentListType;
typedef FragmentListType::const_iterator const_iterator;
typedef FragmentListType::iterator iterator;
- typedef std::vector<Fixup>::const_iterator const_fixup_iterator;
- typedef std::vector<Fixup>::iterator fixup_iterator;
+ typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+ typedef FragmentListType::reverse_iterator reverse_iterator;
private:
iplist<MCFragment> Fragments;
@@ -343,19 +381,13 @@ private:
/// initialized.
uint64_t FileSize;
- /// LastFixupLookup - Cache for the last looked up fixup.
- mutable unsigned LastFixupLookup;
-
- /// Fixups - The list of fixups in this section.
- std::vector<Fixup> Fixups;
-
/// HasInstructions - Whether this section has had instructions emitted into
/// it.
unsigned HasInstructions : 1;
/// @}
-public:
+public:
// Only for use as sentinel.
MCSectionData();
MCSectionData(const MCSection &Section, MCAssembler *A = 0);
@@ -377,27 +409,15 @@ public:
iterator end() { return Fragments.end(); }
const_iterator end() const { return Fragments.end(); }
- size_t size() const { return Fragments.size(); }
-
- bool empty() const { return Fragments.empty(); }
+ reverse_iterator rbegin() { return Fragments.rbegin(); }
+ const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
- /// @}
- /// @name Fixup Access
- /// @{
-
- std::vector<Fixup> &getFixups() {
- return Fixups;
- }
-
- fixup_iterator fixup_begin() {
- return Fixups.begin();
- }
+ reverse_iterator rend() { return Fragments.rend(); }
+ const_reverse_iterator rend() const { return Fragments.rend(); }
- fixup_iterator fixup_end() {
- return Fixups.end();
- }
+ size_t size() const { return Fragments.size(); }
- size_t fixup_size() const { return Fixups.size(); }
+ bool empty() const { return Fragments.empty(); }
/// @}
/// @name Assembler Backend Support
@@ -405,38 +425,30 @@ public:
//
// FIXME: This could all be kept private to the assembler implementation.
- /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg
- /// Offset.
- ///
- /// If multiple fixups exist for the same fragment and offset it is undefined
- /// which one is returned.
- //
- // FIXME: This isn't horribly slow in practice, but there are much nicer
- // solutions to applying the fixups.
- const Fixup *LookupFixup(const MCFragment *Fragment, uint64_t Offset) const;
-
- uint64_t getAddress() const {
+ uint64_t getAddress() const {
assert(Address != ~UINT64_C(0) && "Address not set!");
return Address;
}
void setAddress(uint64_t Value) { Address = Value; }
- uint64_t getSize() const {
+ uint64_t getSize() const {
assert(Size != ~UINT64_C(0) && "File size not set!");
return Size;
}
void setSize(uint64_t Value) { Size = Value; }
- uint64_t getFileSize() const {
+ uint64_t getFileSize() const {
assert(FileSize != ~UINT64_C(0) && "File size not set!");
return FileSize;
}
- void setFileSize(uint64_t Value) { FileSize = Value; }
+ void setFileSize(uint64_t Value) { FileSize = Value; }
bool hasInstructions() const { return HasInstructions; }
void setHasInstructions(bool Value) { HasInstructions = Value; }
/// @}
+
+ void dump();
};
// FIXME: Same concerns as with SectionData.
@@ -450,7 +462,7 @@ public:
/// Offset - The offset to apply to the fragment address to form this symbol's
/// value.
uint64_t Offset;
-
+
/// IsExternal - True if this symbol is visible outside this translation
/// unit.
unsigned IsExternal : 1;
@@ -496,10 +508,10 @@ public:
/// @}
/// @name Symbol Attributes
/// @{
-
+
bool isExternal() const { return IsExternal; }
void setExternal(bool Value) { IsExternal = Value; }
-
+
bool isPrivateExtern() const { return IsPrivateExtern; }
void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
@@ -532,14 +544,16 @@ public:
/// setFlags - Set the (implementation defined) symbol flags.
void setFlags(uint32_t Value) { Flags = Value; }
-
+
/// getIndex - Get the (implementation defined) index.
uint64_t getIndex() const { return Index; }
/// setIndex - Set the (implementation defined) index.
void setIndex(uint64_t Value) { Index = Value; }
-
- /// @}
+
+ /// @}
+
+ void dump();
};
// FIXME: This really doesn't belong here. See comments below.
@@ -568,7 +582,7 @@ private:
MCContext &Context;
raw_ostream &OS;
-
+
iplist<MCSectionData> Sections;
iplist<MCSymbolData> Symbols;
@@ -612,7 +626,7 @@ public:
/// @{
const SectionDataListType &getSectionList() const { return Sections; }
- SectionDataListType &getSectionList() { return Sections; }
+ SectionDataListType &getSectionList() { return Sections; }
iterator begin() { return Sections.begin(); }
const_iterator begin() const { return Sections.begin(); }
@@ -659,6 +673,8 @@ public:
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
/// @}
+
+ void dump();
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index 5565945..fe1aff4 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -56,7 +56,7 @@ public:
virtual unsigned getNumFixupKinds() const = 0;
/// getFixupKindInfo - Get information on a fixup kind.
- virtual MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const = 0;
+ virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
/// @}
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 95c6bd4..74415e2 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -46,30 +46,28 @@ namespace llvm {
/// @name Symbol Managment
/// @{
- /// CreateSymbol - Create a new symbol with the specified @param Name.
+ /// CreateSymbol - Create a new symbol with the specified @p Name.
///
/// @param Name - The symbol name, which must be unique across all symbols.
MCSymbol *CreateSymbol(StringRef Name);
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
- /// @param Name. If it exists, return it. If not, create a forward
+ /// @p Name. If it exists, return it. If not, create a forward
/// reference and return it.
///
/// @param Name - The symbol name, which must be unique across all symbols.
- /// @param IsTemporary - Whether this symbol is an assembler temporary,
- /// which should not survive into the symbol table for the translation unit.
MCSymbol *GetOrCreateSymbol(StringRef Name);
MCSymbol *GetOrCreateSymbol(const Twine &Name);
/// CreateTemporarySymbol - Create a new temporary symbol with the specified
- /// @param Name.
+ /// @p Name.
///
/// @param Name - The symbol name, for debugging purposes only, temporary
/// symbols do not surive assembly. If non-empty the name must be unique
/// across all symbols.
MCSymbol *CreateTemporarySymbol(StringRef Name = "");
- /// LookupSymbol - Get the symbol for @param Name, or null.
+ /// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const;
/// @}
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
index 609a9a4..1f7364d 100644
--- a/include/llvm/MC/MCDirectives.h
+++ b/include/llvm/MC/MCDirectives.h
@@ -17,32 +17,32 @@
namespace llvm {
enum MCSymbolAttr {
- MCSA_Invalid = 0, /// Not a valid directive.
+ MCSA_Invalid = 0, ///< Not a valid directive.
// Various directives in alphabetical order.
- MCSA_ELF_TypeFunction, /// .type _foo, STT_FUNC # aka @function
- MCSA_ELF_TypeIndFunction, /// .type _foo, STT_GNU_IFUNC
- MCSA_ELF_TypeObject, /// .type _foo, STT_OBJECT # aka @object
- MCSA_ELF_TypeTLS, /// .type _foo, STT_TLS # aka @tls_object
- MCSA_ELF_TypeCommon, /// .type _foo, STT_COMMON # aka @common
- MCSA_ELF_TypeNoType, /// .type _foo, STT_NOTYPE # aka @notype
- 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)
+ MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function
+ MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
+ MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object
+ MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object
+ MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common
+ MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
+ 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)
+ MCAF_SubsectionsViaSymbols ///< .subsections_via_symbols (MachO)
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 48a13f6..fce7602 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -340,7 +340,7 @@ class MCTargetExpr : public MCExpr {
virtual void Anchor();
protected:
MCTargetExpr() : MCExpr(Target) {}
-
+ virtual ~MCTargetExpr() {}
public:
virtual void PrintImpl(raw_ostream &OS) const = 0;
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index f325d65..cd0dd19 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -89,6 +89,18 @@ public:
unsigned getOffset() const { return Offset; }
const MCExpr *getValue() const { return Value; }
+
+ /// getKindForSize - Return the generic fixup kind for a value with the given
+ /// size. It is an error to pass an unsupported size.
+ static MCFixupKind getKindForSize(unsigned Size) {
+ switch (Size) {
+ default: assert(0 && "Invalid generic fixup size!");
+ case 1: return FK_Data_1;
+ case 2: return FK_Data_2;
+ case 4: return FK_Data_4;
+ case 8: return FK_Data_8;
+ }
+ }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index 8829518..d2ddc5b 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -14,8 +14,8 @@ namespace llvm {
class MCInst;
class raw_ostream;
class MCAsmInfo;
+class StringRef;
-
/// MCInstPrinter - This is an instance of a target assembly language printer
/// that converts an MCInst to valid target assembly syntax.
class MCInstPrinter {
@@ -40,6 +40,10 @@ public:
/// printInst - Print the specified MCInst to the current raw_ostream.
///
virtual void printInst(const MCInst *MI) = 0;
+
+ /// getOpcodeName - Return the name of the specified opcode enum (e.g.
+ /// "MOV32ri") or empty if we can't resolve it.
+ virtual StringRef getOpcodeName(unsigned Opcode) const;
};
} // namespace llvm
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 624d9a6..696d024 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -92,12 +92,12 @@ namespace llvm {
const MCSection *getCurrentSection() const { return CurSection; }
/// SwitchSection - Set the current section where code is being emitted to
- /// @param Section. This is required to update CurSection.
+ /// @p Section. This is required to update CurSection.
///
/// This corresponds to assembler directives like .section, .text, etc.
virtual void SwitchSection(const MCSection *Section) = 0;
- /// EmitLabel - Emit a label for @param Symbol into the current section.
+ /// EmitLabel - Emit a label for @p Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
/// foo:
@@ -107,10 +107,10 @@ namespace llvm {
/// used in an assignment.
virtual void EmitLabel(MCSymbol *Symbol) = 0;
- /// EmitAssemblerFlag - Note in the output the specified @param Flag
+ /// EmitAssemblerFlag - Note in the output the specified @p Flag
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
- /// EmitAssignment - Emit an assignment of @param Value to @param Symbol.
+ /// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
/// This corresponds to an assembler statement such as:
/// symbol = value
@@ -123,11 +123,11 @@ namespace llvm {
/// @param Value - The value for the symbol.
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0;
- /// EmitSymbolAttribute - Add the given @param Attribute to @param Symbol.
+ /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
virtual void EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) = 0;
- /// EmitSymbolDesc - Set the @param DescValue for the @param Symbol.
+ /// EmitSymbolDesc - Set the @p DescValue for the @p Symbol.
///
/// @param Symbol - The symbol to have its n_desc field set.
/// @param DescValue - The value to set into the n_desc field.
@@ -176,8 +176,8 @@ namespace llvm {
/// etc.
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.
+ /// EmitValue - Emit the expression @p Value into the output as a native
+ /// integer of the given @p Size bytes.
///
/// This is used to implement assembler directives such as .word, .quad,
/// etc.
@@ -192,7 +192,7 @@ namespace llvm {
/// to pass in a MCExpr for constant integers.
virtual void EmitIntValue(uint64_t Value, unsigned Size,unsigned AddrSpace);
- /// EmitGPRel32Value - Emit the expression @param Value into the output as a
+ /// EmitGPRel32Value - Emit the expression @p Value into the output as a
/// gprel32 (32-bit GP relative) value.
///
/// This is used to implement assembler directives such as .gprel32 on
@@ -211,11 +211,11 @@ namespace llvm {
}
- /// EmitValueToAlignment - Emit some number of copies of @param Value until
- /// the byte alignment @param ByteAlignment is reached.
+ /// EmitValueToAlignment - Emit some number of copies of @p Value until
+ /// the byte alignment @p ByteAlignment is reached.
///
/// If the number of bytes need to emit for the alignment is not a multiple
- /// of @param ValueSize, then the contents of the emitted fill bytes is
+ /// of @p ValueSize, then the contents of the emitted fill bytes is
/// undefined.
///
/// This used to implement the .align assembler directive.
@@ -223,8 +223,8 @@ namespace llvm {
/// @param ByteAlignment - The alignment to reach. This must be a power of
/// two on some targets.
/// @param Value - The value to use when filling bytes.
- /// @param Size - The size of the integer (in bytes) to emit for @param
- /// Value. This must match a native machine width.
+ /// @param ValueSize - The size of the integer (in bytes) to emit for
+ /// @p Value. This must match a native machine width.
/// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
@@ -232,8 +232,22 @@ namespace llvm {
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) = 0;
- /// EmitValueToOffset - Emit some number of copies of @param Value until the
- /// byte offset @param Offset is reached.
+ /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
+ /// is reached.
+ ///
+ /// This used to align code where the alignment bytes may be executed. This
+ /// can emit different bytes for different sizes to optimize execution.
+ ///
+ /// @param ByteAlignment - The alignment to reach. This must be a power of
+ /// two on some targets.
+ /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+ /// the alignment cannot be reached in this many bytes, no bytes are
+ /// emitted.
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0) = 0;
+
+ /// EmitValueToOffset - Emit some number of copies of @p Value until the
+ /// byte offset @p Offset is reached.
///
/// This is used to implement assembler directives such as .org.
///
@@ -254,7 +268,7 @@ namespace llvm {
/// directive.
virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0;
- /// EmitInstruction - Emit the given @param Instruction into the current
+ /// EmitInstruction - Emit the given @p Instruction into the current
/// section.
virtual void EmitInstruction(const MCInst &Inst) = 0;
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index 4e459bf..e536322 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -75,6 +75,7 @@ class MDNode : public Value, public FoldingSetNode {
MDNode(const MDNode &); // DO NOT IMPLEMENT
void operator=(const MDNode &); // DO NOT IMPLEMENT
friend class MDNodeOperand;
+ friend class LLVMContextImpl;
/// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the
/// end of this MDNode.
@@ -103,9 +104,13 @@ class MDNode : public Value, public FoldingSetNode {
FL_Yes = 1
};
- // Replace each instance of F from the operand list of this node with T.
+ /// replaceOperand - Replace each instance of F from the operand list of this
+ /// node with T.
void replaceOperand(MDNodeOperand *Op, Value *NewVal);
~MDNode();
+ /// replaceAllOperandsWithNull - This is used while destroying llvm context to
+ /// gracefully delete all nodes. This method replaces all operands with null.
+ void replaceAllOperandsWithNull();
protected:
explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index ab08afb..8fc3a53 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -56,11 +56,11 @@ typedef const PassInfo* AnalysisID;
/// Ordering of pass manager types is important here.
enum PassManagerType {
PMT_Unknown = 0,
- PMT_ModulePassManager = 1, /// MPPassManager
- PMT_CallGraphPassManager, /// CGPassManager
- PMT_FunctionPassManager, /// FPPassManager
- PMT_LoopPassManager, /// LPPassManager
- PMT_BasicBlockPassManager, /// BBPassManager
+ PMT_ModulePassManager = 1, ///< MPPassManager
+ PMT_CallGraphPassManager, ///< CGPassManager
+ PMT_FunctionPassManager, ///< FPPassManager
+ PMT_LoopPassManager, ///< LPPassManager
+ PMT_BasicBlockPassManager, ///< BBPassManager
PMT_Last
};
@@ -163,7 +163,7 @@ public:
/// 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) {
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *) {
return this;
}
virtual ImmutablePass *getAsImmutablePass() { return 0; }
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 3ee2313..61c3256 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -93,9 +93,9 @@ enum ValueExpected { // Is a value required for the option?
};
enum OptionHidden { // Control whether -help shows this option
- NotHidden = 0x20, // Option included in --help & --help-hidden
- Hidden = 0x40, // -help doesn't, but --help-hidden does
- ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg
+ NotHidden = 0x20, // Option included in -help & -help-hidden
+ Hidden = 0x40, // -help doesn't, but -help-hidden does
+ ReallyHidden = 0x60, // Neither -help nor -help-hidden show this arg
HiddenMask = 0x60
};
@@ -159,7 +159,7 @@ class Option {
Option *NextRegistered; // Singly linked list of registered options.
public:
const char *ArgStr; // The argument string itself (ex: "help", "o")
- const char *HelpStr; // The descriptive text message for --help
+ const char *HelpStr; // The descriptive text message for -help
const char *ValueStr; // String describing what the value of this option is
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
@@ -251,14 +251,14 @@ public:
// command line option parsers...
//
-// desc - Modifier to set the description shown in the --help output...
+// desc - Modifier to set the description shown in the -help output...
struct desc {
const char *Desc;
desc(const char *Str) : Desc(Str) {}
void apply(Option &O) const { O.setDescription(Desc); }
};
-// value_desc - Modifier to set the value description shown in the --help
+// value_desc - Modifier to set the value description shown in the -help
// output...
struct value_desc {
const char *Desc;
@@ -437,7 +437,7 @@ protected:
// Default parser implementation - This implementation depends on having a
// mapping of recognized options to values of some sort. In addition to this,
// each entry in the mapping also tracks a help message that is printed with the
-// command line option for --help. Because this is a simple mapping parser, the
+// command line option for -help. Because this is a simple mapping parser, the
// data type can be any unsupported type.
//
template <class DataType>
@@ -1373,7 +1373,7 @@ struct extrahelp {
void PrintVersionMessage();
// This function just prints the help message, exactly the same way as if the
-// --help option had been given on the command line.
+// -help option had been given on the command line.
// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
void PrintHelpMessage();
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 1376e46..881a0fe 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -78,7 +78,9 @@
// ALWAYS_INLINE - On compilers where we have a directive to do so, mark a
// method "always inline" because it is performance sensitive.
-#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+// GCC 3.4 supported this but is buggy in various cases and produces
+// unimplemented errors, just use it in GCC 4.0 and later.
+#if __GNUC__ > 3
#define ALWAYS_INLINE __attribute__((always_inline))
#else
// TODO: No idea how to do this with MSVC.
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index bfccc52..5f591d4 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -580,7 +580,6 @@ const char *MacinfoString(unsigned Encoding);
/// CallFrameString - Return the string for the specified call frame instruction
/// encodings.
const char *CallFrameString(unsigned Encoding);
-
} // End of namespace dwarf
} // End of namespace llvm
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index af546f0..58a1885 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/FormattedStream.h - Formatted streams ------*- C++ -*-===//
+//===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -119,7 +119,7 @@ namespace llvm
/// space.
///
/// \param NewCol - The column to move to.
- void PadToColumn(unsigned NewCol);
+ formatted_raw_ostream &PadToColumn(unsigned NewCol);
private:
void releaseStream() {
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index 0139793..1f4e598 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -94,7 +94,7 @@ public:
//===--------------------------------------------------------------------===//
/// CreateGlobalString - Make a new global variable with an initializer that
- /// has array of i8 type filled in the nul terminated string value
+ /// has array of i8 type filled in with the nul terminated string value
/// specified. If Name is specified, it is the name of the global variable
/// created.
Value *CreateGlobalString(const char *Str = "", const Twine &Name = "");
@@ -143,6 +143,10 @@ public:
return Type::getVoidTy(Context);
}
+ const Type *getInt8PtrTy() {
+ return Type::getInt8PtrTy(Context);
+ }
+
/// getCurrentFunctionReturnType - Get the return type of the current function
/// that we're emitting into.
const Type *getCurrentFunctionReturnType() const;
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index c954c0d..591af00 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -56,6 +56,19 @@ namespace llvm {
///
/// This returns true on a successful match.
bool match(const StringRef &String, SmallVectorImpl<StringRef> *Matches=0);
+
+ /// sub - Return the result of replacing the first match of the regex in
+ /// \arg String with the \arg Repl string. Backreferences like "\0" in the
+ /// replacement string are replaced with the appropriate match substring.
+ ///
+ /// Note that the replacement string has backslash escaping performed on
+ /// it. Invalid backreferences are ignored (replaced by empty strings).
+ ///
+ /// \param Error If non-null, any errors in the substitution (invalid
+ /// backreferences, trailing backslashes) will be recorded as a non-empty
+ /// string.
+ std::string sub(StringRef Repl, StringRef String, std::string *Error = 0);
+
private:
struct llvm_regex *preg;
int error;
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index bed2f13..fd56b16 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -132,7 +132,7 @@ class SMDiagnostic {
unsigned ShowLine : 1;
public:
- SMDiagnostic() : LineNo(0), ColumnNo(0) {}
+ SMDiagnostic() : LineNo(0), ColumnNo(0), ShowLine(0) {}
SMDiagnostic(const std::string &FN, int Line, int Col,
const std::string &Msg, const std::string &LineStr,
bool showline = true)
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index 384c493..d34f35f 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -185,7 +185,9 @@ public:
return C; // avoid calling Fold
return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
}
-
+ Constant *CreatePointerCast(Constant *C, const Type *DestTy) const {
+ return ConstantExpr::getPointerCast(C, DestTy);
+ }
Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
return CreateCast(Instruction::BitCast, C, DestTy);
}
diff --git a/include/llvm/System/DataTypes.h b/include/llvm/System/DataTypes.h
new file mode 100644
index 0000000..d325c66
--- /dev/null
+++ b/include/llvm/System/DataTypes.h
@@ -0,0 +1,111 @@
+/*===-- include/System/DataTypes.h - Define fixed size types -----*- 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 definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough. This file exports the following *|
+|* definitions: *|
+|* *|
+|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+|* *|
+|* No library is required when using these functinons. *|
+|* *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_UINT64_T 1
+/* #undef HAVE_U_INT64_T */
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+ being defined. We would define it here, but in order to prevent Bad Things
+ happening when system headers or C++ STL headers include stdint.h before we
+ define it here, we define it on the g++ command line (in Makefile.rules). */
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+ "#including System/DataTypes.h"
+#endif
+
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/System/AIXDataTypesFix.h"
+#endif
+
+/* Handle incorrect definition of uint64_t as u_int64_t */
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h
index 1be27b2..d4af478 100644
--- a/include/llvm/System/Path.h
+++ b/include/llvm/System/Path.h
@@ -203,7 +203,7 @@ namespace sys {
}
/// Makes a copy of \p that to \p this.
- /// @param \p that A StringRef denoting the path
+ /// @param that A StringRef denoting the path
/// @returns \p this
/// @brief Assignment Operator
Path &operator=(StringRef that);
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index 04de4e9..45cbf9d 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
+//===-- llvm/Target/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 9a117df..0cffffb 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -211,16 +211,9 @@ class Instruction {
// hasSideEffects - The instruction has side effects that are not
// captured by any operands of the instruction or other flags.
//
- // mayHaveSideEffects - Some instances of the instruction can have side
- // effects. The virtual method "isReallySideEffectFree" is called to
- // determine this. Load instructions are an example of where this is
- // useful. In general, loads always have side effects. However, loads from
- // constant pools don't. Individual back ends make this determination.
- //
// neverHasSideEffects - Set on an instruction with no pattern if it has no
// side effects.
bit hasSideEffects = 0;
- bit mayHaveSideEffects = 0;
bit neverHasSideEffects = 0;
// Is this instruction a "real" instruction (with a distinct machine
diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h
new file mode 100644
index 0000000..dfdabdb
--- /dev/null
+++ b/include/llvm/Target/TargetAsmBackend.h
@@ -0,0 +1,35 @@
+//===-- llvm/Target/TargetAsmBackend.h - Target Asm Backend -----*- 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_TARGETASMBACKEND_H
+#define LLVM_TARGET_TARGETASMBACKEND_H
+
+namespace llvm {
+class Target;
+
+/// TargetAsmBackend - Generic interface to target specific assembler backends.
+class TargetAsmBackend {
+ TargetAsmBackend(const TargetAsmBackend &); // DO NOT IMPLEMENT
+ void operator=(const TargetAsmBackend &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ TargetAsmBackend(const Target &);
+
+ /// TheTarget - The Target that this machine was created for.
+ const Target &TheTarget;
+
+public:
+ virtual ~TargetAsmBackend();
+
+ const Target &getTarget() const { return TheTarget; }
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h
index da9ba2b..85315c1 100644
--- a/include/llvm/Target/TargetAsmParser.h
+++ b/include/llvm/Target/TargetAsmParser.h
@@ -42,8 +42,8 @@ public:
/// line should be parsed up to and including the end-of-statement token. On
/// failure, the parser is not required to read to the end of the line.
//
- /// \param AP - The current parser object.
/// \param Name - The instruction name.
+ /// \param NameLoc - The source location of the name.
/// \param Operands [out] - The list of parsed operands, this returns
/// ownership of them to the caller.
/// \return True on failure.
@@ -59,7 +59,7 @@ public:
/// the target, the entire line is parsed up to and including the
/// end-of-statement token and false is returned.
///
- /// \param ID - the identifier token of the directive.
+ /// \param DirectiveID - the identifier token of the directive.
virtual bool ParseDirective(AsmToken DirectiveID) = 0;
/// MatchInstruction - Recognize a series of operands of a parsed instruction
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index d95e4e8..4b26beb 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -19,14 +19,14 @@
namespace llvm {
-class MCAsmInfo;
-class TargetRegisterClass;
-class TargetRegisterInfo;
-class LiveVariables;
class CalleeSavedInfo;
+class LiveVariables;
+class MCAsmInfo;
+class MachineMemOperand;
class SDNode;
class SelectionDAG;
-class MachineMemOperand;
+class TargetRegisterClass;
+class TargetRegisterInfo;
template<class T> class SmallVectorImpl;
@@ -243,13 +243,11 @@ public:
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const = 0;
- /// isIdentical - Return true if two instructions are identical. This differs
- /// from MachineInstr::isIdenticalTo() in that it does not require the
- /// virtual destination registers to be the same. This is used by MachineLICM
- /// and other MI passes to perform CSE.
- virtual bool isIdentical(const MachineInstr *MI,
- const MachineInstr *Other,
- const MachineRegisterInfo *MRI) const = 0;
+ /// produceSameValue - Return true if two machine instructions would produce
+ /// identical values. By default, this is only true when the two instructions
+ /// are deemed identical except for defs.
+ virtual bool produceSameValue(const MachineInstr *MI0,
+ const MachineInstr *MI1) const = 0;
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
@@ -560,10 +558,8 @@ public:
const TargetRegisterInfo *TRI) const;
virtual MachineInstr *duplicate(MachineInstr *Orig,
MachineFunction &MF) const;
- virtual bool isIdentical(const MachineInstr *MI,
- const MachineInstr *Other,
- const MachineRegisterInfo *MRI) const;
-
+ virtual bool produceSameValue(const MachineInstr *MI0,
+ const MachineInstr *MI1) const;
virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
};
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index e172edf..5bc1c0e 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -346,6 +346,11 @@ public:
return true;
}
+ /// canOpTrap - Returns true if the operation can trap for the value type.
+ /// VT must be a legal type. By default, we optimistically assume most
+ /// operations don't trap except for divide and remainder.
+ virtual bool canOpTrap(unsigned Op, EVT VT) const;
+
/// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is
/// used by Targets can use this to indicate if there is a suitable
/// VECTOR_SHUFFLE that can be used to replace a VAND with a constant
@@ -659,12 +664,12 @@ public:
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove lowering.
- /// It returns EVT::iAny if SelectionDAG should be responsible for
+ /// It returns EVT::Other if SelectionDAG should be responsible for
/// determining it.
virtual EVT getOptimalMemOpType(uint64_t Size, unsigned Align,
bool isSrcConst, bool isSrcStr,
SelectionDAG &DAG) const {
- return MVT::iAny;
+ return MVT::Other;
}
/// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
@@ -1159,7 +1164,7 @@ public:
bool isVarArg, bool isInreg, unsigned NumFixedArgs,
CallingConv::ID CallConv, bool isTailCall,
bool isReturnValueUsed, SDValue Callee, ArgListTy &Args,
- SelectionDAG &DAG, DebugLoc dl, unsigned Order);
+ SelectionDAG &DAG, DebugLoc dl);
/// LowerCall - This hook must be implemented to lower calls into the
/// the specified DAG. The outgoing arguments to the call are described
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index d3e5cf2..42d88a0 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -25,6 +25,7 @@ namespace llvm {
class MCExpr;
class MCSection;
class MCSectionMachO;
+ class MCSymbol;
class MCContext;
class GlobalValue;
class TargetMachine;
@@ -175,187 +176,26 @@ public:
return 0;
}
- /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a
- /// pc-relative reference to the specified global variable from exception
- /// handling information. In addition to the symbol, this returns
- /// by-reference:
- ///
- /// IsIndirect - True if the returned symbol is actually a stub that contains
- /// the address of the symbol, false if the symbol is the global itself.
- ///
- /// IsPCRel - True if the symbol reference is already pc-relative, false if
- /// the caller needs to subtract off the address of the reference from the
- /// symbol.
+ /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference
+ /// to the specified global variable from exception handling information.
///
virtual const MCExpr *
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
-
-protected:
- virtual const MCSection *
- SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-};
-
-
-
+ MachineModuleInfo *MMI, unsigned Encoding) const;
-class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
- mutable void *UniquingMap;
-protected:
- /// TLSDataSection - Section directive for Thread Local data.
- ///
- const MCSection *TLSDataSection; // Defaults to ".tdata".
-
- /// TLSBSSSection - Section directive for Thread Local uninitialized data.
- /// Null if this target doesn't support a BSS section.
- ///
- const MCSection *TLSBSSSection; // Defaults to ".tbss".
-
- const MCSection *DataRelSection;
- const MCSection *DataRelLocalSection;
- const MCSection *DataRelROSection;
- const MCSection *DataRelROLocalSection;
-
- const MCSection *MergeableConst4Section;
- const MCSection *MergeableConst8Section;
- const MCSection *MergeableConst16Section;
-
-protected:
- const MCSection *getELFSection(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind,
- bool IsExplicit = false) const;
-public:
- TargetLoweringObjectFileELF() : UniquingMap(0) {}
- ~TargetLoweringObjectFileELF();
-
- virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
-
- /// getSectionForConstant - Given a constant with the SectionKind, return a
- /// section that it should be placed in.
- virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
-
-
- virtual const MCSection *
- getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
- virtual const MCSection *
- SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-};
-
-
-
-class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
- mutable void *UniquingMap;
-
- const MCSection *CStringSection;
- const MCSection *UStringSection;
- const MCSection *TextCoalSection;
- const MCSection *ConstTextCoalSection;
- const MCSection *ConstDataCoalSection;
- const MCSection *ConstDataSection;
- const MCSection *DataCoalSection;
- const MCSection *DataCommonSection;
- const MCSection *DataBSSSection;
- const MCSection *FourByteConstantSection;
- const MCSection *EightByteConstantSection;
- const MCSection *SixteenByteConstantSection;
-
- const MCSection *LazySymbolPointerSection;
- const MCSection *NonLazySymbolPointerSection;
-public:
- TargetLoweringObjectFileMachO() : UniquingMap(0) {}
- ~TargetLoweringObjectFileMachO();
-
- virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
-
- virtual const MCSection *
- SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
- virtual const MCSection *
- getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
- virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
-
- /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
- /// decide not to emit the UsedDirective for some symbols in llvm.used.
- /// FIXME: REMOVE this (rdar://7071300)
- virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
- Mangler *) const;
-
- /// getMachOSection - Return the MCSection for the specified mach-o section.
- /// This requires the operands to be valid.
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
- unsigned TypeAndAttributes,
- SectionKind K) const {
- return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
- }
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2,
- SectionKind K) const;
-
- /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak
- /// text symbols into.
- const MCSection *getTextCoalSection() const {
- return TextCoalSection;
- }
-
- /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section
- /// we put weak read-only symbols into.
- const MCSection *getConstTextCoalSection() const {
- return ConstTextCoalSection;
- }
-
- /// getLazySymbolPointerSection - Return the section corresponding to
- /// the .lazy_symbol_pointer directive.
- const MCSection *getLazySymbolPointerSection() const {
- return LazySymbolPointerSection;
- }
-
- /// getNonLazySymbolPointerSection - Return the section corresponding to
- /// the .non_lazy_symbol_pointer directive.
- const MCSection *getNonLazySymbolPointerSection() const {
- return NonLazySymbolPointerSection;
- }
-
- /// getSymbolForDwarfGlobalReference - The mach-o version of this method
- /// defaults to returning a stub reference.
virtual const MCExpr *
- getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
-};
+ getSymbolForDwarfReference(const MCSymbol *Sym, MachineModuleInfo *MMI,
+ unsigned Encoding) const;
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
-
-class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
- mutable void *UniquingMap;
-public:
- TargetLoweringObjectFileCOFF() : UniquingMap(0) {}
- ~TargetLoweringObjectFileCOFF();
-
- virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
-
- virtual const MCSection *
- getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
+protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
-
- /// getCOFFSection - Return the MCSection for the specified COFF section.
- /// FIXME: Switch this to a semantic view eventually.
- const MCSection *getCOFFSection(StringRef Name, bool isDirective,
- SectionKind K) const;
};
} // end namespace llvm
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 63e28ac..a7062ac 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -68,15 +68,6 @@ 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
- };
-}
-
//===----------------------------------------------------------------------===//
///
/// TargetMachine - Primary interface to the complete machine description for
@@ -179,20 +170,6 @@ 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, and returned by
/// it to indicate what type of file could actually be made.
@@ -212,8 +189,9 @@ public:
/// is not supported, or false on success.
virtual bool addPassesToEmitFile(PassManagerBase &,
formatted_raw_ostream &,
- CodeGenFileType Filetype,
- CodeGenOpt::Level) {
+ CodeGenFileType,
+ CodeGenOpt::Level,
+ bool DisableVerify = true) {
return true;
}
@@ -225,7 +203,8 @@ public:
///
virtual bool addPassesToEmitMachineCode(PassManagerBase &,
JITCodeEmitter &,
- CodeGenOpt::Level) {
+ CodeGenOpt::Level,
+ bool DisableVerify = true) {
return true;
}
@@ -235,7 +214,8 @@ public:
virtual bool WantsWholeFile() const { return false; }
virtual bool addPassesToEmitWholeFile(PassManager &, formatted_raw_ostream &,
CodeGenFileType,
- CodeGenOpt::Level) {
+ CodeGenOpt::Level,
+ bool DisableVerify = true) {
return true;
}
};
@@ -250,7 +230,8 @@ protected: // Can only create subclasses.
/// addCommonCodeGenPasses - Add standard LLVM codegen passes used for
/// both emitting to assembly files or machine code output.
///
- bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level);
+ bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level,
+ bool DisableVerify);
private:
virtual void setCodeModelForJIT();
@@ -265,7 +246,8 @@ public:
virtual bool addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- CodeGenOpt::Level);
+ CodeGenOpt::Level,
+ bool DisableVerify = true);
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted. This uses a JITCodeEmitter object to handle
@@ -275,7 +257,8 @@ public:
///
virtual bool addPassesToEmitMachineCode(PassManagerBase &PM,
JITCodeEmitter &MCE,
- CodeGenOpt::Level);
+ CodeGenOpt::Level,
+ bool DisableVerify = true);
/// Target-Independent Code Generator Pass Configuration Options.
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index 10cb45f..48665b7 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -16,7 +16,7 @@
namespace llvm {
-// Invariant opcodes: All instruction sets have these as their low opcodes.
+/// Invariant opcodes: All instruction sets have these as their low opcodes.
namespace TargetOpcode {
enum {
PHI = 0,
@@ -63,7 +63,7 @@ namespace TargetOpcode {
/// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
COPY_TO_REGCLASS = 10,
- // DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
+ /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
DBG_VALUE = 11
};
} // end namespace TargetOpcode
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 65b60f7..212cc93 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -587,6 +587,17 @@ public:
return !hasFP(MF);
}
+ /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
+ /// call frame pseudo ops before doing frame index elimination. This is
+ /// possible only when frame index references between the pseudos won't
+ /// need adjusted for the call frame adjustments. Normally, that's true
+ /// if the function has a reserved call frame or a frame pointer. Some
+ /// targets (Thumb2, for example) may have more complicated criteria,
+ /// however, and can override this behavior.
+ virtual bool canSimplifyCallFramePseudos(MachineFunction &MF) const {
+ return hasReservedCallFrame(MF) || hasFP(MF);
+ }
+
/// hasReservedSpillSlot - Return true if target has reserved a spill slot in
/// the stack frame of the given function for the specified register. e.g. On
/// x86, if the frame register is required, the first fixed stack object is
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index 1738997..a409b62 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -26,6 +26,7 @@
namespace llvm {
class AsmPrinter;
class Module;
+ class MCAssembler;
class MCAsmInfo;
class MCAsmParser;
class MCCodeEmitter;
@@ -33,6 +34,7 @@ namespace llvm {
class MCDisassembler;
class MCInstPrinter;
class MCStreamer;
+ class TargetAsmBackend;
class TargetAsmLexer;
class TargetAsmParser;
class TargetMachine;
@@ -63,6 +65,8 @@ namespace llvm {
MCContext &Ctx,
MCStreamer &Streamer,
const MCAsmInfo *MAI);
+ typedef TargetAsmBackend *(*AsmBackendCtorTy)(const Target &T,
+ MCAssembler &A);
typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
const MCAsmInfo &MAI);
typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P);
@@ -72,7 +76,8 @@ namespace llvm {
const MCAsmInfo &MAI,
raw_ostream &O);
typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
- TargetMachine &TM);
+ TargetMachine &TM,
+ MCContext &Ctx);
private:
/// Next - The next registered target in the linked list, maintained by the
@@ -93,32 +98,35 @@ namespace llvm {
bool HasJIT;
AsmInfoCtorFnTy AsmInfoCtorFn;
-
+
/// TargetMachineCtorFn - Construction function for this target's
/// TargetMachine, if registered.
TargetMachineCtorTy TargetMachineCtorFn;
- /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
- /// if registered.
- AsmPrinterCtorTy AsmPrinterCtorFn;
+ /// AsmBackendCtorFn - Construction function for this target's
+ /// TargetAsmBackend, if registered.
+ AsmBackendCtorTy AsmBackendCtorFn;
/// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer,
/// if registered.
AsmLexerCtorTy AsmLexerCtorFn;
-
+
/// AsmParserCtorFn - Construction function for this target's
/// TargetAsmParser, if registered.
AsmParserCtorTy AsmParserCtorFn;
-
+
+ /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
+ /// if registered.
+ AsmPrinterCtorTy AsmPrinterCtorFn;
+
/// MCDisassemblerCtorFn - Construction function for this target's
/// MCDisassembler, if registered.
MCDisassemblerCtorTy MCDisassemblerCtorFn;
-
- /// MCInstPrinterCtorFn - Construction function for this target's
+ /// MCInstPrinterCtorFn - Construction function for this target's
/// MCInstPrinter, if registered.
MCInstPrinterCtorTy MCInstPrinterCtorFn;
-
+
/// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
/// if registered.
CodeEmitterCtorTy CodeEmitterCtorFn;
@@ -146,12 +154,18 @@ namespace llvm {
/// hasTargetMachine - Check if this target supports code generation.
bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
- /// hasAsmPrinter - Check if this target supports .s printing.
- bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
+ /// hasAsmBackend - Check if this target supports .o generation.
+ bool hasAsmBackend() const { return AsmBackendCtorFn != 0; }
+
+ /// hasAsmLexer - Check if this target supports .s lexing.
+ bool hasAsmLexer() const { return AsmLexerCtorFn != 0; }
/// hasAsmParser - Check if this target supports .s parsing.
bool hasAsmParser() const { return AsmParserCtorFn != 0; }
-
+
+ /// hasAsmPrinter - Check if this target supports .s printing.
+ bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
+
/// hasMCDisassembler - Check if this target has a disassembler.
bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
@@ -164,7 +178,7 @@ namespace llvm {
/// @}
/// @name Feature Constructors
/// @{
-
+
/// createAsmInfo - Create a MCAsmInfo implementation for the specified
/// target triple.
///
@@ -177,7 +191,7 @@ namespace llvm {
return 0;
return AsmInfoCtorFn(*this, Triple);
}
-
+
/// createTargetMachine - Create a target specific machine implementation
/// for the specified \arg Triple.
///
@@ -192,14 +206,13 @@ namespace llvm {
return TargetMachineCtorFn(*this, Triple, Features);
}
- /// createAsmPrinter - Create a target specific assembly printer pass. This
- /// takes ownership of the MCContext and MCStreamer objects but not the MAI.
- AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *MAI) const {
- if (!AsmPrinterCtorFn)
+ /// createAsmBackend - Create a target specific assembly parser.
+ ///
+ /// \arg Backend - The target independent assembler object.
+ TargetAsmBackend *createAsmBackend(MCAssembler &Backend) const {
+ if (!AsmBackendCtorFn)
return 0;
- return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI);
+ return AsmBackendCtorFn(*this, Backend);
}
/// createAsmLexer - Create a target specific assembly lexer.
@@ -209,7 +222,7 @@ namespace llvm {
return 0;
return AsmLexerCtorFn(*this, MAI);
}
-
+
/// createAsmParser - Create a target specific assembly parser.
///
/// \arg Parser - The target independent parser implementation to use for
@@ -219,7 +232,17 @@ namespace llvm {
return 0;
return AsmParserCtorFn(*this, Parser);
}
-
+
+ /// createAsmPrinter - Create a target specific assembly printer pass. This
+ /// takes ownership of the MCContext and MCStreamer objects but not the MAI.
+ AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM,
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *MAI) const {
+ if (!AsmPrinterCtorFn)
+ return 0;
+ return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI);
+ }
+
const MCDisassembler *createMCDisassembler() const {
if (!MCDisassemblerCtorFn)
return 0;
@@ -233,13 +256,13 @@ namespace llvm {
return 0;
return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, O);
}
-
-
+
+
/// createCodeEmitter - Create a target specific code emitter.
- MCCodeEmitter *createCodeEmitter(TargetMachine &TM) const {
+ MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const {
if (!CodeEmitterCtorFn)
return 0;
- return CodeEmitterCtorFn(*this, TM);
+ return CodeEmitterCtorFn(*this, TM, Ctx);
}
/// @}
@@ -269,8 +292,8 @@ namespace llvm {
return *this;
}
iterator operator++(int) { // Postincrement
- iterator tmp = *this;
- ++*this;
+ iterator tmp = *this;
+ ++*this;
return tmp;
}
@@ -312,7 +335,7 @@ namespace llvm {
/// RegisterTarget - Register the given target. Attempts to register a
/// target which has already been registered will be ignored.
- ///
+ ///
/// 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.
@@ -320,7 +343,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Name - The target name. This should be a static string.
/// @param ShortDesc - A short target description. This should be a static
- /// string.
+ /// string.
/// @param TQualityFn - The triple match quality computation function for
/// this target.
/// @param HasJIT - Whether the target supports JIT code
@@ -333,11 +356,11 @@ namespace llvm {
/// RegisterAsmInfo - Register a MCAsmInfo 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 a MCAsmInfo for the target.
static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) {
@@ -345,76 +368,90 @@ namespace llvm {
if (!T.AsmInfoCtorFn)
T.AsmInfoCtorFn = Fn;
}
-
+
/// RegisterTargetMachine - Register a TargetMachine 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 a TargetMachine for the target.
- static void RegisterTargetMachine(Target &T,
+ static void RegisterTargetMachine(Target &T,
Target::TargetMachineCtorTy Fn) {
// Ignore duplicate registration.
if (!T.TargetMachineCtorFn)
T.TargetMachineCtorFn = Fn;
}
- /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
- /// target.
- ///
+ /// RegisterAsmBackend - Register a TargetAsmBackend 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 RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
- // Ignore duplicate registration.
- if (!T.AsmPrinterCtorFn)
- T.AsmPrinterCtorFn = Fn;
+ /// @param Fn - A function to construct an AsmBackend for the target.
+ static void RegisterAsmBackend(Target &T, Target::AsmBackendCtorTy Fn) {
+ if (!T.AsmBackendCtorFn)
+ T.AsmBackendCtorFn = 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.
+ /// @param Fn - A function to construct an AsmLexer 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.
- ///
+ ///
/// 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.
+ /// @param Fn - A function to construct an AsmParser for the target.
static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
if (!T.AsmParserCtorFn)
T.AsmParserCtorFn = Fn;
}
-
+
+ /// RegisterAsmPrinter - Register an AsmPrinter 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 RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.AsmPrinterCtorFn)
+ T.AsmPrinterCtorFn = Fn;
+ }
+
/// RegisterMCDisassembler - Register a MCDisassembler 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 MCDisassembler for the target.
- static void RegisterMCDisassembler(Target &T,
+ static void RegisterMCDisassembler(Target &T,
Target::MCDisassemblerCtorTy Fn) {
if (!T.MCDisassemblerCtorFn)
T.MCDisassemblerCtorFn = Fn;
@@ -422,7 +459,7 @@ namespace llvm {
/// RegisterMCInstPrinter - Register a MCInstPrinter 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.
@@ -434,7 +471,7 @@ namespace llvm {
if (!T.MCInstPrinterCtorFn)
T.MCInstPrinterCtorFn = Fn;
}
-
+
/// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the
/// given target.
///
@@ -443,7 +480,7 @@ namespace llvm {
/// 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.
+ /// @param Fn - A function to construct an MCCodeEmitter for the target.
static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) {
if (!T.CodeEmitterCtorFn)
T.CodeEmitterCtorFn = Fn;
@@ -497,7 +534,7 @@ namespace llvm {
static const MCAsmInfo *Allocator(const Target &T, StringRef TT) {
return new MCAsmInfoImpl(T, TT);
}
-
+
};
/// RegisterAsmInfoFn - Helper template for registering a target assembly info
@@ -536,25 +573,22 @@ namespace llvm {
}
};
- /// RegisterAsmPrinter - Helper template for registering a target specific
- /// assembly printer, for use in the target machine initialization
- /// function. Usage:
+ /// RegisterAsmBackend - Helper template for registering a target specific
+ /// assembler backend. Usage:
///
- /// extern "C" void LLVMInitializeFooAsmPrinter() {
+ /// extern "C" void LLVMInitializeFooAsmBackend() {
/// extern Target TheFooTarget;
- /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
+ /// RegisterAsmBackend<FooAsmLexer> X(TheFooTarget);
/// }
- template<class AsmPrinterImpl>
- struct RegisterAsmPrinter {
- RegisterAsmPrinter(Target &T) {
- TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+ template<class AsmBackendImpl>
+ struct RegisterAsmBackend {
+ RegisterAsmBackend(Target &T) {
+ TargetRegistry::RegisterAsmBackend(T, &Allocator);
}
private:
- static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *MAI) {
- return new AsmPrinterImpl(OS, TM, Ctx, Streamer, MAI);
+ static TargetAsmBackend *Allocator(const Target &T, MCAssembler &Backend) {
+ return new AsmBackendImpl(T, Backend);
}
};
@@ -571,7 +605,7 @@ namespace llvm {
RegisterAsmLexer(Target &T) {
TargetRegistry::RegisterAsmLexer(T, &Allocator);
}
-
+
private:
static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) {
return new AsmLexerImpl(T, MAI);
@@ -598,6 +632,28 @@ namespace llvm {
}
};
+ /// RegisterAsmPrinter - Helper template for registering a target specific
+ /// assembly printer, for use in the target machine initialization
+ /// function. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooAsmPrinter() {
+ /// extern Target TheFooTarget;
+ /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
+ /// }
+ template<class AsmPrinterImpl>
+ struct RegisterAsmPrinter {
+ RegisterAsmPrinter(Target &T) {
+ TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+ }
+
+ private:
+ static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM,
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *MAI) {
+ return new AsmPrinterImpl(OS, TM, Ctx, Streamer, MAI);
+ }
+ };
+
/// RegisterCodeEmitter - Helper template for registering a target specific
/// machine code emitter, for use in the target initialization
/// function. Usage:
@@ -613,8 +669,9 @@ namespace llvm {
}
private:
- static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM) {
- return new CodeEmitterImpl(T, TM);
+ static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM,
+ MCContext &Ctx) {
+ return new CodeEmitterImpl(T, TM, Ctx);
}
};
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 4b72f81..4365d33 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -479,7 +479,6 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>;
def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>;
-def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>;
def immAllOnesV: PatLeaf<(build_vector), [{
return ISD::isBuildVectorAllOnes(N);
}]>;
@@ -496,7 +495,7 @@ def immAllZerosV_bc: PatLeaf<(bitconvert), [{
// Other helper fragments.
-def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>;
+def not : PatFrag<(ops node:$in), (xor node:$in, -1)>;
def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
def vnot_conv : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV_bc)>;
def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 7159f86..6893bad 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -263,7 +263,7 @@ extern const PassInfo *const LCSSAID;
// GVN - This pass performs global value numbering and redundant load
// elimination cotemporaneously.
//
-FunctionPass *createGVNPass(bool NoPRE = false, bool NoLoads = false);
+FunctionPass *createGVNPass(bool NoLoads = false);
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 3f4571e..5279e96 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -102,6 +102,12 @@ void FindFunctionBackedges(const Function &F,
//
void RemoveSuccessor(TerminatorInst *TI, unsigned SuccNum);
+/// GetSuccessorNumber - Search for the specified successor of basic block BB
+/// and return its position in the terminator instruction's list of
+/// successors. It is an error to call this with a block that is not a
+/// successor.
+unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ);
+
/// isCriticalEdge - Return true if the specified edge is a critical edge.
/// Critical edges are edges from a block with multiple successors to a block
/// with multiple predecessors.
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
new file mode 100644
index 0000000..03716a8
--- /dev/null
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -0,0 +1,96 @@
+//===- BuildLibCalls.h - Utility builder for libcalls -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an interface to build some C language libcalls for
+// optimization passes that need to call the various functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H
+#define TRANSFORMS_UTILS_BUILDLIBCALLS_H
+
+#include "llvm/Support/IRBuilder.h"
+
+namespace llvm {
+ class Value;
+ class TargetData;
+
+ /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
+ Value *CastToCStr(Value *V, IRBuilder<> &B);
+
+ /// EmitStrLen - Emit a call to the strlen function to the builder, for the
+ /// specified pointer. Ptr is required to be some pointer type, and the
+ /// return value has 'intptr_t' type.
+ Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitStrChr - Emit a call to the strchr function to the builder, for the
+ /// specified pointer and character. Ptr is required to be some pointer type,
+ /// and the return value has 'i8*' type.
+ Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
+ /// specified pointer arguments.
+ Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// 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,
+ unsigned Align, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitMemMove - Emit a call to the memmove function to the builder. This
+ /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
+ Value *EmitMemMove(Value *Dst, Value *Src, Value *Len,
+ unsigned Align, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
+ /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
+ Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitMemCmp - Emit a call to the memcmp function.
+ Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitMemSet - Emit a call to the memset function
+ Value *EmitMemSet(Value *Dst, Value *Val, Value *Len, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
+ /// (e.g. 'floor'). This function is known to take a single of type matching
+ /// 'Op' and returns one value with the same type. If 'Op' is a long double,
+ /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f'
+ /// suffix.
+ Value *EmitUnaryFloatFnCall(Value *Op, const char *Name, IRBuilder<> &B,
+ const AttrListPtr &Attrs);
+
+ /// EmitPutChar - Emit a call to the putchar function. This assumes that Char
+ /// is an integer.
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitPutS - Emit a call to the puts function. This assumes that Str is
+ /// some pointer.
+ void EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
+ /// an i32, and File is a pointer to FILE.
+ void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitFPutS - Emit a call to the puts function. Str is required to be a
+ /// pointer and File is a pointer to FILE.
+ void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
+ /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
+ void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
+ const TargetData *TD);
+}
+
+#endif
diff --git a/include/llvm/Type.h b/include/llvm/Type.h
index bc319c6..d09913a 100644
--- a/include/llvm/Type.h
+++ b/include/llvm/Type.h
@@ -82,13 +82,14 @@ public:
IntegerTyID, ///< 8: Arbitrary bit width integers
FunctionTyID, ///< 9: Functions
StructTyID, ///< 10: Structures
- ArrayTyID, ///< 11: Arrays
- PointerTyID, ///< 12: Pointers
- OpaqueTyID, ///< 13: Opaque: type with unknown structure
- VectorTyID, ///< 14: SIMD 'packed' format, or other vector type
+ UnionTyID, ///< 11: Unions
+ ArrayTyID, ///< 12: Arrays
+ PointerTyID, ///< 13: Pointers
+ OpaqueTyID, ///< 14: Opaque: type with unknown structure
+ VectorTyID, ///< 15: SIMD 'packed' format, or other vector type
NumTypeIDs, // Must remain as last defined ID
- LastPrimitiveTyID = LabelTyID,
+ LastPrimitiveTyID = MetadataTyID,
FirstDerivedTyID = IntegerTyID
};
@@ -181,6 +182,9 @@ public:
// are defined in private classes defined in Type.cpp for primitive types.
//
+ /// getDescription - Return the string representation of the type.
+ std::string getDescription() const;
+
/// getTypeID - Return the type id for the type. This will return one
/// of the TypeID enum elements defined above.
///
@@ -204,55 +208,60 @@ public:
/// isPPC_FP128Ty - Return true if this is powerpc long double.
bool isPPC_FP128Ty() const { return ID == PPC_FP128TyID; }
+ /// isFloatingPointTy - Return true if this is one of the five floating point
+ /// types
+ bool isFloatingPointTy() const { return ID == FloatTyID || ID == DoubleTyID ||
+ ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; }
+
+ /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP.
+ ///
+ bool isFPOrFPVectorTy() const;
+
/// isLabelTy - Return true if this is 'label'.
bool isLabelTy() const { return ID == LabelTyID; }
/// isMetadataTy - Return true if this is 'metadata'.
bool isMetadataTy() const { return ID == MetadataTyID; }
- /// getDescription - Return the string representation of the type.
- std::string getDescription() const;
-
- /// isInteger - True if this is an instance of IntegerType.
+ /// isIntegerTy - True if this is an instance of IntegerType.
///
- bool isInteger() const { return ID == IntegerTyID; }
+ bool isIntegerTy() const { return ID == IntegerTyID; }
- /// isInteger - Return true if this is an IntegerType of the specified width.
- bool isInteger(unsigned Bitwidth) const;
+ /// isIntegerTy - Return true if this is an IntegerType of the given width.
+ bool isIntegerTy(unsigned Bitwidth) const;
- /// isIntOrIntVector - Return true if this is an integer type or a vector of
+ /// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
/// integer types.
///
- bool isIntOrIntVector() const;
+ bool isIntOrIntVectorTy() const;
- /// isFloatingPoint - Return true if this is one of the five floating point
- /// types
- bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID ||
- ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; }
+ /// isFunctionTy - True if this is an instance of FunctionType.
+ ///
+ bool isFunctionTy() const { return ID == FunctionTyID; }
- /// isFPOrFPVector - Return true if this is a FP type or a vector of FP types.
+ /// isStructTy - True if this is an instance of StructType.
///
- bool isFPOrFPVector() const;
-
- /// isFunction - True if this is an instance of FunctionType.
+ bool isStructTy() const { return ID == StructTyID; }
+
+ /// isUnionTy - True if this is an instance of UnionType.
///
- bool isFunction() const { return ID == FunctionTyID; }
+ bool isUnionTy() const { return ID == UnionTyID; }
- /// isStruct - True if this is an instance of StructType.
+ /// isArrayTy - True if this is an instance of ArrayType.
///
- bool isStruct() const { return ID == StructTyID; }
+ bool isArrayTy() const { return ID == ArrayTyID; }
- /// isArray - True if this is an instance of ArrayType.
+ /// isPointerTy - True if this is an instance of PointerType.
///
- bool isArray() const { return ID == ArrayTyID; }
+ bool isPointerTy() const { return ID == PointerTyID; }
- /// isPointer - True if this is an instance of PointerType.
+ /// isOpaqueTy - True if this is an instance of OpaqueType.
///
- bool isPointer() const { return ID == PointerTyID; }
+ bool isOpaqueTy() const { return ID == OpaqueTyID; }
- /// isVector - True if this is an instance of VectorType.
+ /// isVectorTy - True if this is an instance of VectorType.
///
- bool isVector() const { return ID == VectorTyID; }
+ bool isVectorTy() const { return ID == VectorTyID; }
/// isAbstract - True if the type is either an Opaque type, or is a derived
/// type that includes an opaque type somewhere in it.
@@ -297,7 +306,7 @@ public:
/// does not include vector types.
///
inline bool isAggregateType() const {
- return ID == StructTyID || ID == ArrayTyID;
+ return ID == StructTyID || ID == ArrayTyID || ID == UnionTyID;
}
/// isSized - Return true if it makes sense to take the size of this type. To
@@ -306,11 +315,12 @@ public:
///
bool isSized() const {
// If it's a primitive, it is always sized.
- if (ID == IntegerTyID || isFloatingPoint() || ID == PointerTyID)
+ if (ID == IntegerTyID || isFloatingPointTy() || ID == PointerTyID)
return true;
// If it is not something that can have a size (e.g. a function or label),
// it doesn't have a size.
- if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID)
+ if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID &&
+ ID != UnionTyID)
return false;
// If it is something that can have a size and it's concrete, it definitely
// has a size, otherwise we have to try harder to decide.
diff --git a/include/llvm/Value.h b/include/llvm/Value.h
index 9045906..d06cbc0 100644
--- a/include/llvm/Value.h
+++ b/include/llvm/Value.h
@@ -215,6 +215,7 @@ public:
ConstantFPVal, // This is an instance of ConstantFP
ConstantArrayVal, // This is an instance of ConstantArray
ConstantStructVal, // This is an instance of ConstantStruct
+ ConstantUnionVal, // This is an instance of ConstantUnion
ConstantVectorVal, // This is an instance of ConstantVector
ConstantPointerNullVal, // This is an instance of ConstantPointerNull
MDNodeVal, // This is an instance of MDNode
diff --git a/lib/Analysis/AliasAnalysisCounter.cpp b/lib/Analysis/AliasAnalysisCounter.cpp
index 761cd46..1053955 100644
--- a/lib/Analysis/AliasAnalysisCounter.cpp
+++ b/lib/Analysis/AliasAnalysisCounter.cpp
@@ -162,7 +162,7 @@ AliasAnalysisCounter::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
errs() << MRString << ": Ptr: ";
errs() << "[" << Size << "B] ";
WriteAsOperand(errs(), P, true, M);
- errs() << "\t<->" << *CS.getInstruction();
+ errs() << "\t<->" << *CS.getInstruction() << '\n';
}
return R;
}
diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp
index 6b0a956..308b9e3 100644
--- a/lib/Analysis/AliasAnalysisEvaluator.cpp
+++ b/lib/Analysis/AliasAnalysisEvaluator.cpp
@@ -115,11 +115,11 @@ bool AAEval::runOnFunction(Function &F) {
SetVector<CallSite> CallSites;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
- if (isa<PointerType>(I->getType())) // Add all pointer arguments
+ if (I->getType()->isPointerTy()) // Add all pointer arguments
Pointers.insert(I);
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
- if (isa<PointerType>(I->getType())) // Add all pointer instructions
+ if (I->getType()->isPointerTy()) // Add all pointer instructions
Pointers.insert(&*I);
Instruction &Inst = *I;
User::op_iterator OI = Inst.op_begin();
@@ -128,7 +128,7 @@ bool AAEval::runOnFunction(Function &F) {
isa<Function>(CS.getCalledValue()))
++OI; // Skip actual functions for direct function calls.
for (; OI != Inst.op_end(); ++OI)
- if (isa<PointerType>((*OI)->getType()) && !isa<ConstantPointerNull>(*OI))
+ if ((*OI)->getType()->isPointerTy() && !isa<ConstantPointerNull>(*OI))
Pointers.insert(*OI);
if (CS.getInstruction()) CallSites.insert(CS);
diff --git a/lib/Analysis/Android.mk b/lib/Analysis/Android.mk
new file mode 100644
index 0000000..1d038f2
--- /dev/null
+++ b/lib/Analysis/Android.mk
@@ -0,0 +1,69 @@
+LOCAL_PATH:= $(call my-dir)
+
+analysis_SRC_FILES := \
+ AliasAnalysis.cpp \
+ AliasAnalysisCounter.cpp \
+ AliasAnalysisEvaluator.cpp \
+ AliasDebugger.cpp \
+ AliasSetTracker.cpp \
+ Analysis.cpp \
+ BasicAliasAnalysis.cpp \
+ CFGPrinter.cpp \
+ CaptureTracking.cpp \
+ ConstantFolding.cpp \
+ DbgInfoPrinter.cpp \
+ DebugInfo.cpp \
+ DomPrinter.cpp \
+ IVUsers.cpp \
+ InlineCost.cpp \
+ InstCount.cpp \
+ InstructionSimplify.cpp \
+ Interval.cpp \
+ IntervalPartition.cpp \
+ LazyValueInfo.cpp \
+ LibCallAliasAnalysis.cpp \
+ LibCallSemantics.cpp \
+ LiveValues.cpp \
+ MemoryBuiltins.cpp \
+ MemoryDependenceAnalysis.cpp \
+ LoopDependenceAnalysis.cpp \
+ LoopInfo.cpp \
+ LoopPass.cpp \
+ PHITransAddr.cpp \
+ PointerTracking.cpp \
+ PostDominators.cpp \
+ ProfileEstimatorPass.cpp \
+ ProfileInfo.cpp \
+ ProfileInfoLoader.cpp \
+ ProfileInfoLoaderPass.cpp \
+ ProfileVerifierPass.cpp \
+ ScalarEvolution.cpp \
+ ScalarEvolutionAliasAnalysis.cpp \
+ ScalarEvolutionExpander.cpp \
+ SparsePropagation.cpp \
+ Trace.cpp \
+ ValueTracking.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(analysis_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMAnalysis
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(analysis_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMAnalysis
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 36b831c..31a649d 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -290,7 +290,7 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
CI != CE; ++CI, ++ArgNo) {
// Only look at the no-capture pointer arguments.
- if (!isa<PointerType>((*CI)->getType()) ||
+ if (!(*CI)->getType()->isPointerTy() ||
!CS.paramHasAttr(ArgNo+1, Attribute::NoCapture))
continue;
@@ -662,7 +662,7 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, unsigned V1Size,
// Are we checking for alias of the same value?
if (V1 == V2) return MustAlias;
- if (!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType()))
+ if (!V1->getType()->isPointerTy() || !V2->getType()->isPointerTy())
return NoAlias; // Scalars cannot alias each other
// Figure out what objects these things are pointing to if we can.
diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp
index 10a8b11..8767c18 100644
--- a/lib/Analysis/CaptureTracking.cpp
+++ b/lib/Analysis/CaptureTracking.cpp
@@ -44,7 +44,7 @@ static int const Threshold = 20;
/// counts as capturing it or not.
bool llvm::PointerMayBeCaptured(const Value *V,
bool ReturnCaptures, bool StoreCaptures) {
- assert(isa<PointerType>(V->getType()) && "Capture is for pointers only!");
+ assert(V->getType()->isPointerTy() && "Capture is for pointers only!");
SmallVector<Use*, Threshold> Worklist;
SmallSet<Use*, Threshold> Visited;
int Count = 0;
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index ba87040..114db2d 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -80,7 +80,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy,
// First thing is first. We only want to think about integer here, so if
// we have something in FP form, recast it as integer.
- if (DstEltTy->isFloatingPoint()) {
+ if (DstEltTy->isFloatingPointTy()) {
// Fold to an vector of integers with same size as our FP type.
unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits();
const Type *DestIVTy =
@@ -95,7 +95,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy,
// Okay, we know the destination is integer, if the input is FP, convert
// it to integer first.
- if (SrcEltTy->isFloatingPoint()) {
+ if (SrcEltTy->isFloatingPointTy()) {
unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
const Type *SrcIVTy =
VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElt);
@@ -359,7 +359,7 @@ static Constant *FoldReinterpretLoadFromConstPtr(Constant *C,
MapTy = Type::getInt32PtrTy(C->getContext());
else if (LoadTy->isDoubleTy())
MapTy = Type::getInt64PtrTy(C->getContext());
- else if (isa<VectorType>(LoadTy)) {
+ else if (LoadTy->isVectorTy()) {
MapTy = IntegerType::get(C->getContext(),
TD.getTypeAllocSizeInBits(LoadTy));
MapTy = PointerType::getUnqual(MapTy);
@@ -605,7 +605,7 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
SmallVector<Constant*, 32> NewIdxs;
do {
if (const SequentialType *ATy = dyn_cast<SequentialType>(Ty)) {
- if (isa<PointerType>(ATy)) {
+ if (ATy->isPointerTy()) {
// The only pointer indexing we'll do is on the first index of the GEP.
if (!NewIdxs.empty())
break;
@@ -783,45 +783,12 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
// If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
// the int size is >= the ptr size. This requires knowing the width of a
// pointer, so it can't be done in ConstantExpr::getCast.
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0]))
if (TD &&
- TD->getPointerSizeInBits() <=
- CE->getType()->getScalarSizeInBits()) {
- if (CE->getOpcode() == Instruction::PtrToInt)
- return FoldBitCast(CE->getOperand(0), DestTy, *TD);
-
- // If there's a constant offset added to the integer value before
- // it is casted back to a pointer, see if the expression can be
- // converted into a GEP.
- if (CE->getOpcode() == Instruction::Add)
- if (ConstantInt *L = dyn_cast<ConstantInt>(CE->getOperand(0)))
- if (ConstantExpr *R = dyn_cast<ConstantExpr>(CE->getOperand(1)))
- if (R->getOpcode() == Instruction::PtrToInt)
- if (GlobalVariable *GV =
- dyn_cast<GlobalVariable>(R->getOperand(0))) {
- const PointerType *GVTy = cast<PointerType>(GV->getType());
- if (const ArrayType *AT =
- dyn_cast<ArrayType>(GVTy->getElementType())) {
- const Type *ElTy = AT->getElementType();
- uint64_t AllocSize = TD->getTypeAllocSize(ElTy);
- APInt PSA(L->getValue().getBitWidth(), AllocSize);
- if (ElTy == cast<PointerType>(DestTy)->getElementType() &&
- L->getValue().urem(PSA) == 0) {
- APInt ElemIdx = L->getValue().udiv(PSA);
- if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(),
- AT->getNumElements()))) {
- Constant *Index[] = {
- Constant::getNullValue(CE->getType()),
- ConstantInt::get(ElTy->getContext(), ElemIdx)
- };
- return
- ConstantExpr::getGetElementPtr(GV, &Index[0], 2);
- }
- }
- }
- }
- }
- }
+ TD->getPointerSizeInBits() <= CE->getType()->getScalarSizeInBits() &&
+ CE->getOpcode() == Instruction::PtrToInt)
+ return FoldBitCast(CE->getOperand(0), DestTy, *TD);
+
return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
case Instruction::Trunc:
case Instruction::ZExt:
@@ -1179,6 +1146,12 @@ llvm::ConstantFoldCall(Function *F,
return 0;
}
+ if (isa<UndefValue>(Operands[0])) {
+ if (Name.startswith("llvm.bswap"))
+ return Operands[0];
+ return 0;
+ }
+
return 0;
}
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index 258f1db..5cfe666 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -1007,12 +1007,15 @@ DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context,
/// CreateBlock - This creates a descriptor for a lexical block with the
/// specified parent VMContext.
-DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context) {
+DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context,
+ unsigned LineNo, unsigned Col) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_lexical_block),
- Context.getNode()
+ Context.getNode(),
+ ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
+ ConstantInt::get(Type::getInt32Ty(VMContext), Col)
};
- return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2));
+ return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 4));
}
/// CreateNameSpace - This creates new descriptor for a namespace
diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp
deleted file mode 100644
index 4180206..0000000
--- a/lib/Analysis/IPA/Andersens.cpp
+++ /dev/null
@@ -1,2868 +0,0 @@
-//===- Andersens.cpp - Andersen's Interprocedural Alias Analysis ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines an implementation of Andersen's interprocedural alias
-// analysis
-//
-// In pointer analysis terms, this is a subset-based, flow-insensitive,
-// field-sensitive, and context-insensitive algorithm pointer algorithm.
-//
-// This algorithm is implemented as three stages:
-// 1. Object identification.
-// 2. Inclusion constraint identification.
-// 3. Offline constraint graph optimization
-// 4. Inclusion constraint solving.
-//
-// The object identification stage identifies all of the memory objects in the
-// program, which includes globals, heap allocated objects, and stack allocated
-// objects.
-//
-// The inclusion constraint identification stage finds all inclusion constraints
-// in the program by scanning the program, looking for pointer assignments and
-// other statements that effect the points-to graph. For a statement like "A =
-// B", this statement is processed to indicate that A can point to anything that
-// B can point to. Constraints can handle copies, loads, and stores, and
-// address taking.
-//
-// The offline constraint graph optimization portion includes offline variable
-// substitution algorithms intended to compute pointer and location
-// equivalences. Pointer equivalences are those pointers that will have the
-// same points-to sets, and location equivalences are those variables that
-// always appear together in points-to sets. It also includes an offline
-// cycle detection algorithm that allows cycles to be collapsed sooner
-// during solving.
-//
-// The inclusion constraint solving phase iteratively propagates the inclusion
-// constraints until a fixed point is reached. This is an O(N^3) algorithm.
-//
-// Function constraints are handled as if they were structs with X fields.
-// Thus, an access to argument X of function Y is an access to node index
-// getNode(Y) + X. This representation allows handling of indirect calls
-// without any issues. To wit, an indirect call Y(a,b) is equivalent to
-// *(Y + 1) = a, *(Y + 2) = b.
-// The return node for a function is always located at getNode(F) +
-// CallReturnPos. The arguments start at getNode(F) + CallArgPos.
-//
-// Future Improvements:
-// Use of BDD's.
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "anders-aa"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/MemoryBuiltins.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/System/Atomic.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/SparseBitVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include <algorithm>
-#include <set>
-#include <list>
-#include <map>
-#include <stack>
-#include <vector>
-#include <queue>
-
-// Determining the actual set of nodes the universal set can consist of is very
-// expensive because it means propagating around very large sets. We rely on
-// other analysis being able to determine which nodes can never be pointed to in
-// order to disambiguate further than "points-to anything".
-#define FULL_UNIVERSAL 0
-
-using namespace llvm;
-#ifndef NDEBUG
-STATISTIC(NumIters , "Number of iterations to reach convergence");
-#endif
-STATISTIC(NumConstraints, "Number of constraints");
-STATISTIC(NumNodes , "Number of nodes");
-STATISTIC(NumUnified , "Number of variables unified");
-STATISTIC(NumErased , "Number of redundant constraints erased");
-
-static const unsigned SelfRep = (unsigned)-1;
-static const unsigned Unvisited = (unsigned)-1;
-// Position of the function return node relative to the function node.
-static const unsigned CallReturnPos = 1;
-// Position of the function call node relative to the function node.
-static const unsigned CallFirstArgPos = 2;
-
-namespace {
- struct BitmapKeyInfo {
- static inline SparseBitVector<> *getEmptyKey() {
- return reinterpret_cast<SparseBitVector<> *>(-1);
- }
- static inline SparseBitVector<> *getTombstoneKey() {
- return reinterpret_cast<SparseBitVector<> *>(-2);
- }
- static unsigned getHashValue(const SparseBitVector<> *bitmap) {
- return bitmap->getHashValue();
- }
- static bool isEqual(const SparseBitVector<> *LHS,
- const SparseBitVector<> *RHS) {
- if (LHS == RHS)
- return true;
- else if (LHS == getEmptyKey() || RHS == getEmptyKey()
- || LHS == getTombstoneKey() || RHS == getTombstoneKey())
- return false;
-
- return *LHS == *RHS;
- }
- };
-
- class Andersens : public ModulePass, public AliasAnalysis,
- private InstVisitor<Andersens> {
- struct Node;
-
- /// Constraint - Objects of this structure are used to represent the various
- /// constraints identified by the algorithm. The constraints are 'copy',
- /// for statements like "A = B", 'load' for statements like "A = *B",
- /// 'store' for statements like "*A = B", and AddressOf for statements like
- /// A = alloca; The Offset is applied as *(A + K) = B for stores,
- /// A = *(B + K) for loads, and A = B + K for copies. It is
- /// illegal on addressof constraints (because it is statically
- /// resolvable to A = &C where C = B + K)
-
- struct Constraint {
- enum ConstraintType { Copy, Load, Store, AddressOf } Type;
- unsigned Dest;
- unsigned Src;
- unsigned Offset;
-
- Constraint(ConstraintType Ty, unsigned D, unsigned S, unsigned O = 0)
- : Type(Ty), Dest(D), Src(S), Offset(O) {
- assert((Offset == 0 || Ty != AddressOf) &&
- "Offset is illegal on addressof constraints");
- }
-
- bool operator==(const Constraint &RHS) const {
- return RHS.Type == Type
- && RHS.Dest == Dest
- && RHS.Src == Src
- && RHS.Offset == Offset;
- }
-
- bool operator!=(const Constraint &RHS) const {
- return !(*this == RHS);
- }
-
- bool operator<(const Constraint &RHS) const {
- if (RHS.Type != Type)
- return RHS.Type < Type;
- else if (RHS.Dest != Dest)
- return RHS.Dest < Dest;
- else if (RHS.Src != Src)
- return RHS.Src < Src;
- return RHS.Offset < Offset;
- }
- };
-
- // Information DenseSet requires implemented in order to be able to do
- // it's thing
- struct PairKeyInfo {
- static inline std::pair<unsigned, unsigned> getEmptyKey() {
- return std::make_pair(~0U, ~0U);
- }
- static inline std::pair<unsigned, unsigned> getTombstoneKey() {
- return std::make_pair(~0U - 1, ~0U - 1);
- }
- static unsigned getHashValue(const std::pair<unsigned, unsigned> &P) {
- return P.first ^ P.second;
- }
- static unsigned isEqual(const std::pair<unsigned, unsigned> &LHS,
- const std::pair<unsigned, unsigned> &RHS) {
- return LHS == RHS;
- }
- };
-
- struct ConstraintKeyInfo {
- static inline Constraint getEmptyKey() {
- return Constraint(Constraint::Copy, ~0U, ~0U, ~0U);
- }
- static inline Constraint getTombstoneKey() {
- return Constraint(Constraint::Copy, ~0U - 1, ~0U - 1, ~0U - 1);
- }
- static unsigned getHashValue(const Constraint &C) {
- return C.Src ^ C.Dest ^ C.Type ^ C.Offset;
- }
- static bool isEqual(const Constraint &LHS,
- const Constraint &RHS) {
- return LHS.Type == RHS.Type && LHS.Dest == RHS.Dest
- && LHS.Src == RHS.Src && LHS.Offset == RHS.Offset;
- }
- };
-
- // Node class - This class is used to represent a node in the constraint
- // graph. Due to various optimizations, it is not always the case that
- // there is a mapping from a Node to a Value. In particular, we add
- // artificial Node's that represent the set of pointed-to variables shared
- // for each location equivalent Node.
- struct Node {
- private:
- static volatile sys::cas_flag Counter;
-
- public:
- Value *Val;
- SparseBitVector<> *Edges;
- SparseBitVector<> *PointsTo;
- SparseBitVector<> *OldPointsTo;
- std::list<Constraint> Constraints;
-
- // Pointer and location equivalence labels
- unsigned PointerEquivLabel;
- unsigned LocationEquivLabel;
- // Predecessor edges, both real and implicit
- SparseBitVector<> *PredEdges;
- SparseBitVector<> *ImplicitPredEdges;
- // Set of nodes that point to us, only use for location equivalence.
- SparseBitVector<> *PointedToBy;
- // Number of incoming edges, used during variable substitution to early
- // free the points-to sets
- unsigned NumInEdges;
- // True if our points-to set is in the Set2PEClass map
- bool StoredInHash;
- // True if our node has no indirect constraints (complex or otherwise)
- bool Direct;
- // True if the node is address taken, *or* it is part of a group of nodes
- // that must be kept together. This is set to true for functions and
- // their arg nodes, which must be kept at the same position relative to
- // their base function node.
- bool AddressTaken;
-
- // Nodes in cycles (or in equivalence classes) are united together using a
- // standard union-find representation with path compression. NodeRep
- // gives the index into GraphNodes for the representative Node.
- unsigned NodeRep;
-
- // Modification timestamp. Assigned from Counter.
- // Used for work list prioritization.
- unsigned Timestamp;
-
- explicit Node(bool direct = true) :
- Val(0), Edges(0), PointsTo(0), OldPointsTo(0),
- PointerEquivLabel(0), LocationEquivLabel(0), PredEdges(0),
- ImplicitPredEdges(0), PointedToBy(0), NumInEdges(0),
- StoredInHash(false), Direct(direct), AddressTaken(false),
- NodeRep(SelfRep), Timestamp(0) { }
-
- Node *setValue(Value *V) {
- assert(Val == 0 && "Value already set for this node!");
- Val = V;
- return this;
- }
-
- /// getValue - Return the LLVM value corresponding to this node.
- ///
- Value *getValue() const { return Val; }
-
- /// addPointerTo - Add a pointer to the list of pointees of this node,
- /// returning true if this caused a new pointer to be added, or false if
- /// we already knew about the points-to relation.
- bool addPointerTo(unsigned Node) {
- return PointsTo->test_and_set(Node);
- }
-
- /// intersects - Return true if the points-to set of this node intersects
- /// with the points-to set of the specified node.
- bool intersects(Node *N) const;
-
- /// intersectsIgnoring - Return true if the points-to set of this node
- /// intersects with the points-to set of the specified node on any nodes
- /// except for the specified node to ignore.
- bool intersectsIgnoring(Node *N, unsigned) const;
-
- // Timestamp a node (used for work list prioritization)
- void Stamp() {
- Timestamp = sys::AtomicIncrement(&Counter);
- --Timestamp;
- }
-
- bool isRep() const {
- return( (int) NodeRep < 0 );
- }
- };
-
- struct WorkListElement {
- Node* node;
- unsigned Timestamp;
- WorkListElement(Node* n, unsigned t) : node(n), Timestamp(t) {}
-
- // Note that we reverse the sense of the comparison because we
- // actually want to give low timestamps the priority over high,
- // whereas priority is typically interpreted as a greater value is
- // given high priority.
- bool operator<(const WorkListElement& that) const {
- return( this->Timestamp > that.Timestamp );
- }
- };
-
- // Priority-queue based work list specialized for Nodes.
- class WorkList {
- std::priority_queue<WorkListElement> Q;
-
- public:
- void insert(Node* n) {
- Q.push( WorkListElement(n, n->Timestamp) );
- }
-
- // We automatically discard non-representative nodes and nodes
- // that were in the work list twice (we keep a copy of the
- // timestamp in the work list so we can detect this situation by
- // comparing against the node's current timestamp).
- Node* pop() {
- while( !Q.empty() ) {
- WorkListElement x = Q.top(); Q.pop();
- Node* INode = x.node;
-
- if( INode->isRep() &&
- INode->Timestamp == x.Timestamp ) {
- return(x.node);
- }
- }
- return(0);
- }
-
- bool empty() {
- return Q.empty();
- }
- };
-
- /// GraphNodes - This vector is populated as part of the object
- /// identification stage of the analysis, which populates this vector with a
- /// node for each memory object and fills in the ValueNodes map.
- std::vector<Node> GraphNodes;
-
- /// ValueNodes - This map indicates the Node that a particular Value* is
- /// represented by. This contains entries for all pointers.
- DenseMap<Value*, unsigned> ValueNodes;
-
- /// ObjectNodes - This map contains entries for each memory object in the
- /// program: globals, alloca's and mallocs.
- DenseMap<Value*, unsigned> ObjectNodes;
-
- /// ReturnNodes - This map contains an entry for each function in the
- /// program that returns a value.
- DenseMap<Function*, unsigned> ReturnNodes;
-
- /// VarargNodes - This map contains the entry used to represent all pointers
- /// passed through the varargs portion of a function call for a particular
- /// function. An entry is not present in this map for functions that do not
- /// take variable arguments.
- DenseMap<Function*, unsigned> VarargNodes;
-
-
- /// Constraints - This vector contains a list of all of the constraints
- /// identified by the program.
- std::vector<Constraint> Constraints;
-
- // Map from graph node to maximum K value that is allowed (for functions,
- // this is equivalent to the number of arguments + CallFirstArgPos)
- std::map<unsigned, unsigned> MaxK;
-
- /// This enum defines the GraphNodes indices that correspond to important
- /// fixed sets.
- enum {
- UniversalSet = 0,
- NullPtr = 1,
- NullObject = 2,
- NumberSpecialNodes
- };
- // Stack for Tarjan's
- std::stack<unsigned> SCCStack;
- // Map from Graph Node to DFS number
- std::vector<unsigned> Node2DFS;
- // Map from Graph Node to Deleted from graph.
- std::vector<bool> Node2Deleted;
- // Same as Node Maps, but implemented as std::map because it is faster to
- // clear
- std::map<unsigned, unsigned> Tarjan2DFS;
- std::map<unsigned, bool> Tarjan2Deleted;
- // Current DFS number
- unsigned DFSNumber;
-
- // Work lists.
- WorkList w1, w2;
- WorkList *CurrWL, *NextWL; // "current" and "next" work lists
-
- // Offline variable substitution related things
-
- // Temporary rep storage, used because we can't collapse SCC's in the
- // predecessor graph by uniting the variables permanently, we can only do so
- // for the successor graph.
- std::vector<unsigned> VSSCCRep;
- // Mapping from node to whether we have visited it during SCC finding yet.
- std::vector<bool> Node2Visited;
- // During variable substitution, we create unknowns to represent the unknown
- // value that is a dereference of a variable. These nodes are known as
- // "ref" nodes (since they represent the value of dereferences).
- unsigned FirstRefNode;
- // During HVN, we create represent address taken nodes as if they were
- // unknown (since HVN, unlike HU, does not evaluate unions).
- unsigned FirstAdrNode;
- // Current pointer equivalence class number
- unsigned PEClass;
- // Mapping from points-to sets to equivalence classes
- typedef DenseMap<SparseBitVector<> *, unsigned, BitmapKeyInfo> BitVectorMap;
- BitVectorMap Set2PEClass;
- // Mapping from pointer equivalences to the representative node. -1 if we
- // have no representative node for this pointer equivalence class yet.
- std::vector<int> PEClass2Node;
- // Mapping from pointer equivalences to representative node. This includes
- // pointer equivalent but not location equivalent variables. -1 if we have
- // no representative node for this pointer equivalence class yet.
- std::vector<int> PENLEClass2Node;
- // Union/Find for HCD
- std::vector<unsigned> HCDSCCRep;
- // HCD's offline-detected cycles; "Statically DeTected"
- // -1 if not part of such a cycle, otherwise a representative node.
- std::vector<int> SDT;
- // Whether to use SDT (UniteNodes can use it during solving, but not before)
- bool SDTActive;
-
- public:
- static char ID;
- Andersens() : ModulePass(&ID) {}
-
- bool runOnModule(Module &M) {
- InitializeAliasAnalysis(this);
- IdentifyObjects(M);
- CollectConstraints(M);
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa-constraints"
- DEBUG(PrintConstraints());
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa"
- SolveConstraints();
- DEBUG(PrintPointsToGraph());
-
- // Free the constraints list, as we don't need it to respond to alias
- // requests.
- std::vector<Constraint>().swap(Constraints);
- //These are needed for Print() (-analyze in opt)
- //ObjectNodes.clear();
- //ReturnNodes.clear();
- //VarargNodes.clear();
- return false;
- }
-
- void releaseMemory() {
- // FIXME: Until we have transitively required passes working correctly,
- // this cannot be enabled! Otherwise, using -count-aa with the pass
- // causes memory to be freed too early. :(
-#if 0
- // The memory objects and ValueNodes data structures at the only ones that
- // are still live after construction.
- std::vector<Node>().swap(GraphNodes);
- ValueNodes.clear();
-#endif
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AliasAnalysis::getAnalysisUsage(AU);
- 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
- //
- AliasResult alias(const Value *V1, unsigned V1Size,
- const Value *V2, unsigned V2Size);
- virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
- virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
- bool pointsToConstantMemory(const Value *P);
-
- virtual void deleteValue(Value *V) {
- ValueNodes.erase(V);
- getAnalysis<AliasAnalysis>().deleteValue(V);
- }
-
- virtual void copyValue(Value *From, Value *To) {
- ValueNodes[To] = ValueNodes[From];
- getAnalysis<AliasAnalysis>().copyValue(From, To);
- }
-
- private:
- /// getNode - Return the node corresponding to the specified pointer scalar.
- ///
- unsigned getNode(Value *V) {
- if (Constant *C = dyn_cast<Constant>(V))
- if (!isa<GlobalValue>(C))
- return getNodeForConstantPointer(C);
-
- DenseMap<Value*, unsigned>::iterator I = ValueNodes.find(V);
- if (I == ValueNodes.end()) {
-#ifndef NDEBUG
- V->dump();
-#endif
- llvm_unreachable("Value does not have a node in the points-to graph!");
- }
- return I->second;
- }
-
- /// getObject - Return the node corresponding to the memory object for the
- /// specified global or allocation instruction.
- unsigned getObject(Value *V) const {
- DenseMap<Value*, unsigned>::const_iterator I = ObjectNodes.find(V);
- assert(I != ObjectNodes.end() &&
- "Value does not have an object in the points-to graph!");
- return I->second;
- }
-
- /// getReturnNode - Return the node representing the return value for the
- /// specified function.
- unsigned getReturnNode(Function *F) const {
- DenseMap<Function*, unsigned>::const_iterator I = ReturnNodes.find(F);
- assert(I != ReturnNodes.end() && "Function does not return a value!");
- return I->second;
- }
-
- /// getVarargNode - Return the node representing the variable arguments
- /// formal for the specified function.
- unsigned getVarargNode(Function *F) const {
- DenseMap<Function*, unsigned>::const_iterator I = VarargNodes.find(F);
- assert(I != VarargNodes.end() && "Function does not take var args!");
- return I->second;
- }
-
- /// getNodeValue - Get the node for the specified LLVM value and set the
- /// value for it to be the specified value.
- unsigned getNodeValue(Value &V) {
- unsigned Index = getNode(&V);
- GraphNodes[Index].setValue(&V);
- return Index;
- }
-
- unsigned UniteNodes(unsigned First, unsigned Second,
- bool UnionByRank = true);
- unsigned FindNode(unsigned Node);
- unsigned FindNode(unsigned Node) const;
-
- void IdentifyObjects(Module &M);
- void CollectConstraints(Module &M);
- bool AnalyzeUsesOfFunction(Value *);
- void CreateConstraintGraph();
- void OptimizeConstraints();
- unsigned FindEquivalentNode(unsigned, unsigned);
- void ClumpAddressTaken();
- void RewriteConstraints();
- void HU();
- void HVN();
- void HCD();
- void Search(unsigned Node);
- void UnitePointerEquivalences();
- void SolveConstraints();
- bool QueryNode(unsigned Node);
- void Condense(unsigned Node);
- void HUValNum(unsigned Node);
- void HVNValNum(unsigned Node);
- unsigned getNodeForConstantPointer(Constant *C);
- unsigned getNodeForConstantPointerTarget(Constant *C);
- void AddGlobalInitializerConstraints(unsigned, Constant *C);
-
- void AddConstraintsForNonInternalLinkage(Function *F);
- void AddConstraintsForCall(CallSite CS, Function *F);
- bool AddConstraintsForExternalCall(CallSite CS, Function *F);
-
-
- void PrintNode(const Node *N) const;
- void PrintConstraints() const ;
- void PrintConstraint(const Constraint &) const;
- void PrintLabels() const;
- void PrintPointsToGraph() const;
-
- //===------------------------------------------------------------------===//
- // Instruction visitation methods for adding constraints
- //
- friend class InstVisitor<Andersens>;
- void visitReturnInst(ReturnInst &RI);
- void visitInvokeInst(InvokeInst &II) { visitCallSite(CallSite(&II)); }
- void visitCallInst(CallInst &CI) {
- if (isMalloc(&CI)) visitAlloc(CI);
- else visitCallSite(CallSite(&CI));
- }
- void visitCallSite(CallSite CS);
- void visitAllocaInst(AllocaInst &I);
- void visitAlloc(Instruction &I);
- void visitLoadInst(LoadInst &LI);
- void visitStoreInst(StoreInst &SI);
- void visitGetElementPtrInst(GetElementPtrInst &GEP);
- void visitPHINode(PHINode &PN);
- void visitCastInst(CastInst &CI);
- void visitICmpInst(ICmpInst &ICI) {} // NOOP!
- void visitFCmpInst(FCmpInst &ICI) {} // NOOP!
- void visitSelectInst(SelectInst &SI);
- void visitVAArg(VAArgInst &I);
- void visitInstruction(Instruction &I);
-
- //===------------------------------------------------------------------===//
- // Implement Analyize interface
- //
- void print(raw_ostream &O, const Module*) const {
- PrintPointsToGraph();
- }
- };
-}
-
-char Andersens::ID = 0;
-static RegisterPass<Andersens>
-X("anders-aa", "Andersen's Interprocedural Alias Analysis (experimental)",
- false, true);
-static RegisterAnalysisGroup<AliasAnalysis> Y(X);
-
-// Initialize Timestamp Counter (static).
-volatile llvm::sys::cas_flag Andersens::Node::Counter = 0;
-
-ModulePass *llvm::createAndersensPass() { return new Andersens(); }
-
-//===----------------------------------------------------------------------===//
-// AliasAnalysis Interface Implementation
-//===----------------------------------------------------------------------===//
-
-AliasAnalysis::AliasResult Andersens::alias(const Value *V1, unsigned V1Size,
- const Value *V2, unsigned V2Size) {
- Node *N1 = &GraphNodes[FindNode(getNode(const_cast<Value*>(V1)))];
- Node *N2 = &GraphNodes[FindNode(getNode(const_cast<Value*>(V2)))];
-
- // Check to see if the two pointers are known to not alias. They don't alias
- // if their points-to sets do not intersect.
- if (!N1->intersectsIgnoring(N2, NullObject))
- return NoAlias;
-
- return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
-}
-
-AliasAnalysis::ModRefResult
-Andersens::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
- // The only thing useful that we can contribute for mod/ref information is
- // when calling external function calls: if we know that memory never escapes
- // from the program, it cannot be modified by an external call.
- //
- // NOTE: This is not really safe, at least not when the entire program is not
- // available. The deal is that the external function could call back into the
- // program and modify stuff. We ignore this technical niggle for now. This
- // is, after all, a "research quality" implementation of Andersen's analysis.
- if (Function *F = CS.getCalledFunction())
- if (F->isDeclaration()) {
- Node *N1 = &GraphNodes[FindNode(getNode(P))];
-
- if (N1->PointsTo->empty())
- return NoModRef;
-#if FULL_UNIVERSAL
- if (!UniversalSet->PointsTo->test(FindNode(getNode(P))))
- return NoModRef; // Universal set does not contain P
-#else
- if (!N1->PointsTo->test(UniversalSet))
- return NoModRef; // P doesn't point to the universal set.
-#endif
- }
-
- return AliasAnalysis::getModRefInfo(CS, P, Size);
-}
-
-AliasAnalysis::ModRefResult
-Andersens::getModRefInfo(CallSite CS1, CallSite CS2) {
- return AliasAnalysis::getModRefInfo(CS1,CS2);
-}
-
-/// pointsToConstantMemory - If we can determine that this pointer only points
-/// to constant memory, return true. In practice, this means that if the
-/// pointer can only point to constant globals, functions, or the null pointer,
-/// return true.
-///
-bool Andersens::pointsToConstantMemory(const Value *P) {
- Node *N = &GraphNodes[FindNode(getNode(const_cast<Value*>(P)))];
- unsigned i;
-
- for (SparseBitVector<>::iterator bi = N->PointsTo->begin();
- bi != N->PointsTo->end();
- ++bi) {
- i = *bi;
- Node *Pointee = &GraphNodes[i];
- if (Value *V = Pointee->getValue()) {
- if (!isa<GlobalValue>(V) || (isa<GlobalVariable>(V) &&
- !cast<GlobalVariable>(V)->isConstant()))
- return AliasAnalysis::pointsToConstantMemory(P);
- } else {
- if (i != NullObject)
- return AliasAnalysis::pointsToConstantMemory(P);
- }
- }
-
- return true;
-}
-
-//===----------------------------------------------------------------------===//
-// Object Identification Phase
-//===----------------------------------------------------------------------===//
-
-/// IdentifyObjects - This stage scans the program, adding an entry to the
-/// GraphNodes list for each memory object in the program (global stack or
-/// heap), and populates the ValueNodes and ObjectNodes maps for these objects.
-///
-void Andersens::IdentifyObjects(Module &M) {
- unsigned NumObjects = 0;
-
- // Object #0 is always the universal set: the object that we don't know
- // anything about.
- assert(NumObjects == UniversalSet && "Something changed!");
- ++NumObjects;
-
- // Object #1 always represents the null pointer.
- assert(NumObjects == NullPtr && "Something changed!");
- ++NumObjects;
-
- // Object #2 always represents the null object (the object pointed to by null)
- assert(NumObjects == NullObject && "Something changed!");
- ++NumObjects;
-
- // Add all the globals first.
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I) {
- ObjectNodes[I] = NumObjects++;
- ValueNodes[I] = NumObjects++;
- }
-
- // Add nodes for all of the functions and the instructions inside of them.
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- // The function itself is a memory object.
- unsigned First = NumObjects;
- ValueNodes[F] = NumObjects++;
- if (isa<PointerType>(F->getFunctionType()->getReturnType()))
- ReturnNodes[F] = NumObjects++;
- if (F->getFunctionType()->isVarArg())
- VarargNodes[F] = NumObjects++;
-
-
- // Add nodes for all of the incoming pointer arguments.
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I)
- {
- if (isa<PointerType>(I->getType()))
- ValueNodes[I] = NumObjects++;
- }
- MaxK[First] = NumObjects - First;
-
- // Scan the function body, creating a memory object for each heap/stack
- // allocation in the body of the function and a node to represent all
- // pointer values defined by instructions and used as operands.
- for (inst_iterator II = inst_begin(F), E = inst_end(F); II != E; ++II) {
- // If this is an heap or stack allocation, create a node for the memory
- // object.
- if (isa<PointerType>(II->getType())) {
- ValueNodes[&*II] = NumObjects++;
- if (AllocaInst *AI = dyn_cast<AllocaInst>(&*II))
- ObjectNodes[AI] = NumObjects++;
- else if (isMalloc(&*II))
- ObjectNodes[&*II] = NumObjects++;
- }
-
- // Calls to inline asm need to be added as well because the callee isn't
- // referenced anywhere else.
- if (CallInst *CI = dyn_cast<CallInst>(&*II)) {
- Value *Callee = CI->getCalledValue();
- if (isa<InlineAsm>(Callee))
- ValueNodes[Callee] = NumObjects++;
- }
- }
- }
-
- // Now that we know how many objects to create, make them all now!
- GraphNodes.resize(NumObjects);
- NumNodes += NumObjects;
-}
-
-//===----------------------------------------------------------------------===//
-// Constraint Identification Phase
-//===----------------------------------------------------------------------===//
-
-/// getNodeForConstantPointer - Return the node corresponding to the constant
-/// pointer itself.
-unsigned Andersens::getNodeForConstantPointer(Constant *C) {
- assert(isa<PointerType>(C->getType()) && "Not a constant pointer!");
-
- if (isa<ConstantPointerNull>(C) || isa<UndefValue>(C))
- return NullPtr;
- else if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
- return getNode(GV);
- else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
- switch (CE->getOpcode()) {
- case Instruction::GetElementPtr:
- return getNodeForConstantPointer(CE->getOperand(0));
- case Instruction::IntToPtr:
- return UniversalSet;
- case Instruction::BitCast:
- return getNodeForConstantPointer(CE->getOperand(0));
- default:
- errs() << "Constant Expr not yet handled: " << *CE << "\n";
- llvm_unreachable(0);
- }
- } else {
- llvm_unreachable("Unknown constant pointer!");
- }
- return 0;
-}
-
-/// getNodeForConstantPointerTarget - Return the node POINTED TO by the
-/// specified constant pointer.
-unsigned Andersens::getNodeForConstantPointerTarget(Constant *C) {
- assert(isa<PointerType>(C->getType()) && "Not a constant pointer!");
-
- if (isa<ConstantPointerNull>(C))
- return NullObject;
- else if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
- return getObject(GV);
- else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
- switch (CE->getOpcode()) {
- case Instruction::GetElementPtr:
- return getNodeForConstantPointerTarget(CE->getOperand(0));
- case Instruction::IntToPtr:
- return UniversalSet;
- case Instruction::BitCast:
- return getNodeForConstantPointerTarget(CE->getOperand(0));
- default:
- errs() << "Constant Expr not yet handled: " << *CE << "\n";
- llvm_unreachable(0);
- }
- } else {
- llvm_unreachable("Unknown constant pointer!");
- }
- return 0;
-}
-
-/// AddGlobalInitializerConstraints - Add inclusion constraints for the memory
-/// object N, which contains values indicated by C.
-void Andersens::AddGlobalInitializerConstraints(unsigned NodeIndex,
- Constant *C) {
- if (C->getType()->isSingleValueType()) {
- if (isa<PointerType>(C->getType()))
- Constraints.push_back(Constraint(Constraint::Copy, NodeIndex,
- getNodeForConstantPointer(C)));
- } else if (C->isNullValue()) {
- Constraints.push_back(Constraint(Constraint::Copy, NodeIndex,
- NullObject));
- return;
- } else if (!isa<UndefValue>(C)) {
- // If this is an array or struct, include constraints for each element.
- assert(isa<ConstantArray>(C) || isa<ConstantStruct>(C));
- for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
- AddGlobalInitializerConstraints(NodeIndex,
- cast<Constant>(C->getOperand(i)));
- }
-}
-
-/// AddConstraintsForNonInternalLinkage - If this function does not have
-/// internal linkage, realize that we can't trust anything passed into or
-/// returned by this function.
-void Andersens::AddConstraintsForNonInternalLinkage(Function *F) {
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
- if (isa<PointerType>(I->getType()))
- // If this is an argument of an externally accessible function, the
- // incoming pointer might point to anything.
- Constraints.push_back(Constraint(Constraint::Copy, getNode(I),
- UniversalSet));
-}
-
-/// AddConstraintsForCall - If this is a call to a "known" function, add the
-/// constraints and return true. If this is a call to an unknown function,
-/// return false.
-bool Andersens::AddConstraintsForExternalCall(CallSite CS, Function *F) {
- assert(F->isDeclaration() && "Not an external function!");
-
- // These functions don't induce any points-to constraints.
- if (F->getName() == "atoi" || F->getName() == "atof" ||
- F->getName() == "atol" || F->getName() == "atoll" ||
- F->getName() == "remove" || F->getName() == "unlink" ||
- F->getName() == "rename" || F->getName() == "memcmp" ||
- F->getName() == "llvm.memset" ||
- F->getName() == "strcmp" || F->getName() == "strncmp" ||
- F->getName() == "execl" || F->getName() == "execlp" ||
- F->getName() == "execle" || F->getName() == "execv" ||
- F->getName() == "execvp" || F->getName() == "chmod" ||
- F->getName() == "puts" || F->getName() == "write" ||
- F->getName() == "open" || F->getName() == "create" ||
- F->getName() == "truncate" || F->getName() == "chdir" ||
- F->getName() == "mkdir" || F->getName() == "rmdir" ||
- F->getName() == "read" || F->getName() == "pipe" ||
- F->getName() == "wait" || F->getName() == "time" ||
- F->getName() == "stat" || F->getName() == "fstat" ||
- F->getName() == "lstat" || F->getName() == "strtod" ||
- F->getName() == "strtof" || F->getName() == "strtold" ||
- F->getName() == "fopen" || F->getName() == "fdopen" ||
- F->getName() == "freopen" ||
- F->getName() == "fflush" || F->getName() == "feof" ||
- F->getName() == "fileno" || F->getName() == "clearerr" ||
- F->getName() == "rewind" || F->getName() == "ftell" ||
- F->getName() == "ferror" || F->getName() == "fgetc" ||
- F->getName() == "fgetc" || F->getName() == "_IO_getc" ||
- F->getName() == "fwrite" || F->getName() == "fread" ||
- F->getName() == "fgets" || F->getName() == "ungetc" ||
- F->getName() == "fputc" ||
- F->getName() == "fputs" || F->getName() == "putc" ||
- F->getName() == "ftell" || F->getName() == "rewind" ||
- F->getName() == "_IO_putc" || F->getName() == "fseek" ||
- F->getName() == "fgetpos" || F->getName() == "fsetpos" ||
- F->getName() == "printf" || F->getName() == "fprintf" ||
- F->getName() == "sprintf" || F->getName() == "vprintf" ||
- F->getName() == "vfprintf" || F->getName() == "vsprintf" ||
- F->getName() == "scanf" || F->getName() == "fscanf" ||
- F->getName() == "sscanf" || F->getName() == "__assert_fail" ||
- F->getName() == "modf")
- return true;
-
-
- // These functions do induce points-to edges.
- if (F->getName() == "llvm.memcpy" ||
- F->getName() == "llvm.memmove" ||
- F->getName() == "memmove") {
-
- const FunctionType *FTy = F->getFunctionType();
- if (FTy->getNumParams() > 1 &&
- isa<PointerType>(FTy->getParamType(0)) &&
- isa<PointerType>(FTy->getParamType(1))) {
-
- // *Dest = *Src, which requires an artificial graph node to represent the
- // constraint. It is broken up into *Dest = temp, temp = *Src
- unsigned FirstArg = getNode(CS.getArgument(0));
- unsigned SecondArg = getNode(CS.getArgument(1));
- unsigned TempArg = GraphNodes.size();
- GraphNodes.push_back(Node());
- Constraints.push_back(Constraint(Constraint::Store,
- FirstArg, TempArg));
- Constraints.push_back(Constraint(Constraint::Load,
- TempArg, SecondArg));
- // In addition, Dest = Src
- Constraints.push_back(Constraint(Constraint::Copy,
- FirstArg, SecondArg));
- return true;
- }
- }
-
- // Result = Arg0
- if (F->getName() == "realloc" || F->getName() == "strchr" ||
- F->getName() == "strrchr" || F->getName() == "strstr" ||
- F->getName() == "strtok") {
- const FunctionType *FTy = F->getFunctionType();
- if (FTy->getNumParams() > 0 &&
- isa<PointerType>(FTy->getParamType(0))) {
- Constraints.push_back(Constraint(Constraint::Copy,
- getNode(CS.getInstruction()),
- getNode(CS.getArgument(0))));
- return true;
- }
- }
-
- return false;
-}
-
-
-
-/// AnalyzeUsesOfFunction - Look at all of the users of the specified function.
-/// If this is used by anything complex (i.e., the address escapes), return
-/// true.
-bool Andersens::AnalyzeUsesOfFunction(Value *V) {
-
- if (!isa<PointerType>(V->getType())) return true;
-
- for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
- if (isa<LoadInst>(*UI)) {
- return false;
- } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
- if (V == SI->getOperand(1)) {
- return false;
- } else if (SI->getOperand(1)) {
- return true; // Storing the pointer
- }
- } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*UI)) {
- if (AnalyzeUsesOfFunction(GEP)) return true;
- } else if (isFreeCall(*UI)) {
- return false;
- } else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
- // Make sure that this is just the function being called, not that it is
- // passing into the function.
- for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
- if (CI->getOperand(i) == V) return true;
- } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
- // Make sure that this is just the function being called, not that it is
- // passing into the function.
- for (unsigned i = 3, e = II->getNumOperands(); i != e; ++i)
- if (II->getOperand(i) == V) return true;
- } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
- if (CE->getOpcode() == Instruction::GetElementPtr ||
- CE->getOpcode() == Instruction::BitCast) {
- if (AnalyzeUsesOfFunction(CE))
- return true;
- } else {
- return true;
- }
- } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
- if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
- return true; // Allow comparison against null.
- } else {
- return true;
- }
- return false;
-}
-
-/// CollectConstraints - This stage scans the program, adding a constraint to
-/// the Constraints list for each instruction in the program that induces a
-/// constraint, and setting up the initial points-to graph.
-///
-void Andersens::CollectConstraints(Module &M) {
- // First, the universal set points to itself.
- Constraints.push_back(Constraint(Constraint::AddressOf, UniversalSet,
- UniversalSet));
- Constraints.push_back(Constraint(Constraint::Store, UniversalSet,
- UniversalSet));
-
- // Next, the null pointer points to the null object.
- Constraints.push_back(Constraint(Constraint::AddressOf, NullPtr, NullObject));
-
- // Next, add any constraints on global variables and their initializers.
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I) {
- // Associate the address of the global object as pointing to the memory for
- // the global: &G = <G memory>
- unsigned ObjectIndex = getObject(I);
- Node *Object = &GraphNodes[ObjectIndex];
- Object->setValue(I);
- Constraints.push_back(Constraint(Constraint::AddressOf, getNodeValue(*I),
- ObjectIndex));
-
- if (I->hasDefinitiveInitializer()) {
- AddGlobalInitializerConstraints(ObjectIndex, I->getInitializer());
- } else {
- // If it doesn't have an initializer (i.e. it's defined in another
- // translation unit), it points to the universal set.
- Constraints.push_back(Constraint(Constraint::Copy, ObjectIndex,
- UniversalSet));
- }
- }
-
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- // Set up the return value node.
- if (isa<PointerType>(F->getFunctionType()->getReturnType()))
- GraphNodes[getReturnNode(F)].setValue(F);
- if (F->getFunctionType()->isVarArg())
- GraphNodes[getVarargNode(F)].setValue(F);
-
- // Set up incoming argument nodes.
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I)
- if (isa<PointerType>(I->getType()))
- getNodeValue(*I);
-
- // At some point we should just add constraints for the escaping functions
- // at solve time, but this slows down solving. For now, we simply mark
- // address taken functions as escaping and treat them as external.
- if (!F->hasLocalLinkage() || AnalyzeUsesOfFunction(F))
- AddConstraintsForNonInternalLinkage(F);
-
- if (!F->isDeclaration()) {
- // Scan the function body, creating a memory object for each heap/stack
- // allocation in the body of the function and a node to represent all
- // pointer values defined by instructions and used as operands.
- visit(F);
- } else {
- // External functions that return pointers return the universal set.
- if (isa<PointerType>(F->getFunctionType()->getReturnType()))
- Constraints.push_back(Constraint(Constraint::Copy,
- getReturnNode(F),
- UniversalSet));
-
- // Any pointers that are passed into the function have the universal set
- // stored into them.
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I)
- if (isa<PointerType>(I->getType())) {
- // Pointers passed into external functions could have anything stored
- // through them.
- Constraints.push_back(Constraint(Constraint::Store, getNode(I),
- UniversalSet));
- // Memory objects passed into external function calls can have the
- // universal set point to them.
-#if FULL_UNIVERSAL
- Constraints.push_back(Constraint(Constraint::Copy,
- UniversalSet,
- getNode(I)));
-#else
- Constraints.push_back(Constraint(Constraint::Copy,
- getNode(I),
- UniversalSet));
-#endif
- }
-
- // If this is an external varargs function, it can also store pointers
- // into any pointers passed through the varargs section.
- if (F->getFunctionType()->isVarArg())
- Constraints.push_back(Constraint(Constraint::Store, getVarargNode(F),
- UniversalSet));
- }
- }
- NumConstraints += Constraints.size();
-}
-
-
-void Andersens::visitInstruction(Instruction &I) {
-#ifdef NDEBUG
- return; // This function is just a big assert.
-#endif
- if (isa<BinaryOperator>(I))
- return;
- // Most instructions don't have any effect on pointer values.
- switch (I.getOpcode()) {
- case Instruction::Br:
- case Instruction::Switch:
- case Instruction::Unwind:
- case Instruction::Unreachable:
- case Instruction::ICmp:
- case Instruction::FCmp:
- return;
- default:
- // Is this something we aren't handling yet?
- errs() << "Unknown instruction: " << I;
- llvm_unreachable(0);
- }
-}
-
-void Andersens::visitAllocaInst(AllocaInst &I) {
- visitAlloc(I);
-}
-
-void Andersens::visitAlloc(Instruction &I) {
- unsigned ObjectIndex = getObject(&I);
- GraphNodes[ObjectIndex].setValue(&I);
- Constraints.push_back(Constraint(Constraint::AddressOf, getNodeValue(I),
- ObjectIndex));
-}
-
-void Andersens::visitReturnInst(ReturnInst &RI) {
- if (RI.getNumOperands() && isa<PointerType>(RI.getOperand(0)->getType()))
- // return V --> <Copy/retval{F}/v>
- Constraints.push_back(Constraint(Constraint::Copy,
- getReturnNode(RI.getParent()->getParent()),
- getNode(RI.getOperand(0))));
-}
-
-void Andersens::visitLoadInst(LoadInst &LI) {
- if (isa<PointerType>(LI.getType()))
- // P1 = load P2 --> <Load/P1/P2>
- Constraints.push_back(Constraint(Constraint::Load, getNodeValue(LI),
- getNode(LI.getOperand(0))));
-}
-
-void Andersens::visitStoreInst(StoreInst &SI) {
- if (isa<PointerType>(SI.getOperand(0)->getType()))
- // store P1, P2 --> <Store/P2/P1>
- Constraints.push_back(Constraint(Constraint::Store,
- getNode(SI.getOperand(1)),
- getNode(SI.getOperand(0))));
-}
-
-void Andersens::visitGetElementPtrInst(GetElementPtrInst &GEP) {
- // P1 = getelementptr P2, ... --> <Copy/P1/P2>
- Constraints.push_back(Constraint(Constraint::Copy, getNodeValue(GEP),
- getNode(GEP.getOperand(0))));
-}
-
-void Andersens::visitPHINode(PHINode &PN) {
- if (isa<PointerType>(PN.getType())) {
- unsigned PNN = getNodeValue(PN);
- for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
- // P1 = phi P2, P3 --> <Copy/P1/P2>, <Copy/P1/P3>, ...
- Constraints.push_back(Constraint(Constraint::Copy, PNN,
- getNode(PN.getIncomingValue(i))));
- }
-}
-
-void Andersens::visitCastInst(CastInst &CI) {
- Value *Op = CI.getOperand(0);
- if (isa<PointerType>(CI.getType())) {
- if (isa<PointerType>(Op->getType())) {
- // P1 = cast P2 --> <Copy/P1/P2>
- Constraints.push_back(Constraint(Constraint::Copy, getNodeValue(CI),
- getNode(CI.getOperand(0))));
- } else {
- // P1 = cast int --> <Copy/P1/Univ>
-#if 0
- Constraints.push_back(Constraint(Constraint::Copy, getNodeValue(CI),
- UniversalSet));
-#else
- getNodeValue(CI);
-#endif
- }
- } else if (isa<PointerType>(Op->getType())) {
- // int = cast P1 --> <Copy/Univ/P1>
-#if 0
- Constraints.push_back(Constraint(Constraint::Copy,
- UniversalSet,
- getNode(CI.getOperand(0))));
-#else
- getNode(CI.getOperand(0));
-#endif
- }
-}
-
-void Andersens::visitSelectInst(SelectInst &SI) {
- if (isa<PointerType>(SI.getType())) {
- unsigned SIN = getNodeValue(SI);
- // P1 = select C, P2, P3 ---> <Copy/P1/P2>, <Copy/P1/P3>
- Constraints.push_back(Constraint(Constraint::Copy, SIN,
- getNode(SI.getOperand(1))));
- Constraints.push_back(Constraint(Constraint::Copy, SIN,
- getNode(SI.getOperand(2))));
- }
-}
-
-void Andersens::visitVAArg(VAArgInst &I) {
- llvm_unreachable("vaarg not handled yet!");
-}
-
-/// AddConstraintsForCall - Add constraints for a call with actual arguments
-/// specified by CS to the function specified by F. Note that the types of
-/// arguments might not match up in the case where this is an indirect call and
-/// the function pointer has been casted. If this is the case, do something
-/// reasonable.
-void Andersens::AddConstraintsForCall(CallSite CS, Function *F) {
- Value *CallValue = CS.getCalledValue();
- bool IsDeref = F == NULL;
-
- // If this is a call to an external function, try to handle it directly to get
- // some taste of context sensitivity.
- if (F && F->isDeclaration() && AddConstraintsForExternalCall(CS, F))
- return;
-
- if (isa<PointerType>(CS.getType())) {
- unsigned CSN = getNode(CS.getInstruction());
- if (!F || isa<PointerType>(F->getFunctionType()->getReturnType())) {
- if (IsDeref)
- Constraints.push_back(Constraint(Constraint::Load, CSN,
- getNode(CallValue), CallReturnPos));
- else
- Constraints.push_back(Constraint(Constraint::Copy, CSN,
- getNode(CallValue) + CallReturnPos));
- } else {
- // If the function returns a non-pointer value, handle this just like we
- // treat a nonpointer cast to pointer.
- Constraints.push_back(Constraint(Constraint::Copy, CSN,
- UniversalSet));
- }
- } else if (F && isa<PointerType>(F->getFunctionType()->getReturnType())) {
-#if FULL_UNIVERSAL
- Constraints.push_back(Constraint(Constraint::Copy,
- UniversalSet,
- getNode(CallValue) + CallReturnPos));
-#else
- Constraints.push_back(Constraint(Constraint::Copy,
- getNode(CallValue) + CallReturnPos,
- UniversalSet));
-#endif
-
-
- }
-
- CallSite::arg_iterator ArgI = CS.arg_begin(), ArgE = CS.arg_end();
- bool external = !F || F->isDeclaration();
- if (F) {
- // Direct Call
- Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
- for (; AI != AE && ArgI != ArgE; ++AI, ++ArgI)
- {
-#if !FULL_UNIVERSAL
- if (external && isa<PointerType>((*ArgI)->getType()))
- {
- // Add constraint that ArgI can now point to anything due to
- // escaping, as can everything it points to. The second portion of
- // this should be taken care of by universal = *universal
- Constraints.push_back(Constraint(Constraint::Copy,
- getNode(*ArgI),
- UniversalSet));
- }
-#endif
- if (isa<PointerType>(AI->getType())) {
- if (isa<PointerType>((*ArgI)->getType())) {
- // Copy the actual argument into the formal argument.
- Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
- getNode(*ArgI)));
- } else {
- Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
- UniversalSet));
- }
- } else if (isa<PointerType>((*ArgI)->getType())) {
-#if FULL_UNIVERSAL
- Constraints.push_back(Constraint(Constraint::Copy,
- UniversalSet,
- getNode(*ArgI)));
-#else
- Constraints.push_back(Constraint(Constraint::Copy,
- getNode(*ArgI),
- UniversalSet));
-#endif
- }
- }
- } else {
- //Indirect Call
- unsigned ArgPos = CallFirstArgPos;
- for (; ArgI != ArgE; ++ArgI) {
- if (isa<PointerType>((*ArgI)->getType())) {
- // Copy the actual argument into the formal argument.
- Constraints.push_back(Constraint(Constraint::Store,
- getNode(CallValue),
- getNode(*ArgI), ArgPos++));
- } else {
- Constraints.push_back(Constraint(Constraint::Store,
- getNode (CallValue),
- UniversalSet, ArgPos++));
- }
- }
- }
- // Copy all pointers passed through the varargs section to the varargs node.
- if (F && F->getFunctionType()->isVarArg())
- for (; ArgI != ArgE; ++ArgI)
- if (isa<PointerType>((*ArgI)->getType()))
- Constraints.push_back(Constraint(Constraint::Copy, getVarargNode(F),
- getNode(*ArgI)));
- // If more arguments are passed in than we track, just drop them on the floor.
-}
-
-void Andersens::visitCallSite(CallSite CS) {
- if (isa<PointerType>(CS.getType()))
- getNodeValue(*CS.getInstruction());
-
- if (Function *F = CS.getCalledFunction()) {
- AddConstraintsForCall(CS, F);
- } else {
- AddConstraintsForCall(CS, NULL);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Constraint Solving Phase
-//===----------------------------------------------------------------------===//
-
-/// intersects - Return true if the points-to set of this node intersects
-/// with the points-to set of the specified node.
-bool Andersens::Node::intersects(Node *N) const {
- return PointsTo->intersects(N->PointsTo);
-}
-
-/// intersectsIgnoring - Return true if the points-to set of this node
-/// intersects with the points-to set of the specified node on any nodes
-/// except for the specified node to ignore.
-bool Andersens::Node::intersectsIgnoring(Node *N, unsigned Ignoring) const {
- // TODO: If we are only going to call this with the same value for Ignoring,
- // we should move the special values out of the points-to bitmap.
- bool WeHadIt = PointsTo->test(Ignoring);
- bool NHadIt = N->PointsTo->test(Ignoring);
- bool Result = false;
- if (WeHadIt)
- PointsTo->reset(Ignoring);
- if (NHadIt)
- N->PointsTo->reset(Ignoring);
- Result = PointsTo->intersects(N->PointsTo);
- if (WeHadIt)
- PointsTo->set(Ignoring);
- if (NHadIt)
- N->PointsTo->set(Ignoring);
- return Result;
-}
-
-
-/// Clump together address taken variables so that the points-to sets use up
-/// less space and can be operated on faster.
-
-void Andersens::ClumpAddressTaken() {
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa-renumber"
- std::vector<unsigned> Translate;
- std::vector<Node> NewGraphNodes;
-
- Translate.resize(GraphNodes.size());
- unsigned NewPos = 0;
-
- for (unsigned i = 0; i < Constraints.size(); ++i) {
- Constraint &C = Constraints[i];
- if (C.Type == Constraint::AddressOf) {
- GraphNodes[C.Src].AddressTaken = true;
- }
- }
- for (unsigned i = 0; i < NumberSpecialNodes; ++i) {
- unsigned Pos = NewPos++;
- Translate[i] = Pos;
- NewGraphNodes.push_back(GraphNodes[i]);
- DEBUG(dbgs() << "Renumbering node " << i << " to node " << Pos << "\n");
- }
-
- // I believe this ends up being faster than making two vectors and splicing
- // them.
- for (unsigned i = NumberSpecialNodes; i < GraphNodes.size(); ++i) {
- if (GraphNodes[i].AddressTaken) {
- unsigned Pos = NewPos++;
- Translate[i] = Pos;
- NewGraphNodes.push_back(GraphNodes[i]);
- DEBUG(dbgs() << "Renumbering node " << i << " to node " << Pos << "\n");
- }
- }
-
- for (unsigned i = NumberSpecialNodes; i < GraphNodes.size(); ++i) {
- if (!GraphNodes[i].AddressTaken) {
- unsigned Pos = NewPos++;
- Translate[i] = Pos;
- NewGraphNodes.push_back(GraphNodes[i]);
- DEBUG(dbgs() << "Renumbering node " << i << " to node " << Pos << "\n");
- }
- }
-
- for (DenseMap<Value*, unsigned>::iterator Iter = ValueNodes.begin();
- Iter != ValueNodes.end();
- ++Iter)
- Iter->second = Translate[Iter->second];
-
- for (DenseMap<Value*, unsigned>::iterator Iter = ObjectNodes.begin();
- Iter != ObjectNodes.end();
- ++Iter)
- Iter->second = Translate[Iter->second];
-
- for (DenseMap<Function*, unsigned>::iterator Iter = ReturnNodes.begin();
- Iter != ReturnNodes.end();
- ++Iter)
- Iter->second = Translate[Iter->second];
-
- for (DenseMap<Function*, unsigned>::iterator Iter = VarargNodes.begin();
- Iter != VarargNodes.end();
- ++Iter)
- Iter->second = Translate[Iter->second];
-
- for (unsigned i = 0; i < Constraints.size(); ++i) {
- Constraint &C = Constraints[i];
- C.Src = Translate[C.Src];
- C.Dest = Translate[C.Dest];
- }
-
- GraphNodes.swap(NewGraphNodes);
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa"
-}
-
-/// The technique used here is described in "Exploiting Pointer and Location
-/// Equivalence to Optimize Pointer Analysis. In the 14th International Static
-/// Analysis Symposium (SAS), August 2007." It is known as the "HVN" algorithm,
-/// and is equivalent to value numbering the collapsed constraint graph without
-/// evaluating unions. This is used as a pre-pass to HU in order to resolve
-/// first order pointer dereferences and speed up/reduce memory usage of HU.
-/// Running both is equivalent to HRU without the iteration
-/// HVN in more detail:
-/// Imagine the set of constraints was simply straight line code with no loops
-/// (we eliminate cycles, so there are no loops), such as:
-/// E = &D
-/// E = &C
-/// E = F
-/// F = G
-/// G = F
-/// Applying value numbering to this code tells us:
-/// G == F == E
-///
-/// For HVN, this is as far as it goes. We assign new value numbers to every
-/// "address node", and every "reference node".
-/// To get the optimal result for this, we use a DFS + SCC (since all nodes in a
-/// cycle must have the same value number since the = operation is really
-/// inclusion, not overwrite), and value number nodes we receive points-to sets
-/// before we value our own node.
-/// The advantage of HU over HVN is that HU considers the inclusion property, so
-/// that if you have
-/// E = &D
-/// E = &C
-/// E = F
-/// F = G
-/// F = &D
-/// G = F
-/// HU will determine that G == F == E. HVN will not, because it cannot prove
-/// that the points to information ends up being the same because they all
-/// receive &D from E anyway.
-
-void Andersens::HVN() {
- DEBUG(dbgs() << "Beginning HVN\n");
- // Build a predecessor graph. This is like our constraint graph with the
- // edges going in the opposite direction, and there are edges for all the
- // constraints, instead of just copy constraints. We also build implicit
- // edges for constraints are implied but not explicit. I.E for the constraint
- // a = &b, we add implicit edges *a = b. This helps us capture more cycles
- for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- Constraint &C = Constraints[i];
- if (C.Type == Constraint::AddressOf) {
- GraphNodes[C.Src].AddressTaken = true;
- GraphNodes[C.Src].Direct = false;
-
- // Dest = &src edge
- unsigned AdrNode = C.Src + FirstAdrNode;
- if (!GraphNodes[C.Dest].PredEdges)
- GraphNodes[C.Dest].PredEdges = new SparseBitVector<>;
- GraphNodes[C.Dest].PredEdges->set(AdrNode);
-
- // *Dest = src edge
- unsigned RefNode = C.Dest + FirstRefNode;
- if (!GraphNodes[RefNode].ImplicitPredEdges)
- GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>;
- GraphNodes[RefNode].ImplicitPredEdges->set(C.Src);
- } else if (C.Type == Constraint::Load) {
- if (C.Offset == 0) {
- // dest = *src edge
- if (!GraphNodes[C.Dest].PredEdges)
- GraphNodes[C.Dest].PredEdges = new SparseBitVector<>;
- GraphNodes[C.Dest].PredEdges->set(C.Src + FirstRefNode);
- } else {
- GraphNodes[C.Dest].Direct = false;
- }
- } else if (C.Type == Constraint::Store) {
- if (C.Offset == 0) {
- // *dest = src edge
- unsigned RefNode = C.Dest + FirstRefNode;
- if (!GraphNodes[RefNode].PredEdges)
- GraphNodes[RefNode].PredEdges = new SparseBitVector<>;
- GraphNodes[RefNode].PredEdges->set(C.Src);
- }
- } else {
- // Dest = Src edge and *Dest = *Src edge
- if (!GraphNodes[C.Dest].PredEdges)
- GraphNodes[C.Dest].PredEdges = new SparseBitVector<>;
- GraphNodes[C.Dest].PredEdges->set(C.Src);
- unsigned RefNode = C.Dest + FirstRefNode;
- if (!GraphNodes[RefNode].ImplicitPredEdges)
- GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>;
- GraphNodes[RefNode].ImplicitPredEdges->set(C.Src + FirstRefNode);
- }
- }
- PEClass = 1;
- // Do SCC finding first to condense our predecessor graph
- DFSNumber = 0;
- Node2DFS.insert(Node2DFS.begin(), GraphNodes.size(), 0);
- Node2Deleted.insert(Node2Deleted.begin(), GraphNodes.size(), false);
- Node2Visited.insert(Node2Visited.begin(), GraphNodes.size(), false);
-
- for (unsigned i = 0; i < FirstRefNode; ++i) {
- unsigned Node = VSSCCRep[i];
- if (!Node2Visited[Node])
- HVNValNum(Node);
- }
- for (BitVectorMap::iterator Iter = Set2PEClass.begin();
- Iter != Set2PEClass.end();
- ++Iter)
- delete Iter->first;
- Set2PEClass.clear();
- Node2DFS.clear();
- Node2Deleted.clear();
- Node2Visited.clear();
- DEBUG(dbgs() << "Finished HVN\n");
-
-}
-
-/// This is the workhorse of HVN value numbering. We combine SCC finding at the
-/// same time because it's easy.
-void Andersens::HVNValNum(unsigned NodeIndex) {
- unsigned MyDFS = DFSNumber++;
- Node *N = &GraphNodes[NodeIndex];
- Node2Visited[NodeIndex] = true;
- Node2DFS[NodeIndex] = MyDFS;
-
- // First process all our explicit edges
- if (N->PredEdges)
- for (SparseBitVector<>::iterator Iter = N->PredEdges->begin();
- Iter != N->PredEdges->end();
- ++Iter) {
- unsigned j = VSSCCRep[*Iter];
- if (!Node2Deleted[j]) {
- if (!Node2Visited[j])
- HVNValNum(j);
- if (Node2DFS[NodeIndex] > Node2DFS[j])
- Node2DFS[NodeIndex] = Node2DFS[j];
- }
- }
-
- // Now process all the implicit edges
- if (N->ImplicitPredEdges)
- for (SparseBitVector<>::iterator Iter = N->ImplicitPredEdges->begin();
- Iter != N->ImplicitPredEdges->end();
- ++Iter) {
- unsigned j = VSSCCRep[*Iter];
- if (!Node2Deleted[j]) {
- if (!Node2Visited[j])
- HVNValNum(j);
- if (Node2DFS[NodeIndex] > Node2DFS[j])
- Node2DFS[NodeIndex] = Node2DFS[j];
- }
- }
-
- // See if we found any cycles
- if (MyDFS == Node2DFS[NodeIndex]) {
- while (!SCCStack.empty() && Node2DFS[SCCStack.top()] >= MyDFS) {
- unsigned CycleNodeIndex = SCCStack.top();
- Node *CycleNode = &GraphNodes[CycleNodeIndex];
- VSSCCRep[CycleNodeIndex] = NodeIndex;
- // Unify the nodes
- N->Direct &= CycleNode->Direct;
-
- if (CycleNode->PredEdges) {
- if (!N->PredEdges)
- N->PredEdges = new SparseBitVector<>;
- *(N->PredEdges) |= CycleNode->PredEdges;
- delete CycleNode->PredEdges;
- CycleNode->PredEdges = NULL;
- }
- if (CycleNode->ImplicitPredEdges) {
- if (!N->ImplicitPredEdges)
- N->ImplicitPredEdges = new SparseBitVector<>;
- *(N->ImplicitPredEdges) |= CycleNode->ImplicitPredEdges;
- delete CycleNode->ImplicitPredEdges;
- CycleNode->ImplicitPredEdges = NULL;
- }
-
- SCCStack.pop();
- }
-
- Node2Deleted[NodeIndex] = true;
-
- if (!N->Direct) {
- GraphNodes[NodeIndex].PointerEquivLabel = PEClass++;
- return;
- }
-
- // Collect labels of successor nodes
- bool AllSame = true;
- unsigned First = ~0;
- SparseBitVector<> *Labels = new SparseBitVector<>;
- bool Used = false;
-
- if (N->PredEdges)
- for (SparseBitVector<>::iterator Iter = N->PredEdges->begin();
- Iter != N->PredEdges->end();
- ++Iter) {
- unsigned j = VSSCCRep[*Iter];
- unsigned Label = GraphNodes[j].PointerEquivLabel;
- // Ignore labels that are equal to us or non-pointers
- if (j == NodeIndex || Label == 0)
- continue;
- if (First == (unsigned)~0)
- First = Label;
- else if (First != Label)
- AllSame = false;
- Labels->set(Label);
- }
-
- // We either have a non-pointer, a copy of an existing node, or a new node.
- // Assign the appropriate pointer equivalence label.
- if (Labels->empty()) {
- GraphNodes[NodeIndex].PointerEquivLabel = 0;
- } else if (AllSame) {
- GraphNodes[NodeIndex].PointerEquivLabel = First;
- } else {
- GraphNodes[NodeIndex].PointerEquivLabel = Set2PEClass[Labels];
- if (GraphNodes[NodeIndex].PointerEquivLabel == 0) {
- unsigned EquivClass = PEClass++;
- Set2PEClass[Labels] = EquivClass;
- GraphNodes[NodeIndex].PointerEquivLabel = EquivClass;
- Used = true;
- }
- }
- if (!Used)
- delete Labels;
- } else {
- SCCStack.push(NodeIndex);
- }
-}
-
-/// The technique used here is described in "Exploiting Pointer and Location
-/// Equivalence to Optimize Pointer Analysis. In the 14th International Static
-/// Analysis Symposium (SAS), August 2007." It is known as the "HU" algorithm,
-/// and is equivalent to value numbering the collapsed constraint graph
-/// including evaluating unions.
-void Andersens::HU() {
- DEBUG(dbgs() << "Beginning HU\n");
- // Build a predecessor graph. This is like our constraint graph with the
- // edges going in the opposite direction, and there are edges for all the
- // constraints, instead of just copy constraints. We also build implicit
- // edges for constraints are implied but not explicit. I.E for the constraint
- // a = &b, we add implicit edges *a = b. This helps us capture more cycles
- for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- Constraint &C = Constraints[i];
- if (C.Type == Constraint::AddressOf) {
- GraphNodes[C.Src].AddressTaken = true;
- GraphNodes[C.Src].Direct = false;
-
- GraphNodes[C.Dest].PointsTo->set(C.Src);
- // *Dest = src edge
- unsigned RefNode = C.Dest + FirstRefNode;
- if (!GraphNodes[RefNode].ImplicitPredEdges)
- GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>;
- GraphNodes[RefNode].ImplicitPredEdges->set(C.Src);
- GraphNodes[C.Src].PointedToBy->set(C.Dest);
- } else if (C.Type == Constraint::Load) {
- if (C.Offset == 0) {
- // dest = *src edge
- if (!GraphNodes[C.Dest].PredEdges)
- GraphNodes[C.Dest].PredEdges = new SparseBitVector<>;
- GraphNodes[C.Dest].PredEdges->set(C.Src + FirstRefNode);
- } else {
- GraphNodes[C.Dest].Direct = false;
- }
- } else if (C.Type == Constraint::Store) {
- if (C.Offset == 0) {
- // *dest = src edge
- unsigned RefNode = C.Dest + FirstRefNode;
- if (!GraphNodes[RefNode].PredEdges)
- GraphNodes[RefNode].PredEdges = new SparseBitVector<>;
- GraphNodes[RefNode].PredEdges->set(C.Src);
- }
- } else {
- // Dest = Src edge and *Dest = *Src edg
- if (!GraphNodes[C.Dest].PredEdges)
- GraphNodes[C.Dest].PredEdges = new SparseBitVector<>;
- GraphNodes[C.Dest].PredEdges->set(C.Src);
- unsigned RefNode = C.Dest + FirstRefNode;
- if (!GraphNodes[RefNode].ImplicitPredEdges)
- GraphNodes[RefNode].ImplicitPredEdges = new SparseBitVector<>;
- GraphNodes[RefNode].ImplicitPredEdges->set(C.Src + FirstRefNode);
- }
- }
- PEClass = 1;
- // Do SCC finding first to condense our predecessor graph
- DFSNumber = 0;
- Node2DFS.insert(Node2DFS.begin(), GraphNodes.size(), 0);
- Node2Deleted.insert(Node2Deleted.begin(), GraphNodes.size(), false);
- Node2Visited.insert(Node2Visited.begin(), GraphNodes.size(), false);
-
- for (unsigned i = 0; i < FirstRefNode; ++i) {
- if (FindNode(i) == i) {
- unsigned Node = VSSCCRep[i];
- if (!Node2Visited[Node])
- Condense(Node);
- }
- }
-
- // Reset tables for actual labeling
- Node2DFS.clear();
- Node2Visited.clear();
- Node2Deleted.clear();
- // Pre-grow our densemap so that we don't get really bad behavior
- Set2PEClass.resize(GraphNodes.size());
-
- // Visit the condensed graph and generate pointer equivalence labels.
- Node2Visited.insert(Node2Visited.begin(), GraphNodes.size(), false);
- for (unsigned i = 0; i < FirstRefNode; ++i) {
- if (FindNode(i) == i) {
- unsigned Node = VSSCCRep[i];
- if (!Node2Visited[Node])
- HUValNum(Node);
- }
- }
- // PEClass nodes will be deleted by the deleting of N->PointsTo in our caller.
- Set2PEClass.clear();
- DEBUG(dbgs() << "Finished HU\n");
-}
-
-
-/// Implementation of standard Tarjan SCC algorithm as modified by Nuutilla.
-void Andersens::Condense(unsigned NodeIndex) {
- unsigned MyDFS = DFSNumber++;
- Node *N = &GraphNodes[NodeIndex];
- Node2Visited[NodeIndex] = true;
- Node2DFS[NodeIndex] = MyDFS;
-
- // First process all our explicit edges
- if (N->PredEdges)
- for (SparseBitVector<>::iterator Iter = N->PredEdges->begin();
- Iter != N->PredEdges->end();
- ++Iter) {
- unsigned j = VSSCCRep[*Iter];
- if (!Node2Deleted[j]) {
- if (!Node2Visited[j])
- Condense(j);
- if (Node2DFS[NodeIndex] > Node2DFS[j])
- Node2DFS[NodeIndex] = Node2DFS[j];
- }
- }
-
- // Now process all the implicit edges
- if (N->ImplicitPredEdges)
- for (SparseBitVector<>::iterator Iter = N->ImplicitPredEdges->begin();
- Iter != N->ImplicitPredEdges->end();
- ++Iter) {
- unsigned j = VSSCCRep[*Iter];
- if (!Node2Deleted[j]) {
- if (!Node2Visited[j])
- Condense(j);
- if (Node2DFS[NodeIndex] > Node2DFS[j])
- Node2DFS[NodeIndex] = Node2DFS[j];
- }
- }
-
- // See if we found any cycles
- if (MyDFS == Node2DFS[NodeIndex]) {
- while (!SCCStack.empty() && Node2DFS[SCCStack.top()] >= MyDFS) {
- unsigned CycleNodeIndex = SCCStack.top();
- Node *CycleNode = &GraphNodes[CycleNodeIndex];
- VSSCCRep[CycleNodeIndex] = NodeIndex;
- // Unify the nodes
- N->Direct &= CycleNode->Direct;
-
- *(N->PointsTo) |= CycleNode->PointsTo;
- delete CycleNode->PointsTo;
- CycleNode->PointsTo = NULL;
- if (CycleNode->PredEdges) {
- if (!N->PredEdges)
- N->PredEdges = new SparseBitVector<>;
- *(N->PredEdges) |= CycleNode->PredEdges;
- delete CycleNode->PredEdges;
- CycleNode->PredEdges = NULL;
- }
- if (CycleNode->ImplicitPredEdges) {
- if (!N->ImplicitPredEdges)
- N->ImplicitPredEdges = new SparseBitVector<>;
- *(N->ImplicitPredEdges) |= CycleNode->ImplicitPredEdges;
- delete CycleNode->ImplicitPredEdges;
- CycleNode->ImplicitPredEdges = NULL;
- }
- SCCStack.pop();
- }
-
- Node2Deleted[NodeIndex] = true;
-
- // Set up number of incoming edges for other nodes
- if (N->PredEdges)
- for (SparseBitVector<>::iterator Iter = N->PredEdges->begin();
- Iter != N->PredEdges->end();
- ++Iter)
- ++GraphNodes[VSSCCRep[*Iter]].NumInEdges;
- } else {
- SCCStack.push(NodeIndex);
- }
-}
-
-void Andersens::HUValNum(unsigned NodeIndex) {
- Node *N = &GraphNodes[NodeIndex];
- Node2Visited[NodeIndex] = true;
-
- // Eliminate dereferences of non-pointers for those non-pointers we have
- // already identified. These are ref nodes whose non-ref node:
- // 1. Has already been visited determined to point to nothing (and thus, a
- // dereference of it must point to nothing)
- // 2. Any direct node with no predecessor edges in our graph and with no
- // points-to set (since it can't point to anything either, being that it
- // receives no points-to sets and has none).
- if (NodeIndex >= FirstRefNode) {
- unsigned j = VSSCCRep[FindNode(NodeIndex - FirstRefNode)];
- if ((Node2Visited[j] && !GraphNodes[j].PointerEquivLabel)
- || (GraphNodes[j].Direct && !GraphNodes[j].PredEdges
- && GraphNodes[j].PointsTo->empty())){
- return;
- }
- }
- // Process all our explicit edges
- if (N->PredEdges)
- for (SparseBitVector<>::iterator Iter = N->PredEdges->begin();
- Iter != N->PredEdges->end();
- ++Iter) {
- unsigned j = VSSCCRep[*Iter];
- if (!Node2Visited[j])
- HUValNum(j);
-
- // If this edge turned out to be the same as us, or got no pointer
- // equivalence label (and thus points to nothing) , just decrement our
- // incoming edges and continue.
- if (j == NodeIndex || GraphNodes[j].PointerEquivLabel == 0) {
- --GraphNodes[j].NumInEdges;
- continue;
- }
-
- *(N->PointsTo) |= GraphNodes[j].PointsTo;
-
- // If we didn't end up storing this in the hash, and we're done with all
- // the edges, we don't need the points-to set anymore.
- --GraphNodes[j].NumInEdges;
- if (!GraphNodes[j].NumInEdges && !GraphNodes[j].StoredInHash) {
- delete GraphNodes[j].PointsTo;
- GraphNodes[j].PointsTo = NULL;
- }
- }
- // If this isn't a direct node, generate a fresh variable.
- if (!N->Direct) {
- N->PointsTo->set(FirstRefNode + NodeIndex);
- }
-
- // See If we have something equivalent to us, if not, generate a new
- // equivalence class.
- if (N->PointsTo->empty()) {
- delete N->PointsTo;
- N->PointsTo = NULL;
- } else {
- if (N->Direct) {
- N->PointerEquivLabel = Set2PEClass[N->PointsTo];
- if (N->PointerEquivLabel == 0) {
- unsigned EquivClass = PEClass++;
- N->StoredInHash = true;
- Set2PEClass[N->PointsTo] = EquivClass;
- N->PointerEquivLabel = EquivClass;
- }
- } else {
- N->PointerEquivLabel = PEClass++;
- }
- }
-}
-
-/// Rewrite our list of constraints so that pointer equivalent nodes are
-/// replaced by their the pointer equivalence class representative.
-void Andersens::RewriteConstraints() {
- std::vector<Constraint> NewConstraints;
- DenseSet<Constraint, ConstraintKeyInfo> Seen;
-
- PEClass2Node.clear();
- PENLEClass2Node.clear();
-
- // We may have from 1 to Graphnodes + 1 equivalence classes.
- PEClass2Node.insert(PEClass2Node.begin(), GraphNodes.size() + 1, -1);
- PENLEClass2Node.insert(PENLEClass2Node.begin(), GraphNodes.size() + 1, -1);
-
- // Rewrite constraints, ignoring non-pointer constraints, uniting equivalent
- // nodes, and rewriting constraints to use the representative nodes.
- for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- Constraint &C = Constraints[i];
- unsigned RHSNode = FindNode(C.Src);
- unsigned LHSNode = FindNode(C.Dest);
- unsigned RHSLabel = GraphNodes[VSSCCRep[RHSNode]].PointerEquivLabel;
- unsigned LHSLabel = GraphNodes[VSSCCRep[LHSNode]].PointerEquivLabel;
-
- // First we try to eliminate constraints for things we can prove don't point
- // to anything.
- if (LHSLabel == 0) {
- DEBUG(PrintNode(&GraphNodes[LHSNode]));
- DEBUG(dbgs() << " is a non-pointer, ignoring constraint.\n");
- continue;
- }
- if (RHSLabel == 0) {
- DEBUG(PrintNode(&GraphNodes[RHSNode]));
- DEBUG(dbgs() << " is a non-pointer, ignoring constraint.\n");
- continue;
- }
- // This constraint may be useless, and it may become useless as we translate
- // it.
- if (C.Src == C.Dest && C.Type == Constraint::Copy)
- continue;
-
- C.Src = FindEquivalentNode(RHSNode, RHSLabel);
- C.Dest = FindEquivalentNode(FindNode(LHSNode), LHSLabel);
- if ((C.Src == C.Dest && C.Type == Constraint::Copy)
- || Seen.count(C))
- continue;
-
- Seen.insert(C);
- NewConstraints.push_back(C);
- }
- Constraints.swap(NewConstraints);
- PEClass2Node.clear();
-}
-
-/// See if we have a node that is pointer equivalent to the one being asked
-/// about, and if so, unite them and return the equivalent node. Otherwise,
-/// return the original node.
-unsigned Andersens::FindEquivalentNode(unsigned NodeIndex,
- unsigned NodeLabel) {
- if (!GraphNodes[NodeIndex].AddressTaken) {
- if (PEClass2Node[NodeLabel] != -1) {
- // We found an existing node with the same pointer label, so unify them.
- // We specifically request that Union-By-Rank not be used so that
- // PEClass2Node[NodeLabel] U= NodeIndex and not the other way around.
- return UniteNodes(PEClass2Node[NodeLabel], NodeIndex, false);
- } else {
- PEClass2Node[NodeLabel] = NodeIndex;
- PENLEClass2Node[NodeLabel] = NodeIndex;
- }
- } else if (PENLEClass2Node[NodeLabel] == -1) {
- PENLEClass2Node[NodeLabel] = NodeIndex;
- }
-
- return NodeIndex;
-}
-
-void Andersens::PrintLabels() const {
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- if (i < FirstRefNode) {
- PrintNode(&GraphNodes[i]);
- } else if (i < FirstAdrNode) {
- DEBUG(dbgs() << "REF(");
- PrintNode(&GraphNodes[i-FirstRefNode]);
- DEBUG(dbgs() <<")");
- } else {
- DEBUG(dbgs() << "ADR(");
- PrintNode(&GraphNodes[i-FirstAdrNode]);
- DEBUG(dbgs() <<")");
- }
-
- DEBUG(dbgs() << " has pointer label " << GraphNodes[i].PointerEquivLabel
- << " and SCC rep " << VSSCCRep[i]
- << " and is " << (GraphNodes[i].Direct ? "Direct" : "Not direct")
- << "\n");
- }
-}
-
-/// The technique used here is described in "The Ant and the
-/// Grasshopper: Fast and Accurate Pointer Analysis for Millions of
-/// Lines of Code. In Programming Language Design and Implementation
-/// (PLDI), June 2007." It is known as the "HCD" (Hybrid Cycle
-/// Detection) algorithm. It is called a hybrid because it performs an
-/// offline analysis and uses its results during the solving (online)
-/// phase. This is just the offline portion; the results of this
-/// operation are stored in SDT and are later used in SolveContraints()
-/// and UniteNodes().
-void Andersens::HCD() {
- DEBUG(dbgs() << "Starting HCD.\n");
- HCDSCCRep.resize(GraphNodes.size());
-
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- GraphNodes[i].Edges = new SparseBitVector<>;
- HCDSCCRep[i] = i;
- }
-
- for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- Constraint &C = Constraints[i];
- assert (C.Src < GraphNodes.size() && C.Dest < GraphNodes.size());
- if (C.Type == Constraint::AddressOf) {
- continue;
- } else if (C.Type == Constraint::Load) {
- if( C.Offset == 0 )
- GraphNodes[C.Dest].Edges->set(C.Src + FirstRefNode);
- } else if (C.Type == Constraint::Store) {
- if( C.Offset == 0 )
- GraphNodes[C.Dest + FirstRefNode].Edges->set(C.Src);
- } else {
- GraphNodes[C.Dest].Edges->set(C.Src);
- }
- }
-
- Node2DFS.insert(Node2DFS.begin(), GraphNodes.size(), 0);
- Node2Deleted.insert(Node2Deleted.begin(), GraphNodes.size(), false);
- Node2Visited.insert(Node2Visited.begin(), GraphNodes.size(), false);
- SDT.insert(SDT.begin(), GraphNodes.size() / 2, -1);
-
- DFSNumber = 0;
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- unsigned Node = HCDSCCRep[i];
- if (!Node2Deleted[Node])
- Search(Node);
- }
-
- for (unsigned i = 0; i < GraphNodes.size(); ++i)
- if (GraphNodes[i].Edges != NULL) {
- delete GraphNodes[i].Edges;
- GraphNodes[i].Edges = NULL;
- }
-
- while( !SCCStack.empty() )
- SCCStack.pop();
-
- Node2DFS.clear();
- Node2Visited.clear();
- Node2Deleted.clear();
- HCDSCCRep.clear();
- DEBUG(dbgs() << "HCD complete.\n");
-}
-
-// Component of HCD:
-// Use Nuutila's variant of Tarjan's algorithm to detect
-// Strongly-Connected Components (SCCs). For non-trivial SCCs
-// containing ref nodes, insert the appropriate information in SDT.
-void Andersens::Search(unsigned Node) {
- unsigned MyDFS = DFSNumber++;
-
- Node2Visited[Node] = true;
- Node2DFS[Node] = MyDFS;
-
- for (SparseBitVector<>::iterator Iter = GraphNodes[Node].Edges->begin(),
- End = GraphNodes[Node].Edges->end();
- Iter != End;
- ++Iter) {
- unsigned J = HCDSCCRep[*Iter];
- assert(GraphNodes[J].isRep() && "Debug check; must be representative");
- if (!Node2Deleted[J]) {
- if (!Node2Visited[J])
- Search(J);
- if (Node2DFS[Node] > Node2DFS[J])
- Node2DFS[Node] = Node2DFS[J];
- }
- }
-
- if( MyDFS != Node2DFS[Node] ) {
- SCCStack.push(Node);
- return;
- }
-
- // This node is the root of a SCC, so process it.
- //
- // If the SCC is "non-trivial" (not a singleton) and contains a reference
- // node, we place this SCC into SDT. We unite the nodes in any case.
- if (!SCCStack.empty() && Node2DFS[SCCStack.top()] >= MyDFS) {
- SparseBitVector<> SCC;
-
- SCC.set(Node);
-
- bool Ref = (Node >= FirstRefNode);
-
- Node2Deleted[Node] = true;
-
- do {
- unsigned P = SCCStack.top(); SCCStack.pop();
- Ref |= (P >= FirstRefNode);
- SCC.set(P);
- HCDSCCRep[P] = Node;
- } while (!SCCStack.empty() && Node2DFS[SCCStack.top()] >= MyDFS);
-
- if (Ref) {
- unsigned Rep = SCC.find_first();
- assert(Rep < FirstRefNode && "The SCC didn't have a non-Ref node!");
-
- SparseBitVector<>::iterator i = SCC.begin();
-
- // Skip over the non-ref nodes
- while( *i < FirstRefNode )
- ++i;
-
- while( i != SCC.end() )
- SDT[ (*i++) - FirstRefNode ] = Rep;
- }
- }
-}
-
-
-/// Optimize the constraints by performing offline variable substitution and
-/// other optimizations.
-void Andersens::OptimizeConstraints() {
- DEBUG(dbgs() << "Beginning constraint optimization\n");
-
- SDTActive = false;
-
- // Function related nodes need to stay in the same relative position and can't
- // be location equivalent.
- for (std::map<unsigned, unsigned>::iterator Iter = MaxK.begin();
- Iter != MaxK.end();
- ++Iter) {
- for (unsigned i = Iter->first;
- i != Iter->first + Iter->second;
- ++i) {
- GraphNodes[i].AddressTaken = true;
- GraphNodes[i].Direct = false;
- }
- }
-
- ClumpAddressTaken();
- FirstRefNode = GraphNodes.size();
- FirstAdrNode = FirstRefNode + GraphNodes.size();
- GraphNodes.insert(GraphNodes.end(), 2 * GraphNodes.size(),
- Node(false));
- VSSCCRep.resize(GraphNodes.size());
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- VSSCCRep[i] = i;
- }
- HVN();
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- Node *N = &GraphNodes[i];
- delete N->PredEdges;
- N->PredEdges = NULL;
- delete N->ImplicitPredEdges;
- N->ImplicitPredEdges = NULL;
- }
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa-labels"
- DEBUG(PrintLabels());
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa"
- RewriteConstraints();
- // Delete the adr nodes.
- GraphNodes.resize(FirstRefNode * 2);
-
- // Now perform HU
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- Node *N = &GraphNodes[i];
- if (FindNode(i) == i) {
- N->PointsTo = new SparseBitVector<>;
- N->PointedToBy = new SparseBitVector<>;
- // Reset our labels
- }
- VSSCCRep[i] = i;
- N->PointerEquivLabel = 0;
- }
- HU();
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa-labels"
- DEBUG(PrintLabels());
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa"
- RewriteConstraints();
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- if (FindNode(i) == i) {
- Node *N = &GraphNodes[i];
- delete N->PointsTo;
- N->PointsTo = NULL;
- delete N->PredEdges;
- N->PredEdges = NULL;
- delete N->ImplicitPredEdges;
- N->ImplicitPredEdges = NULL;
- delete N->PointedToBy;
- N->PointedToBy = NULL;
- }
- }
-
- // perform Hybrid Cycle Detection (HCD)
- HCD();
- SDTActive = true;
-
- // No longer any need for the upper half of GraphNodes (for ref nodes).
- GraphNodes.erase(GraphNodes.begin() + FirstRefNode, GraphNodes.end());
-
- // HCD complete.
-
- DEBUG(dbgs() << "Finished constraint optimization\n");
- FirstRefNode = 0;
- FirstAdrNode = 0;
-}
-
-/// Unite pointer but not location equivalent variables, now that the constraint
-/// graph is built.
-void Andersens::UnitePointerEquivalences() {
- DEBUG(dbgs() << "Uniting remaining pointer equivalences\n");
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- if (GraphNodes[i].AddressTaken && GraphNodes[i].isRep()) {
- unsigned Label = GraphNodes[i].PointerEquivLabel;
-
- if (Label && PENLEClass2Node[Label] != -1)
- UniteNodes(i, PENLEClass2Node[Label]);
- }
- }
- DEBUG(dbgs() << "Finished remaining pointer equivalences\n");
- PENLEClass2Node.clear();
-}
-
-/// Create the constraint graph used for solving points-to analysis.
-///
-void Andersens::CreateConstraintGraph() {
- for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- Constraint &C = Constraints[i];
- assert (C.Src < GraphNodes.size() && C.Dest < GraphNodes.size());
- if (C.Type == Constraint::AddressOf)
- GraphNodes[C.Dest].PointsTo->set(C.Src);
- else if (C.Type == Constraint::Load)
- GraphNodes[C.Src].Constraints.push_back(C);
- else if (C.Type == Constraint::Store)
- GraphNodes[C.Dest].Constraints.push_back(C);
- else if (C.Offset != 0)
- GraphNodes[C.Src].Constraints.push_back(C);
- else
- GraphNodes[C.Src].Edges->set(C.Dest);
- }
-}
-
-// Perform DFS and cycle detection.
-bool Andersens::QueryNode(unsigned Node) {
- assert(GraphNodes[Node].isRep() && "Querying a non-rep node");
- unsigned OurDFS = ++DFSNumber;
- SparseBitVector<> ToErase;
- SparseBitVector<> NewEdges;
- Tarjan2DFS[Node] = OurDFS;
-
- // Changed denotes a change from a recursive call that we will bubble up.
- // Merged is set if we actually merge a node ourselves.
- bool Changed = false, Merged = false;
-
- for (SparseBitVector<>::iterator bi = GraphNodes[Node].Edges->begin();
- bi != GraphNodes[Node].Edges->end();
- ++bi) {
- unsigned RepNode = FindNode(*bi);
- // If this edge points to a non-representative node but we are
- // already planning to add an edge to its representative, we have no
- // need for this edge anymore.
- if (RepNode != *bi && NewEdges.test(RepNode)){
- ToErase.set(*bi);
- continue;
- }
-
- // Continue about our DFS.
- if (!Tarjan2Deleted[RepNode]){
- if (Tarjan2DFS[RepNode] == 0) {
- Changed |= QueryNode(RepNode);
- // May have been changed by QueryNode
- RepNode = FindNode(RepNode);
- }
- if (Tarjan2DFS[RepNode] < Tarjan2DFS[Node])
- Tarjan2DFS[Node] = Tarjan2DFS[RepNode];
- }
-
- // We may have just discovered that this node is part of a cycle, in
- // which case we can also erase it.
- if (RepNode != *bi) {
- ToErase.set(*bi);
- NewEdges.set(RepNode);
- }
- }
-
- GraphNodes[Node].Edges->intersectWithComplement(ToErase);
- GraphNodes[Node].Edges |= NewEdges;
-
- // If this node is a root of a non-trivial SCC, place it on our
- // worklist to be processed.
- if (OurDFS == Tarjan2DFS[Node]) {
- while (!SCCStack.empty() && Tarjan2DFS[SCCStack.top()] >= OurDFS) {
- Node = UniteNodes(Node, SCCStack.top());
-
- SCCStack.pop();
- Merged = true;
- }
- Tarjan2Deleted[Node] = true;
-
- if (Merged)
- NextWL->insert(&GraphNodes[Node]);
- } else {
- SCCStack.push(Node);
- }
-
- return(Changed | Merged);
-}
-
-/// SolveConstraints - This stage iteratively processes the constraints list
-/// propagating constraints (adding edges to the Nodes in the points-to graph)
-/// until a fixed point is reached.
-///
-/// We use a variant of the technique called "Lazy Cycle Detection", which is
-/// described in "The Ant and the Grasshopper: Fast and Accurate Pointer
-/// Analysis for Millions of Lines of Code. In Programming Language Design and
-/// Implementation (PLDI), June 2007."
-/// The paper describes performing cycle detection one node at a time, which can
-/// be expensive if there are no cycles, but there are long chains of nodes that
-/// it heuristically believes are cycles (because it will DFS from each node
-/// without state from previous nodes).
-/// Instead, we use the heuristic to build a worklist of nodes to check, then
-/// cycle detect them all at the same time to do this more cheaply. This
-/// catches cycles slightly later than the original technique did, but does it
-/// make significantly cheaper.
-
-void Andersens::SolveConstraints() {
- CurrWL = &w1;
- NextWL = &w2;
-
- OptimizeConstraints();
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa-constraints"
- DEBUG(PrintConstraints());
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "anders-aa"
-
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- Node *N = &GraphNodes[i];
- N->PointsTo = new SparseBitVector<>;
- N->OldPointsTo = new SparseBitVector<>;
- N->Edges = new SparseBitVector<>;
- }
- CreateConstraintGraph();
- UnitePointerEquivalences();
- assert(SCCStack.empty() && "SCC Stack should be empty by now!");
- Node2DFS.clear();
- Node2Deleted.clear();
- Node2DFS.insert(Node2DFS.begin(), GraphNodes.size(), 0);
- Node2Deleted.insert(Node2Deleted.begin(), GraphNodes.size(), false);
- DFSNumber = 0;
- DenseSet<Constraint, ConstraintKeyInfo> Seen;
- DenseSet<std::pair<unsigned,unsigned>, PairKeyInfo> EdgesChecked;
-
- // Order graph and add initial nodes to work list.
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- Node *INode = &GraphNodes[i];
-
- // Add to work list if it's a representative and can contribute to the
- // calculation right now.
- if (INode->isRep() && !INode->PointsTo->empty()
- && (!INode->Edges->empty() || !INode->Constraints.empty())) {
- INode->Stamp();
- CurrWL->insert(INode);
- }
- }
- std::queue<unsigned int> TarjanWL;
-#if !FULL_UNIVERSAL
- // "Rep and special variables" - in order for HCD to maintain conservative
- // results when !FULL_UNIVERSAL, we need to treat the special variables in
- // the same way that the !FULL_UNIVERSAL tweak does throughout the rest of
- // the analysis - it's ok to add edges from the special nodes, but never
- // *to* the special nodes.
- std::vector<unsigned int> RSV;
-#endif
- while( !CurrWL->empty() ) {
- DEBUG(dbgs() << "Starting iteration #" << ++NumIters << "\n");
-
- Node* CurrNode;
- unsigned CurrNodeIndex;
-
- // Actual cycle checking code. We cycle check all of the lazy cycle
- // candidates from the last iteration in one go.
- if (!TarjanWL.empty()) {
- DFSNumber = 0;
-
- Tarjan2DFS.clear();
- Tarjan2Deleted.clear();
- while (!TarjanWL.empty()) {
- unsigned int ToTarjan = TarjanWL.front();
- TarjanWL.pop();
- if (!Tarjan2Deleted[ToTarjan]
- && GraphNodes[ToTarjan].isRep()
- && Tarjan2DFS[ToTarjan] == 0)
- QueryNode(ToTarjan);
- }
- }
-
- // Add to work list if it's a representative and can contribute to the
- // calculation right now.
- while( (CurrNode = CurrWL->pop()) != NULL ) {
- CurrNodeIndex = CurrNode - &GraphNodes[0];
- CurrNode->Stamp();
-
-
- // Figure out the changed points to bits
- SparseBitVector<> CurrPointsTo;
- CurrPointsTo.intersectWithComplement(CurrNode->PointsTo,
- CurrNode->OldPointsTo);
- if (CurrPointsTo.empty())
- continue;
-
- *(CurrNode->OldPointsTo) |= CurrPointsTo;
-
- // Check the offline-computed equivalencies from HCD.
- bool SCC = false;
- unsigned Rep;
-
- if (SDT[CurrNodeIndex] >= 0) {
- SCC = true;
- Rep = FindNode(SDT[CurrNodeIndex]);
-
-#if !FULL_UNIVERSAL
- RSV.clear();
-#endif
- for (SparseBitVector<>::iterator bi = CurrPointsTo.begin();
- bi != CurrPointsTo.end(); ++bi) {
- unsigned Node = FindNode(*bi);
-#if !FULL_UNIVERSAL
- if (Node < NumberSpecialNodes) {
- RSV.push_back(Node);
- continue;
- }
-#endif
- Rep = UniteNodes(Rep,Node);
- }
-#if !FULL_UNIVERSAL
- RSV.push_back(Rep);
-#endif
-
- NextWL->insert(&GraphNodes[Rep]);
-
- if ( ! CurrNode->isRep() )
- continue;
- }
-
- Seen.clear();
-
- /* Now process the constraints for this node. */
- for (std::list<Constraint>::iterator li = CurrNode->Constraints.begin();
- li != CurrNode->Constraints.end(); ) {
- li->Src = FindNode(li->Src);
- li->Dest = FindNode(li->Dest);
-
- // Delete redundant constraints
- if( Seen.count(*li) ) {
- std::list<Constraint>::iterator lk = li; li++;
-
- CurrNode->Constraints.erase(lk);
- ++NumErased;
- continue;
- }
- Seen.insert(*li);
-
- // Src and Dest will be the vars we are going to process.
- // This may look a bit ugly, but what it does is allow us to process
- // both store and load constraints with the same code.
- // Load constraints say that every member of our RHS solution has K
- // added to it, and that variable gets an edge to LHS. We also union
- // RHS+K's solution into the LHS solution.
- // Store constraints say that every member of our LHS solution has K
- // added to it, and that variable gets an edge from RHS. We also union
- // RHS's solution into the LHS+K solution.
- unsigned *Src;
- unsigned *Dest;
- unsigned K = li->Offset;
- unsigned CurrMember;
- if (li->Type == Constraint::Load) {
- Src = &CurrMember;
- Dest = &li->Dest;
- } else if (li->Type == Constraint::Store) {
- Src = &li->Src;
- Dest = &CurrMember;
- } else {
- // TODO Handle offseted copy constraint
- li++;
- continue;
- }
-
- // See if we can use Hybrid Cycle Detection (that is, check
- // if it was a statically detected offline equivalence that
- // involves pointers; if so, remove the redundant constraints).
- if( SCC && K == 0 ) {
-#if FULL_UNIVERSAL
- CurrMember = Rep;
-
- if (GraphNodes[*Src].Edges->test_and_set(*Dest))
- if (GraphNodes[*Dest].PointsTo |= *(GraphNodes[*Src].PointsTo))
- NextWL->insert(&GraphNodes[*Dest]);
-#else
- for (unsigned i=0; i < RSV.size(); ++i) {
- CurrMember = RSV[i];
-
- if (*Dest < NumberSpecialNodes)
- continue;
- if (GraphNodes[*Src].Edges->test_and_set(*Dest))
- if (GraphNodes[*Dest].PointsTo |= *(GraphNodes[*Src].PointsTo))
- NextWL->insert(&GraphNodes[*Dest]);
- }
-#endif
- // since all future elements of the points-to set will be
- // equivalent to the current ones, the complex constraints
- // become redundant.
- //
- std::list<Constraint>::iterator lk = li; li++;
-#if !FULL_UNIVERSAL
- // In this case, we can still erase the constraints when the
- // elements of the points-to sets are referenced by *Dest,
- // but not when they are referenced by *Src (i.e. for a Load
- // constraint). This is because if another special variable is
- // put into the points-to set later, we still need to add the
- // new edge from that special variable.
- if( lk->Type != Constraint::Load)
-#endif
- GraphNodes[CurrNodeIndex].Constraints.erase(lk);
- } else {
- const SparseBitVector<> &Solution = CurrPointsTo;
-
- for (SparseBitVector<>::iterator bi = Solution.begin();
- bi != Solution.end();
- ++bi) {
- CurrMember = *bi;
-
- // Need to increment the member by K since that is where we are
- // supposed to copy to/from. Note that in positive weight cycles,
- // which occur in address taking of fields, K can go past
- // MaxK[CurrMember] elements, even though that is all it could point
- // to.
- if (K > 0 && K > MaxK[CurrMember])
- continue;
- else
- CurrMember = FindNode(CurrMember + K);
-
- // Add an edge to the graph, so we can just do regular
- // bitmap ior next time. It may also let us notice a cycle.
-#if !FULL_UNIVERSAL
- if (*Dest < NumberSpecialNodes)
- continue;
-#endif
- if (GraphNodes[*Src].Edges->test_and_set(*Dest))
- if (GraphNodes[*Dest].PointsTo |= *(GraphNodes[*Src].PointsTo))
- NextWL->insert(&GraphNodes[*Dest]);
-
- }
- li++;
- }
- }
- SparseBitVector<> NewEdges;
- SparseBitVector<> ToErase;
-
- // Now all we have left to do is propagate points-to info along the
- // edges, erasing the redundant edges.
- for (SparseBitVector<>::iterator bi = CurrNode->Edges->begin();
- bi != CurrNode->Edges->end();
- ++bi) {
-
- unsigned DestVar = *bi;
- unsigned Rep = FindNode(DestVar);
-
- // If we ended up with this node as our destination, or we've already
- // got an edge for the representative, delete the current edge.
- if (Rep == CurrNodeIndex ||
- (Rep != DestVar && NewEdges.test(Rep))) {
- ToErase.set(DestVar);
- continue;
- }
-
- std::pair<unsigned,unsigned> edge(CurrNodeIndex,Rep);
-
- // This is where we do lazy cycle detection.
- // If this is a cycle candidate (equal points-to sets and this
- // particular edge has not been cycle-checked previously), add to the
- // list to check for cycles on the next iteration.
- if (!EdgesChecked.count(edge) &&
- *(GraphNodes[Rep].PointsTo) == *(CurrNode->PointsTo)) {
- EdgesChecked.insert(edge);
- TarjanWL.push(Rep);
- }
- // Union the points-to sets into the dest
-#if !FULL_UNIVERSAL
- if (Rep >= NumberSpecialNodes)
-#endif
- if (GraphNodes[Rep].PointsTo |= CurrPointsTo) {
- NextWL->insert(&GraphNodes[Rep]);
- }
- // If this edge's destination was collapsed, rewrite the edge.
- if (Rep != DestVar) {
- ToErase.set(DestVar);
- NewEdges.set(Rep);
- }
- }
- CurrNode->Edges->intersectWithComplement(ToErase);
- CurrNode->Edges |= NewEdges;
- }
-
- // Switch to other work list.
- WorkList* t = CurrWL; CurrWL = NextWL; NextWL = t;
- }
-
-
- Node2DFS.clear();
- Node2Deleted.clear();
- for (unsigned i = 0; i < GraphNodes.size(); ++i) {
- Node *N = &GraphNodes[i];
- delete N->OldPointsTo;
- delete N->Edges;
- }
- SDTActive = false;
- SDT.clear();
-}
-
-//===----------------------------------------------------------------------===//
-// Union-Find
-//===----------------------------------------------------------------------===//
-
-// Unite nodes First and Second, returning the one which is now the
-// representative node. First and Second are indexes into GraphNodes
-unsigned Andersens::UniteNodes(unsigned First, unsigned Second,
- bool UnionByRank) {
- assert (First < GraphNodes.size() && Second < GraphNodes.size() &&
- "Attempting to merge nodes that don't exist");
-
- Node *FirstNode = &GraphNodes[First];
- Node *SecondNode = &GraphNodes[Second];
-
- assert (SecondNode->isRep() && FirstNode->isRep() &&
- "Trying to unite two non-representative nodes!");
- if (First == Second)
- return First;
-
- if (UnionByRank) {
- int RankFirst = (int) FirstNode ->NodeRep;
- int RankSecond = (int) SecondNode->NodeRep;
-
- // Rank starts at -1 and gets decremented as it increases.
- // Translation: higher rank, lower NodeRep value, which is always negative.
- if (RankFirst > RankSecond) {
- unsigned t = First; First = Second; Second = t;
- Node* tp = FirstNode; FirstNode = SecondNode; SecondNode = tp;
- } else if (RankFirst == RankSecond) {
- FirstNode->NodeRep = (unsigned) (RankFirst - 1);
- }
- }
-
- SecondNode->NodeRep = First;
-#if !FULL_UNIVERSAL
- if (First >= NumberSpecialNodes)
-#endif
- if (FirstNode->PointsTo && SecondNode->PointsTo)
- FirstNode->PointsTo |= *(SecondNode->PointsTo);
- if (FirstNode->Edges && SecondNode->Edges)
- FirstNode->Edges |= *(SecondNode->Edges);
- if (!SecondNode->Constraints.empty())
- FirstNode->Constraints.splice(FirstNode->Constraints.begin(),
- SecondNode->Constraints);
- if (FirstNode->OldPointsTo) {
- delete FirstNode->OldPointsTo;
- FirstNode->OldPointsTo = new SparseBitVector<>;
- }
-
- // Destroy interesting parts of the merged-from node.
- delete SecondNode->OldPointsTo;
- delete SecondNode->Edges;
- delete SecondNode->PointsTo;
- SecondNode->Edges = NULL;
- SecondNode->PointsTo = NULL;
- SecondNode->OldPointsTo = NULL;
-
- NumUnified++;
- DEBUG(dbgs() << "Unified Node ");
- DEBUG(PrintNode(FirstNode));
- DEBUG(dbgs() << " and Node ");
- DEBUG(PrintNode(SecondNode));
- DEBUG(dbgs() << "\n");
-
- if (SDTActive)
- if (SDT[Second] >= 0) {
- if (SDT[First] < 0)
- SDT[First] = SDT[Second];
- else {
- UniteNodes( FindNode(SDT[First]), FindNode(SDT[Second]) );
- First = FindNode(First);
- }
- }
-
- return First;
-}
-
-// Find the index into GraphNodes of the node representing Node, performing
-// path compression along the way
-unsigned Andersens::FindNode(unsigned NodeIndex) {
- assert (NodeIndex < GraphNodes.size()
- && "Attempting to find a node that can't exist");
- Node *N = &GraphNodes[NodeIndex];
- if (N->isRep())
- return NodeIndex;
- else
- return (N->NodeRep = FindNode(N->NodeRep));
-}
-
-// Find the index into GraphNodes of the node representing Node,
-// don't perform path compression along the way (for Print)
-unsigned Andersens::FindNode(unsigned NodeIndex) const {
- assert (NodeIndex < GraphNodes.size()
- && "Attempting to find a node that can't exist");
- const Node *N = &GraphNodes[NodeIndex];
- if (N->isRep())
- return NodeIndex;
- else
- return FindNode(N->NodeRep);
-}
-
-//===----------------------------------------------------------------------===//
-// Debugging Output
-//===----------------------------------------------------------------------===//
-
-void Andersens::PrintNode(const Node *N) const {
- if (N == &GraphNodes[UniversalSet]) {
- dbgs() << "<universal>";
- return;
- } else if (N == &GraphNodes[NullPtr]) {
- dbgs() << "<nullptr>";
- return;
- } else if (N == &GraphNodes[NullObject]) {
- dbgs() << "<null>";
- return;
- }
- if (!N->getValue()) {
- dbgs() << "artificial" << (intptr_t) N;
- return;
- }
-
- assert(N->getValue() != 0 && "Never set node label!");
- Value *V = N->getValue();
- if (Function *F = dyn_cast<Function>(V)) {
- if (isa<PointerType>(F->getFunctionType()->getReturnType()) &&
- N == &GraphNodes[getReturnNode(F)]) {
- dbgs() << F->getName() << ":retval";
- return;
- } else if (F->getFunctionType()->isVarArg() &&
- N == &GraphNodes[getVarargNode(F)]) {
- dbgs() << F->getName() << ":vararg";
- return;
- }
- }
-
- if (Instruction *I = dyn_cast<Instruction>(V))
- dbgs() << I->getParent()->getParent()->getName() << ":";
- else if (Argument *Arg = dyn_cast<Argument>(V))
- dbgs() << Arg->getParent()->getName() << ":";
-
- if (V->hasName())
- dbgs() << V->getName();
- else
- dbgs() << "(unnamed)";
-
- if (isa<GlobalValue>(V) || isa<AllocaInst>(V) || isMalloc(V))
- if (N == &GraphNodes[getObject(V)])
- dbgs() << "<mem>";
-}
-void Andersens::PrintConstraint(const Constraint &C) const {
- if (C.Type == Constraint::Store) {
- dbgs() << "*";
- if (C.Offset != 0)
- dbgs() << "(";
- }
- PrintNode(&GraphNodes[C.Dest]);
- if (C.Type == Constraint::Store && C.Offset != 0)
- dbgs() << " + " << C.Offset << ")";
- dbgs() << " = ";
- if (C.Type == Constraint::Load) {
- dbgs() << "*";
- if (C.Offset != 0)
- dbgs() << "(";
- }
- else if (C.Type == Constraint::AddressOf)
- dbgs() << "&";
- PrintNode(&GraphNodes[C.Src]);
- if (C.Offset != 0 && C.Type != Constraint::Store)
- dbgs() << " + " << C.Offset;
- if (C.Type == Constraint::Load && C.Offset != 0)
- dbgs() << ")";
- dbgs() << "\n";
-}
-
-void Andersens::PrintConstraints() const {
- dbgs() << "Constraints:\n";
-
- for (unsigned i = 0, e = Constraints.size(); i != e; ++i)
- PrintConstraint(Constraints[i]);
-}
-
-void Andersens::PrintPointsToGraph() const {
- dbgs() << "Points-to graph:\n";
- for (unsigned i = 0, e = GraphNodes.size(); i != e; ++i) {
- const Node *N = &GraphNodes[i];
- if (FindNode(i) != i) {
- PrintNode(N);
- dbgs() << "\t--> same as ";
- PrintNode(&GraphNodes[FindNode(i)]);
- dbgs() << "\n";
- } else {
- dbgs() << "[" << (N->PointsTo->count()) << "] ";
- PrintNode(N);
- dbgs() << "\t--> ";
-
- bool first = true;
- for (SparseBitVector<>::iterator bi = N->PointsTo->begin();
- bi != N->PointsTo->end();
- ++bi) {
- if (!first)
- dbgs() << ", ";
- PrintNode(&GraphNodes[*bi]);
- first = false;
- }
- dbgs() << "\n";
- }
- }
-}
diff --git a/lib/Analysis/IPA/CMakeLists.txt b/lib/Analysis/IPA/CMakeLists.txt
index 1ebb0be..007ad22 100644
--- a/lib/Analysis/IPA/CMakeLists.txt
+++ b/lib/Analysis/IPA/CMakeLists.txt
@@ -1,5 +1,4 @@
add_llvm_library(LLVMipa
- Andersens.cpp
CallGraph.cpp
CallGraphSCCPass.cpp
FindUsedTypes.cpp
diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp
index ec94bc8..7b43089 100644
--- a/lib/Analysis/IPA/GlobalsModRef.cpp
+++ b/lib/Analysis/IPA/GlobalsModRef.cpp
@@ -213,7 +213,7 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
++NumNonAddrTakenGlobalVars;
// If this global holds a pointer type, see if it is an indirect global.
- if (isa<PointerType>(I->getType()->getElementType()) &&
+ if (I->getType()->getElementType()->isPointerTy() &&
AnalyzeIndirectGlobalMemory(I))
++NumIndirectGlobalVars;
}
@@ -231,7 +231,7 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
std::vector<Function*> &Readers,
std::vector<Function*> &Writers,
GlobalValue *OkayStoreDest) {
- if (!isa<PointerType>(V->getType())) return true;
+ if (!V->getType()->isPointerTy()) return true;
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index 9c472ae..98a436f 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -21,6 +21,7 @@
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Assembly/AsmAnnotationWriter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -35,42 +36,30 @@ Pass *llvm::createIVUsersPass() {
return new IVUsers();
}
-/// containsAddRecFromDifferentLoop - Determine whether expression S involves a
-/// subexpression that is an AddRec from a loop other than L. An outer loop
-/// of L is OK, but not an inner loop nor a disjoint loop.
-static bool containsAddRecFromDifferentLoop(const SCEV *S, Loop *L) {
- // This is very common, put it first.
- if (isa<SCEVConstant>(S))
- return false;
- if (const SCEVCommutativeExpr *AE = dyn_cast<SCEVCommutativeExpr>(S)) {
- for (unsigned int i=0; i< AE->getNumOperands(); i++)
- if (containsAddRecFromDifferentLoop(AE->getOperand(i), L))
- return true;
- return false;
- }
- if (const SCEVAddRecExpr *AE = dyn_cast<SCEVAddRecExpr>(S)) {
- if (const Loop *newLoop = AE->getLoop()) {
- if (newLoop == L)
- return false;
- // if newLoop is an outer loop of L, this is OK.
- if (newLoop->contains(L))
- return false;
+/// CollectSubexprs - Split S into subexpressions which can be pulled out into
+/// separate registers.
+static void CollectSubexprs(const SCEV *S,
+ SmallVectorImpl<const SCEV *> &Ops,
+ ScalarEvolution &SE) {
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ // Break out add operands.
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I)
+ CollectSubexprs(*I, Ops, SE);
+ return;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ // Split a non-zero base out of an addrec.
+ if (!AR->getStart()->isZero()) {
+ CollectSubexprs(AR->getStart(), Ops, SE);
+ CollectSubexprs(SE.getAddRecExpr(SE.getIntegerSCEV(0, AR->getType()),
+ AR->getStepRecurrence(SE),
+ AR->getLoop()), Ops, SE);
+ return;
}
- return true;
}
- if (const SCEVUDivExpr *DE = dyn_cast<SCEVUDivExpr>(S))
- return containsAddRecFromDifferentLoop(DE->getLHS(), L) ||
- containsAddRecFromDifferentLoop(DE->getRHS(), L);
-#if 0
- // SCEVSDivExpr has been backed out temporarily, but will be back; we'll
- // need this when it is.
- if (const SCEVSDivExpr *DE = dyn_cast<SCEVSDivExpr>(S))
- return containsAddRecFromDifferentLoop(DE->getLHS(), L) ||
- containsAddRecFromDifferentLoop(DE->getRHS(), L);
-#endif
- if (const SCEVCastExpr *CE = dyn_cast<SCEVCastExpr>(S))
- return containsAddRecFromDifferentLoop(CE->getOperand(), L);
- return false;
+
+ // Otherwise use the value itself.
+ Ops.push_back(S);
}
/// getSCEVStartAndStride - Compute the start and stride of this expression,
@@ -89,35 +78,42 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop,
if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(SH)) {
for (unsigned i = 0, e = AE->getNumOperands(); i != e; ++i)
if (const SCEVAddRecExpr *AddRec =
- dyn_cast<SCEVAddRecExpr>(AE->getOperand(i))) {
- if (AddRec->getLoop() == L)
- TheAddRec = SE->getAddExpr(AddRec, TheAddRec);
- else
- return false; // Nested IV of some sort?
- } else {
+ dyn_cast<SCEVAddRecExpr>(AE->getOperand(i)))
+ TheAddRec = SE->getAddExpr(AddRec, TheAddRec);
+ else
Start = SE->getAddExpr(Start, AE->getOperand(i));
- }
} else if (isa<SCEVAddRecExpr>(SH)) {
TheAddRec = SH;
} else {
return false; // not analyzable.
}
- const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(TheAddRec);
- if (!AddRec || AddRec->getLoop() != L) return false;
+ // Break down TheAddRec into its component parts.
+ SmallVector<const SCEV *, 4> Subexprs;
+ CollectSubexprs(TheAddRec, Subexprs, *SE);
+
+ // Look for an addrec on the current loop among the parts.
+ const SCEV *AddRecStride = 0;
+ for (SmallVectorImpl<const SCEV *>::iterator I = Subexprs.begin(),
+ E = Subexprs.end(); I != E; ++I) {
+ const SCEV *S = *I;
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S))
+ if (AR->getLoop() == L) {
+ *I = AR->getStart();
+ AddRecStride = AR->getStepRecurrence(*SE);
+ break;
+ }
+ }
+ if (!AddRecStride)
+ return false;
+
+ // Add up everything else into a start value (which may not be
+ // loop-invariant).
+ const SCEV *AddRecStart = SE->getAddExpr(Subexprs);
// Use getSCEVAtScope to attempt to simplify other loops out of
// the picture.
- const SCEV *AddRecStart = AddRec->getStart();
AddRecStart = SE->getSCEVAtScope(AddRecStart, UseLoop);
- const SCEV *AddRecStride = AddRec->getStepRecurrence(*SE);
-
- // FIXME: If Start contains an SCEVAddRecExpr from a different loop, other
- // than an outer loop of the current loop, reject it. LSR has no concept of
- // operating on more than one loop at a time so don't confuse it with such
- // expressions.
- if (containsAddRecFromDifferentLoop(AddRecStart, L))
- return false;
Start = SE->getAddExpr(Start, AddRecStart);
@@ -130,7 +126,7 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop,
DEBUG(dbgs() << "[";
WriteAsOperand(dbgs(), L->getHeader(), /*PrintType=*/false);
- dbgs() << "] Variable stride: " << *AddRec << "\n");
+ dbgs() << "] Variable stride: " << *AddRecStride << "\n");
}
Stride = AddRecStride;
@@ -146,8 +142,7 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop,
/// the loop, resulting in reg-reg copies (if we use the pre-inc value when we
/// should use the post-inc value).
static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV,
- Loop *L, LoopInfo *LI, DominatorTree *DT,
- Pass *P) {
+ Loop *L, DominatorTree *DT) {
// If the user is in the loop, use the preinc value.
if (L->contains(User)) return false;
@@ -227,7 +222,7 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
// Descend recursively, but not into PHI nodes outside the current loop.
// It's important to see the entire expression outside the loop to get
// choices that depend on addressing mode use right, although we won't
- // consider references ouside the loop in all cases.
+ // consider references outside the loop in all cases.
// If User is already in Processed, we don't want to recurse into it again,
// but do want to record a second reference in the same instruction.
bool AddUserToIVUsers = false;
@@ -246,42 +241,28 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
}
if (AddUserToIVUsers) {
- IVUsersOfOneStride *StrideUses = IVUsesByStride[Stride];
- if (!StrideUses) { // First occurrence of this stride?
- StrideOrder.push_back(Stride);
- StrideUses = new IVUsersOfOneStride(Stride);
- IVUses.push_back(StrideUses);
- IVUsesByStride[Stride] = StrideUses;
- }
-
// Okay, we found a user that we cannot reduce. Analyze the instruction
// and decide what to do with it. If we are a use inside of the loop, use
// the value before incrementation, otherwise use it after incrementation.
- if (IVUseShouldUsePostIncValue(User, I, L, LI, DT, this)) {
+ if (IVUseShouldUsePostIncValue(User, I, L, DT)) {
// The value used will be incremented by the stride more than we are
// expecting, so subtract this off.
const SCEV *NewStart = SE->getMinusSCEV(Start, Stride);
- StrideUses->addUser(NewStart, User, I);
- StrideUses->Users.back().setIsUseOfPostIncrementedValue(true);
+ IVUses.push_back(new IVStrideUse(this, Stride, NewStart, User, I));
+ IVUses.back().setIsUseOfPostIncrementedValue(true);
DEBUG(dbgs() << " USING POSTINC SCEV, START=" << *NewStart<< "\n");
} else {
- StrideUses->addUser(Start, User, I);
+ IVUses.push_back(new IVStrideUse(this, Stride, Start, User, I));
}
}
}
return true;
}
-void IVUsers::AddUser(const SCEV *Stride, const SCEV *Offset,
- Instruction *User, Value *Operand) {
- IVUsersOfOneStride *StrideUses = IVUsesByStride[Stride];
- if (!StrideUses) { // First occurrence of this stride?
- StrideOrder.push_back(Stride);
- StrideUses = new IVUsersOfOneStride(Stride);
- IVUses.push_back(StrideUses);
- IVUsesByStride[Stride] = StrideUses;
- }
- IVUsesByStride[Stride]->addUser(Offset, User, Operand);
+IVStrideUse &IVUsers::AddUser(const SCEV *Stride, const SCEV *Offset,
+ Instruction *User, Value *Operand) {
+ IVUses.push_back(new IVStrideUse(this, Stride, Offset, User, Operand));
+ return IVUses.back();
}
IVUsers::IVUsers()
@@ -315,15 +296,15 @@ bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
/// value of the OperandValToReplace of the given IVStrideUse.
const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const {
// Start with zero.
- const SCEV *RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
+ const SCEV *RetVal = SE->getIntegerSCEV(0, U.getStride()->getType());
// Create the basic add recurrence.
- RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L);
+ RetVal = SE->getAddRecExpr(RetVal, U.getStride(), L);
// Add the offset in a separate step, because it may be loop-variant.
RetVal = SE->getAddExpr(RetVal, U.getOffset());
// For uses of post-incremented values, add an extra stride to compute
// the actual replacement value.
if (U.isUseOfPostIncrementedValue())
- RetVal = SE->getAddExpr(RetVal, U.getParent()->Stride);
+ RetVal = SE->getAddExpr(RetVal, U.getStride());
return RetVal;
}
@@ -332,9 +313,9 @@ const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const {
/// isUseOfPostIncrementedValue flag.
const SCEV *IVUsers::getCanonicalExpr(const IVStrideUse &U) const {
// Start with zero.
- const SCEV *RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
+ const SCEV *RetVal = SE->getIntegerSCEV(0, U.getStride()->getType());
// Create the basic add recurrence.
- RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L);
+ RetVal = SE->getAddRecExpr(RetVal, U.getStride(), L);
// Add the offset in a separate step, because it may be loop-variant.
RetVal = SE->getAddExpr(RetVal, U.getOffset());
return RetVal;
@@ -349,24 +330,20 @@ void IVUsers::print(raw_ostream &OS, const Module *M) const {
}
OS << ":\n";
- for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e; ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride*>::const_iterator SI =
- IVUsesByStride.find(StrideOrder[Stride]);
- assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
- OS << " Stride " << *SI->first->getType() << " " << *SI->first << ":\n";
-
- for (ilist<IVStrideUse>::const_iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; ++UI) {
- OS << " ";
- WriteAsOperand(OS, UI->getOperandValToReplace(), false);
- OS << " = ";
- OS << *getReplacementExpr(*UI);
- if (UI->isUseOfPostIncrementedValue())
- OS << " (post-inc)";
- OS << " in ";
- UI->getUser()->print(OS);
- OS << '\n';
- }
+ // Use a default AssemblyAnnotationWriter to suppress the default info
+ // comments, which aren't relevant here.
+ AssemblyAnnotationWriter Annotator;
+ for (ilist<IVStrideUse>::const_iterator UI = IVUses.begin(),
+ E = IVUses.end(); UI != E; ++UI) {
+ OS << " ";
+ WriteAsOperand(OS, UI->getOperandValToReplace(), false);
+ OS << " = "
+ << *getReplacementExpr(*UI);
+ if (UI->isUseOfPostIncrementedValue())
+ OS << " (post-inc)";
+ OS << " in ";
+ UI->getUser()->print(OS, &Annotator);
+ OS << '\n';
}
}
@@ -375,37 +352,12 @@ void IVUsers::dump() const {
}
void IVUsers::releaseMemory() {
- IVUsesByStride.clear();
- StrideOrder.clear();
Processed.clear();
IVUses.clear();
}
void IVStrideUse::deleted() {
// Remove this user from the list.
- Parent->Users.erase(this);
+ Parent->IVUses.erase(this);
// this now dangles!
}
-
-void IVUsersOfOneStride::print(raw_ostream &OS) const {
- OS << "IV Users of one stride:\n";
-
- if (Stride)
- OS << " Stride: " << *Stride << '\n';
-
- OS << " Users:\n";
-
- unsigned Count = 1;
-
- for (ilist<IVStrideUse>::const_iterator
- I = Users.begin(), E = Users.end(); I != E; ++I) {
- const IVStrideUse &SU = *I;
- OS << " " << Count++ << '\n';
- OS << " Offset: " << *SU.getOffset() << '\n';
- OS << " Instr: " << *SU << '\n';
- }
-}
-
-void IVUsersOfOneStride::dump() const {
- print(dbgs());
-}
diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp
index 972d034..ca50a17 100644
--- a/lib/Analysis/InlineCost.cpp
+++ b/lib/Analysis/InlineCost.cpp
@@ -84,7 +84,7 @@ unsigned InlineCostAnalyzer::FunctionInfo::
//
unsigned InlineCostAnalyzer::FunctionInfo::
CountCodeReductionForAlloca(Value *V) {
- if (!isa<PointerType>(V->getType())) return 0; // Not a pointer
+ if (!V->getType()->isPointerTy()) return 0; // Not a pointer
unsigned Reduction = 0;
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
Instruction *I = cast<Instruction>(*UI);
@@ -175,7 +175,7 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
this->usesDynamicAlloca = true;
}
- if (isa<ExtractElementInst>(II) || isa<VectorType>(II->getType()))
+ if (isa<ExtractElementInst>(II) || II->getType()->isVectorTy())
++NumVectorInsts;
if (const CastInst *CI = dyn_cast<CastInst>(II)) {
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index b53ac13..8288e96 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -194,11 +194,10 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const Type *ITy = GetCompareTy(LHS);
// icmp X, X -> true/false
- if (LHS == RHS)
+ // X icmp undef -> true/false. For example, icmp ugt %X, undef -> false
+ // because X could be 0.
+ if (LHS == RHS || isa<UndefValue>(RHS))
return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
-
- if (isa<UndefValue>(RHS)) // X icmp undef -> undef
- return UndefValue::get(ITy);
// icmp <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
// addresses never equal each other! We already know that Op0 != Op1.
@@ -283,6 +282,32 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// True if unordered.
return ConstantInt::getTrue(CFP->getContext());
}
+ // Check whether the constant is an infinity.
+ if (CFP->getValueAPF().isInfinity()) {
+ if (CFP->getValueAPF().isNegative()) {
+ switch (Pred) {
+ case FCmpInst::FCMP_OLT:
+ // No value is ordered and less than negative infinity.
+ return ConstantInt::getFalse(CFP->getContext());
+ case FCmpInst::FCMP_UGE:
+ // All values are unordered with or at least negative infinity.
+ return ConstantInt::getTrue(CFP->getContext());
+ default:
+ break;
+ }
+ } else {
+ switch (Pred) {
+ case FCmpInst::FCMP_OGT:
+ // No value is ordered and greater than infinity.
+ return ConstantInt::getFalse(CFP->getContext());
+ case FCmpInst::FCMP_ULE:
+ // All values are unordered with and at most infinity.
+ return ConstantInt::getTrue(CFP->getContext());
+ default:
+ break;
+ }
+ }
+ }
}
}
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index 2d74709d..2aa2f17 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -580,7 +580,7 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) {
void MemoryDependenceAnalysis::
getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *FromBB,
SmallVectorImpl<NonLocalDepResult> &Result) {
- assert(isa<PointerType>(Pointer->getType()) &&
+ assert(Pointer->getType()->isPointerTy() &&
"Can't get pointer deps of a non-pointer!");
Result.clear();
@@ -861,7 +861,7 @@ getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t PointeeSize,
// Get the PHI translated pointer in this predecessor. This can fail if
// not translatable, in which case the getAddr() returns null.
PHITransAddr PredPointer(Pointer);
- PredPointer.PHITranslateValue(BB, Pred);
+ PredPointer.PHITranslateValue(BB, Pred, 0);
Value *PredPtrVal = PredPointer.getAddr();
@@ -1009,13 +1009,20 @@ RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P) {
/// in more places that cached info does not necessarily keep.
void MemoryDependenceAnalysis::invalidateCachedPointerInfo(Value *Ptr) {
// If Ptr isn't really a pointer, just ignore it.
- if (!isa<PointerType>(Ptr->getType())) return;
+ if (!Ptr->getType()->isPointerTy()) return;
// Flush store info for the pointer.
RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, false));
// Flush load info for the pointer.
RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, true));
}
+/// invalidateCachedPredecessors - Clear the PredIteratorCache info.
+/// This needs to be done when the CFG changes, e.g., due to splitting
+/// critical edges.
+void MemoryDependenceAnalysis::invalidateCachedPredecessors() {
+ PredCache->clear();
+}
+
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
/// This method attempts to keep the cache coherent using the reverse map.
@@ -1050,7 +1057,7 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) {
// Remove it from both the load info and the store info. The instruction
// can't be in either of these maps if it is non-pointer.
- if (isa<PointerType>(RemInst->getType())) {
+ if (RemInst->getType()->isPointerTy()) {
RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst, false));
RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst, true));
}
diff --git a/lib/Analysis/PHITransAddr.cpp b/lib/Analysis/PHITransAddr.cpp
index 334a188..8e4fa03 100644
--- a/lib/Analysis/PHITransAddr.cpp
+++ b/lib/Analysis/PHITransAddr.cpp
@@ -134,7 +134,8 @@ static void RemoveInstInputs(Value *V,
}
Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
- BasicBlock *PredBB) {
+ BasicBlock *PredBB,
+ const DominatorTree *DT) {
// If this is a non-instruction value, it can't require PHI translation.
Instruction *Inst = dyn_cast<Instruction>(V);
if (Inst == 0) return V;
@@ -177,7 +178,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
// operands need to be phi translated, and if so, reconstruct it.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
- Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB);
+ Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB, DT);
if (PHIIn == 0) return 0;
if (PHIIn == BC->getOperand(0))
return BC;
@@ -193,7 +194,8 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end();
UI != E; ++UI) {
if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI))
- if (BCI->getType() == BC->getType())
+ if (BCI->getType() == BC->getType() &&
+ (!DT || DT->dominates(BCI->getParent(), PredBB)))
return BCI;
}
return 0;
@@ -204,7 +206,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
SmallVector<Value*, 8> GEPOps;
bool AnyChanged = false;
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
- Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB);
+ Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB, DT);
if (GEPOp == 0) return 0;
AnyChanged |= GEPOp != GEP->getOperand(i);
@@ -229,7 +231,8 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
if (GEPI->getType() == GEP->getType() &&
GEPI->getNumOperands() == GEPOps.size() &&
- GEPI->getParent()->getParent() == CurBB->getParent()) {
+ GEPI->getParent()->getParent() == CurBB->getParent() &&
+ (!DT || DT->dominates(GEPI->getParent(), PredBB))) {
bool Mismatch = false;
for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
if (GEPI->getOperand(i) != GEPOps[i]) {
@@ -251,7 +254,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();
- Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB);
+ Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB, DT);
if (LHS == 0) return 0;
// If the PHI translated LHS is an add of a constant, fold the immediates.
@@ -287,7 +290,8 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*UI))
if (BO->getOpcode() == Instruction::Add &&
BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
- BO->getParent()->getParent() == CurBB->getParent())
+ BO->getParent()->getParent() == CurBB->getParent() &&
+ (!DT || DT->dominates(BO->getParent(), PredBB)))
return BO;
}
@@ -300,33 +304,24 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
/// PHITranslateValue - PHI translate the current address up the CFG from
-/// CurBB to Pred, updating our state the reflect any needed changes. This
-/// returns true on failure and sets Addr to null.
-bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) {
+/// CurBB to Pred, updating our state to reflect any needed changes. If the
+/// dominator tree DT is non-null, the translated value must dominate
+/// PredBB. This returns true on failure and sets Addr to null.
+bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
+ const DominatorTree *DT) {
assert(Verify() && "Invalid PHITransAddr!");
- Addr = PHITranslateSubExpr(Addr, CurBB, PredBB);
+ Addr = PHITranslateSubExpr(Addr, CurBB, PredBB, DT);
assert(Verify() && "Invalid PHITransAddr!");
- return Addr == 0;
-}
-/// GetAvailablePHITranslatedSubExpr - Return the value computed by
-/// PHITranslateSubExpr if it dominates PredBB, otherwise return null.
-Value *PHITransAddr::
-GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB,BasicBlock *PredBB,
- const DominatorTree &DT) const {
- PHITransAddr Tmp(V, TD);
- Tmp.PHITranslateValue(CurBB, PredBB);
-
- // See if PHI translation succeeds.
- V = Tmp.getAddr();
-
- // Make sure the value is live in the predecessor.
- if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
- if (!DT.dominates(Inst->getParent(), PredBB))
- return 0;
- return V;
-}
+ if (DT) {
+ // Make sure the value is live in the predecessor.
+ if (Instruction *Inst = dyn_cast_or_null<Instruction>(Addr))
+ if (!DT->dominates(Inst->getParent(), PredBB))
+ Addr = 0;
+ }
+ return Addr == 0;
+}
/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
@@ -365,8 +360,9 @@ InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
SmallVectorImpl<Instruction*> &NewInsts) {
// See if we have a version of this value already available and dominating
// PredBB. If so, there is no need to insert a new instance of it.
- if (Value *Res = GetAvailablePHITranslatedSubExpr(InVal, CurBB, PredBB, DT))
- return Res;
+ PHITransAddr Tmp(InVal, TD);
+ if (!Tmp.PHITranslateValue(CurBB, PredBB, &DT))
+ return Tmp.getAddr();
// If we don't have an available version of this value, it must be an
// instruction.
diff --git a/lib/Analysis/PointerTracking.cpp b/lib/Analysis/PointerTracking.cpp
index 8da07e7..ce7ac89 100644
--- a/lib/Analysis/PointerTracking.cpp
+++ b/lib/Analysis/PointerTracking.cpp
@@ -231,7 +231,7 @@ void PointerTracking::print(raw_ostream &OS, const Module* M) const {
// this should be safe for the same reason its safe for SCEV.
PointerTracking &PT = *const_cast<PointerTracking*>(this);
for (inst_iterator I=inst_begin(*FF), E=inst_end(*FF); I != E; ++I) {
- if (!isa<PointerType>(I->getType()))
+ if (!I->getType()->isPointerTy())
continue;
Value *Base;
const SCEV *Limit, *Offset;
diff --git a/lib/Analysis/ProfileInfo.cpp b/lib/Analysis/ProfileInfo.cpp
index 85531be..66760c6 100644
--- a/lib/Analysis/ProfileInfo.cpp
+++ b/lib/Analysis/ProfileInfo.cpp
@@ -246,7 +246,7 @@ const BasicBlock *ProfileInfoT<Function,BasicBlock>::
succ_const_iterator Succ = succ_begin(BB), End = succ_end(BB);
if (Succ == End) {
- P[0] = BB;
+ P[ reinterpret_cast<const llvm::BasicBlock*>(0) ] = BB;
if (Mode & GetPathToExit) {
hasFoundPath = true;
BB = 0;
@@ -753,10 +753,10 @@ void ProfileInfoT<Function,BasicBlock>::repair(const Function *F) {
Succ != End; ++Succ) {
Path P;
GetPath(*Succ, 0, P, GetPathToExit);
- if (Dest && Dest != P[0]) {
+ if (Dest && Dest != P[ reinterpret_cast<const llvm::BasicBlock*>(0) ]) {
AllEdgesHaveSameReturn = false;
}
- Dest = P[0];
+ Dest = P[ reinterpret_cast<const llvm::BasicBlock*>(0) ];
}
if (AllEdgesHaveSameReturn) {
if(EstimateMissingEdges(BB)) {
@@ -928,7 +928,7 @@ void ProfileInfoT<Function,BasicBlock>::repair(const Function *F) {
Path P;
const BasicBlock *Dest = GetPath(BB, 0, P, GetPathToExit | GetPathWithNewEdges);
- Dest = P[0];
+ Dest = P[ reinterpret_cast<const llvm::BasicBlock*>(0) ];
if (!Dest) continue;
if (getEdgeWeight(getEdge(Dest,0)) == MissingValue) {
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 82be9cd..b979f33 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -214,8 +214,8 @@ bool SCEVCastExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeID &ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scTruncate, op, ty) {
- assert((Op->getType()->isInteger() || isa<PointerType>(Op->getType())) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot truncate non-integer value!");
}
@@ -226,8 +226,8 @@ void SCEVTruncateExpr::print(raw_ostream &OS) const {
SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeID &ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scZeroExtend, op, ty) {
- assert((Op->getType()->isInteger() || isa<PointerType>(Op->getType())) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot zero extend non-integer value!");
}
@@ -238,8 +238,8 @@ void SCEVZeroExtendExpr::print(raw_ostream &OS) const {
SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeID &ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scSignExtend, op, ty) {
- assert((Op->getType()->isInteger() || isa<PointerType>(Op->getType())) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot sign extend non-integer value!");
}
@@ -312,6 +312,21 @@ bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const {
return true;
}
+bool
+SCEVAddRecExpr::dominates(BasicBlock *BB, DominatorTree *DT) const {
+ return DT->dominates(L->getHeader(), BB) &&
+ SCEVNAryExpr::dominates(BB, DT);
+}
+
+bool
+SCEVAddRecExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
+ // This uses a "dominates" query instead of "properly dominates" query because
+ // the instruction which produces the addrec's value is a PHI, and a PHI
+ // effectively properly dominates its entire containing block.
+ return DT->dominates(L->getHeader(), BB) &&
+ SCEVNAryExpr::properlyDominates(BB, DT);
+}
+
void SCEVAddRecExpr::print(raw_ostream &OS) const {
OS << "{" << *Operands[0];
for (unsigned i = 1, e = Operands.size(); i != e; ++i)
@@ -379,7 +394,7 @@ bool SCEVUnknown::isAlignOf(const Type *&AllocTy) const {
if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(2)))
if (CI->isOne() &&
STy->getNumElements() == 2 &&
- STy->getElementType(0)->isInteger(1)) {
+ STy->getElementType(0)->isIntegerTy(1)) {
AllocTy = STy->getElementType(1);
return true;
}
@@ -401,7 +416,7 @@ bool SCEVUnknown::isOffsetOf(const Type *&CTy, Constant *&FieldNo) const {
cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
// Ignore vector types here so that ScalarEvolutionExpander doesn't
// emit getelementptrs that index into vectors.
- if (isa<StructType>(Ty) || isa<ArrayType>(Ty)) {
+ if (Ty->isStructTy() || Ty->isArrayTy()) {
CTy = Ty;
FieldNo = CE->getOperand(2);
return true;
@@ -503,9 +518,9 @@ namespace {
// Order pointer values after integer values. This helps SCEVExpander
// form GEPs.
- if (isa<PointerType>(LU->getType()) && !isa<PointerType>(RU->getType()))
+ if (LU->getType()->isPointerTy() && !RU->getType()->isPointerTy())
return false;
- if (isa<PointerType>(RU->getType()) && !isa<PointerType>(LU->getType()))
+ if (RU->getType()->isPointerTy() && !LU->getType()->isPointerTy())
return true;
// Compare getValueID values.
@@ -601,7 +616,7 @@ namespace {
/// When this routine is finished, we know that any duplicates in the vector are
/// consecutive and that complexity is monotonically increasing.
///
-/// Note that we go take special precautions to ensure that we get determinstic
+/// Note that we go take special precautions to ensure that we get deterministic
/// results from this routine. In other words, we don't want the results of
/// this to depend on where the addresses of various SCEV objects happened to
/// land in memory.
@@ -729,7 +744,7 @@ static const SCEV *BinomialCoefficient(const SCEV *It, unsigned K,
// We need at least W + T bits for the multiplication step
unsigned CalculationBits = W + T;
- // Calcuate 2^T, at width T+W.
+ // Calculate 2^T, at width T+W.
APInt DivFactor = APInt(CalculationBits, 1).shl(T);
// Calculate the multiplicative inverse of K! / 2^T;
@@ -906,9 +921,7 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
if (MaxBECount == RecastedMaxBECount) {
const Type *WideTy = IntegerType::get(getContext(), BitWidth * 2);
// Check whether Start+Step*MaxBECount has no unsigned overflow.
- const SCEV *ZMul =
- getMulExpr(CastedMaxBECount,
- getTruncateOrZeroExtend(Step, Start->getType()));
+ const SCEV *ZMul = getMulExpr(CastedMaxBECount, Step);
const SCEV *Add = getAddExpr(Start, ZMul);
const SCEV *OperandExtendedAdd =
getAddExpr(getZeroExtendExpr(Start, WideTy),
@@ -922,9 +935,7 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
// Similar to above, only this time treat the step value as signed.
// This covers loops that count down.
- const SCEV *SMul =
- getMulExpr(CastedMaxBECount,
- getTruncateOrSignExtend(Step, Start->getType()));
+ const SCEV *SMul = getMulExpr(CastedMaxBECount, Step);
Add = getAddExpr(Start, SMul);
OperandExtendedAdd =
getAddExpr(getZeroExtendExpr(Start, WideTy),
@@ -1045,9 +1056,7 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
if (MaxBECount == RecastedMaxBECount) {
const Type *WideTy = IntegerType::get(getContext(), BitWidth * 2);
// Check whether Start+Step*MaxBECount has no signed overflow.
- const SCEV *SMul =
- getMulExpr(CastedMaxBECount,
- getTruncateOrSignExtend(Step, Start->getType()));
+ const SCEV *SMul = getMulExpr(CastedMaxBECount, Step);
const SCEV *Add = getAddExpr(Start, SMul);
const SCEV *OperandExtendedAdd =
getAddExpr(getSignExtendExpr(Start, WideTy),
@@ -1061,9 +1070,7 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
// Similar to above, only this time treat the step value as unsigned.
// This covers loops that count up with an unsigned step.
- const SCEV *UMul =
- getMulExpr(CastedMaxBECount,
- getTruncateOrZeroExtend(Step, Start->getType()));
+ const SCEV *UMul = getMulExpr(CastedMaxBECount, Step);
Add = getAddExpr(Start, UMul);
OperandExtendedAdd =
getAddExpr(getSignExtendExpr(Start, WideTy),
@@ -1403,7 +1410,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
// If we deleted at least one add, we added operands to the end of the list,
// and they are not necessarily sorted. Recurse to resort and resimplify
- // any operands we just aquired.
+ // any operands we just acquired.
if (DeletedAdd)
return getAddExpr(Ops);
}
@@ -1710,7 +1717,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// If we deleted at least one mul, we added operands to the end of the list,
// and they are not necessarily sorted. Recurse to resort and resimplify
- // any operands we just aquired.
+ // any operands we just acquired.
if (DeletedMul)
return getMulExpr(Ops);
}
@@ -1958,6 +1965,12 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
return getAddRecExpr(Operands, L, HasNUW, HasNSW); // {X,+,0} --> X
}
+ // It's tempting to want to call getMaxBackedgeTakenCount count here and
+ // use that information to infer NUW and NSW flags. However, computing a
+ // BE count requires calling getAddRecExpr, so we may not yet have a
+ // meaningful BE count at this point (and if we don't, we'd be stuck
+ // with a SCEVCouldNotCompute as the cached BE count).
+
// If HasNSW is true and all the operands are non-negative, infer HasNUW.
if (!HasNUW && HasNSW) {
bool All = true;
@@ -2293,7 +2306,7 @@ const SCEV *ScalarEvolution::getUnknown(Value *V) {
/// has access to target-specific information.
bool ScalarEvolution::isSCEVable(const Type *Ty) const {
// Integers and pointers are always SCEVable.
- return Ty->isInteger() || isa<PointerType>(Ty);
+ return Ty->isIntegerTy() || Ty->isPointerTy();
}
/// getTypeSizeInBits - Return the size in bits of the specified type,
@@ -2306,12 +2319,12 @@ uint64_t ScalarEvolution::getTypeSizeInBits(const Type *Ty) const {
return TD->getTypeSizeInBits(Ty);
// Integer types have fixed sizes.
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Ty->getPrimitiveSizeInBits();
// The only other support type is pointer. Without TargetData, conservatively
// assume pointers are 64-bit.
- assert(isa<PointerType>(Ty) && "isSCEVable permitted a non-SCEVable type!");
+ assert(Ty->isPointerTy() && "isSCEVable permitted a non-SCEVable type!");
return 64;
}
@@ -2322,11 +2335,11 @@ uint64_t ScalarEvolution::getTypeSizeInBits(const Type *Ty) const {
const Type *ScalarEvolution::getEffectiveSCEVType(const Type *Ty) const {
assert(isSCEVable(Ty) && "Type is not SCEVable!");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Ty;
// The only other support type is pointer.
- assert(isa<PointerType>(Ty) && "Unexpected non-pointer non-integer type!");
+ assert(Ty->isPointerTy() && "Unexpected non-pointer non-integer type!");
if (TD) return TD->getIntPtrType(getContext());
// Without TargetData, conservatively assume pointers are 64-bit.
@@ -2397,8 +2410,8 @@ const SCEV *
ScalarEvolution::getTruncateOrZeroExtend(const SCEV *V,
const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot truncate or zero extend with non-integer arguments!");
if (getTypeSizeInBits(SrcTy) == getTypeSizeInBits(Ty))
return V; // No conversion
@@ -2414,8 +2427,8 @@ const SCEV *
ScalarEvolution::getTruncateOrSignExtend(const SCEV *V,
const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot truncate or zero extend with non-integer arguments!");
if (getTypeSizeInBits(SrcTy) == getTypeSizeInBits(Ty))
return V; // No conversion
@@ -2430,8 +2443,8 @@ ScalarEvolution::getTruncateOrSignExtend(const SCEV *V,
const SCEV *
ScalarEvolution::getNoopOrZeroExtend(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot noop or zero extend with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) &&
"getNoopOrZeroExtend cannot truncate!");
@@ -2446,8 +2459,8 @@ ScalarEvolution::getNoopOrZeroExtend(const SCEV *V, const Type *Ty) {
const SCEV *
ScalarEvolution::getNoopOrSignExtend(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot noop or sign extend with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) &&
"getNoopOrSignExtend cannot truncate!");
@@ -2463,8 +2476,8 @@ ScalarEvolution::getNoopOrSignExtend(const SCEV *V, const Type *Ty) {
const SCEV *
ScalarEvolution::getNoopOrAnyExtend(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot noop or any extend with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) &&
"getNoopOrAnyExtend cannot truncate!");
@@ -2478,8 +2491,8 @@ ScalarEvolution::getNoopOrAnyExtend(const SCEV *V, const Type *Ty) {
const SCEV *
ScalarEvolution::getTruncateOrNoop(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
+ (Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Cannot truncate or noop with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) >= getTypeSizeInBits(Ty) &&
"getTruncateOrNoop cannot extend!");
@@ -2536,12 +2549,12 @@ PushDefUseChildren(Instruction *I,
/// the Scalars map if they reference SymName. This is used during PHI
/// resolution.
void
-ScalarEvolution::ForgetSymbolicName(Instruction *I, const SCEV *SymName) {
+ScalarEvolution::ForgetSymbolicName(Instruction *PN, const SCEV *SymName) {
SmallVector<Instruction *, 16> Worklist;
- PushDefUseChildren(I, Worklist);
+ PushDefUseChildren(PN, Worklist);
SmallPtrSet<Instruction *, 8> Visited;
- Visited.insert(I);
+ Visited.insert(PN);
while (!Worklist.empty()) {
Instruction *I = Worklist.pop_back_val();
if (!Visited.insert(I)) continue;
@@ -2551,16 +2564,19 @@ ScalarEvolution::ForgetSymbolicName(Instruction *I, const SCEV *SymName) {
if (It != Scalars.end()) {
// Short-circuit the def-use traversal if the symbolic name
// ceases to appear in expressions.
- if (!It->second->hasOperand(SymName))
+ if (It->second != SymName && !It->second->hasOperand(SymName))
continue;
// SCEVUnknown for a PHI either means that it has an unrecognized
- // structure, or it's a PHI that's in the progress of being computed
- // by createNodeForPHI. In the former case, additional loop trip
- // count information isn't going to change anything. In the later
- // case, createNodeForPHI will perform the necessary updates on its
- // own when it gets to that point.
- if (!isa<PHINode>(I) || !isa<SCEVUnknown>(It->second)) {
+ // structure, it's a PHI that's in the progress of being computed
+ // by createNodeForPHI, or it's a single-value PHI. In the first case,
+ // additional loop trip count information isn't going to change anything.
+ // In the second case, createNodeForPHI will perform the necessary
+ // updates on its own when it gets to that point. In the third, we do
+ // want to forget the SCEVUnknown.
+ if (!isa<PHINode>(I) ||
+ !isa<SCEVUnknown>(It->second) ||
+ (I != PN && It->second == SymName)) {
ValuesAtScopes.erase(It->second);
Scalars.erase(It);
}
@@ -2683,9 +2699,21 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
return SymbolicName;
}
- // It's tempting to recognize PHIs with a unique incoming value, however
- // this leads passes like indvars to break LCSSA form. Fortunately, such
- // PHIs are rare, as instcombine zaps them.
+ // If the PHI has a single incoming value, follow that value, unless the
+ // PHI's incoming blocks are in a different loop, in which case doing so
+ // risks breaking LCSSA form. Instcombine would normally zap these, but
+ // it doesn't have DominatorTree information, so it may miss cases.
+ if (Value *V = PN->hasConstantValue(DT)) {
+ bool AllSameLoop = true;
+ Loop *PNLoop = LI->getLoopFor(PN->getParent());
+ for (size_t i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (LI->getLoopFor(PN->getIncomingBlock(i)) != PNLoop) {
+ AllSameLoop = false;
+ break;
+ }
+ if (AllSameLoop)
+ return getSCEV(V);
+ }
// If it's not a loop phi, we can't handle it yet.
return getUnknown(PN);
@@ -2718,7 +2746,7 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
} else {
// For an array, add the element offset, explicitly scaled.
const SCEV *LocalOffset = getSCEV(Index);
- // Getelementptr indicies are signed.
+ // Getelementptr indices are signed.
LocalOffset = getTruncateOrSignExtend(LocalOffset, IntPtrTy);
// Lower "inbounds" GEPs to NSW arithmetic.
LocalOffset = getMulExpr(LocalOffset, getSizeOfExpr(*GTI),
@@ -2921,7 +2949,6 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
// For a SCEVUnknown, ask ValueTracking.
- unsigned BitWidth = getTypeSizeInBits(U->getType());
APInt Mask = APInt::getAllOnesValue(BitWidth);
APInt Zeros(BitWidth, 0), Ones(BitWidth, 0);
ComputeMaskedBits(U->getValue(), Mask, Zeros, Ones, TD);
@@ -3053,7 +3080,7 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
// For a SCEVUnknown, ask ValueTracking.
- if (!U->getValue()->getType()->isInteger() && !TD)
+ if (!U->getValue()->getType()->isIntegerTy() && !TD)
return ConservativeResult;
unsigned NS = ComputeNumSignBits(U->getValue(), TD);
if (NS == 1)
@@ -3193,7 +3220,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
const Type *Z0Ty = Z0->getType();
unsigned Z0TySize = getTypeSizeInBits(Z0Ty);
- // If C is a low-bits mask, the zero extend is zerving to
+ // If C is a low-bits mask, the zero extend is serving to
// mask off the high bits. Complement the operand and
// re-apply the zext.
if (APIntOps::isMask(Z0TySize, CI->getValue()))
@@ -3378,7 +3405,7 @@ PushLoopPHIs(const Loop *L, SmallVectorImpl<Instruction *> &Worklist) {
const ScalarEvolution::BackedgeTakenInfo &
ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
// Initially insert a CouldNotCompute for this loop. If the insertion
- // succeeds, procede to actually compute a backedge-taken count and
+ // succeeds, proceed to actually compute a backedge-taken count and
// update the value. The temporary CouldNotCompute value tells SCEV
// code elsewhere that it shouldn't attempt to request a new
// backedge-taken count, which could result in infinite recursion.
@@ -3470,6 +3497,35 @@ void ScalarEvolution::forgetLoop(const Loop *L) {
}
}
+/// forgetValue - This method should be called by the client when it has
+/// changed a value in a way that may effect its value, or which may
+/// disconnect it from a def-use chain linking it to a loop.
+void ScalarEvolution::forgetValue(Value *V) {
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (!I) return;
+
+ // Drop information about expressions based on loop-header PHIs.
+ SmallVector<Instruction *, 16> Worklist;
+ Worklist.push_back(I);
+
+ SmallPtrSet<Instruction *, 8> Visited;
+ while (!Worklist.empty()) {
+ I = Worklist.pop_back_val();
+ if (!Visited.insert(I)) continue;
+
+ std::map<SCEVCallbackVH, const SCEV *>::iterator It =
+ Scalars.find(static_cast<Value *>(I));
+ if (It != Scalars.end()) {
+ ValuesAtScopes.erase(It->second);
+ Scalars.erase(It);
+ if (PHINode *PN = dyn_cast<PHINode>(I))
+ ConstantEvolutionLoopExitValue.erase(PN);
+ }
+
+ PushDefUseChildren(I, Worklist);
+ }
+}
+
/// ComputeBackedgeTakenCount - Compute the number of times the backedge
/// of the specified loop will execute.
ScalarEvolution::BackedgeTakenInfo
@@ -3566,7 +3622,7 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L,
return getCouldNotCompute();
}
- // Procede to the next level to examine the exit condition expression.
+ // Proceed to the next level to examine the exit condition expression.
return ComputeBackedgeTakenCountFromExitCond(L, ExitBr->getCondition(),
ExitBr->getSuccessor(0),
ExitBr->getSuccessor(1));
@@ -3655,10 +3711,23 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCond(const Loop *L,
}
// With an icmp, it may be feasible to compute an exact backedge-taken count.
- // Procede to the next level to examine the icmp.
+ // Proceed to the next level to examine the icmp.
if (ICmpInst *ExitCondICmp = dyn_cast<ICmpInst>(ExitCond))
return ComputeBackedgeTakenCountFromExitCondICmp(L, ExitCondICmp, TBB, FBB);
+ // Check for a constant condition. These are normally stripped out by
+ // SimplifyCFG, but ScalarEvolution may be used by a pass which wishes to
+ // preserve the CFG and is temporarily leaving constant conditions
+ // in place.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(ExitCond)) {
+ if (L->contains(FBB) == !CI->getZExtValue())
+ // The backedge is always taken.
+ return getCouldNotCompute();
+ else
+ // The backedge is never taken.
+ return getIntegerSCEV(0, CI->getType());
+ }
+
// If it's not an integer or pointer comparison then compute it the hard way.
return ComputeBackedgeTakenCountExhaustively(L, ExitCond, !L->contains(TBB));
}
@@ -3682,14 +3751,10 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
// Handle common loops like: for (X = "string"; *X; ++X)
if (LoadInst *LI = dyn_cast<LoadInst>(ExitCond->getOperand(0)))
if (Constant *RHS = dyn_cast<Constant>(ExitCond->getOperand(1))) {
- const SCEV *ItCnt =
+ BackedgeTakenInfo ItCnt =
ComputeLoadConstantCompareBackedgeTakenCount(LI, RHS, L, Cond);
- if (!isa<SCEVCouldNotCompute>(ItCnt)) {
- unsigned BitWidth = getTypeSizeInBits(ItCnt->getType());
- return BackedgeTakenInfo(ItCnt,
- isa<SCEVConstant>(ItCnt) ? ItCnt :
- getConstant(APInt::getMaxValue(BitWidth)-1));
- }
+ if (ItCnt.hasAnyInfo())
+ return ItCnt;
}
const SCEV *LHS = getSCEV(ExitCond->getOperand(0));
@@ -3723,14 +3788,14 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
switch (Cond) {
case ICmpInst::ICMP_NE: { // while (X != Y)
// Convert to: while (X-Y != 0)
- const SCEV *TC = HowFarToZero(getMinusSCEV(LHS, RHS), L);
- if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEV(LHS, RHS), L);
+ if (BTI.hasAnyInfo()) return BTI;
break;
}
case ICmpInst::ICMP_EQ: { // while (X == Y)
// Convert to: while (X-Y == 0)
- const SCEV *TC = HowFarToNonZero(getMinusSCEV(LHS, RHS), L);
- if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ BackedgeTakenInfo BTI = HowFarToNonZero(getMinusSCEV(LHS, RHS), L);
+ if (BTI.hasAnyInfo()) return BTI;
break;
}
case ICmpInst::ICMP_SLT: {
@@ -3817,7 +3882,7 @@ GetAddressedElementFromGlobal(GlobalVariable *GV,
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition of
/// 'icmp op load X, cst', try to see if we can compute the backedge
/// execution count.
-const SCEV *
+ScalarEvolution::BackedgeTakenInfo
ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
LoadInst *LI,
Constant *RHS,
@@ -3826,6 +3891,7 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
if (LI->isVolatile()) return getCouldNotCompute();
// Check to see if the loaded pointer is a getelementptr of a global.
+ // TODO: Use SCEV instead of manually grubbing with GEPs.
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0));
if (!GEP) return getCouldNotCompute();
@@ -4175,14 +4241,15 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
}
}
- Constant *C;
+ Constant *C = 0;
if (const CmpInst *CI = dyn_cast<CmpInst>(I))
C = ConstantFoldCompareInstOperands(CI->getPredicate(),
Operands[0], Operands[1], TD);
else
C = ConstantFoldInstOperands(I->getOpcode(), I->getType(),
&Operands[0], Operands.size(), TD);
- return getSCEV(C);
+ if (C)
+ return getSCEV(C);
}
}
@@ -4390,7 +4457,8 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) {
/// HowFarToZero - Return the number of times a backedge comparing the specified
/// value to zero will execute. If not computable, return CouldNotCompute.
-const SCEV *ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
+ScalarEvolution::BackedgeTakenInfo
+ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
// If the value is a constant
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
// If the value is already zero, the branch will execute zero times.
@@ -4435,7 +4503,7 @@ const SCEV *ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
-StartC->getValue()->getValue(),
*this);
}
- } else if (AddRec->isQuadratic() && AddRec->getType()->isInteger()) {
+ } else if (AddRec->isQuadratic() && AddRec->getType()->isIntegerTy()) {
// If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of
// the quadratic equation to solve it.
std::pair<const SCEV *,const SCEV *> Roots = SolveQuadraticEquation(AddRec,
@@ -4470,7 +4538,8 @@ const SCEV *ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
/// HowFarToNonZero - Return the number of times a backedge checking the
/// specified value for nonzero will execute. If not computable, return
/// CouldNotCompute
-const SCEV *ScalarEvolution::HowFarToNonZero(const SCEV *V, const Loop *L) {
+ScalarEvolution::BackedgeTakenInfo
+ScalarEvolution::HowFarToNonZero(const SCEV *V, const Loop *L) {
// Loops that look like: while (X == 0) are very strange indeed. We don't
// handle them yet except for the trivial case. This could be expanded in the
// future as needed.
@@ -4711,7 +4780,7 @@ bool ScalarEvolution::isImpliedCond(Value *CondValue,
ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
bool Inverse) {
- // Recursivly handle And and Or conditions.
+ // Recursively handle And and Or conditions.
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CondValue)) {
if (BO->getOpcode() == Instruction::And) {
if (!Inverse)
@@ -4914,7 +4983,7 @@ bool ScalarEvolution::isImpliedCond(Value *CondValue,
}
/// isImpliedCondOperands - Test whether the condition described by Pred,
-/// LHS, and RHS is true whenever the condition desribed by Pred, FoundLHS,
+/// LHS, and RHS is true whenever the condition described by Pred, FoundLHS,
/// and FoundRHS is true.
bool ScalarEvolution::isImpliedCondOperands(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
@@ -4929,7 +4998,7 @@ bool ScalarEvolution::isImpliedCondOperands(ICmpInst::Predicate Pred,
}
/// isImpliedCondOperandsHelper - Test whether the condition described by
-/// Pred, LHS, and RHS is true whenever the condition desribed by Pred,
+/// Pred, LHS, and RHS is true whenever the condition described by Pred,
/// FoundLHS, and FoundRHS is true.
bool
ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
@@ -5087,7 +5156,7 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
// If MaxEnd is within a step of the maximum integer value in its type,
// adjust it down to the minimum value which would produce the same effect.
- // This allows the subsequent ceiling divison of (N+(step-1))/step to
+ // This allows the subsequent ceiling division of (N+(step-1))/step to
// compute the correct value.
const SCEV *StepMinusOne = getMinusSCEV(Step,
getIntegerSCEV(1, Step->getType()));
@@ -5304,8 +5373,8 @@ ScalarEvolution::ScalarEvolution()
bool ScalarEvolution::runOnFunction(Function &F) {
this->F = &F;
LI = &getAnalysis<LoopInfo>();
- DT = &getAnalysis<DominatorTree>();
TD = getAnalysisIfAvailable<TargetData>();
+ DT = &getAnalysis<DominatorTree>();
return false;
}
@@ -5364,7 +5433,7 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE,
}
void ScalarEvolution::print(raw_ostream &OS, const Module *) const {
- // ScalarEvolution's implementaiton of the print method is to print
+ // ScalarEvolution's implementation of the print method is to print
// out SCEV values of all instructions that are interesting. Doing
// this potentially causes it to create new SCEV objects though,
// which technically conflicts with the const qualifier. This isn't
diff --git a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
index 498c4a8..17b254f 100644
--- a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
+++ b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
@@ -10,6 +10,10 @@
// This file defines the ScalarEvolutionAliasAnalysis pass, which implements a
// simple alias analysis implemented in terms of ScalarEvolution queries.
//
+// This differs from traditional loop dependence analysis in that it tests
+// for dependencies within a single iteration of a loop, rather than
+// dependences between different iterations.
+//
// ScalarEvolution has a more complete understanding of pointer arithmetic
// than BasicAliasAnalysis' collection of ad-hoc analyses.
//
@@ -41,7 +45,7 @@ namespace {
return (AliasAnalysis*)this;
return this;
}
-
+
private:
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnFunction(Function &F);
@@ -89,7 +93,7 @@ ScalarEvolutionAliasAnalysis::GetBaseValue(const SCEV *S) {
} else if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(S)) {
// If there's a pointer operand, it'll be sorted at the end of the list.
const SCEV *Last = A->getOperand(A->getNumOperands()-1);
- if (isa<PointerType>(Last->getType()))
+ if (Last->getType()->isPointerTy())
return GetBaseValue(Last);
} else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
// This is a leaf node.
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index 4310e3c..e27da96 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -15,6 +15,7 @@
#include "llvm/Analysis/ScalarEvolutionExpander.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/STLExtras.h"
@@ -137,6 +138,10 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
if (IP != BlockBegin) {
--IP;
for (; ScanLimit; --IP, --ScanLimit) {
+ // Don't count dbg.value against the ScanLimit, to avoid perturbing the
+ // generated code.
+ if (isa<DbgInfoIntrinsic>(IP))
+ ScanLimit++;
if (IP->getOpcode() == (unsigned)Opcode && IP->getOperand(0) == LHS &&
IP->getOperand(1) == RHS)
return IP;
@@ -144,15 +149,34 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
}
}
+ // Save the original insertion point so we can restore it when we're done.
+ BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
+ BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
+
+ // Move the insertion point out of as many loops as we can.
+ while (const Loop *L = SE.LI->getLoopFor(Builder.GetInsertBlock())) {
+ if (!L->isLoopInvariant(LHS) || !L->isLoopInvariant(RHS)) break;
+ BasicBlock *Preheader = L->getLoopPreheader();
+ if (!Preheader) break;
+
+ // Ok, move up a level.
+ Builder.SetInsertPoint(Preheader, Preheader->getTerminator());
+ }
+
// If we haven't found this binop, insert it.
Value *BO = Builder.CreateBinOp(Opcode, LHS, RHS, "tmp");
rememberInstruction(BO);
+
+ // Restore the original insert point.
+ if (SaveInsertBB)
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
+
return BO;
}
/// FactorOutConstant - Test if S is divisible by Factor, using signed
/// division. If so, update S with Factor divided out and return true.
-/// S need not be evenly divisble if a reasonable remainder can be
+/// S need not be evenly divisible if a reasonable remainder can be
/// computed.
/// TODO: When ScalarEvolution gets a SCEVSDivExpr, this can be made
/// unnecessary; in its place, just signed-divide Ops[i] by the scale and
@@ -462,7 +486,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
break;
}
- // If none of the operands were convertable to proper GEP indices, cast
+ // If none of the operands were convertible to proper GEP indices, cast
// the base to i8* and do an ugly getelementptr with that. It's still
// better than ptrtoint+arithmetic+inttoptr at least.
if (!AnyNonZeroIndices) {
@@ -486,6 +510,10 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
if (IP != BlockBegin) {
--IP;
for (; ScanLimit; --IP, --ScanLimit) {
+ // Don't count dbg.value against the ScanLimit, to avoid perturbing the
+ // generated code.
+ if (isa<DbgInfoIntrinsic>(IP))
+ ScanLimit++;
if (IP->getOpcode() == Instruction::GetElementPtr &&
IP->getOperand(0) == V && IP->getOperand(1) == Idx)
return IP;
@@ -493,12 +521,56 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
}
}
+ // Save the original insertion point so we can restore it when we're done.
+ BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
+ BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
+
+ // Move the insertion point out of as many loops as we can.
+ while (const Loop *L = SE.LI->getLoopFor(Builder.GetInsertBlock())) {
+ if (!L->isLoopInvariant(V) || !L->isLoopInvariant(Idx)) break;
+ BasicBlock *Preheader = L->getLoopPreheader();
+ if (!Preheader) break;
+
+ // Ok, move up a level.
+ Builder.SetInsertPoint(Preheader, Preheader->getTerminator());
+ }
+
// Emit a GEP.
Value *GEP = Builder.CreateGEP(V, Idx, "uglygep");
rememberInstruction(GEP);
+
+ // Restore the original insert point.
+ if (SaveInsertBB)
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
+
return GEP;
}
+ // Save the original insertion point so we can restore it when we're done.
+ BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
+ BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
+
+ // Move the insertion point out of as many loops as we can.
+ while (const Loop *L = SE.LI->getLoopFor(Builder.GetInsertBlock())) {
+ if (!L->isLoopInvariant(V)) break;
+
+ bool AnyIndexNotLoopInvariant = false;
+ for (SmallVectorImpl<Value *>::const_iterator I = GepIndices.begin(),
+ E = GepIndices.end(); I != E; ++I)
+ if (!L->isLoopInvariant(*I)) {
+ AnyIndexNotLoopInvariant = true;
+ break;
+ }
+ if (AnyIndexNotLoopInvariant)
+ break;
+
+ BasicBlock *Preheader = L->getLoopPreheader();
+ if (!Preheader) break;
+
+ // Ok, move up a level.
+ Builder.SetInsertPoint(Preheader, Preheader->getTerminator());
+ }
+
// 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.
@@ -511,6 +583,11 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
"scevgep");
Ops.push_back(SE.getUnknown(GEP));
rememberInstruction(GEP);
+
+ // Restore the original insert point.
+ if (SaveInsertBB)
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
+
return expand(SE.getAddExpr(Ops));
}
@@ -528,70 +605,179 @@ static bool isNonConstantNegative(const SCEV *F) {
return SC->getValue()->getValue().isNegative();
}
-Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
- int NumOperands = S->getNumOperands();
- const Type *Ty = SE.getEffectiveSCEVType(S->getType());
+/// PickMostRelevantLoop - Given two loops pick the one that's most relevant for
+/// SCEV expansion. If they are nested, this is the most nested. If they are
+/// neighboring, pick the later.
+static const Loop *PickMostRelevantLoop(const Loop *A, const Loop *B,
+ DominatorTree &DT) {
+ if (!A) return B;
+ if (!B) return A;
+ if (A->contains(B)) return B;
+ if (B->contains(A)) return A;
+ if (DT.dominates(A->getHeader(), B->getHeader())) return B;
+ if (DT.dominates(B->getHeader(), A->getHeader())) return A;
+ return A; // Arbitrarily break the tie.
+}
- // Find the index of an operand to start with. Choose the operand with
- // pointer type, if there is one, or the last operand otherwise.
- int PIdx = 0;
- for (; PIdx != NumOperands - 1; ++PIdx)
- if (isa<PointerType>(S->getOperand(PIdx)->getType())) break;
+/// GetRelevantLoop - Get the most relevant loop associated with the given
+/// expression, according to PickMostRelevantLoop.
+static const Loop *GetRelevantLoop(const SCEV *S, LoopInfo &LI,
+ DominatorTree &DT) {
+ if (isa<SCEVConstant>(S))
+ return 0;
+ if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
+ if (const Instruction *I = dyn_cast<Instruction>(U->getValue()))
+ return LI.getLoopFor(I->getParent());
+ return 0;
+ }
+ if (const SCEVNAryExpr *N = dyn_cast<SCEVNAryExpr>(S)) {
+ const Loop *L = 0;
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S))
+ L = AR->getLoop();
+ for (SCEVNAryExpr::op_iterator I = N->op_begin(), E = N->op_end();
+ I != E; ++I)
+ L = PickMostRelevantLoop(L, GetRelevantLoop(*I, LI, DT), DT);
+ return L;
+ }
+ if (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(S))
+ return GetRelevantLoop(C->getOperand(), LI, DT);
+ if (const SCEVUDivExpr *D = dyn_cast<SCEVUDivExpr>(S))
+ return PickMostRelevantLoop(GetRelevantLoop(D->getLHS(), LI, DT),
+ GetRelevantLoop(D->getRHS(), LI, DT),
+ DT);
+ llvm_unreachable("Unexpected SCEV type!");
+}
- // Expand code for the operand that we chose.
- Value *V = expand(S->getOperand(PIdx));
+/// LoopCompare - Compare loops by PickMostRelevantLoop.
+class LoopCompare {
+ DominatorTree &DT;
+public:
+ explicit LoopCompare(DominatorTree &dt) : DT(dt) {}
+
+ bool operator()(std::pair<const Loop *, const SCEV *> LHS,
+ std::pair<const Loop *, const SCEV *> RHS) const {
+ // Compare loops with PickMostRelevantLoop.
+ if (LHS.first != RHS.first)
+ return PickMostRelevantLoop(LHS.first, RHS.first, DT) != LHS.first;
+
+ // If one operand is a non-constant negative and the other is not,
+ // put the non-constant negative on the right so that a sub can
+ // be used instead of a negate and add.
+ if (isNonConstantNegative(LHS.second)) {
+ if (!isNonConstantNegative(RHS.second))
+ return false;
+ } else if (isNonConstantNegative(RHS.second))
+ return true;
- // Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the
- // comments on expandAddToGEP for details.
- if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) {
- // Take the operand at PIdx out of the list.
- const SmallVectorImpl<const SCEV *> &Ops = S->getOperands();
- SmallVector<const SCEV *, 8> NewOps;
- NewOps.insert(NewOps.end(), Ops.begin(), Ops.begin() + PIdx);
- NewOps.insert(NewOps.end(), Ops.begin() + PIdx + 1, Ops.end());
- // Make a GEP.
- return expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, V);
+ // Otherwise they are equivalent according to this comparison.
+ return false;
}
+};
- // Otherwise, we'll expand the rest of the SCEVAddExpr as plain integer
- // arithmetic.
- V = InsertNoopCastOfTo(V, Ty);
+Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
+ const Type *Ty = SE.getEffectiveSCEVType(S->getType());
- // Emit a bunch of add instructions
- for (int i = NumOperands-1; i >= 0; --i) {
- if (i == PIdx) continue;
- const SCEV *Op = S->getOperand(i);
- if (isNonConstantNegative(Op)) {
+ // Collect all the add operands in a loop, along with their associated loops.
+ // Iterate in reverse so that constants are emitted last, all else equal, and
+ // so that pointer operands are inserted first, which the code below relies on
+ // to form more involved GEPs.
+ SmallVector<std::pair<const Loop *, const SCEV *>, 8> OpsAndLoops;
+ for (std::reverse_iterator<SCEVAddExpr::op_iterator> I(S->op_end()),
+ E(S->op_begin()); I != E; ++I)
+ OpsAndLoops.push_back(std::make_pair(GetRelevantLoop(*I, *SE.LI, *SE.DT),
+ *I));
+
+ // Sort by loop. Use a stable sort so that constants follow non-constants and
+ // pointer operands precede non-pointer operands.
+ std::stable_sort(OpsAndLoops.begin(), OpsAndLoops.end(), LoopCompare(*SE.DT));
+
+ // Emit instructions to add all the operands. Hoist as much as possible
+ // out of loops, and form meaningful getelementptrs where possible.
+ Value *Sum = 0;
+ for (SmallVectorImpl<std::pair<const Loop *, const SCEV *> >::iterator
+ I = OpsAndLoops.begin(), E = OpsAndLoops.end(); I != E; ) {
+ const Loop *CurLoop = I->first;
+ const SCEV *Op = I->second;
+ if (!Sum) {
+ // This is the first operand. Just expand it.
+ Sum = expand(Op);
+ ++I;
+ } else if (const PointerType *PTy = dyn_cast<PointerType>(Sum->getType())) {
+ // The running sum expression is a pointer. Try to form a getelementptr
+ // at this level with that as the base.
+ SmallVector<const SCEV *, 4> NewOps;
+ for (; I != E && I->first == CurLoop; ++I)
+ NewOps.push_back(I->second);
+ Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, Sum);
+ } else if (const PointerType *PTy = dyn_cast<PointerType>(Op->getType())) {
+ // The running sum is an integer, and there's a pointer at this level.
+ // Try to form a getelementptr.
+ SmallVector<const SCEV *, 4> NewOps;
+ NewOps.push_back(SE.getUnknown(Sum));
+ for (++I; I != E && I->first == CurLoop; ++I)
+ NewOps.push_back(I->second);
+ Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, expand(Op));
+ } else if (isNonConstantNegative(Op)) {
+ // Instead of doing a negate and add, just do a subtract.
Value *W = expandCodeFor(SE.getNegativeSCEV(Op), Ty);
- V = InsertBinop(Instruction::Sub, V, W);
+ Sum = InsertNoopCastOfTo(Sum, Ty);
+ Sum = InsertBinop(Instruction::Sub, Sum, W);
+ ++I;
} else {
+ // A simple add.
Value *W = expandCodeFor(Op, Ty);
- V = InsertBinop(Instruction::Add, V, W);
+ Sum = InsertNoopCastOfTo(Sum, Ty);
+ // Canonicalize a constant to the RHS.
+ if (isa<Constant>(Sum)) std::swap(Sum, W);
+ Sum = InsertBinop(Instruction::Add, Sum, W);
+ ++I;
}
}
- return V;
+
+ return Sum;
}
Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) {
const Type *Ty = SE.getEffectiveSCEVType(S->getType());
- int FirstOp = 0; // Set if we should emit a subtract.
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(S->getOperand(0)))
- if (SC->getValue()->isAllOnesValue())
- FirstOp = 1;
-
- int i = S->getNumOperands()-2;
- Value *V = expandCodeFor(S->getOperand(i+1), Ty);
-
- // Emit a bunch of multiply instructions
- for (; i >= FirstOp; --i) {
- Value *W = expandCodeFor(S->getOperand(i), Ty);
- V = InsertBinop(Instruction::Mul, V, W);
+
+ // Collect all the mul operands in a loop, along with their associated loops.
+ // Iterate in reverse so that constants are emitted last, all else equal.
+ SmallVector<std::pair<const Loop *, const SCEV *>, 8> OpsAndLoops;
+ for (std::reverse_iterator<SCEVMulExpr::op_iterator> I(S->op_end()),
+ E(S->op_begin()); I != E; ++I)
+ OpsAndLoops.push_back(std::make_pair(GetRelevantLoop(*I, *SE.LI, *SE.DT),
+ *I));
+
+ // Sort by loop. Use a stable sort so that constants follow non-constants.
+ std::stable_sort(OpsAndLoops.begin(), OpsAndLoops.end(), LoopCompare(*SE.DT));
+
+ // Emit instructions to mul all the operands. Hoist as much as possible
+ // out of loops.
+ Value *Prod = 0;
+ for (SmallVectorImpl<std::pair<const Loop *, const SCEV *> >::iterator
+ I = OpsAndLoops.begin(), E = OpsAndLoops.end(); I != E; ) {
+ const SCEV *Op = I->second;
+ if (!Prod) {
+ // This is the first operand. Just expand it.
+ Prod = expand(Op);
+ ++I;
+ } else if (Op->isAllOnesValue()) {
+ // Instead of doing a multiply by negative one, just do a negate.
+ Prod = InsertNoopCastOfTo(Prod, Ty);
+ Prod = InsertBinop(Instruction::Sub, Constant::getNullValue(Ty), Prod);
+ ++I;
+ } else {
+ // A simple mul.
+ Value *W = expandCodeFor(Op, Ty);
+ Prod = InsertNoopCastOfTo(Prod, Ty);
+ // Canonicalize a constant to the RHS.
+ if (isa<Constant>(Prod)) std::swap(Prod, W);
+ Prod = InsertBinop(Instruction::Mul, Prod, W);
+ ++I;
+ }
}
- // -1 * ... ---> 0 - ...
- if (FirstOp == 1)
- V = InsertBinop(Instruction::Sub, Constant::getNullValue(Ty), V);
- return V;
+ return Prod;
}
Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) {
@@ -641,8 +827,65 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// 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;
+ if (SE.isSCEVable(PN->getType()) &&
+ (SE.getEffectiveSCEVType(PN->getType()) ==
+ SE.getEffectiveSCEVType(Normalized->getType())) &&
+ SE.getSCEV(PN) == Normalized)
+ if (BasicBlock *LatchBlock = L->getLoopLatch()) {
+ Instruction *IncV =
+ cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock));
+
+ // Determine if this is a well-behaved chain of instructions leading
+ // back to the PHI. It probably will be, if we're scanning an inner
+ // loop already visited by LSR for example, but it wouldn't have
+ // to be.
+ do {
+ if (IncV->getNumOperands() == 0 || isa<PHINode>(IncV)) {
+ IncV = 0;
+ break;
+ }
+ // If any of the operands don't dominate the insert position, bail.
+ // Addrec operands are always loop-invariant, so this can only happen
+ // if there are instructions which haven't been hoisted.
+ for (User::op_iterator OI = IncV->op_begin()+1,
+ OE = IncV->op_end(); OI != OE; ++OI)
+ if (Instruction *OInst = dyn_cast<Instruction>(OI))
+ if (!SE.DT->dominates(OInst, IVIncInsertPos)) {
+ IncV = 0;
+ break;
+ }
+ if (!IncV)
+ break;
+ // Advance to the next instruction.
+ IncV = dyn_cast<Instruction>(IncV->getOperand(0));
+ if (!IncV)
+ break;
+ if (IncV->mayHaveSideEffects()) {
+ IncV = 0;
+ break;
+ }
+ } while (IncV != PN);
+
+ if (IncV) {
+ // Ok, the add recurrence looks usable.
+ // Remember this PHI, even in post-inc mode.
+ InsertedValues.insert(PN);
+ // Remember the increment.
+ IncV = cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock));
+ rememberInstruction(IncV);
+ if (L == IVIncInsertLoop)
+ do {
+ if (SE.DT->dominates(IncV, IVIncInsertPos))
+ break;
+ // Make sure the increment is where we want it. But don't move it
+ // down past a potential existing post-inc user.
+ IncV->moveBefore(IVIncInsertPos);
+ IVIncInsertPos = IncV;
+ IncV = cast<Instruction>(IncV->getOperand(0));
+ } while (IncV != PN);
+ return PN;
+ }
+ }
// Save the original insertion point so we can restore it when we're done.
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
@@ -658,7 +901,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// 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 isPointer = ExpandTy->isPointerTy();
bool isNegative = !isPointer && isNonConstantNegative(Step);
if (isNegative)
Step = SE.getNegativeSCEV(Step);
@@ -713,7 +956,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// Restore the original insert point.
if (SaveInsertBB)
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
// Remember this PHI, even in post-inc mode.
InsertedValues.insert(PN);
@@ -763,7 +1006,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
const Type *ExpandTy = PostLoopScale ? IntTy : STy;
PHINode *PN = getAddRecExprPHILiterally(Normalized, L, ExpandTy, IntTy);
- // Accomodate post-inc mode, if necessary.
+ // Accommodate post-inc mode, if necessary.
Value *Result;
if (L != PostIncLoop)
Result = PN;
@@ -776,6 +1019,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
// Re-apply any non-loop-dominating scale.
if (PostLoopScale) {
+ Result = InsertNoopCastOfTo(Result, IntTy);
Result = Builder.CreateMul(Result,
expandCodeFor(PostLoopScale, IntTy));
rememberInstruction(Result);
@@ -787,6 +1031,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
const SCEV *const OffsetArray[1] = { PostLoopOffset };
Result = expandAddToGEP(OffsetArray, OffsetArray+1, PTy, IntTy, Result);
} else {
+ Result = InsertNoopCastOfTo(Result, IntTy);
Result = Builder.CreateAdd(Result,
expandCodeFor(PostLoopOffset, IntTy));
rememberInstruction(Result);
@@ -806,7 +1051,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
PHINode *CanonicalIV = 0;
if (PHINode *PN = L->getCanonicalInductionVariable())
if (SE.isSCEVable(PN->getType()) &&
- isa<IntegerType>(SE.getEffectiveSCEVType(PN->getType())) &&
+ SE.getEffectiveSCEVType(PN->getType())->isIntegerTy() &&
SE.getTypeSizeInBits(PN->getType()) >= SE.getTypeSizeInBits(Ty))
CanonicalIV = PN;
@@ -827,7 +1072,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
while (isa<PHINode>(NewInsertPt)) ++NewInsertPt;
V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), 0,
NewInsertPt);
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
return V;
}
@@ -1022,13 +1267,24 @@ Value *SCEVExpander::expand(const SCEV *S) {
L = L->getParentLoop())
if (S->isLoopInvariant(L)) {
if (!L) break;
- if (BasicBlock *Preheader = L->getLoopPreheader())
+ if (BasicBlock *Preheader = L->getLoopPreheader()) {
InsertPt = Preheader->getTerminator();
+ BasicBlock::iterator IP = InsertPt;
+ // Back past any debug info instructions. Sometimes we inserted
+ // something earlier before debug info but after any real instructions.
+ // This should behave the same as if debug info was not present.
+ while (IP != Preheader->begin()) {
+ --IP;
+ if (!isa<DbgInfoIntrinsic>(IP))
+ break;
+ InsertPt = IP;
+ }
+ }
} else {
// If the SCEV is computable at this level, insert it into the header
// after the PHIs (and after any other instructions that we've inserted
// there) so that it is guaranteed to dominate any user inside the loop.
- if (L && S->hasComputableLoopEvolution(L))
+ if (L && S->hasComputableLoopEvolution(L) && L != PostIncLoop)
InsertPt = L->getHeader()->getFirstNonPHI();
while (isInsertedInstruction(InsertPt))
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
@@ -1053,10 +1309,32 @@ Value *SCEVExpander::expand(const SCEV *S) {
if (!PostIncLoop)
InsertedExpressions[std::make_pair(S, InsertPt)] = V;
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
return V;
}
+void SCEVExpander::rememberInstruction(Value *I) {
+ if (!PostIncLoop)
+ InsertedValues.insert(I);
+
+ // If we just claimed an existing instruction and that instruction had
+ // been the insert point, adjust the insert point forward so that
+ // subsequently inserted code will be dominated.
+ if (Builder.GetInsertPoint() == I) {
+ BasicBlock::iterator It = cast<Instruction>(I);
+ do { ++It; } while (isInsertedInstruction(It));
+ Builder.SetInsertPoint(Builder.GetInsertBlock(), It);
+ }
+}
+
+void SCEVExpander::restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I) {
+ // If we acquired more instructions since the old insert point was saved,
+ // advance past them.
+ while (isInsertedInstruction(I)) ++I;
+
+ Builder.SetInsertPoint(BB, I);
+}
+
/// getOrInsertCanonicalInductionVariable - This method returns the
/// canonical induction variable of the specified type for the specified
/// loop (inserting one if there is none). A canonical induction variable
@@ -1064,13 +1342,13 @@ Value *SCEVExpander::expand(const SCEV *S) {
Value *
SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
const Type *Ty) {
- assert(Ty->isInteger() && "Can only insert integer induction variables!");
+ assert(Ty->isIntegerTy() && "Can only insert integer induction variables!");
const SCEV *H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
SE.getIntegerSCEV(1, Ty), L);
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
Value *V = expandCodeFor(H, 0, L->getHeader()->begin());
if (SaveInsertBB)
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
return V;
}
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index f9331e7..92cbb7c 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -23,6 +23,7 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include <cstring>
using namespace llvm;
@@ -49,11 +50,11 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
assert(V && "No Value?");
assert(Depth <= MaxDepth && "Limit Search Depth");
unsigned BitWidth = Mask.getBitWidth();
- assert((V->getType()->isIntOrIntVector() || isa<PointerType>(V->getType())) &&
- "Not integer or pointer type!");
+ assert((V->getType()->isIntOrIntVectorTy() || V->getType()->isPointerTy())
+ && "Not integer or pointer type!");
assert((!TD ||
TD->getTypeSizeInBits(V->getType()->getScalarType()) == BitWidth) &&
- (!V->getType()->isIntOrIntVector() ||
+ (!V->getType()->isIntOrIntVectorTy() ||
V->getType()->getScalarSizeInBits() == BitWidth) &&
KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth &&
@@ -249,7 +250,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
unsigned SrcBitWidth;
// Note that we handle pointer operands here because of inttoptr/ptrtoint
// which fall through here.
- if (isa<PointerType>(SrcTy))
+ if (SrcTy->isPointerTy())
SrcBitWidth = TD->getTypeSizeInBits(SrcTy);
else
SrcBitWidth = SrcTy->getScalarSizeInBits();
@@ -269,10 +270,10 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
}
case Instruction::BitCast: {
const Type *SrcTy = I->getOperand(0)->getType();
- if ((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
+ if ((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
// TODO: For now, not handling conversions like:
// (bitcast i64 %x to <2 x i32>)
- !isa<VectorType>(I->getType())) {
+ !I->getType()->isVectorTy()) {
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, TD,
Depth+1);
return;
@@ -649,7 +650,7 @@ bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask,
///
unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD,
unsigned Depth) {
- assert((TD || V->getType()->isIntOrIntVector()) &&
+ assert((TD || V->getType()->isIntOrIntVectorTy()) &&
"ComputeNumSignBits requires a TargetData object to operate "
"on non-integer values!");
const Type *Ty = V->getType();
@@ -823,7 +824,7 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
assert(V && "No Value?");
assert(Depth <= MaxDepth && "Limit Search Depth");
- assert(V->getType()->isInteger() && "Not integer or pointer type!");
+ assert(V->getType()->isIntegerTy() && "Not integer or pointer type!");
const Type *T = V->getType();
@@ -980,7 +981,7 @@ bool llvm::CannotBeNegativeZero(const Value *V, unsigned Depth) {
/// may not be represented in the result.
static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
const TargetData *TD, unsigned Depth) {
- assert(isa<IntegerType>(V->getType()) && "Not an integer value");
+ assert(V->getType()->isIntegerTy() && "Not an integer value");
// Limit our recursion depth.
if (Depth == 6) {
@@ -1253,7 +1254,7 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
if (idx_begin == idx_end)
return V;
// We have indices, so V should have an indexable type
- assert((isa<StructType>(V->getType()) || isa<ArrayType>(V->getType()))
+ assert((V->getType()->isStructTy() || V->getType()->isArrayTy())
&& "Not looking at a struct or array?");
assert(ExtractValueInst::getIndexedType(V->getType(), idx_begin, idx_end)
&& "Invalid indices for type?");
@@ -1372,7 +1373,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
// Make sure the index-ee is a pointer to array of i8.
const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
- if (AT == 0 || !AT->getElementType()->isInteger(8))
+ if (AT == 0 || !AT->getElementType()->isIntegerTy(8))
return false;
// Check to make sure that the first operand of the GEP is an integer and
@@ -1411,7 +1412,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
// Must be a Constant Array
ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
- if (Array == 0 || !Array->getType()->getElementType()->isInteger(8))
+ if (Array == 0 || !Array->getType()->getElementType()->isIntegerTy(8))
return false;
// Get the number of elements in the array
@@ -1436,3 +1437,131 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
// The array isn't null terminated, but maybe this is a memcpy, not a strcpy.
return true;
}
+
+// These next two are very similar to the above, but also look through PHI
+// nodes.
+// TODO: See if we can integrate these two together.
+
+/// GetStringLengthH - If we can compute the length of the string pointed to by
+/// the specified pointer, return 'len+1'. If we can't, return 0.
+static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) {
+ // Look through noop bitcast instructions.
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
+ return GetStringLengthH(BCI->getOperand(0), PHIs);
+
+ // If this is a PHI node, there are two cases: either we have already seen it
+ // or we haven't.
+ if (PHINode *PN = dyn_cast<PHINode>(V)) {
+ if (!PHIs.insert(PN))
+ return ~0ULL; // already in the set.
+
+ // If it was new, see if all the input strings are the same length.
+ uint64_t LenSoFar = ~0ULL;
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+ uint64_t Len = GetStringLengthH(PN->getIncomingValue(i), PHIs);
+ if (Len == 0) return 0; // Unknown length -> unknown.
+
+ if (Len == ~0ULL) continue;
+
+ if (Len != LenSoFar && LenSoFar != ~0ULL)
+ return 0; // Disagree -> unknown.
+ LenSoFar = Len;
+ }
+
+ // Success, all agree.
+ return LenSoFar;
+ }
+
+ // strlen(select(c,x,y)) -> strlen(x) ^ strlen(y)
+ if (SelectInst *SI = dyn_cast<SelectInst>(V)) {
+ uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs);
+ if (Len1 == 0) return 0;
+ uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs);
+ if (Len2 == 0) return 0;
+ if (Len1 == ~0ULL) return Len2;
+ if (Len2 == ~0ULL) return Len1;
+ if (Len1 != Len2) return 0;
+ return Len1;
+ }
+
+ // If the value is not a GEP instruction nor a constant expression with a
+ // GEP instruction, then return unknown.
+ User *GEP = 0;
+ if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
+ GEP = GEPI;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+ if (CE->getOpcode() != Instruction::GetElementPtr)
+ return 0;
+ GEP = CE;
+ } else {
+ return 0;
+ }
+
+ // Make sure the GEP has exactly three arguments.
+ if (GEP->getNumOperands() != 3)
+ return 0;
+
+ // Check to make sure that the first operand of the GEP is an integer and
+ // has value 0 so that we are sure we're indexing into the initializer.
+ if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
+ if (!Idx->isZero())
+ return 0;
+ } else
+ return 0;
+
+ // If the second index isn't a ConstantInt, then this is a variable index
+ // into the array. If this occurs, we can't say anything meaningful about
+ // the string.
+ uint64_t StartIdx = 0;
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
+ StartIdx = CI->getZExtValue();
+ else
+ return 0;
+
+ // The GEP instruction, constant or instruction, must reference a global
+ // variable that is a constant and is initialized. The referenced constant
+ // initializer is the array that we'll use for optimization.
+ GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
+ if (!GV || !GV->isConstant() || !GV->hasInitializer() ||
+ GV->mayBeOverridden())
+ return 0;
+ Constant *GlobalInit = GV->getInitializer();
+
+ // Handle the ConstantAggregateZero case, which is a degenerate case. The
+ // initializer is constant zero so the length of the string must be zero.
+ if (isa<ConstantAggregateZero>(GlobalInit))
+ return 1; // Len = 0 offset by 1.
+
+ // Must be a Constant Array
+ ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
+ if (!Array || !Array->getType()->getElementType()->isIntegerTy(8))
+ return false;
+
+ // Get the number of elements in the array
+ uint64_t NumElts = Array->getType()->getNumElements();
+
+ // Traverse the constant array from StartIdx (derived above) which is
+ // the place the GEP refers to in the array.
+ for (unsigned i = StartIdx; i != NumElts; ++i) {
+ Constant *Elt = Array->getOperand(i);
+ ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
+ if (!CI) // This array isn't suitable, non-int initializer.
+ return 0;
+ if (CI->isZero())
+ return i-StartIdx+1; // We found end of string, success!
+ }
+
+ return 0; // The array isn't null terminated, conservatively return 'unknown'.
+}
+
+/// GetStringLength - If we can compute the length of the string pointed to by
+/// the specified pointer, return 'len+1'. If we can't, return 0.
+uint64_t llvm::GetStringLength(Value *V) {
+ if (!V->getType()->isPointerTy()) return 0;
+
+ SmallPtrSet<PHINode*, 32> PHIs;
+ uint64_t Len = GetStringLengthH(V, PHIs);
+ // If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return
+ // an empty string as a length.
+ return Len == ~0ULL ? 1 : Len;
+}
diff --git a/lib/AsmParser/Android.mk b/lib/AsmParser/Android.mk
new file mode 100644
index 0000000..548f719
--- /dev/null
+++ b/lib/AsmParser/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH:= $(call my-dir)
+
+asm_parser_SRC_FILES := \
+ LLLexer.cpp \
+ LLParser.cpp \
+ Parser.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(asm_parser_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMAsmParser
+
+include $(LOCAL_PATH)/../../llvm-host-build.mk
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(asm_parser_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMAsmParser
+
+include $(LOCAL_PATH)/../../llvm-device-build.mk
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 8ad658d..46f3cbc 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -570,6 +570,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(type);
KEYWORD(opaque);
+ KEYWORD(union);
KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 5dd6569..8083a07 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -614,7 +614,7 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
Aliasee = ID.ConstantVal;
}
- if (!isa<PointerType>(Aliasee->getType()))
+ if (!Aliasee->getType()->isPointerTy())
return Error(AliaseeLoc, "alias must have pointer type");
// Okay, create the alias but do not insert it into the module yet.
@@ -685,7 +685,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
return true;
}
- if (isa<FunctionType>(Ty) || Ty->isLabelTy())
+ if (Ty->isFunctionTy() || Ty->isLabelTy())
return Error(TyLoc, "invalid type for global variable");
GlobalVariable *GV = 0;
@@ -791,7 +791,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty,
GlobalValue *FwdVal;
if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
// Function types can return opaque but functions can't.
- if (isa<OpaqueType>(FT->getReturnType())) {
+ if (FT->getReturnType()->isOpaqueTy()) {
Error(Loc, "function may not return opaque type");
return 0;
}
@@ -836,7 +836,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) {
GlobalValue *FwdVal;
if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
// Function types can return opaque but functions can't.
- if (isa<OpaqueType>(FT->getReturnType())) {
+ if (FT->getReturnType()->isOpaqueTy()) {
Error(Loc, "function may not return opaque type");
return 0;
}
@@ -956,6 +956,14 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
case lltok::kw_naked: Attrs |= Attribute::Naked; break;
+ case lltok::kw_alignstack: {
+ unsigned Alignment;
+ if (ParseOptionalStackAlignment(Alignment))
+ return true;
+ Attrs |= Attribute::constructStackAlignmentFromInt(Alignment);
+ continue;
+ }
+
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
@@ -963,6 +971,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
Attrs |= Attribute::constructAlignmentFromInt(Alignment);
continue;
}
+
}
Lex.Lex();
}
@@ -1131,6 +1140,25 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
return false;
}
+/// ParseOptionalStackAlignment
+/// ::= /* empty */
+/// ::= 'alignstack' '(' 4 ')'
+bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) {
+ Alignment = 0;
+ if (!EatIfPresent(lltok::kw_alignstack))
+ return false;
+ LocTy ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::lparen))
+ return Error(ParenLoc, "expected '('");
+ LocTy AlignLoc = Lex.getLoc();
+ if (ParseUInt32(Alignment)) return true;
+ ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::rparen))
+ return Error(ParenLoc, "expected ')'");
+ if (!isPowerOf2_32(Alignment))
+ return Error(AlignLoc, "stack alignment is not a power of two");
+ return false;
+}
/// ParseIndexList - This parses the index list for an insert/extractvalue
/// instruction. This sets AteExtraComma in the case where we eat an extra
@@ -1267,6 +1295,11 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
if (ParseStructType(Result, false))
return true;
break;
+ case lltok::kw_union:
+ // TypeRec ::= 'union' '{' ... '}'
+ if (ParseUnionType(Result))
+ return true;
+ break;
case lltok::lsquare:
// TypeRec ::= '[' ... ']'
Lex.Lex(); // eat the lsquare.
@@ -1482,7 +1515,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
Name = "";
}
- if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
+ if (!ArgTy->isFirstClassType() && !ArgTy->isOpaqueTy())
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
@@ -1576,6 +1609,38 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
return false;
}
+/// ParseUnionType
+/// TypeRec
+/// ::= 'union' '{' TypeRec (',' TypeRec)* '}'
+bool LLParser::ParseUnionType(PATypeHolder &Result) {
+ assert(Lex.getKind() == lltok::kw_union);
+ Lex.Lex(); // Consume the 'union'
+
+ if (ParseToken(lltok::lbrace, "'{' expected after 'union'")) return true;
+
+ SmallVector<PATypeHolder, 8> ParamsList;
+ do {
+ LocTy EltTyLoc = Lex.getLoc();
+ if (ParseTypeRec(Result)) return true;
+ ParamsList.push_back(Result);
+
+ if (Result->isVoidTy())
+ return Error(EltTyLoc, "union element can not have void type");
+ if (!UnionType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for union");
+
+ } while (EatIfPresent(lltok::comma)) ;
+
+ if (ParseToken(lltok::rbrace, "expected '}' at end of union"))
+ return true;
+
+ SmallVector<const Type*, 8> ParamsListTy;
+ for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
+ ParamsListTy.push_back(ParamsList[i].get());
+ Result = HandleUpRefs(UnionType::get(&ParamsListTy[0], ParamsListTy.size()));
+ return false;
+}
+
/// ParseArrayVectorType - Parse an array or vector type, assuming the first
/// token has already been consumed.
/// TypeRec
@@ -1720,7 +1785,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
}
// Don't make placeholders with invalid type.
- if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) && !Ty->isLabelTy()) {
+ if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
return 0;
}
@@ -1761,7 +1826,7 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty,
return 0;
}
- if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) && !Ty->isLabelTy()) {
+ if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
return 0;
}
@@ -1992,8 +2057,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
if (Elts.empty())
return Error(ID.Loc, "constant vector must not be empty");
- if (!Elts[0]->getType()->isInteger() &&
- !Elts[0]->getType()->isFloatingPoint())
+ if (!Elts[0]->getType()->isIntegerTy() &&
+ !Elts[0]->getType()->isFloatingPointTy())
return Error(FirstEltLoc,
"vector elements must have integer or floating point type");
@@ -2135,8 +2200,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ParseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
- return Error(ID.Loc, "extractvalue operand must be array or struct");
+ if (!Val->getType()->isAggregateType())
+ return Error(ID.Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for extractvalue");
@@ -2156,8 +2221,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ParseIndexList(Indices) ||
ParseToken(lltok::rparen, "expected ')' in insertvalue constantexpr"))
return true;
- if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
- return Error(ID.Loc, "extractvalue operand must be array or struct");
+ if (!Val0->getType()->isAggregateType())
+ return Error(ID.Loc, "insertvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for insertvalue");
@@ -2185,13 +2250,13 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
CmpInst::Predicate Pred = (CmpInst::Predicate)PredVal;
if (Opc == Instruction::FCmp) {
- if (!Val0->getType()->isFPOrFPVector())
+ if (!Val0->getType()->isFPOrFPVectorTy())
return Error(ID.Loc, "fcmp requires floating point operands");
ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1);
} else {
assert(Opc == Instruction::ICmp && "Unexpected opcode for CmpInst!");
- if (!Val0->getType()->isIntOrIntVector() &&
- !isa<PointerType>(Val0->getType()))
+ if (!Val0->getType()->isIntOrIntVectorTy() &&
+ !Val0->getType()->isPointerTy())
return Error(ID.Loc, "icmp requires pointer or integer operands");
ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1);
}
@@ -2241,7 +2306,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
if (Val0->getType() != Val1->getType())
return Error(ID.Loc, "operands of constexpr must have same type");
- if (!Val0->getType()->isIntOrIntVector()) {
+ if (!Val0->getType()->isIntOrIntVectorTy()) {
if (NUW)
return Error(ModifierLoc, "nuw only applies to integer operations");
if (NSW)
@@ -2249,8 +2314,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
}
// API compatibility: Accept either integer or floating-point types with
// add, sub, and mul.
- if (!Val0->getType()->isIntOrIntVector() &&
- !Val0->getType()->isFPOrFPVector())
+ if (!Val0->getType()->isIntOrIntVectorTy() &&
+ !Val0->getType()->isFPOrFPVectorTy())
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
unsigned Flags = 0;
if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
@@ -2280,7 +2345,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
if (Val0->getType() != Val1->getType())
return Error(ID.Loc, "operands of constexpr must have same type");
- if (!Val0->getType()->isIntOrIntVector())
+ if (!Val0->getType()->isIntOrIntVectorTy())
return Error(ID.Loc,
"constexpr requires integer or integer vector operands");
ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1);
@@ -2305,7 +2370,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
if (Opc == Instruction::GetElementPtr) {
- if (Elts.size() == 0 || !isa<PointerType>(Elts[0]->getType()))
+ if (Elts.size() == 0 || !Elts[0]->getType()->isPointerTy())
return Error(ID.Loc, "getelementptr requires pointer operand");
if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(),
@@ -2405,7 +2470,7 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
PerFunctionState *PFS) {
- if (isa<FunctionType>(Ty))
+ if (Ty->isFunctionTy())
return Error(ID.Loc, "functions are not values, refer to them as pointers");
switch (ID.Kind) {
@@ -2444,13 +2509,13 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc);
return V == 0;
case ValID::t_APSInt:
- if (!isa<IntegerType>(Ty))
+ if (!Ty->isIntegerTy())
return Error(ID.Loc, "integer constant must have integer type");
ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits());
V = ConstantInt::get(Context, ID.APSIntVal);
return false;
case ValID::t_APFloat:
- if (!Ty->isFloatingPoint() ||
+ if (!Ty->isFloatingPointTy() ||
!ConstantFP::isValueValidForType(Ty, ID.APFloatVal))
return Error(ID.Loc, "floating point constant invalid for type");
@@ -2470,19 +2535,19 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
return false;
case ValID::t_Null:
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error(ID.Loc, "null must be a pointer type");
V = ConstantPointerNull::get(cast<PointerType>(Ty));
return false;
case ValID::t_Undef:
// FIXME: LabelTy should not be a first-class type.
if ((!Ty->isFirstClassType() || Ty->isLabelTy()) &&
- !isa<OpaqueType>(Ty))
+ !Ty->isOpaqueTy())
return Error(ID.Loc, "invalid type for undef constant");
V = UndefValue::get(Ty);
return false;
case ValID::t_EmptyArray:
- if (!isa<ArrayType>(Ty) || cast<ArrayType>(Ty)->getNumElements() != 0)
+ if (!Ty->isArrayTy() || cast<ArrayType>(Ty)->getNumElements() != 0)
return Error(ID.Loc, "invalid empty array initializer");
V = UndefValue::get(Ty);
return false;
@@ -2493,8 +2558,17 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
V = Constant::getNullValue(Ty);
return false;
case ValID::t_Constant:
- if (ID.ConstantVal->getType() != Ty)
+ if (ID.ConstantVal->getType() != Ty) {
+ // Allow a constant struct with a single member to be converted
+ // to a union, if the union has a member which is the same type
+ // as the struct member.
+ if (const UnionType* utype = dyn_cast<UnionType>(Ty)) {
+ return ParseUnionValue(utype, ID, V);
+ }
+
return Error(ID.Loc, "constant expression type mismatch");
+ }
+
V = ID.ConstantVal;
return false;
}
@@ -2524,6 +2598,22 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
return false;
}
+bool LLParser::ParseUnionValue(const UnionType* utype, ValID &ID, Value *&V) {
+ if (const StructType* stype = dyn_cast<StructType>(ID.ConstantVal->getType())) {
+ if (stype->getNumContainedTypes() != 1)
+ return Error(ID.Loc, "constant expression type mismatch");
+ int index = utype->getElementTypeIndex(stype->getContainedType(0));
+ if (index < 0)
+ return Error(ID.Loc, "initializer type is not a member of the union");
+
+ V = ConstantUnion::get(
+ utype, cast<Constant>(ID.ConstantVal->getOperand(0)));
+ return false;
+ }
+
+ return Error(ID.Loc, "constant expression type mismatch");
+}
+
/// FunctionHeader
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
@@ -2572,7 +2662,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
}
if (!FunctionType::isValidReturnType(RetType) ||
- isa<OpaqueType>(RetType))
+ RetType->isOpaqueTy())
return Error(RetTypeLoc, "invalid function return type");
LocTy NameLoc = Lex.getLoc();
@@ -2873,7 +2963,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
// API compatibility: Accept either integer or floating-point types.
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 0);
if (!Result) {
- if (!Inst->getType()->isIntOrIntVector()) {
+ if (!Inst->getType()->isIntOrIntVectorTy()) {
if (NUW)
return Error(ModifierLoc, "nuw only applies to integer operations");
if (NSW)
@@ -3096,7 +3186,7 @@ bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
ParseToken(lltok::lsquare, "expected '[' with switch table"))
return true;
- if (!isa<IntegerType>(Cond->getType()))
+ if (!Cond->getType()->isIntegerTy())
return Error(CondLoc, "switch condition must have integer type");
// Parse the jump table pairs.
@@ -3139,7 +3229,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
ParseToken(lltok::lsquare, "expected '[' with indirectbr"))
return true;
- if (!isa<PointerType>(Address->getType()))
+ if (!Address->getType()->isPointerTy())
return Error(AddrLoc, "indirectbr address must have pointer type");
// Parse the destination list.
@@ -3292,11 +3382,11 @@ bool LLParser::ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
switch (OperandType) {
default: llvm_unreachable("Unknown operand type!");
case 0: // int or FP.
- Valid = LHS->getType()->isIntOrIntVector() ||
- LHS->getType()->isFPOrFPVector();
+ Valid = LHS->getType()->isIntOrIntVectorTy() ||
+ LHS->getType()->isFPOrFPVectorTy();
break;
- case 1: Valid = LHS->getType()->isIntOrIntVector(); break;
- case 2: Valid = LHS->getType()->isFPOrFPVector(); break;
+ case 1: Valid = LHS->getType()->isIntOrIntVectorTy(); break;
+ case 2: Valid = LHS->getType()->isFPOrFPVectorTy(); break;
}
if (!Valid)
@@ -3316,7 +3406,7 @@ bool LLParser::ParseLogical(Instruction *&Inst, PerFunctionState &PFS,
ParseValue(LHS->getType(), RHS, PFS))
return true;
- if (!LHS->getType()->isIntOrIntVector())
+ if (!LHS->getType()->isIntOrIntVectorTy())
return Error(Loc,"instruction requires integer or integer vector operands");
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
@@ -3340,13 +3430,13 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS,
return true;
if (Opc == Instruction::FCmp) {
- if (!LHS->getType()->isFPOrFPVector())
+ if (!LHS->getType()->isFPOrFPVectorTy())
return Error(Loc, "fcmp requires floating point operands");
Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
} else {
assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!");
- if (!LHS->getType()->isIntOrIntVector() &&
- !isa<PointerType>(LHS->getType()))
+ if (!LHS->getType()->isIntOrIntVectorTy() &&
+ !LHS->getType()->isPointerTy())
return Error(Loc, "icmp requires integer operands");
Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
}
@@ -3643,7 +3733,7 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
}
}
- if (Size && !Size->getType()->isInteger(32))
+ if (Size && !Size->getType()->isIntegerTy(32))
return Error(SizeLoc, "element count must be i32");
if (isAlloca) {
@@ -3671,7 +3761,7 @@ bool LLParser::ParseFree(Instruction *&Inst, PerFunctionState &PFS,
BasicBlock* BB) {
Value *Val; LocTy Loc;
if (ParseTypeAndValue(Val, Loc, PFS)) return true;
- if (!isa<PointerType>(Val->getType()))
+ if (!Val->getType()->isPointerTy())
return Error(Loc, "operand to free must be a pointer");
Inst = CallInst::CreateFree(Val, BB);
return false;
@@ -3688,7 +3778,7 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
ParseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
- if (!isa<PointerType>(Val->getType()) ||
+ if (!Val->getType()->isPointerTy() ||
!cast<PointerType>(Val->getType())->getElementType()->isFirstClassType())
return Error(Loc, "load operand must be a pointer to a first class type");
@@ -3709,7 +3799,7 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
ParseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
- if (!isa<PointerType>(Ptr->getType()))
+ if (!Ptr->getType()->isPointerTy())
return Error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType())
return Error(Loc, "store operand must be a first class value");
@@ -3731,7 +3821,7 @@ bool LLParser::ParseGetResult(Instruction *&Inst, PerFunctionState &PFS) {
ParseUInt32(Element, EltLoc))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
+ if (!Val->getType()->isStructTy() && !Val->getType()->isArrayTy())
return Error(ValLoc, "getresult inst requires an aggregate operand");
if (!ExtractValueInst::getIndexedType(Val->getType(), Element))
return Error(EltLoc, "invalid getresult index for value");
@@ -3748,7 +3838,7 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
- if (!isa<PointerType>(Ptr->getType()))
+ if (!Ptr->getType()->isPointerTy())
return Error(Loc, "base of getelementptr must be a pointer");
SmallVector<Value*, 16> Indices;
@@ -3759,7 +3849,7 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
break;
}
if (ParseTypeAndValue(Val, EltLoc, PFS)) return true;
- if (!isa<IntegerType>(Val->getType()))
+ if (!Val->getType()->isIntegerTy())
return Error(EltLoc, "getelementptr index must be an integer");
Indices.push_back(Val);
}
@@ -3783,8 +3873,8 @@ int LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
ParseIndexList(Indices, AteExtraComma))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
- return Error(Loc, "extractvalue operand must be array or struct");
+ if (!Val->getType()->isAggregateType())
+ return Error(Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
@@ -3805,8 +3895,8 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
ParseIndexList(Indices, AteExtraComma))
return true;
- if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
- return Error(Loc0, "extractvalue operand must be array or struct");
+ if (!Val0->getType()->isAggregateType())
+ return Error(Loc0, "insertvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 85c07ff..9abe404 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -31,6 +31,7 @@ namespace llvm {
class GlobalValue;
class MDString;
class MDNode;
+ class UnionType;
/// ValID - Represents a reference of a definition of some sort with no type.
/// There are several cases where we have to parse the value but where the
@@ -169,6 +170,7 @@ namespace llvm {
bool ParseOptionalVisibility(unsigned &Visibility);
bool ParseOptionalCallingConv(CallingConv::ID &CC);
bool ParseOptionalAlignment(unsigned &Alignment);
+ bool ParseOptionalStackAlignment(unsigned &Alignment);
bool ParseInstructionMetadata(SmallVectorImpl<std::pair<unsigned,
MDNode *> > &);
bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma);
@@ -211,6 +213,7 @@ namespace llvm {
}
bool ParseTypeRec(PATypeHolder &H);
bool ParseStructType(PATypeHolder &H, bool Packed);
+ bool ParseUnionType(PATypeHolder &H);
bool ParseArrayVectorType(PATypeHolder &H, bool isVector);
bool ParseFunctionType(PATypeHolder &Result);
PATypeHolder HandleUpRefs(const Type *Ty);
@@ -279,6 +282,8 @@ namespace llvm {
return ParseTypeAndBasicBlock(BB, Loc, PFS);
}
+ bool ParseUnionValue(const UnionType* utype, ValID &ID, Value *&V);
+
struct ParamInfo {
LocTy Loc;
Value *V;
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 7f1807c..3ac9169 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -97,6 +97,7 @@ namespace lltok {
kw_type,
kw_opaque,
+ kw_union,
kw_eq, kw_ne, kw_slt, kw_sgt, kw_sle, kw_sge, kw_ult, kw_ugt, kw_ule,
kw_uge, kw_oeq, kw_one, kw_olt, kw_ogt, kw_ole, kw_oge, kw_ord, kw_uno,
diff --git a/lib/Bitcode/Reader/Android.mk b/lib/Bitcode/Reader/Android.mk
new file mode 100644
index 0000000..165b0d0
--- /dev/null
+++ b/lib/Bitcode/Reader/Android.mk
@@ -0,0 +1,29 @@
+LOCAL_PATH:= $(call my-dir)
+
+bitcode_reader_SRC_FILES := \
+ BitReader.cpp \
+ BitcodeReader.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(bitcode_reader_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMBitReader
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(bitcode_reader_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMBitReader
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Bitcode/Reader/BitReader.cpp b/lib/Bitcode/Reader/BitReader.cpp
index 1facbc3..15844c0 100644
--- a/lib/Bitcode/Reader/BitReader.cpp
+++ b/lib/Bitcode/Reader/BitReader.cpp
@@ -21,17 +21,8 @@ using namespace llvm;
Optionally returns a human-readable error message via OutMessage. */
LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
LLVMModuleRef *OutModule, char **OutMessage) {
- std::string Message;
-
- *OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), getGlobalContext(),
- &Message));
- if (!*OutModule) {
- if (OutMessage)
- *OutMessage = strdup(Message.c_str());
- return 1;
- }
-
- return 0;
+ return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
+ OutMessage);
}
LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
@@ -54,36 +45,44 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
/* Reads a module from the specified path, returning via the OutModule parameter
a module provider which performs lazy deserialization. Returns 0 on success.
Optionally returns a human-readable error message via OutMessage. */
-LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
- LLVMModuleProviderRef *OutMP,
- char **OutMessage) {
+LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutM,
+ char **OutMessage) {
std::string Message;
-
- *OutMP = reinterpret_cast<LLVMModuleProviderRef>(
- getLazyBitcodeModule(unwrap(MemBuf), getGlobalContext(), &Message));
-
- if (!*OutMP) {
+
+ *OutM = wrap(getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef),
+ &Message));
+ if (!*OutM) {
if (OutMessage)
*OutMessage = strdup(Message.c_str());
- return 1;
+ return 1;
}
-
+
return 0;
+
}
+LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+ char **OutMessage) {
+ return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
+ OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
LLVMMemoryBufferRef MemBuf,
LLVMModuleProviderRef *OutMP,
char **OutMessage) {
- std::string Message;
-
- *OutMP = reinterpret_cast<LLVMModuleProviderRef>(
- getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef), &Message));
- if (!*OutMP) {
- if (OutMessage)
- *OutMessage = strdup(Message.c_str());
- return 1;
- }
-
- return 0;
+ return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf,
+ reinterpret_cast<LLVMModuleRef*>(OutMP),
+ OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModule instead. */
+LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
+ LLVMModuleProviderRef *OutMP,
+ char **OutMessage) {
+ return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf,
+ OutMP, OutMessage);
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 4dfc6ce..a328837 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -108,17 +108,17 @@ static int GetDecodedBinaryOpcode(unsigned Val, const Type *Ty) {
switch (Val) {
default: return -1;
case bitc::BINOP_ADD:
- return Ty->isFPOrFPVector() ? Instruction::FAdd : Instruction::Add;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add;
case bitc::BINOP_SUB:
- return Ty->isFPOrFPVector() ? Instruction::FSub : Instruction::Sub;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub;
case bitc::BINOP_MUL:
- return Ty->isFPOrFPVector() ? Instruction::FMul : Instruction::Mul;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul;
case bitc::BINOP_UDIV: return Instruction::UDiv;
case bitc::BINOP_SDIV:
- return Ty->isFPOrFPVector() ? Instruction::FDiv : Instruction::SDiv;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv;
case bitc::BINOP_UREM: return Instruction::URem;
case bitc::BINOP_SREM:
- return Ty->isFPOrFPVector() ? Instruction::FRem : Instruction::SRem;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem;
case bitc::BINOP_SHL: return Instruction::Shl;
case bitc::BINOP_LSHR: return Instruction::LShr;
case bitc::BINOP_ASHR: return Instruction::AShr;
@@ -585,6 +585,13 @@ bool BitcodeReader::ParseTypeTable() {
ResultTy = StructType::get(Context, EltTys, Record[0]);
break;
}
+ case bitc::TYPE_CODE_UNION: { // UNION: [eltty x N]
+ SmallVector<const Type*, 8> EltTys;
+ for (unsigned i = 0, e = Record.size(); i != e; ++i)
+ EltTys.push_back(getTypeByID(Record[i], true));
+ ResultTy = UnionType::get(&EltTys[0], EltTys.size());
+ break;
+ }
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid ARRAY type record");
@@ -956,12 +963,12 @@ bool BitcodeReader::ParseConstants() {
V = Constant::getNullValue(CurTy);
break;
case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
- if (!isa<IntegerType>(CurTy) || Record.empty())
+ if (!CurTy->isIntegerTy() || Record.empty())
return Error("Invalid CST_INTEGER record");
V = ConstantInt::get(CurTy, DecodeSignRotatedValue(Record[0]));
break;
case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
- if (!isa<IntegerType>(CurTy) || Record.empty())
+ if (!CurTy->isIntegerTy() || Record.empty())
return Error("Invalid WIDE_INTEGER record");
unsigned NumWords = Record.size();
@@ -1168,7 +1175,7 @@ bool BitcodeReader::ParseConstants() {
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
- if (OpTy->isFPOrFPVector())
+ if (OpTy->isFPOrFPVectorTy())
V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
else
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
@@ -1400,7 +1407,7 @@ bool BitcodeReader::ParseModule() {
if (Record.size() < 6)
return Error("Invalid MODULE_CODE_GLOBALVAR record");
const Type *Ty = getTypeByID(Record[0]);
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error("Global not a pointer type!");
unsigned AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
Ty = cast<PointerType>(Ty)->getElementType();
@@ -1443,7 +1450,7 @@ bool BitcodeReader::ParseModule() {
if (Record.size() < 8)
return Error("Invalid MODULE_CODE_FUNCTION record");
const Type *Ty = getTypeByID(Record[0]);
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error("Function not a pointer type!");
const FunctionType *FTy =
dyn_cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
@@ -1484,7 +1491,7 @@ bool BitcodeReader::ParseModule() {
if (Record.size() < 3)
return Error("Invalid MODULE_ALIAS record");
const Type *Ty = getTypeByID(Record[0]);
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error("Function not a pointer type!");
GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]),
@@ -1615,6 +1622,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
return Error("Malformed block record");
+ InstructionList.clear();
unsigned ModuleValueListSize = ValueList.size();
// Add all the function arguments to the value table.
@@ -1885,7 +1893,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
OpNum+1 != Record.size())
return Error("Invalid CMP record");
- if (LHS->getType()->isFPOrFPVector())
+ if (LHS->getType()->isFPOrFPVectorTy())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
else
I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
@@ -1925,7 +1933,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
const Type *ReturnType = F->getReturnType();
if (Vs.size() > 1 ||
- (isa<StructType>(ReturnType) &&
+ (ReturnType->isStructTy() &&
(Vs.empty() || Vs[0]->getType() != ReturnType))) {
Value *RV = UndefValue::get(ReturnType);
for (unsigned i = 0, e = Vs.size(); i != e; ++i) {
diff --git a/lib/Bitcode/Writer/BitWriter.cpp b/lib/Bitcode/Writer/BitWriter.cpp
index 7ed651b..4288422 100644
--- a/lib/Bitcode/Writer/BitWriter.cpp
+++ b/lib/Bitcode/Writer/BitWriter.cpp
@@ -27,20 +27,14 @@ int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) {
return 0;
}
-#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR >= 4)
-#include <ext/stdio_filebuf.h>
-
-int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int FileHandle) {
- raw_fd_ostream OS(FileHandle, false);
+int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
+ int Unbuffered) {
+ raw_fd_ostream OS(FD, ShouldClose, Unbuffered);
WriteBitcodeToFile(unwrap(M), OS);
return 0;
}
-#else
-
int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int FileHandle) {
- return -1; // Not supported.
+ return LLVMWriteBitcodeToFD(M, FileHandle, true, false);
}
-
-#endif
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index a5bb526..82e73b5 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -181,6 +181,14 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Log2_32_Ceil(VE.getTypes().size()+1)));
unsigned StructAbbrev = Stream.EmitAbbrev(Abbv);
+ // Abbrev for TYPE_CODE_UNION.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_UNION));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ Log2_32_Ceil(VE.getTypes().size()+1)));
+ unsigned UnionAbbrev = Stream.EmitAbbrev(Abbv);
+
// Abbrev for TYPE_CODE_ARRAY.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
@@ -250,6 +258,17 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
AbbrevToUse = StructAbbrev;
break;
}
+ case Type::UnionTyID: {
+ const UnionType *UT = cast<UnionType>(T);
+ // UNION: [eltty x N]
+ Code = bitc::TYPE_CODE_UNION;
+ // Output all of the element types.
+ for (UnionType::element_iterator I = UT->element_begin(),
+ E = UT->element_end(); I != E; ++I)
+ TypeVals.push_back(VE.getTypeID(*I));
+ AbbrevToUse = UnionAbbrev;
+ break;
+ }
case Type::ArrayTyID: {
const ArrayType *AT = cast<ArrayType>(T);
// ARRAY: [numelts, eltty]
@@ -789,7 +808,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
else if (isCStr7)
AbbrevToUse = CString7Abbrev;
} else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) ||
- isa<ConstantVector>(V)) {
+ isa<ConstantUnion>(C) || isa<ConstantVector>(V)) {
Code = bitc::CST_CODE_AGGREGATE;
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
Record.push_back(VE.getValueID(C->getOperand(i)));
@@ -1510,16 +1529,50 @@ enum {
DarwinBCHeaderSize = 5*4
};
+/// isARMTriplet - Return true if the triplet looks like:
+/// arm-*, thumb-*, armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*.
+static bool isARMTriplet(const std::string &TT) {
+ size_t Pos = 0;
+ size_t Size = TT.size();
+ if (Size >= 6 &&
+ TT[0] == 't' && TT[1] == 'h' && TT[2] == 'u' &&
+ TT[3] == 'm' && TT[4] == 'b')
+ Pos = 5;
+ else if (Size >= 4 && TT[0] == 'a' && TT[1] == 'r' && TT[2] == 'm')
+ Pos = 3;
+ else
+ return false;
+
+ if (TT[Pos] == '-')
+ return true;
+ else if (TT[Pos] == 'v') {
+ if (Size >= Pos+4 &&
+ TT[Pos+1] == '6' && TT[Pos+2] == 't' && TT[Pos+3] == '2')
+ return true;
+ else if (Size >= Pos+4 &&
+ TT[Pos+1] == '5' && TT[Pos+2] == 't' && TT[Pos+3] == 'e')
+ return true;
+ } else
+ return false;
+ while (++Pos < Size && TT[Pos] != '-') {
+ if (!isdigit(TT[Pos]))
+ return false;
+ }
+ return true;
+}
+
static void EmitDarwinBCHeader(BitstreamWriter &Stream,
const std::string &TT) {
unsigned CPUType = ~0U;
- // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*. The CPUType is a
- // magic number from /usr/include/mach/machine.h. It is ok to reproduce the
+ // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
+ // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic
+ // number from /usr/include/mach/machine.h. It is ok to reproduce the
// specific constants here because they are implicitly part of the Darwin ABI.
enum {
DARWIN_CPU_ARCH_ABI64 = 0x01000000,
DARWIN_CPU_TYPE_X86 = 7,
+ DARWIN_CPU_TYPE_ARM = 12,
DARWIN_CPU_TYPE_POWERPC = 18
};
@@ -1532,6 +1585,8 @@ static void EmitDarwinBCHeader(BitstreamWriter &Stream,
CPUType = DARWIN_CPU_TYPE_POWERPC;
else if (TT.find("powerpc64-") == 0)
CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
+ else if (isARMTriplet(TT))
+ CPUType = DARWIN_CPU_TYPE_ARM;
// Traditional Bitcode starts after header.
unsigned BCOffset = DarwinBCHeaderSize;
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 595497f..aa4c3af 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -27,7 +27,7 @@ static bool isSingleValueType(const std::pair<const llvm::Type*,
}
static bool isIntegerValue(const std::pair<const Value*, unsigned> &V) {
- return isa<IntegerType>(V.first->getType());
+ return V.first->getType()->isIntegerTy();
}
static bool CompareByFrequency(const std::pair<const llvm::Type*,
@@ -39,8 +39,6 @@ static bool CompareByFrequency(const std::pair<const llvm::Type*,
/// ValueEnumerator - Enumerate module-level information.
ValueEnumerator::ValueEnumerator(const Module *M) {
- InstructionCount = 0;
-
// Enumerate the global variables.
for (Module::const_global_iterator I = M->global_begin(),
E = M->global_end(); I != E; ++I)
@@ -377,6 +375,7 @@ void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) {
void ValueEnumerator::incorporateFunction(const Function &F) {
+ InstructionCount = 0;
NumModuleValues = Values.size();
// Adding function arguments to the value table.
diff --git a/lib/CodeGen/Android.mk b/lib/CodeGen/Android.mk
new file mode 100644
index 0000000..9fa2ecd
--- /dev/null
+++ b/lib/CodeGen/Android.mk
@@ -0,0 +1,99 @@
+LOCAL_PATH:= $(call my-dir)
+
+codegen_SRC_FILES := \
+ AggressiveAntiDepBreaker.cpp \
+ BranchFolding.cpp \
+ CalcSpillWeights.cpp \
+ CodePlacementOpt.cpp \
+ CriticalAntiDepBreaker.cpp \
+ DeadMachineInstructionElim.cpp \
+ DwarfEHPrepare.cpp \
+ ELFCodeEmitter.cpp \
+ ELFWriter.cpp \
+ ExactHazardRecognizer.cpp \
+ GCMetadata.cpp \
+ GCMetadataPrinter.cpp \
+ GCStrategy.cpp \
+ IfConversion.cpp \
+ IntrinsicLowering.cpp \
+ LLVMTargetMachine.cpp \
+ LatencyPriorityQueue.cpp \
+ LiveInterval.cpp \
+ LiveIntervalAnalysis.cpp \
+ LiveStackAnalysis.cpp \
+ LiveVariables.cpp \
+ LowerSubregs.cpp \
+ MachineBasicBlock.cpp \
+ MachineCSE.cpp \
+ MachineDominators.cpp \
+ MachineFunction.cpp \
+ MachineFunctionAnalysis.cpp \
+ MachineFunctionPass.cpp \
+ MachineInstr.cpp \
+ MachineLICM.cpp \
+ MachineLoopInfo.cpp \
+ MachineModuleInfo.cpp \
+ MachineModuleInfoImpls.cpp \
+ MachinePassRegistry.cpp \
+ MachineRegisterInfo.cpp \
+ MachineSSAUpdater.cpp \
+ MachineSink.cpp \
+ MachineVerifier.cpp \
+ ObjectCodeEmitter.cpp \
+ OcamlGC.cpp \
+ OptimizeExts.cpp \
+ OptimizePHIs.cpp \
+ PHIElimination.cpp \
+ Passes.cpp \
+ PostRASchedulerList.cpp \
+ PreAllocSplitting.cpp \
+ ProcessImplicitDefs.cpp \
+ PrologEpilogInserter.cpp \
+ PseudoSourceValue.cpp \
+ RegAllocLinearScan.cpp \
+ RegAllocLocal.cpp \
+ RegAllocPBQP.cpp \
+ RegisterCoalescer.cpp \
+ RegisterScavenging.cpp \
+ ScheduleDAG.cpp \
+ ScheduleDAGEmit.cpp \
+ ScheduleDAGInstrs.cpp \
+ ScheduleDAGPrinter.cpp \
+ ShadowStackGC.cpp \
+ ShrinkWrapping.cpp \
+ SimpleRegisterCoalescing.cpp \
+ SjLjEHPrepare.cpp \
+ SlotIndexes.cpp \
+ Spiller.cpp \
+ StackProtector.cpp \
+ StackSlotColoring.cpp \
+ StrongPHIElimination.cpp \
+ TailDuplication.cpp \
+ TargetInstrInfoImpl.cpp \
+ TargetLoweringObjectFileImpl.cpp \
+ TwoAddressInstructionPass.cpp \
+ UnreachableBlockElim.cpp \
+ VirtRegMap.cpp \
+ VirtRegRewriter.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(codegen_SRC_FILES)
+LOCAL_MODULE:= libLLVMCodeGen
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(codegen_SRC_FILES)
+LOCAL_MODULE:= libLLVMCodeGen
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/CodeGen/AsmPrinter/Android.mk b/lib/CodeGen/AsmPrinter/Android.mk
new file mode 100644
index 0000000..62601f0
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/Android.mk
@@ -0,0 +1,31 @@
+LOCAL_PATH := $(call my-dir)
+
+codegen_asmprinter_SRC_FILES := \
+ AsmPrinter.cpp \
+ DIE.cpp \
+ DwarfDebug.cpp \
+ DwarfException.cpp \
+ DwarfLabel.cpp \
+ DwarfPrinter.cpp \
+ DwarfWriter.cpp \
+ OcamlGCPrinter.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(codegen_asmprinter_SRC_FILES)
+LOCAL_MODULE:= libLLVMAsmPrinter
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(codegen_asmprinter_SRC_FILES)
+LOCAL_MODULE:= libLLVMAsmPrinter
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index fc08384..bbeb026 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -50,6 +50,7 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include <cerrno>
+#include <ctype.h>
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -917,11 +918,10 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV,
if (NumBits == 0) return; // No need to emit alignment.
- unsigned FillValue = 0;
if (getCurrentSection()->getKind().isText())
- FillValue = MAI->getTextAlignFillValue();
-
- OutStreamer.EmitValueToAlignment(1 << NumBits, FillValue, 1, 0);
+ OutStreamer.EmitCodeAlignment(1 << NumBits);
+ else
+ OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0);
}
/// LowerConstant - Lower the specified LLVM Constant to an MCExpr.
@@ -1717,7 +1717,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
}
// Print the main label for the block.
- if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) {
+ if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) {
if (VerboseAsm) {
// NOTE: Want this comment at start of line.
O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':';
@@ -1764,6 +1764,39 @@ void AsmPrinter::printOffset(int64_t Offset) const {
O << Offset;
}
+/// isBlockOnlyReachableByFallthough - Return true if the basic block has
+/// exactly one predecessor and the control transfer mechanism between
+/// the predecessor and this block is a fall-through.
+bool AsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
+ const {
+ // If this is a landing pad, it isn't a fall through. If it has no preds,
+ // then nothing falls through to it.
+ if (MBB->isLandingPad() || MBB->pred_empty())
+ return false;
+
+ // If there isn't exactly one predecessor, it can't be a fall through.
+ MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
+ ++PI2;
+ if (PI2 != MBB->pred_end())
+ return false;
+
+ // The predecessor has to be immediately before this block.
+ const MachineBasicBlock *Pred = *PI;
+
+ if (!Pred->isLayoutSuccessor(MBB))
+ return false;
+
+ // If the block is completely empty, then it definitely does fall through.
+ if (Pred->empty())
+ return true;
+
+ // Otherwise, check the last instruction.
+ const MachineInstr &LastInst = Pred->back();
+ return !LastInst.getDesc().isBarrier();
+}
+
+
+
GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
if (!S->usesMetadata())
return 0;
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index 349e0ac..63360c0 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -313,6 +313,7 @@ void DIESectionOffset::EmitValue(DwarfPrinter *D, unsigned Form) const {
D->EmitSectionOffset(Label.getTag(), Section.getTag(),
Label.getNumber(), Section.getNumber(),
IsSmall, IsEH, UseSet);
+ D->getAsm()->O << '\n'; // FIXME: Necesssary?
}
/// SizeOf - Determine size of delta value in bytes.
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 5093dd9..5ad1e5e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -238,7 +238,18 @@ public:
LIndex = DSI;
}
}
- setLastInsn(LastInsn);
+
+ unsigned CurrentLastInsnIndex = 0;
+ if (const MachineInstr *CL = getLastInsn())
+ CurrentLastInsnIndex = MIIndexMap[CL];
+ unsigned FIndex = MIIndexMap[getFirstInsn()];
+
+ // Set LastInsn as the last instruction for this scope only if
+ // it follows
+ // 1) this scope's first instruction and
+ // 2) current last instruction for this scope, if any.
+ if (LIndex >= CurrentLastInsnIndex && LIndex >= FIndex)
+ setLastInsn(LastInsn);
}
#ifndef NDEBUG
@@ -1166,7 +1177,9 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
return SPDie;
SPDie = new DIE(dwarf::DW_TAG_subprogram);
- addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
+ // Constructors and operators for anonymous aggregates do not have names.
+ if (!SP.getName().empty())
+ addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
StringRef LinkageName = SP.getLinkageName();
if (!LinkageName.empty())
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index b6801dc..2b08ba4 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -50,26 +50,6 @@ DwarfException::~DwarfException() {
delete ExceptionTimer;
}
-/// SizeOfEncodedValue - Return the size of the encoding in bytes.
-unsigned DwarfException::SizeOfEncodedValue(unsigned Encoding) {
- if (Encoding == dwarf::DW_EH_PE_omit)
- return 0;
-
- switch (Encoding & 0x07) {
- case dwarf::DW_EH_PE_absptr:
- return TD->getPointerSize();
- case dwarf::DW_EH_PE_udata2:
- return 2;
- case dwarf::DW_EH_PE_udata4:
- return 4;
- case dwarf::DW_EH_PE_udata8:
- return 8;
- }
-
- assert(0 && "Invalid encoded value.");
- return 0;
-}
-
/// CreateLabelDiff - Emit a label and subtract it from the expression we
/// already have. This is equivalent to emitting "foo - .", but we have to emit
/// the label for "." directly.
@@ -100,7 +80,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
TD->getPointerSize() : -TD->getPointerSize();
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-
+
// Begin eh frame section.
Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection());
@@ -128,30 +108,16 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// The personality presence indicates that language specific information will
// show up in the eh frame. Find out how we are supposed to lower the
// personality function reference:
- const MCExpr *PersonalityRef = 0;
- bool IsPersonalityIndirect = false, IsPersonalityPCRel = false;
- if (PersonalityFn) {
- // FIXME: HANDLE STATIC CODEGEN MODEL HERE.
-
- // In non-static mode, ask the object file how to represent this reference.
- PersonalityRef =
- TLOF.getSymbolForDwarfGlobalReference(PersonalityFn, Asm->Mang,
- Asm->MMI,
- IsPersonalityIndirect,
- IsPersonalityPCRel);
- }
-
- unsigned PerEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- if (IsPersonalityIndirect)
- PerEncoding |= dwarf::DW_EH_PE_indirect;
- unsigned LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- unsigned FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+
+ unsigned LSDAEncoding = TLOF.getLSDAEncoding();
+ unsigned FDEEncoding = TLOF.getFDEEncoding();
+ unsigned PerEncoding = TLOF.getPersonalityEncoding();
char Augmentation[6] = { 0 };
unsigned AugmentationSize = 0;
char *APtr = Augmentation + 1;
- if (PersonalityRef) {
+ if (PersonalityFn) {
// There is a personality function.
*APtr++ = 'P';
AugmentationSize += 1 + SizeOfEncodedValue(PerEncoding);
@@ -181,20 +147,19 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
EOL("CIE Return Address Column");
- EmitULEB128(AugmentationSize, "Augmentation Size");
- EmitEncodingByte(PerEncoding, "Personality");
-
- // If there is a personality, we need to indicate the function's location.
- if (PersonalityRef) {
- if (!IsPersonalityPCRel)
- PersonalityRef = CreateLabelDiff(PersonalityRef, "personalityref_addr",
- Index);
+ if (Augmentation[0]) {
+ EmitULEB128(AugmentationSize, "Augmentation Size");
- O << MAI->getData32bitsDirective() << *PersonalityRef;
- EOL("Personality");
-
- EmitEncodingByte(LSDAEncoding, "LSDA");
- EmitEncodingByte(FDEEncoding, "FDE");
+ // If there is a personality, we need to indicate the function's location.
+ if (PersonalityFn) {
+ EmitEncodingByte(PerEncoding, "Personality");
+ EmitReference(PersonalityFn, PerEncoding);
+ EOL("Personality");
+ }
+ if (UsesLSDA[Index])
+ EmitEncodingByte(LSDAEncoding, "LSDA");
+ if (FDEEncoding != dwarf::DW_EH_PE_absptr)
+ EmitEncodingByte(FDEEncoding, "FDE");
}
// Indicate locations of general callee saved registers in frame.
@@ -216,8 +181,12 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
"Should not emit 'available externally' functions at all");
const Function *TheFunc = EHFrameInfo.function;
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
- Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection());
+ unsigned LSDAEncoding = TLOF.getLSDAEncoding();
+ unsigned FDEEncoding = TLOF.getFDEEncoding();
+
+ Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection());
// Externally visible entry into the functions eh frame info. If the
// corresponding function is static, this should not be externally visible.
@@ -255,7 +224,8 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// EH frame header.
EmitDifference("eh_frame_end", EHFrameInfo.Number,
- "eh_frame_begin", EHFrameInfo.Number, true);
+ "eh_frame_begin", EHFrameInfo.Number,
+ true);
EOL("Length of Frame Information Entry");
EmitLabel("eh_frame_begin", EHFrameInfo.Number);
@@ -266,33 +236,23 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
EOL("FDE CIE offset");
- EmitReference("eh_func_begin", EHFrameInfo.Number, true, true);
+ EmitReference("eh_func_begin", EHFrameInfo.Number, FDEEncoding);
EOL("FDE initial location");
EmitDifference("eh_func_end", EHFrameInfo.Number,
- "eh_func_begin", EHFrameInfo.Number, true);
+ "eh_func_begin", EHFrameInfo.Number,
+ SizeOfEncodedValue(FDEEncoding) == 4);
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) {
+ unsigned Size = SizeOfEncodedValue(LSDAEncoding);
- if (Asm->TM.getLSDAEncoding() != DwarfLSDAEncoding::EightByte) {
- EmitULEB128(4, "Augmentation size");
-
- if (EHFrameInfo.hasLandingPads)
- EmitReference("exception", EHFrameInfo.Number, true, true);
- else
- 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*/);
- }
- }
+ EmitULEB128(Size, "Augmentation size");
+ if (EHFrameInfo.hasLandingPads)
+ EmitReference("exception", EHFrameInfo.Number, LSDAEncoding);
+ else
+ Asm->OutStreamer.EmitIntValue(0, Size/*size*/, 0/*addrspace*/);
EOL("Language Specific Data Area");
} else {
@@ -407,20 +367,22 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
if (NumShared < TypeIds.size()) {
unsigned SizeAction = 0;
- ActionEntry *PrevAction = 0;
+ unsigned PrevAction = (unsigned)-1;
if (NumShared) {
const unsigned SizePrevIds = PrevLPI->TypeIds.size();
assert(Actions.size());
- PrevAction = &Actions.back();
- SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
- MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
+ PrevAction = Actions.size() - 1;
+ SizeAction =
+ MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) +
+ MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID);
for (unsigned j = NumShared; j != SizePrevIds; ++j) {
+ assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!");
SizeAction -=
- MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
- SizeAction += -PrevAction->NextAction;
- PrevAction = PrevAction->Previous;
+ MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID);
+ SizeAction += -Actions[PrevAction].NextAction;
+ PrevAction = Actions[PrevAction].Previous;
}
}
@@ -437,7 +399,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
Actions.push_back(Action);
- PrevAction = &Actions.back();
+ PrevAction = Actions.size() - 1;
}
// Record the first action of the landing pad site.
@@ -447,7 +409,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
// Information used when created the call-site table. The action record
// field of the call site record is the offset of the first associated
// action record, relative to the start of the actions table. This value is
- // biased by 1 (1 in dicating the start of the actions table), and 0
+ // biased by 1 (1 indicating the start of the actions table), and 0
// indicates that there are no actions.
FirstActions.push_back(FirstAction);
@@ -648,8 +610,7 @@ void DwarfException::EmitExceptionTable() {
// landing pad site.
SmallVector<ActionEntry, 32> Actions;
SmallVector<unsigned, 64> FirstActions;
- unsigned SizeActions = ComputeActionsTable(LandingPads, Actions,
- FirstActions);
+ unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions);
// Invokes and nounwind calls have entries in PadMap (due to being bracketed
// by try-range labels when lowered). Ordinary calls do not, so appropriate
@@ -677,29 +638,29 @@ void DwarfException::EmitExceptionTable() {
const unsigned LandingPadSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4);
bool IsSJLJ = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true;
- unsigned SizeSites;
+ unsigned CallSiteTableLength;
if (IsSJLJ)
- SizeSites = 0;
+ CallSiteTableLength = 0;
else
- SizeSites = CallSites.size() *
+ CallSiteTableLength = CallSites.size() *
(SiteStartSize + SiteLengthSize + LandingPadSize);
for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
- SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
+ CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action);
if (IsSJLJ)
- SizeSites += MCAsmInfo::getULEB128Size(i);
+ CallSiteTableLength += MCAsmInfo::getULEB128Size(i);
}
// Type infos.
const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection();
- unsigned TTypeFormat;
+ unsigned TTypeEncoding;
unsigned TypeFormatSize;
if (!HaveTTData) {
// For SjLj exceptions, if there is no TypeInfo, then we just explicitly say
// that we're omitting that bit.
- TTypeFormat = dwarf::DW_EH_PE_omit;
+ TTypeEncoding = dwarf::DW_EH_PE_omit;
TypeFormatSize = SizeOfEncodedValue(dwarf::DW_EH_PE_absptr);
} else {
// Okay, we have actual filters or typeinfos to emit. As such, we need to
@@ -729,21 +690,28 @@ void DwarfException::EmitExceptionTable() {
// somewhere. This predicate should be moved to a shared location that is
// in target-independent code.
//
- if (LSDASection->getKind().isWriteable() ||
- Asm->TM.getRelocationModel() == Reloc::Static)
- TTypeFormat = dwarf::DW_EH_PE_absptr;
- else
- TTypeFormat = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata4;
-
- TypeFormatSize = SizeOfEncodedValue(TTypeFormat);
+ TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding();
+ TypeFormatSize = SizeOfEncodedValue(TTypeEncoding);
}
// Begin the exception table.
Asm->OutStreamer.SwitchSection(LSDASection);
Asm->EmitAlignment(2, 0, 0, false);
+ // Emit the LSDA.
O << "GCC_except_table" << SubprogramCount << ":\n";
+ EmitLabel("exception", SubprogramCount);
+
+ if (IsSJLJ) {
+ SmallString<16> LSDAName;
+ raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() <<
+ "_LSDA_" << Asm->getFunctionNumber();
+ O << LSDAName.str() << ":\n";
+ }
+
+ // Emit the LSDA header.
+ EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+ EmitEncodingByte(TTypeEncoding, "@TType");
// The type infos need to be aligned. GCC does this by inserting padding just
// before the type infos. However, this changes the size of the exception
@@ -752,7 +720,7 @@ void DwarfException::EmitExceptionTable() {
// So by increasing the size by inserting padding, you may increase the number
// of bytes used for writing the size. If it increases, say by one byte, then
// you now need to output one less byte of padding to get the type infos
- // aligned. However this decreases the size of the exception table. This
+ // aligned. However this decreases the size of the exception table. This
// changes the value you have to output for the exception table size. Due to
// the variable length encoding, the number of bytes used for writing the
// length may decrease. If so, you then have to increase the amount of
@@ -761,41 +729,35 @@ void DwarfException::EmitExceptionTable() {
// We chose another solution: don't output padding inside the table like GCC
// does, instead output it before the table.
unsigned SizeTypes = TypeInfos.size() * TypeFormatSize;
- unsigned TyOffset = sizeof(int8_t) + // Call site format
- MCAsmInfo::getULEB128Size(SizeSites) + // Call site table length
- SizeSites + SizeActions + SizeTypes;
- unsigned TotalSize = sizeof(int8_t) + // LPStart format
- sizeof(int8_t) + // TType format
- (HaveTTData ?
- MCAsmInfo::getULEB128Size(TyOffset) : 0) + // TType base offset
- TyOffset;
+ unsigned CallSiteTableLengthSize =
+ MCAsmInfo::getULEB128Size(CallSiteTableLength);
+ unsigned TTypeBaseOffset =
+ sizeof(int8_t) + // Call site format
+ CallSiteTableLengthSize + // Call site table length size
+ CallSiteTableLength + // Call site table length
+ SizeActions + // Actions size
+ SizeTypes;
+ unsigned TTypeBaseOffsetSize = MCAsmInfo::getULEB128Size(TTypeBaseOffset);
+ unsigned TotalSize =
+ sizeof(int8_t) + // LPStart format
+ sizeof(int8_t) + // TType format
+ (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size
+ TTypeBaseOffset; // TType base offset
unsigned SizeAlign = (4 - TotalSize) & 3;
- for (unsigned i = 0; i != SizeAlign; ++i) {
- Asm->EmitInt8(0);
- EOL("Padding");
- }
-
- EmitLabel("exception", SubprogramCount);
-
- if (IsSJLJ) {
- SmallString<16> LSDAName;
- raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() <<
- "_LSDA_" << Asm->getFunctionNumber();
- O << LSDAName.str() << ":\n";
+ if (HaveTTData) {
+ // Account for any extra padding that will be added to the call site table
+ // length.
+ EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign);
+ SizeAlign = 0;
}
- // Emit the header.
- EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
- EmitEncodingByte(TTypeFormat, "@TType");
-
- if (HaveTTData)
- EmitULEB128(TyOffset, "@TType base offset");
-
// SjLj Exception handling
if (IsSJLJ) {
EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
- EmitULEB128(SizeSites, "Call site table length");
+
+ // Add extra padding if it wasn't added to the TType base offset.
+ EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
// Emit the landing pad site information.
unsigned idx = 0;
@@ -836,7 +798,9 @@ void DwarfException::EmitExceptionTable() {
// Emit the landing pad call site table.
EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
- EmitULEB128(SizeSites, "Call site table length");
+
+ // Add extra padding if it wasn't added to the TType base offset.
+ EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
@@ -906,23 +870,23 @@ void DwarfException::EmitExceptionTable() {
}
// Emit the Catch TypeInfos.
- if (TypeInfos.size() != 0) EOL("-- Catch TypeInfos --");
+ if (!TypeInfos.empty()) EOL("-- Catch TypeInfos --");
for (std::vector<GlobalVariable *>::const_reverse_iterator
I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
const GlobalVariable *GV = *I;
- PrintRelDirective();
if (GV) {
- O << *Asm->GetGlobalValueSymbol(GV);
+ EmitReference(GV, TTypeEncoding);
EOL("TypeInfo");
} else {
+ PrintRelDirective(TTypeEncoding);
O << "0x0";
EOL("");
}
}
// Emit the Exception Specifications.
- if (FilterIds.size() != 0) EOL("-- Filter IDs --");
+ if (!FilterIds.empty()) EOL("-- Filter IDs --");
for (std::vector<unsigned>::const_iterator
I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
unsigned TypeID = *I;
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index 06033a1..3db1a00 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -76,9 +76,6 @@ class DwarfException : public DwarfPrinter {
/// ExceptionTimer - Timer for the Dwarf exception writer.
Timer *ExceptionTimer;
- /// SizeOfEncodedValue - Return the size of the encoding in bytes.
- unsigned SizeOfEncodedValue(unsigned Encoding);
-
/// EmitCIE - Emit a Common Information Entry (CIE). This holds information
/// that is shared among many Frame Description Entries. There is at least
/// one CIE in every non-empty .debug_frame section.
@@ -135,7 +132,7 @@ class DwarfException : public DwarfPrinter {
struct ActionEntry {
int ValueForTypeID; // The value to write - may not be equal to the type id.
int NextAction;
- struct ActionEntry *Previous;
+ unsigned Previous;
};
/// CallSiteEntry - Structure describing an entry in the call-site table.
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
index 415390b..28ff0eb 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// Emit general DWARF directives.
-//
+//
//===----------------------------------------------------------------------===//
#include "DwarfPrinter.h"
@@ -18,13 +18,17 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/SmallString.h"
using namespace llvm;
DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
@@ -33,6 +37,26 @@ DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
SubprogramCount(0), Flavor(flavor), SetCounter(1) {}
+/// SizeOfEncodedValue - Return the size of the encoding in bytes.
+unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const {
+ if (Encoding == dwarf::DW_EH_PE_omit)
+ return 0;
+
+ switch (Encoding & 0x07) {
+ case dwarf::DW_EH_PE_absptr:
+ return TD->getPointerSize();
+ case dwarf::DW_EH_PE_udata2:
+ return 2;
+ case dwarf::DW_EH_PE_udata4:
+ return 4;
+ case dwarf::DW_EH_PE_udata8:
+ return 8;
+ }
+
+ assert(0 && "Invalid encoded value.");
+ return 0;
+}
+
void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const {
if (isInSection && MAI->getDwarfSectionOffsetDirective())
O << MAI->getDwarfSectionOffsetDirective();
@@ -42,6 +66,14 @@ void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const {
O << MAI->getData64bitsDirective();
}
+void DwarfPrinter::PrintRelDirective(unsigned Encoding) const {
+ unsigned Size = SizeOfEncodedValue(Encoding);
+ assert((Size == 4 || Size == 8) && "Do not support other types or rels!");
+
+ O << (Size == 4 ?
+ MAI->getData32bitsDirective() : 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 {
@@ -127,29 +159,35 @@ void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const {
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 {
+void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc,
+ unsigned PadTo) const {
if (Asm->VerboseAsm && Desc)
Asm->OutStreamer.AddComment(Desc);
- if (MAI->hasLEB128()) {
+ if (MAI->hasLEB128() && PadTo == 0) {
O << "\t.uleb128\t" << Value;
Asm->OutStreamer.AddBlankLine();
return;
}
- // If we don't have .uleb128, emit as .bytes.
+ // If we don't have .uleb128 or we want to emit padding, emit as .bytes.
do {
unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
Value >>= 7;
- if (Value) Byte |= 0x80;
+ if (Value || PadTo != 0) Byte |= 0x80;
Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
} while (Value);
+
+ if (PadTo) {
+ if (PadTo > 1)
+ Asm->OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/);
+ Asm->OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/);
+ }
}
@@ -195,6 +233,31 @@ void DwarfPrinter::EmitReference(const MCSymbol *Sym, bool IsPCRelative,
if (IsPCRelative) O << "-" << MAI->getPCSymbol();
}
+void DwarfPrinter::EmitReference(const char *Tag, unsigned Number,
+ unsigned Encoding) const {
+ SmallString<64> Name;
+ raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
+ << Tag << Number;
+
+ MCSymbol *Sym = Asm->OutContext.GetOrCreateSymbol(Name.str());
+ EmitReference(Sym, Encoding);
+}
+
+void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+
+ PrintRelDirective(Encoding);
+ O << *TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding);;
+}
+
+void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const {
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+
+ PrintRelDirective(Encoding);
+ O << *TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang,
+ Asm->MMI, Encoding);;
+}
+
/// EmitDifference - Emit the difference between two labels. If this assembler
/// supports .set, we emit a .set of a temporary and then use it in the .word.
void DwarfPrinter::EmitDifference(const char *TagHi, unsigned NumberHi,
@@ -248,7 +311,6 @@ void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section,
PrintRelDirective(IsSmall);
PrintLabelName("set", SetCounter, Flavor);
++SetCounter;
- O << "\n";
} else {
PrintRelDirective(IsSmall, true);
PrintLabelName(Label, LabelNumber);
@@ -257,7 +319,6 @@ void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section,
O << "-";
PrintLabelName(Section, SectionNumber);
}
- O << "\n";
}
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
index 69d9c27..bd715f2 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
@@ -28,6 +28,7 @@ class Module;
class MCAsmInfo;
class TargetData;
class TargetRegisterInfo;
+class GlobalValue;
class MCSymbol;
class Twine;
@@ -85,6 +86,10 @@ public:
const MCAsmInfo *getMCAsmInfo() const { return MAI; }
const TargetData *getTargetData() const { return TD; }
+ /// SizeOfEncodedValue - Return the size of the encoding in bytes.
+ unsigned SizeOfEncodedValue(unsigned Encoding) const;
+
+ void PrintRelDirective(unsigned Encoding) const;
void PrintRelDirective(bool Force32Bit = false,
bool isInSection = false) const;
@@ -106,7 +111,8 @@ public:
void EmitSLEB128(int Value, const char *Desc) const;
/// EmitULEB128 - emit the specified unsigned leb128 value.
- void EmitULEB128(unsigned Value, const char *Desc = 0) const;
+ void EmitULEB128(unsigned Value, const char *Desc = 0,
+ unsigned PadTo = 0) const;
/// PrintLabelName - Print label name in form used by Dwarf writer.
@@ -140,6 +146,10 @@ public:
void EmitReference(const MCSymbol *Sym, bool IsPCRelative = false,
bool Force32Bit = false) const;
+ void EmitReference(const char *Tag, unsigned Number, unsigned Encoding) const;
+ void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
+ void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
+
/// EmitDifference - Emit the difference between two labels.
void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo,
bool IsSmall = false) {
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index 3531ed6..a9502fd 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -22,6 +22,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
+#include <ctype.h>
using namespace llvm;
namespace {
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index faf4d95..d94729a 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -334,7 +334,9 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
unsigned TailLen = 0;
while (I1 != MBB1->begin() && I2 != MBB2->begin()) {
--I1; --I2;
- if (!I1->isIdenticalTo(I2) ||
+ // Don't merge debugging pseudos.
+ if (I1->isDebugValue() || I2->isDebugValue() ||
+ !I1->isIdenticalTo(I2) ||
// FIXME: This check is dubious. It's used to get around a problem where
// people incorrectly expect inline asm directives to remain in the same
// relative order. This is untenable because normal compiler
@@ -412,6 +414,8 @@ static unsigned EstimateRuntime(MachineBasicBlock::iterator I,
MachineBasicBlock::iterator E) {
unsigned Time = 0;
for (; I != E; ++I) {
+ if (I->isDebugValue())
+ continue;
const TargetInstrDesc &TID = I->getDesc();
if (TID.isCall())
Time += 10;
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 9fcbea9..d385b86 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -22,6 +22,7 @@ add_llvm_library(LLVMCodeGen
LiveVariables.cpp
LowerSubregs.cpp
MachineBasicBlock.cpp
+ MachineCSE.cpp
MachineDominators.cpp
MachineFunction.cpp
MachineFunctionAnalysis.cpp
@@ -39,6 +40,7 @@ add_llvm_library(LLVMCodeGen
ObjectCodeEmitter.cpp
OcamlGC.cpp
OptimizeExts.cpp
+ OptimizePHIs.cpp
PHIElimination.cpp
Passes.cpp
PostRASchedulerList.cpp
@@ -66,6 +68,7 @@ add_llvm_library(LLVMCodeGen
StrongPHIElimination.cpp
TailDuplication.cpp
TargetInstrInfoImpl.cpp
+ TargetLoweringObjectFileImpl.cpp
TwoAddressInstructionPass.cpp
UnreachableBlockElim.cpp
VirtRegMap.cpp
diff --git a/lib/CodeGen/CalcSpillWeights.cpp b/lib/CodeGen/CalcSpillWeights.cpp
index 2bedd04..a328d0e 100644
--- a/lib/CodeGen/CalcSpillWeights.cpp
+++ b/lib/CodeGen/CalcSpillWeights.cpp
@@ -131,10 +131,7 @@ bool CalculateSpillWeights::runOnMachineFunction(MachineFunction &fn) {
if (Hint.first || Hint.second)
li.weight *= 1.01F;
- // Divide the weight of the interval by its size. This encourages
- // spilling of intervals that are large and have few uses, and
- // discourages spilling of small intervals with many uses.
- li.weight /= lis->getApproximateInstructionCount(li) * SlotIndex::NUM;
+ lis->normalizeSpillWeight(li);
}
}
diff --git a/lib/CodeGen/CodePlacementOpt.cpp b/lib/CodeGen/CodePlacementOpt.cpp
index 05a57d4..3ff2a04 100644
--- a/lib/CodeGen/CodePlacementOpt.cpp
+++ b/lib/CodeGen/CodePlacementOpt.cpp
@@ -102,22 +102,23 @@ bool CodePlacementOpt::HasAnalyzableTerminator(MachineBasicBlock *MBB) {
// Conservatively ignore EH landing pads.
if (MBB->isLandingPad()) return false;
- // Ignore blocks which look like they might have EH-related control flow.
- // At the time of this writing, there are blocks which AnalyzeBranch
- // thinks end in single uncoditional branches, yet which have two CFG
- // successors. Code in this file is not prepared to reason about such things.
- if (!MBB->empty() && MBB->back().isEHLabel())
- return false;
-
// Aggressively handle return blocks and similar constructs.
if (MBB->succ_empty()) return true;
// Ask the target's AnalyzeBranch if it can handle this block.
MachineBasicBlock *TBB = 0, *FBB = 0;
SmallVector<MachineOperand, 4> Cond;
- // Make the terminator is understood.
+ // Make sure the terminator is understood.
if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond))
return false;
+ // Ignore blocks which look like they might have EH-related control flow.
+ // AnalyzeBranch thinks it knows how to analyze such things, but it doesn't
+ // recognize the possibility of a control transfer through an unwind.
+ // Such blocks contain EH_LABEL instructions, however they may be in the
+ // middle of the block. Instead of searching for them, just check to see
+ // if the CFG disagrees with AnalyzeBranch.
+ if (1u + !Cond.empty() != MBB->succ_size())
+ return false;
// Make sure we have the option of reversing the condition.
if (!Cond.empty() && TII->ReverseBranchCondition(Cond))
return false;
diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp
index 056e2d5..7d3de89 100644
--- a/lib/CodeGen/CriticalAntiDepBreaker.cpp
+++ b/lib/CodeGen/CriticalAntiDepBreaker.cpp
@@ -119,6 +119,8 @@ void CriticalAntiDepBreaker::FinishBlock() {
void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
unsigned InsertPosIndex) {
+ if (MI->isDebugValue())
+ return;
assert(Count < InsertPosIndex && "Instruction index out of expected range!");
// Any register which was defined within the previous scheduling region
@@ -409,6 +411,8 @@ BreakAntiDependencies(std::vector<SUnit>& SUnits,
for (MachineBasicBlock::iterator I = End, E = Begin;
I != E; --Count) {
MachineInstr *MI = --I;
+ if (MI->isDebugValue())
+ continue;
// Check if this instruction has a dependence on the critical path that
// is an anti-dependence that we may be able to break. If it is, set
diff --git a/lib/CodeGen/DeadMachineInstructionElim.cpp b/lib/CodeGen/DeadMachineInstructionElim.cpp
index b0cb24d..d69c995 100644
--- a/lib/CodeGen/DeadMachineInstructionElim.cpp
+++ b/lib/CodeGen/DeadMachineInstructionElim.cpp
@@ -55,7 +55,7 @@ FunctionPass *llvm::createDeadMachineInstructionElimPass() {
bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
// Don't delete instructions with side effects.
bool SawStore = false;
- if (!MI->isSafeToMove(TII, SawStore, 0))
+ if (!MI->isSafeToMove(TII, 0, SawStore) && !MI->isPHI())
return false;
// Examine each operand.
@@ -64,8 +64,8 @@ bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
if (MO.isReg() && MO.isDef()) {
unsigned Reg = MO.getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg) ?
- LivePhysRegs[Reg] : !MRI->use_empty(Reg)) {
- // This def has a use. Don't delete the instruction!
+ LivePhysRegs[Reg] : !MRI->use_nodbg_empty(Reg)) {
+ // This def has a non-debug use. Don't delete the instruction!
return false;
}
}
@@ -111,23 +111,31 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
MIE = MBB->rend(); MII != MIE; ) {
MachineInstr *MI = &*MII;
- if (MI->isDebugValue()) {
- // Don't delete the DBG_VALUE itself, but if its Value operand is
- // a vreg and this is the only use, substitute an undef operand;
- // the former operand will then be deleted normally.
- if (MI->getNumOperands()==3 && MI->getOperand(0).isReg()) {
- unsigned Reg = MI->getOperand(0).getReg();
- MachineRegisterInfo::use_iterator I = MRI->use_begin(Reg);
- assert(I != MRI->use_end());
- if (++I == MRI->use_end())
- // only one use, which must be this DBG_VALUE.
- MI->getOperand(0).setReg(0U);
- }
- }
-
// If the instruction is dead, delete it!
if (isDead(MI)) {
DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI);
+ // It is possible that some DBG_VALUE instructions refer to this
+ // instruction. Examine each def operand for such references;
+ // if found, mark the DBG_VALUE as undef (but don't delete it).
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(Reg))
+ continue;
+ MachineRegisterInfo::use_iterator nextI;
+ for (MachineRegisterInfo::use_iterator I = MRI->use_begin(Reg),
+ E = MRI->use_end(); I!=E; I=nextI) {
+ nextI = llvm::next(I); // I is invalidated by the setReg
+ MachineOperand& Use = I.getOperand();
+ MachineInstr *UseMI = Use.getParent();
+ if (UseMI==MI)
+ continue;
+ assert(Use.isDebug());
+ UseMI->getOperand(0).setReg(0U);
+ }
+ }
AnyChanges = true;
MI->eraseFromParent();
++NumDeletes;
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index 9997a48..87ab7ef 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -155,7 +155,7 @@ void IntrinsicLowering::AddPrototypes(Module &M) {
/// LowerBSWAP - Emit the code to lower bswap of V before the specified
/// instruction IP.
static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) {
- assert(V->getType()->isInteger() && "Can't bswap a non-integer type!");
+ assert(V->getType()->isIntegerTy() && "Can't bswap a non-integer type!");
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
@@ -251,7 +251,7 @@ static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) {
/// LowerCTPOP - Emit the code to lower ctpop of V before the specified
/// instruction IP.
static Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) {
- assert(V->getType()->isInteger() && "Can't ctpop a non-integer type!");
+ assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!");
static const uint64_t MaskValues[6] = {
0x5555555555555555ULL, 0x3333333333333333ULL,
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 40e0150..5e88865 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -14,6 +14,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/Passes.h"
@@ -66,6 +67,9 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
cl::desc("Verify generated machine code"),
cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));
+static cl::opt<bool> EnableMachineCSE("enable-machine-cse", cl::Hidden,
+ cl::desc("Enable Machine CSE"));
+
static cl::opt<cl::boolOrDefault>
AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
cl::init(cl::BOU_UNSET));
@@ -114,9 +118,10 @@ LLVMTargetMachine::setCodeModelForStatic() {
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel) {
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify) {
// Add common CodeGen passes.
- if (addCommonCodeGenPasses(PM, OptLevel))
+ if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify))
return true;
OwningPtr<MCContext> Context(new MCContext());
@@ -140,7 +145,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
case CGFT_ObjectFile: {
// Create the code emitter for the target if it exists. If not, .o file
// emission fails.
- MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this);
+ MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Context);
if (MCE == 0)
return true;
@@ -192,12 +197,13 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
///
bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
JITCodeEmitter &JCE,
- CodeGenOpt::Level OptLevel) {
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify) {
// Make sure the code model is set.
setCodeModelForJIT();
// Add common CodeGen passes.
- if (addCommonCodeGenPasses(PM, OptLevel))
+ if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify))
return true;
addCodeEmitter(PM, OptLevel, JCE);
@@ -206,6 +212,12 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
return false; // success!
}
+static void printNoVerify(PassManagerBase &PM,
+ const char *Banner) {
+ if (PrintMachineCode)
+ PM.add(createMachineFunctionPrinterPass(dbgs(), Banner));
+}
+
static void printAndVerify(PassManagerBase &PM,
const char *Banner,
bool allowDoubleDefs = false) {
@@ -220,13 +232,19 @@ static void printAndVerify(PassManagerBase &PM,
/// emitting to assembly files or machine code output.
///
bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel) {
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify) {
// Standard LLVM-Level Passes.
+ // Before running any passes, run the verifier to determine if the input
+ // coming from the front-end and/or optimizer is valid.
+ if (!DisableVerify)
+ PM.add(createVerifierPass());
+
// Optionally, tun split-GEPs and no-load GVN.
if (EnableSplitGEPGVN) {
PM.add(createGEPSplitterPass());
- PM.add(createGVNPass(/*NoPRE=*/false, /*NoLoads=*/true));
+ PM.add(createGVNPass(/*NoLoads=*/true));
}
// Run loop strength reduction before anything else.
@@ -273,6 +291,11 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
"*** Final LLVM Code input to ISel ***\n",
&dbgs()));
+ // All passes which modify the LLVM IR are now complete; run the verifier
+ // to ensure that the IR is valid.
+ if (!DisableVerify)
+ PM.add(createVerifierPass());
+
// Standard Lower-Level Passes.
// Set up a MachineFunction for the rest of CodeGen to work on.
@@ -291,6 +314,10 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
printAndVerify(PM, "After Instruction Selection",
/* allowDoubleDefs= */ true);
+ // Optimize PHIs before DCE: removing dead PHI cycles may make more
+ // instructions dead.
+ if (OptLevel != CodeGenOpt::None)
+ PM.add(createOptimizePHIsPass());
// Delete dead machine instructions regardless of optimization level.
PM.add(createDeadMachineInstructionElimPass());
@@ -301,6 +328,8 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
PM.add(createOptimizeExtsPass());
if (!DisableMachineLICM)
PM.add(createMachineLICMPass());
+ if (EnableMachineCSE)
+ PM.add(createMachineCSEPass());
if (!DisableMachineSink)
PM.add(createMachineSinkingPass());
printAndVerify(PM, "After MachineLICM and MachineSinking",
@@ -355,13 +384,13 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Branch folding must be run after regalloc and prolog/epilog insertion.
if (OptLevel != CodeGenOpt::None && !DisableBranchFold) {
PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
- printAndVerify(PM, "After BranchFolding");
+ printNoVerify(PM, "After BranchFolding");
}
// Tail duplication.
if (OptLevel != CodeGenOpt::None && !DisableTailDuplicate) {
PM.add(createTailDuplicatePass(false));
- printAndVerify(PM, "After TailDuplicate");
+ printNoVerify(PM, "After TailDuplicate");
}
PM.add(createGCMachineCodeAnalysisPass());
@@ -371,11 +400,11 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
if (OptLevel != CodeGenOpt::None && !DisableCodePlace) {
PM.add(createCodePlacementOptPass());
- printAndVerify(PM, "After CodePlacementOpt");
+ printNoVerify(PM, "After CodePlacementOpt");
}
if (addPreEmitPass(PM, OptLevel))
- printAndVerify(PM, "After PreEmit passes");
+ printNoVerify(PM, "After PreEmit passes");
return false;
}
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 432409a..ccda66f 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -329,24 +329,43 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
DEBUG(dbgs() << " +" << NewLR);
interval.addRange(NewLR);
- // Iterate over all of the blocks that the variable is completely
- // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the
- // live interval.
- for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(),
- E = vi.AliveBlocks.end(); I != E; ++I) {
- MachineBasicBlock *aliveBlock = mf_->getBlockNumbered(*I);
- LiveRange LR(getMBBStartIdx(aliveBlock), getMBBEndIdx(aliveBlock), ValNo);
- interval.addRange(LR);
- DEBUG(dbgs() << " +" << LR);
+ bool PHIJoin = lv_->isPHIJoin(interval.reg);
+
+ if (PHIJoin) {
+ // A phi join register is killed at the end of the MBB and revived as a new
+ // valno in the killing blocks.
+ assert(vi.AliveBlocks.empty() && "Phi join can't pass through blocks");
+ DEBUG(dbgs() << " phi-join");
+ ValNo->addKill(indexes_->getTerminatorGap(mbb));
+ ValNo->setHasPHIKill(true);
+ } else {
+ // Iterate over all of the blocks that the variable is completely
+ // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the
+ // live interval.
+ for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(),
+ E = vi.AliveBlocks.end(); I != E; ++I) {
+ MachineBasicBlock *aliveBlock = mf_->getBlockNumbered(*I);
+ LiveRange LR(getMBBStartIdx(aliveBlock), getMBBEndIdx(aliveBlock), ValNo);
+ interval.addRange(LR);
+ DEBUG(dbgs() << " +" << LR);
+ }
}
// Finally, this virtual register is live from the start of any killing
// block to the 'use' slot of the killing instruction.
for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
MachineInstr *Kill = vi.Kills[i];
- SlotIndex killIdx =
- getInstructionIndex(Kill).getDefIndex();
- LiveRange LR(getMBBStartIdx(Kill->getParent()), killIdx, ValNo);
+ SlotIndex Start = getMBBStartIdx(Kill->getParent());
+ SlotIndex killIdx = getInstructionIndex(Kill).getDefIndex();
+
+ // Create interval with one of a NEW value number. Note that this value
+ // number isn't actually defined by an instruction, weird huh? :)
+ if (PHIJoin) {
+ ValNo = interval.getNextValue(SlotIndex(Start, true), 0, false,
+ VNInfoAllocator);
+ ValNo->setIsPHIDef(true);
+ }
+ LiveRange LR(Start, killIdx, ValNo);
interval.addRange(LR);
ValNo->addKill(killIdx);
DEBUG(dbgs() << " +" << LR);
@@ -409,48 +428,11 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
interval.print(dbgs(), tri_);
});
} else {
- // Otherwise, this must be because of phi elimination. If this is the
- // first redefinition of the vreg that we have seen, go back and change
- // the live range in the PHI block to be a different value number.
- if (interval.containsOneValue()) {
-
- VNInfo *VNI = interval.getValNumInfo(0);
- // Phi elimination may have reused the register for multiple identical
- // phi nodes. There will be a kill per phi. Remove the old ranges that
- // we now know have an incorrect number.
- for (unsigned ki=0, ke=vi.Kills.size(); ki != ke; ++ki) {
- MachineInstr *Killer = vi.Kills[ki];
- SlotIndex Start = getMBBStartIdx(Killer->getParent());
- SlotIndex End = getInstructionIndex(Killer).getDefIndex();
- DEBUG({
- dbgs() << "\n\t\trenaming [" << Start << "," << End << "] in: ";
- interval.print(dbgs(), tri_);
- });
- interval.removeRange(Start, End);
-
- // Replace the interval with one of a NEW value number. Note that
- // this value number isn't actually defined by an instruction, weird
- // huh? :)
- LiveRange LR(Start, End,
- interval.getNextValue(SlotIndex(Start, true),
- 0, false, VNInfoAllocator));
- LR.valno->setIsPHIDef(true);
- interval.addRange(LR);
- LR.valno->addKill(End);
- }
-
- MachineBasicBlock *killMBB = getMBBFromIndex(VNI->def);
- VNI->addKill(indexes_->getTerminatorGap(killMBB));
- VNI->setHasPHIKill(true);
- DEBUG({
- dbgs() << " RESULT: ";
- interval.print(dbgs(), tri_);
- });
- }
-
+ assert(lv_->isPHIJoin(interval.reg) && "Multiply defined register");
// In the case of PHI elimination, each variable definition is only
// live until the end of the block. We've already taken care of the
// rest of the live range.
+
SlotIndex defIndex = MIIdx.getDefIndex();
if (MO.isEarlyClobber())
defIndex = MIIdx.getUseIndex();
@@ -468,7 +450,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
interval.addRange(LR);
ValNo->addKill(indexes_->getTerminatorGap(mbb));
ValNo->setHasPHIKill(true);
- DEBUG(dbgs() << " +" << LR);
+ DEBUG(dbgs() << " phi-join +" << LR);
}
}
@@ -613,6 +595,9 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
while (mi != E) {
if (mi->isDebugValue()) {
++mi;
+ if (mi != E && !mi->isDebugValue()) {
+ baseIndex = indexes_->getNextNonNullIndex(baseIndex);
+ }
continue;
}
if (mi->killsRegister(interval.reg, tri_)) {
@@ -1355,11 +1340,9 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
MachineBasicBlock *MBB = MI->getParent();
if (ImpUse && MI != ReMatDefMI) {
- // Re-matting an instruction with virtual register use. Update the
- // register interval's spill weight to HUGE_VALF to prevent it from
- // being spilled.
- LiveInterval &ImpLi = getInterval(ImpUse);
- ImpLi.weight = HUGE_VALF;
+ // Re-matting an instruction with virtual register use. Prevent interval
+ // from being spilled.
+ getInterval(ImpUse).markNotSpillable();
}
unsigned MBBId = MBB->getNumber();
@@ -1411,7 +1394,7 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
LiveInterval &nI = getOrCreateInterval(NewVReg);
if (!TrySplit) {
// The spill weight is now infinity as it cannot be spilled again.
- nI.weight = HUGE_VALF;
+ nI.markNotSpillable();
continue;
}
@@ -1559,6 +1542,28 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
}
}
+float
+LiveIntervals::getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) {
+ // Limit the loop depth ridiculousness.
+ if (loopDepth > 200)
+ loopDepth = 200;
+
+ // The loop depth is used to roughly estimate the number of times the
+ // instruction is executed. Something like 10^d is simple, but will quickly
+ // overflow a float. This expression behaves like 10^d for small d, but is
+ // more tempered for large d. At d=200 we get 6.7e33 which leaves a bit of
+ // headroom before overflow.
+ float lc = powf(1 + (100.0f / (loopDepth+10)), (float)loopDepth);
+
+ return (isDef + isUse) * lc;
+}
+
+void
+LiveIntervals::normalizeSpillWeights(std::vector<LiveInterval*> &NewLIs) {
+ for (unsigned i = 0, e = NewLIs.size(); i != e; ++i)
+ normalizeSpillWeight(*NewLIs[i]);
+}
+
std::vector<LiveInterval*> LiveIntervals::
addIntervalsForSpillsFast(const LiveInterval &li,
const MachineLoopInfo *loopInfo,
@@ -1567,8 +1572,7 @@ addIntervalsForSpillsFast(const LiveInterval &li,
std::vector<LiveInterval*> added;
- assert(li.weight != HUGE_VALF &&
- "attempt to spill already spilled interval!");
+ assert(li.isSpillable() && "attempt to spill already spilled interval!");
DEBUG({
dbgs() << "\t\t\t\tadding intervals for spills for interval: ";
@@ -1604,10 +1608,7 @@ addIntervalsForSpillsFast(const LiveInterval &li,
// create a new register for this spill
LiveInterval &nI = getOrCreateInterval(NewVReg);
-
- // the spill weight is now infinity as it
- // cannot be spilled again
- nI.weight = HUGE_VALF;
+ nI.markNotSpillable();
// Rewrite register operands to use the new vreg.
for (SmallVectorImpl<unsigned>::iterator I = Indices.begin(),
@@ -1661,8 +1662,7 @@ addIntervalsForSpills(const LiveInterval &li,
if (EnableFastSpilling)
return addIntervalsForSpillsFast(li, loopInfo, vrm);
- assert(li.weight != HUGE_VALF &&
- "attempt to spill already spilled interval!");
+ assert(li.isSpillable() && "attempt to spill already spilled interval!");
DEBUG({
dbgs() << "\t\t\t\tadding intervals for spills for interval: ";
@@ -1736,6 +1736,7 @@ addIntervalsForSpills(const LiveInterval &li,
}
handleSpilledImpDefs(li, vrm, rc, NewLIs);
+ normalizeSpillWeights(NewLIs);
return NewLIs;
}
@@ -1811,6 +1812,7 @@ addIntervalsForSpills(const LiveInterval &li,
// Insert spills / restores if we are splitting.
if (!TrySplit) {
handleSpilledImpDefs(li, vrm, rc, NewLIs);
+ normalizeSpillWeights(NewLIs);
return NewLIs;
}
@@ -1927,11 +1929,10 @@ addIntervalsForSpills(const LiveInterval &li,
unsigned ImpUse = getReMatImplicitUse(li, ReMatDefMI);
if (ImpUse) {
// Re-matting an instruction with virtual register use. Add the
- // register as an implicit use on the use MI and update the register
- // interval's spill weight to HUGE_VALF to prevent it from being
- // spilled.
+ // register as an implicit use on the use MI and mark the register
+ // interval as unspillable.
LiveInterval &ImpLi = getInterval(ImpUse);
- ImpLi.weight = HUGE_VALF;
+ ImpLi.markNotSpillable();
MI->addOperand(MachineOperand::CreateReg(ImpUse, false, true));
}
}
@@ -1970,6 +1971,7 @@ addIntervalsForSpills(const LiveInterval &li,
}
handleSpilledImpDefs(li, vrm, rc, RetNewLIs);
+ normalizeSpillWeights(RetNewLIs);
return RetNewLIs;
}
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 8a124dc..519990e 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -365,27 +365,7 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
}
}
- if (LastRefOrPartRef == PhysRegDef[Reg] && LastRefOrPartRef != MI) {
- if (LastPartDef)
- // The last partial def kills the register.
- LastPartDef->addOperand(MachineOperand::CreateReg(Reg, false/*IsDef*/,
- true/*IsImp*/, true/*IsKill*/));
- else {
- MachineOperand *MO =
- LastRefOrPartRef->findRegisterDefOperand(Reg, false, TRI);
- bool NeedEC = MO->isEarlyClobber() && MO->getReg() != Reg;
- // If the last reference is the last def, then it's not used at all.
- // That is, unless we are currently processing the last reference itself.
- LastRefOrPartRef->addRegisterDead(Reg, TRI, true);
- if (NeedEC) {
- // If we are adding a subreg def and the superreg def is marked early
- // clobber, add an early clobber marker to the subreg def.
- MO = LastRefOrPartRef->findRegisterDefOperand(Reg);
- if (MO)
- MO->setIsEarlyClobber();
- }
- }
- } else if (!PhysRegUse[Reg]) {
+ if (!PhysRegUse[Reg]) {
// Partial uses. Mark register def dead and add implicit def of
// sub-registers which are used.
// EAX<dead> = op AL<imp-def>
@@ -419,6 +399,26 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
PartUses.erase(*SS);
}
+ } else if (LastRefOrPartRef == PhysRegDef[Reg] && LastRefOrPartRef != MI) {
+ if (LastPartDef)
+ // The last partial def kills the register.
+ LastPartDef->addOperand(MachineOperand::CreateReg(Reg, false/*IsDef*/,
+ true/*IsImp*/, true/*IsKill*/));
+ else {
+ MachineOperand *MO =
+ LastRefOrPartRef->findRegisterDefOperand(Reg, false, TRI);
+ bool NeedEC = MO->isEarlyClobber() && MO->getReg() != Reg;
+ // If the last reference is the last def, then it's not used at all.
+ // That is, unless we are currently processing the last reference itself.
+ LastRefOrPartRef->addRegisterDead(Reg, TRI, true);
+ if (NeedEC) {
+ // If we are adding a subreg def and the superreg def is marked early
+ // clobber, add an early clobber marker to the subreg def.
+ MO = LastRefOrPartRef->findRegisterDefOperand(Reg);
+ if (MO)
+ MO->setIsEarlyClobber();
+ }
+ }
} else
LastRefOrPartRef->addRegisterKilled(Reg, TRI, true);
return true;
@@ -510,6 +510,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
PHIVarInfo = new SmallVector<unsigned, 4>[MF->getNumBlockIDs()];
std::fill(PhysRegDef, PhysRegDef + NumRegs, (MachineInstr*)0);
std::fill(PhysRegUse, PhysRegUse + NumRegs, (MachineInstr*)0);
+ PHIJoins.clear();
/// Get some space for a respectable number of registers.
VirtRegInfo.resize(64);
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index 655a0bf..64134ce 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -143,36 +143,6 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {
return I;
}
-/// isOnlyReachableViaFallthough - Return true if this basic block has
-/// exactly one predecessor and the control transfer mechanism between
-/// the predecessor and this block is a fall-through.
-bool MachineBasicBlock::isOnlyReachableByFallthrough() const {
- // If this is a landing pad, it isn't a fall through. If it has no preds,
- // then nothing falls through to it.
- if (isLandingPad() || pred_empty())
- return false;
-
- // If there isn't exactly one predecessor, it can't be a fall through.
- const_pred_iterator PI = pred_begin(), PI2 = PI;
- ++PI2;
- if (PI2 != pred_end())
- return false;
-
- // The predecessor has to be immediately before this block.
- const MachineBasicBlock *Pred = *PI;
-
- if (!Pred->isLayoutSuccessor(this))
- return false;
-
- // If the block is completely empty, then it definitely does fall through.
- if (Pred->empty())
- return true;
-
- // Otherwise, check the last instruction.
- const MachineInstr &LastInst = Pred->back();
- return !LastInst.getDesc().isBarrier();
-}
-
void MachineBasicBlock::dump() const {
print(dbgs());
}
diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp
new file mode 100644
index 0000000..b376e3d
--- /dev/null
+++ b/lib/CodeGen/MachineCSE.cpp
@@ -0,0 +1,268 @@
+//===-- MachineCSE.cpp - Machine Common Subexpression Elimination Pass ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass performs global common subexpression elimination on machine
+// instructions using a scoped hash table based value numbering scheme. It
+// must be run while the machine function is still in SSA form.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "machine-cse"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/ADT/ScopedHashTable.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+STATISTIC(NumCoalesces, "Number of copies coalesced");
+STATISTIC(NumCSEs, "Number of common subexpression eliminated");
+
+namespace {
+ class MachineCSE : public MachineFunctionPass {
+ const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
+ MachineRegisterInfo *MRI;
+ MachineDominatorTree *DT;
+ AliasAnalysis *AA;
+ public:
+ static char ID; // Pass identification
+ MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {}
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<AliasAnalysis>();
+ AU.addRequired<MachineDominatorTree>();
+ AU.addPreserved<MachineDominatorTree>();
+ }
+
+ private:
+ unsigned CurrVN;
+ ScopedHashTable<MachineInstr*, unsigned, MachineInstrExpressionTrait> VNT;
+ SmallVector<MachineInstr*, 64> Exps;
+
+ bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
+ bool isPhysDefTriviallyDead(unsigned Reg,
+ MachineBasicBlock::const_iterator I,
+ MachineBasicBlock::const_iterator E);
+ bool hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB);
+ bool isCSECandidate(MachineInstr *MI);
+ bool ProcessBlock(MachineDomTreeNode *Node);
+ };
+} // end anonymous namespace
+
+char MachineCSE::ID = 0;
+static RegisterPass<MachineCSE>
+X("machine-cse", "Machine Common Subexpression Elimination");
+
+FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); }
+
+bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
+ MachineBasicBlock *MBB) {
+ bool Changed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isUse())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg))
+ continue;
+ if (!MRI->hasOneUse(Reg))
+ // Only coalesce single use copies. This ensure the copy will be
+ // deleted.
+ continue;
+ MachineInstr *DefMI = MRI->getVRegDef(Reg);
+ if (DefMI->getParent() != MBB)
+ continue;
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
+ TargetRegisterInfo::isVirtualRegister(SrcReg) &&
+ !SrcSubIdx && !DstSubIdx) {
+ MO.setReg(SrcReg);
+ DefMI->eraseFromParent();
+ ++NumCoalesces;
+ Changed = true;
+ }
+ }
+
+ return Changed;
+}
+
+bool MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
+ MachineBasicBlock::const_iterator I,
+ MachineBasicBlock::const_iterator E) {
+ unsigned LookAheadLeft = 5;
+ while (LookAheadLeft--) {
+ if (I == E)
+ // Reached end of block, register is obviously dead.
+ return true;
+
+ if (I->isDebugValue())
+ continue;
+ bool SeenDef = false;
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = I->getOperand(i);
+ if (!MO.isReg() || !MO.getReg())
+ continue;
+ if (!TRI->regsOverlap(MO.getReg(), Reg))
+ continue;
+ if (MO.isUse())
+ return false;
+ SeenDef = true;
+ }
+ if (SeenDef)
+ // See a def of Reg (or an alias) before encountering any use, it's
+ // trivially dead.
+ return true;
+ ++I;
+ }
+ return false;
+}
+
+bool MachineCSE::hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB){
+ unsigned PhysDef = 0;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (!Reg)
+ continue;
+ if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ if (MO.isUse())
+ // Can't touch anything to read a physical register.
+ return true;
+ if (MO.isDead())
+ // If the def is dead, it's ok.
+ continue;
+ // Ok, this is a physical register def that's not marked "dead". That's
+ // common since this pass is run before livevariables. We can scan
+ // forward a few instructions and check if it is obviously dead.
+ if (PhysDef)
+ // Multiple physical register defs. These are rare, forget about it.
+ return true;
+ PhysDef = Reg;
+ }
+ }
+
+ if (PhysDef) {
+ MachineBasicBlock::iterator I = MI; I = llvm::next(I);
+ if (!isPhysDefTriviallyDead(PhysDef, I, MBB->end()))
+ return true;
+ }
+ return false;
+}
+
+bool MachineCSE::isCSECandidate(MachineInstr *MI) {
+ // Ignore copies or instructions that read / write physical registers
+ // (except for dead defs of physical registers).
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) ||
+ MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg())
+ return false;
+
+ // Ignore stuff that we obviously can't move.
+ const TargetInstrDesc &TID = MI->getDesc();
+ if (TID.mayStore() || TID.isCall() || TID.isTerminator() ||
+ TID.hasUnmodeledSideEffects())
+ return false;
+
+ if (TID.mayLoad()) {
+ // Okay, this instruction does a load. As a refinement, we allow the target
+ // to decide whether the loaded value is actually a constant. If so, we can
+ // actually use it as a load.
+ if (!MI->isInvariantLoad(AA))
+ // FIXME: we should be able to hoist loads with no other side effects if
+ // there are no other instructions which can change memory in this loop.
+ // This is a trivial form of alias analysis.
+ return false;
+ }
+ return true;
+}
+
+bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
+ bool Changed = false;
+
+ ScopedHashTableScope<MachineInstr*, unsigned,
+ MachineInstrExpressionTrait> VNTS(VNT);
+ MachineBasicBlock *MBB = Node->getBlock();
+ for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; ) {
+ MachineInstr *MI = &*I;
+ ++I;
+
+ if (!isCSECandidate(MI))
+ continue;
+
+ bool FoundCSE = VNT.count(MI);
+ if (!FoundCSE) {
+ // Look for trivial copy coalescing opportunities.
+ if (PerformTrivialCoalescing(MI, MBB))
+ FoundCSE = VNT.count(MI);
+ }
+ // FIXME: commute commutable instructions?
+
+ // If the instruction defines a physical register and the value *may* be
+ // used, then it's not safe to replace it with a common subexpression.
+ if (FoundCSE && hasLivePhysRegDefUse(MI, MBB))
+ FoundCSE = false;
+
+ if (!FoundCSE) {
+ VNT.insert(MI, CurrVN++);
+ Exps.push_back(MI);
+ continue;
+ }
+
+ // Found a common subexpression, eliminate it.
+ unsigned CSVN = VNT.lookup(MI);
+ MachineInstr *CSMI = Exps[CSVN];
+ DEBUG(dbgs() << "Examining: " << *MI);
+ DEBUG(dbgs() << "*** Found a common subexpression: " << *CSMI);
+ unsigned NumDefs = MI->getDesc().getNumDefs();
+ for (unsigned i = 0, e = MI->getNumOperands(); NumDefs && i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ unsigned OldReg = MO.getReg();
+ unsigned NewReg = CSMI->getOperand(i).getReg();
+ if (OldReg == NewReg)
+ continue;
+ assert(TargetRegisterInfo::isVirtualRegister(OldReg) &&
+ TargetRegisterInfo::isVirtualRegister(NewReg) &&
+ "Do not CSE physical register defs!");
+ MRI->replaceRegWith(OldReg, NewReg);
+ --NumDefs;
+ }
+ MI->eraseFromParent();
+ ++NumCSEs;
+ }
+
+ // Recursively call ProcessBlock with childred.
+ const std::vector<MachineDomTreeNode*> &Children = Node->getChildren();
+ for (unsigned i = 0, e = Children.size(); i != e; ++i)
+ Changed |= ProcessBlock(Children[i]);
+
+ return Changed;
+}
+
+bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
+ TII = MF.getTarget().getInstrInfo();
+ TRI = MF.getTarget().getRegisterInfo();
+ MRI = &MF.getRegInfo();
+ DT = &getAnalysis<MachineDominatorTree>();
+ AA = &getAnalysis<AliasAnalysis>();
+ return ProcessBlock(DT->getRootNode());
+}
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index f141c56..4377d5b 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -95,6 +95,9 @@ MachineFunction::MachineFunction(Function *F, const TargetMachine &TM,
MFInfo = 0;
FrameInfo = new (Allocator.Allocate<MachineFrameInfo>())
MachineFrameInfo(*TM.getFrameInfo());
+ if (Fn->hasFnAttr(Attribute::StackAlignment))
+ FrameInfo->setMaxAlignment(Attribute::getStackAlignmentFromAttrs(
+ Fn->getAttributes().getFnAttributes()));
ConstantPool = new (Allocator.Allocate<MachineConstantPool>())
MachineConstantPool(TM.getTargetData());
Alignment = TM.getTargetLowering()->getFunctionAlignment(F);
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index df61c74..e23670d 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -18,6 +18,7 @@
#include "llvm/Type.h"
#include "llvm/Value.h"
#include "llvm/Assembly/Writer.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -305,7 +306,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
MachineMemOperand::MachineMemOperand(const Value *v, unsigned int f,
int64_t o, uint64_t s, unsigned int a)
: Offset(o), Size(s), V(v),
- Flags((f & 7) | ((Log2_32(a) + 1) << 3)) {
+ Flags((f & ((1 << MOMaxBits) - 1)) | ((Log2_32(a) + 1) << MOMaxBits)) {
assert(getBaseAlignment() == a && "Alignment is not a power of 2!");
assert((isLoad() || isStore()) && "Not a load/store!");
}
@@ -327,7 +328,8 @@ void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
if (MMO->getBaseAlignment() >= getBaseAlignment()) {
// Update the alignment value.
- Flags = (Flags & 7) | ((Log2_32(MMO->getBaseAlignment()) + 1) << 3);
+ Flags = (Flags & ((1 << MOMaxBits) - 1)) |
+ ((Log2_32(MMO->getBaseAlignment()) + 1) << MOMaxBits);
// Also update the base and offset, because the new alignment may
// not be applicable with the old ones.
V = MMO->getValue();
@@ -700,6 +702,35 @@ void MachineInstr::addMemOperand(MachineFunction &MF,
MemRefsEnd = NewMemRefsEnd;
}
+bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
+ MICheckType Check) const {
+ // If opcodes or number of operands are not the same then the two
+ // instructions are obviously not identical.
+ if (Other->getOpcode() != getOpcode() ||
+ Other->getNumOperands() != getNumOperands())
+ return false;
+
+ // Check operands to make sure they match.
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = getOperand(i);
+ const MachineOperand &OMO = Other->getOperand(i);
+ // Clients may or may not want to ignore defs when testing for equality.
+ // For example, machine CSE pass only cares about finding common
+ // subexpressions, so it's safe to ignore virtual register defs.
+ if (Check != CheckDefs && MO.isReg() && MO.isDef()) {
+ if (Check == IgnoreDefs)
+ continue;
+ // Check == IgnoreVRegDefs
+ if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) ||
+ TargetRegisterInfo::isPhysicalRegister(OMO.getReg()))
+ if (MO.getReg() != OMO.getReg())
+ return false;
+ } else if (!MO.isIdenticalTo(OMO))
+ return false;
+ }
+ return true;
+}
+
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, and returns it, but does not delete it.
MachineInstr *MachineInstr::removeFromParent() {
@@ -958,8 +989,8 @@ void MachineInstr::copyPredicates(const MachineInstr *MI) {
/// SawStore is set to true, it means that there is a store (or call) between
/// the instruction's location and its intended destination.
bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII,
- bool &SawStore,
- AliasAnalysis *AA) const {
+ AliasAnalysis *AA,
+ bool &SawStore) const {
// Ignore stuff that we obviously can't move.
if (TID->mayStore() || TID->isCall()) {
SawStore = true;
@@ -984,11 +1015,11 @@ bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII,
/// isSafeToReMat - Return true if it's safe to rematerialize the specified
/// instruction which defined the specified register instead of copying it.
bool MachineInstr::isSafeToReMat(const TargetInstrInfo *TII,
- unsigned DstReg,
- AliasAnalysis *AA) const {
+ AliasAnalysis *AA,
+ unsigned DstReg) const {
bool SawStore = false;
if (!TII->isTriviallyReMaterializable(this, AA) ||
- !isSafeToMove(TII, SawStore, AA))
+ !isSafeToMove(TII, AA, SawStore))
return false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
@@ -1324,3 +1355,48 @@ void MachineInstr::addRegisterDefined(unsigned IncomingReg,
true /*IsDef*/,
true /*IsImp*/));
}
+
+unsigned
+MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
+ unsigned Hash = MI->getOpcode() * 37;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ uint64_t Key = (uint64_t)MO.getType() << 32;
+ switch (MO.getType()) {
+ default: break;
+ case MachineOperand::MO_Register:
+ if (MO.isDef() && MO.getReg() &&
+ TargetRegisterInfo::isVirtualRegister(MO.getReg()))
+ continue; // Skip virtual register defs.
+ Key |= MO.getReg();
+ break;
+ case MachineOperand::MO_Immediate:
+ Key |= MO.getImm();
+ break;
+ case MachineOperand::MO_FrameIndex:
+ case MachineOperand::MO_ConstantPoolIndex:
+ case MachineOperand::MO_JumpTableIndex:
+ Key |= MO.getIndex();
+ break;
+ case MachineOperand::MO_MachineBasicBlock:
+ Key |= DenseMapInfo<void*>::getHashValue(MO.getMBB());
+ break;
+ case MachineOperand::MO_GlobalAddress:
+ Key |= DenseMapInfo<void*>::getHashValue(MO.getGlobal());
+ break;
+ case MachineOperand::MO_BlockAddress:
+ Key |= DenseMapInfo<void*>::getHashValue(MO.getBlockAddress());
+ break;
+ }
+ Key += ~(Key << 32);
+ Key ^= (Key >> 22);
+ Key += ~(Key << 13);
+ Key ^= (Key >> 8);
+ Key += (Key << 3);
+ Key ^= (Key >> 15);
+ Key += ~(Key << 27);
+ Key ^= (Key >> 31);
+ Hash = (unsigned)Key + Hash * 37;
+ }
+ return Hash;
+}
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index 92c84f3..0361694 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -252,32 +252,6 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
return false;
}
- DEBUG({
- dbgs() << "--- Checking if we can hoist " << I;
- if (I.getDesc().getImplicitUses()) {
- dbgs() << " * Instruction has implicit uses:\n";
-
- const TargetRegisterInfo *TRI = TM->getRegisterInfo();
- for (const unsigned *ImpUses = I.getDesc().getImplicitUses();
- *ImpUses; ++ImpUses)
- dbgs() << " -> " << TRI->getName(*ImpUses) << "\n";
- }
-
- if (I.getDesc().getImplicitDefs()) {
- dbgs() << " * Instruction has implicit defines:\n";
-
- const TargetRegisterInfo *TRI = TM->getRegisterInfo();
- for (const unsigned *ImpDefs = I.getDesc().getImplicitDefs();
- *ImpDefs; ++ImpDefs)
- dbgs() << " -> " << TRI->getName(*ImpDefs) << "\n";
- }
- });
-
- if (I.getDesc().getImplicitDefs() || I.getDesc().getImplicitUses()) {
- DEBUG(dbgs() << "Cannot hoist with implicit defines or uses\n");
- return false;
- }
-
// The instruction is loop invariant if all of its operands are.
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = I.getOperand(i);
@@ -311,6 +285,10 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
} else if (!MO.isDead()) {
// A def that isn't dead. We can't move it.
return false;
+ } else if (CurLoop->getHeader()->isLiveIn(Reg)) {
+ // If the reg is live into the loop, we can't hoist an instruction
+ // which would clobber it.
+ return false;
}
}
@@ -467,7 +445,7 @@ MachineLICM::LookForDuplicate(const MachineInstr *MI,
std::vector<const MachineInstr*> &PrevMIs) {
for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) {
const MachineInstr *PrevMI = PrevMIs[i];
- if (TII->isIdentical(MI, PrevMI, RegInfo))
+ if (TII->produceSameValue(MI, PrevMI))
return PrevMI;
}
return 0;
@@ -480,9 +458,20 @@ bool MachineLICM::EliminateCSE(MachineInstr *MI,
if (const MachineInstr *Dup = LookForDuplicate(MI, CI->second)) {
DEBUG(dbgs() << "CSEing " << *MI << " with " << *Dup);
+
+ // Replace virtual registers defined by MI by their counterparts defined
+ // by Dup.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef())
+
+ // Physical registers may not differ here.
+ assert((!MO.isReg() || MO.getReg() == 0 ||
+ !TargetRegisterInfo::isPhysicalRegister(MO.getReg()) ||
+ MO.getReg() == Dup->getOperand(i).getReg()) &&
+ "Instructions with different phys regs are not identical!");
+
+ if (MO.isReg() && MO.isDef() &&
+ !TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg());
}
MI->eraseFromParent();
diff --git a/lib/CodeGen/MachineModuleInfoImpls.cpp b/lib/CodeGen/MachineModuleInfoImpls.cpp
index 8378906..39d2c75 100644
--- a/lib/CodeGen/MachineModuleInfoImpls.cpp
+++ b/lib/CodeGen/MachineModuleInfoImpls.cpp
@@ -22,7 +22,7 @@ using namespace llvm;
// Out of line virtual method.
void MachineModuleInfoMachO::Anchor() {}
-
+void MachineModuleInfoELF::Anchor() {}
static int SortSymbolPair(const void *LHS, const void *RHS) {
const MCSymbol *LHSS =
@@ -34,10 +34,11 @@ static int SortSymbolPair(const void *LHS, const void *RHS) {
/// GetSortedStubs - Return the entries from a DenseMap in a deterministic
/// sorted orer.
-MachineModuleInfoMachO::SymbolListTy
-MachineModuleInfoMachO::GetSortedStubs(const DenseMap<MCSymbol*,
- MCSymbol*> &Map) {
- MachineModuleInfoMachO::SymbolListTy List(Map.begin(), Map.end());
+MachineModuleInfoImpl::SymbolListTy
+MachineModuleInfoImpl::GetSortedStubs(const DenseMap<MCSymbol*,
+ MCSymbol*> &Map) {
+ MachineModuleInfoImpl::SymbolListTy List(Map.begin(), Map.end());
+
if (!List.empty())
qsort(&List[0], List.size(), sizeof(List[0]), SortSymbolPair);
return List;
diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp
index b31973e..d9ab677 100644
--- a/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/lib/CodeGen/MachineRegisterInfo.cpp
@@ -116,6 +116,19 @@ MachineInstr *MachineRegisterInfo::getVRegDef(unsigned Reg) const {
return 0;
}
+bool MachineRegisterInfo::hasOneUse(unsigned RegNo) const {
+ use_iterator UI = use_begin(RegNo);
+ if (UI == use_end())
+ return false;
+ return ++UI == use_end();
+}
+
+bool MachineRegisterInfo::hasOneNonDBGUse(unsigned RegNo) const {
+ use_nodbg_iterator UI = use_nodbg_begin(RegNo);
+ if (UI == use_nodbg_end())
+ return false;
+ return ++UI == use_nodbg_end();
+}
#ifndef NDEBUG
void MachineRegisterInfo::dumpUses(unsigned Reg) const {
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp
index c391576..e47ba7c 100644
--- a/lib/CodeGen/MachineSink.cpp
+++ b/lib/CodeGen/MachineSink.cpp
@@ -72,8 +72,13 @@ bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
MachineBasicBlock *MBB) const {
assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
"Only makes sense for vregs");
- for (MachineRegisterInfo::use_iterator I = RegInfo->use_begin(Reg),
- E = RegInfo->use_end(); I != E; ++I) {
+ // Ignoring debug uses is necessary so debug info doesn't affect the code.
+ // This may leave a referencing dbg_value in the original block, before
+ // the definition of the vreg. Dwarf generator handles this although the
+ // user might not get the right info at runtime.
+ for (MachineRegisterInfo::use_nodbg_iterator I =
+ RegInfo->use_nodbg_begin(Reg),
+ E = RegInfo->use_nodbg_end(); I != E; ++I) {
// Determine the block of the use.
MachineInstr *UseInst = &*I;
MachineBasicBlock *UseBlock = UseInst->getParent();
@@ -135,7 +140,10 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
ProcessedBegin = I == MBB.begin();
if (!ProcessedBegin)
--I;
-
+
+ if (MI->isDebugValue())
+ continue;
+
if (SinkInstruction(MI, SawStore))
++NumSunk, MadeChange = true;
@@ -149,7 +157,7 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
/// instruction out of its current block into a successor.
bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
// Check if it's safe to move the instruction.
- if (!MI->isSafeToMove(TII, SawStore, AA))
+ if (!MI->isSafeToMove(TII, AA, SawStore))
return false;
// FIXME: This should include support for sinking instructions within the
diff --git a/lib/CodeGen/OptimizePHIs.cpp b/lib/CodeGen/OptimizePHIs.cpp
new file mode 100644
index 0000000..2717d4d
--- /dev/null
+++ b/lib/CodeGen/OptimizePHIs.cpp
@@ -0,0 +1,189 @@
+//===-- OptimizePHIs.cpp - Optimize machine instruction PHIs --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass optimizes machine instruction PHIs to take advantage of
+// opportunities created during DAG legalization.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "phi-opt"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Function.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/Statistic.h"
+using namespace llvm;
+
+STATISTIC(NumPHICycles, "Number of PHI cycles replaced");
+STATISTIC(NumDeadPHICycles, "Number of dead PHI cycles");
+
+namespace {
+ class OptimizePHIs : public MachineFunctionPass {
+ MachineRegisterInfo *MRI;
+ const TargetInstrInfo *TII;
+
+ public:
+ static char ID; // Pass identification
+ OptimizePHIs() : MachineFunctionPass(&ID) {}
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ private:
+ typedef SmallPtrSet<MachineInstr*, 16> InstrSet;
+ typedef SmallPtrSetIterator<MachineInstr*> InstrSetIterator;
+
+ bool IsSingleValuePHICycle(MachineInstr *MI, unsigned &SingleValReg,
+ InstrSet &PHIsInCycle);
+ bool IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle);
+ bool OptimizeBB(MachineBasicBlock &MBB);
+ };
+}
+
+char OptimizePHIs::ID = 0;
+static RegisterPass<OptimizePHIs>
+X("opt-phis", "Optimize machine instruction PHIs");
+
+FunctionPass *llvm::createOptimizePHIsPass() { return new OptimizePHIs(); }
+
+bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) {
+ MRI = &Fn.getRegInfo();
+ TII = Fn.getTarget().getInstrInfo();
+
+ // Find dead PHI cycles and PHI cycles that can be replaced by a single
+ // value. InstCombine does these optimizations, but DAG legalization may
+ // introduce new opportunities, e.g., when i64 values are split up for
+ // 32-bit targets.
+ bool Changed = false;
+ for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
+ Changed |= OptimizeBB(*I);
+
+ return Changed;
+}
+
+/// IsSingleValuePHICycle - Check if MI is a PHI where all the source operands
+/// are copies of SingleValReg, possibly via copies through other PHIs. If
+/// SingleValReg is zero on entry, it is set to the register with the single
+/// non-copy value. PHIsInCycle is a set used to keep track of the PHIs that
+/// have been scanned.
+bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI,
+ unsigned &SingleValReg,
+ InstrSet &PHIsInCycle) {
+ assert(MI->isPHI() && "IsSingleValuePHICycle expects a PHI instruction");
+ unsigned DstReg = MI->getOperand(0).getReg();
+
+ // See if we already saw this register.
+ if (!PHIsInCycle.insert(MI))
+ return true;
+
+ // Don't scan crazily complex things.
+ if (PHIsInCycle.size() == 16)
+ return false;
+
+ // Scan the PHI operands.
+ for (unsigned i = 1; i != MI->getNumOperands(); i += 2) {
+ unsigned SrcReg = MI->getOperand(i).getReg();
+ if (SrcReg == DstReg)
+ continue;
+ MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
+
+ // Skip over register-to-register moves.
+ unsigned MvSrcReg, MvDstReg, SrcSubIdx, DstSubIdx;
+ if (SrcMI &&
+ TII->isMoveInstr(*SrcMI, MvSrcReg, MvDstReg, SrcSubIdx, DstSubIdx) &&
+ SrcSubIdx == 0 && DstSubIdx == 0 &&
+ TargetRegisterInfo::isVirtualRegister(MvSrcReg))
+ SrcMI = MRI->getVRegDef(MvSrcReg);
+ if (!SrcMI)
+ return false;
+
+ if (SrcMI->isPHI()) {
+ if (!IsSingleValuePHICycle(SrcMI, SingleValReg, PHIsInCycle))
+ return false;
+ } else {
+ // Fail if there is more than one non-phi/non-move register.
+ if (SingleValReg != 0)
+ return false;
+ SingleValReg = SrcReg;
+ }
+ }
+ return true;
+}
+
+/// IsDeadPHICycle - Check if the register defined by a PHI is only used by
+/// other PHIs in a cycle.
+bool OptimizePHIs::IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle) {
+ assert(MI->isPHI() && "IsDeadPHICycle expects a PHI instruction");
+ unsigned DstReg = MI->getOperand(0).getReg();
+ assert(TargetRegisterInfo::isVirtualRegister(DstReg) &&
+ "PHI destination is not a virtual register");
+
+ // See if we already saw this register.
+ if (!PHIsInCycle.insert(MI))
+ return true;
+
+ // Don't scan crazily complex things.
+ if (PHIsInCycle.size() == 16)
+ return false;
+
+ for (MachineRegisterInfo::use_iterator I = MRI->use_begin(DstReg),
+ E = MRI->use_end(); I != E; ++I) {
+ MachineInstr *UseMI = &*I;
+ if (!UseMI->isPHI() || !IsDeadPHICycle(UseMI, PHIsInCycle))
+ return false;
+ }
+
+ return true;
+}
+
+/// OptimizeBB - Remove dead PHI cycles and PHI cycles that can be replaced by
+/// a single value.
+bool OptimizePHIs::OptimizeBB(MachineBasicBlock &MBB) {
+ bool Changed = false;
+ for (MachineBasicBlock::iterator
+ MII = MBB.begin(), E = MBB.end(); MII != E; ) {
+ MachineInstr *MI = &*MII++;
+ if (!MI->isPHI())
+ break;
+
+ // Check for single-value PHI cycles.
+ unsigned SingleValReg = 0;
+ InstrSet PHIsInCycle;
+ if (IsSingleValuePHICycle(MI, SingleValReg, PHIsInCycle) &&
+ SingleValReg != 0) {
+ MRI->replaceRegWith(MI->getOperand(0).getReg(), SingleValReg);
+ MI->eraseFromParent();
+ ++NumPHICycles;
+ Changed = true;
+ continue;
+ }
+
+ // Check for dead PHI cycles.
+ PHIsInCycle.clear();
+ if (IsDeadPHICycle(MI, PHIsInCycle)) {
+ for (InstrSetIterator PI = PHIsInCycle.begin(), PE = PHIsInCycle.end();
+ PI != PE; ++PI) {
+ MachineInstr *PhiMI = *PI;
+ if (&*MII == PhiMI)
+ ++MII;
+ PhiMI->eraseFromParent();
+ }
+ ++NumDeadPHICycles;
+ Changed = true;
+ }
+ }
+ return Changed;
+}
diff --git a/lib/CodeGen/PBQP/HeuristicSolver.h b/lib/CodeGen/PBQP/HeuristicSolver.h
index b48f548..bd18b52 100644
--- a/lib/CodeGen/PBQP/HeuristicSolver.h
+++ b/lib/CodeGen/PBQP/HeuristicSolver.h
@@ -18,7 +18,6 @@
#include "Graph.h"
#include "Solution.h"
-#include "llvm/Support/raw_ostream.h"
#include <vector>
#include <limits>
@@ -230,7 +229,7 @@ namespace PBQP {
}
/// \brief Apply rule R1.
- /// @param nItr Node iterator for node to apply R1 to.
+ /// @param xnItr Node iterator for node to apply R1 to.
///
/// Node will be automatically pushed to the solver stack.
void applyR1(Graph::NodeItr xnItr) {
@@ -278,7 +277,7 @@ namespace PBQP {
}
/// \brief Apply rule R2.
- /// @param nItr Node iterator for node to apply R2 to.
+ /// @param xnItr Node iterator for node to apply R2 to.
///
/// Node will be automatically pushed to the solver stack.
void applyR2(Graph::NodeItr xnItr) {
@@ -494,14 +493,23 @@ namespace PBQP {
bool tryNormaliseEdgeMatrix(Graph::EdgeItr &eItr) {
+ const PBQPNum infinity = std::numeric_limits<PBQPNum>::infinity();
+
Matrix &edgeCosts = g.getEdgeCosts(eItr);
Vector &uCosts = g.getNodeCosts(g.getEdgeNode1(eItr)),
&vCosts = g.getNodeCosts(g.getEdgeNode2(eItr));
for (unsigned r = 0; r < edgeCosts.getRows(); ++r) {
- PBQPNum rowMin = edgeCosts.getRowMin(r);
+ PBQPNum rowMin = infinity;
+
+ for (unsigned c = 0; c < edgeCosts.getCols(); ++c) {
+ if (vCosts[c] != infinity && edgeCosts[r][c] < rowMin)
+ rowMin = edgeCosts[r][c];
+ }
+
uCosts[r] += rowMin;
- if (rowMin != std::numeric_limits<PBQPNum>::infinity()) {
+
+ if (rowMin != infinity) {
edgeCosts.subFromRow(r, rowMin);
}
else {
@@ -510,9 +518,16 @@ namespace PBQP {
}
for (unsigned c = 0; c < edgeCosts.getCols(); ++c) {
- PBQPNum colMin = edgeCosts.getColMin(c);
+ PBQPNum colMin = infinity;
+
+ for (unsigned r = 0; r < edgeCosts.getRows(); ++r) {
+ if (uCosts[r] != infinity && edgeCosts[r][c] < colMin)
+ colMin = edgeCosts[r][c];
+ }
+
vCosts[c] += colMin;
- if (colMin != std::numeric_limits<PBQPNum>::infinity()) {
+
+ if (colMin != infinity) {
edgeCosts.subFromCol(c, colMin);
}
else {
diff --git a/lib/CodeGen/PBQP/Heuristics/Briggs.h b/lib/CodeGen/PBQP/Heuristics/Briggs.h
index c09ad74..30d34d9 100644
--- a/lib/CodeGen/PBQP/Heuristics/Briggs.h
+++ b/lib/CodeGen/PBQP/Heuristics/Briggs.h
@@ -128,14 +128,7 @@ namespace PBQP {
/// selected for heuristic reduction instead.
bool shouldOptimallyReduce(Graph::NodeItr nItr) {
if (getSolver().getSolverDegree(nItr) < 3) {
- if (getGraph().getNodeCosts(nItr)[0] !=
- std::numeric_limits<PBQPNum>::infinity()) {
- return true;
- }
- // Otherwise we have an infinite spill cost node.
- initializeNode(nItr);
- NodeData &nd = getHeuristicNodeData(nItr);
- return nd.isAllocable;
+ return true;
}
// else
return false;
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index b740c68..8bbe0a7 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -55,8 +55,6 @@ void llvm::PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) {
MRI = &Fn.getRegInfo();
- PHIDefs.clear();
- PHIKills.clear();
bool Changed = false;
// Split critical edges to help the coalescer
@@ -215,10 +213,6 @@ void llvm::PHIElimination::LowerAtomicPHINode(
TII->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC, RC);
}
- // Record PHI def.
- assert(!hasPHIDef(DestReg) && "Vreg has multiple phi-defs?");
- PHIDefs[DestReg] = &MBB;
-
// Update live variable information if there is any.
LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>();
if (LV) {
@@ -229,6 +223,7 @@ void llvm::PHIElimination::LowerAtomicPHINode(
// Increment use count of the newly created virtual register.
VI.NumUses++;
+ LV->setPHIJoin(IncomingReg);
// When we are reusing the incoming register, it may already have been
// killed in this block. The old kill will also have been inserted at
@@ -276,9 +271,6 @@ void llvm::PHIElimination::LowerAtomicPHINode(
// path the PHI.
MachineBasicBlock &opBlock = *MPhi->getOperand(i*2+2).getMBB();
- // Record the kill.
- PHIKills[SrcReg].insert(&opBlock);
-
// If source is defined by an implicit def, there is no need to insert a
// copy.
MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
@@ -451,34 +443,3 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
return NMBB;
}
-
-unsigned
-PHIElimination::PHINodeTraits::getHashValue(const MachineInstr *MI) {
- if (!MI || MI==getEmptyKey() || MI==getTombstoneKey())
- return DenseMapInfo<MachineInstr*>::getHashValue(MI);
- unsigned hash = 0;
- for (unsigned ni = 1, ne = MI->getNumOperands(); ni != ne; ni += 2)
- hash = hash*37 + DenseMapInfo<BBVRegPair>::
- getHashValue(BBVRegPair(MI->getOperand(ni+1).getMBB()->getNumber(),
- MI->getOperand(ni).getReg()));
- return hash;
-}
-
-bool PHIElimination::PHINodeTraits::isEqual(const MachineInstr *LHS,
- const MachineInstr *RHS) {
- const MachineInstr *EmptyKey = getEmptyKey();
- const MachineInstr *TombstoneKey = getTombstoneKey();
- if (!LHS || !RHS || LHS==EmptyKey || RHS==EmptyKey ||
- LHS==TombstoneKey || RHS==TombstoneKey)
- return LHS==RHS;
-
- unsigned ne = LHS->getNumOperands();
- if (ne != RHS->getNumOperands())
- return false;
- // Ignore operand 0, the defined register.
- for (unsigned ni = 1; ni != ne; ni += 2)
- if (LHS->getOperand(ni).getReg() != RHS->getOperand(ni).getReg() ||
- LHS->getOperand(ni+1).getMBB() != RHS->getOperand(ni+1).getMBB())
- return false;
- return true;
-}
diff --git a/lib/CodeGen/PHIElimination.h b/lib/CodeGen/PHIElimination.h
index 895aaa4..7dedf03 100644
--- a/lib/CodeGen/PHIElimination.h
+++ b/lib/CodeGen/PHIElimination.h
@@ -22,17 +22,8 @@ namespace llvm {
/// Lower PHI instructions to copies.
class PHIElimination : public MachineFunctionPass {
MachineRegisterInfo *MRI; // Machine register information
- private:
-
- typedef SmallSet<MachineBasicBlock*, 4> PHIKillList;
- typedef DenseMap<unsigned, PHIKillList> PHIKillMap;
- typedef DenseMap<unsigned, MachineBasicBlock*> PHIDefMap;
public:
-
- typedef PHIKillList::iterator phi_kill_iterator;
- typedef PHIKillList::const_iterator const_phi_kill_iterator;
-
static char ID; // Pass identification, replacement for typeid
PHIElimination() : MachineFunctionPass(&ID) {}
@@ -40,38 +31,6 @@ namespace llvm {
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- /// Return true if the given vreg was defined by a PHI intsr prior to
- /// lowering.
- bool hasPHIDef(unsigned vreg) const {
- return PHIDefs.count(vreg);
- }
-
- /// Returns the block in which the PHI instruction which defined the
- /// given vreg used to reside.
- MachineBasicBlock* getPHIDefBlock(unsigned vreg) {
- PHIDefMap::iterator phiDefItr = PHIDefs.find(vreg);
- assert(phiDefItr != PHIDefs.end() && "vreg has no phi-def.");
- return phiDefItr->second;
- }
-
- /// Returns true if the given vreg was killed by a PHI instr.
- bool hasPHIKills(unsigned vreg) const {
- return PHIKills.count(vreg);
- }
-
- /// Returns an iterator over the BasicBlocks which contained PHI
- /// kills of this register prior to lowering.
- phi_kill_iterator phiKillsBegin(unsigned vreg) {
- PHIKillMap::iterator phiKillItr = PHIKills.find(vreg);
- assert(phiKillItr != PHIKills.end() && "vreg has no phi-kills.");
- return phiKillItr->second.begin();
- }
- phi_kill_iterator phiKillsEnd(unsigned vreg) {
- PHIKillMap::iterator phiKillItr = PHIKills.find(vreg);
- assert(phiKillItr != PHIKills.end() && "vreg has no phi-kills.");
- return phiKillItr->second.end();
- }
-
private:
/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions
/// in predecessor basic blocks.
@@ -109,12 +68,29 @@ namespace llvm {
// SkipPHIsAndLabels - Copies need to be inserted after phi nodes and
// also after any exception handling labels: in landing pads execution
// starts at the label, so any copies placed before it won't be executed!
+ // We also deal with DBG_VALUEs, which are a bit tricky:
+ // PHI
+ // DBG_VALUE
+ // LABEL
+ // Here the DBG_VALUE needs to be skipped, and if it refers to a PHI it
+ // needs to be annulled or, better, moved to follow the label, as well.
+ // PHI
+ // DBG_VALUE
+ // no label
+ // Here it is not a good idea to skip the DBG_VALUE.
+ // FIXME: For now we skip and annul all DBG_VALUEs, maximally simple and
+ // maximally stupid.
MachineBasicBlock::iterator SkipPHIsAndLabels(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) {
// Rather than assuming that EH labels come before other kinds of labels,
// just skip all labels.
- while (I != MBB.end() && (I->isPHI() || I->isLabel()))
+ while (I != MBB.end() &&
+ (I->isPHI() || I->isLabel() || I->isDebugValue())) {
+ if (I->isDebugValue() && I->getNumOperands()==3 &&
+ I->getOperand(0).isReg())
+ I->getOperand(0).setReg(0U);
++I;
+ }
return I;
}
@@ -122,21 +98,13 @@ namespace llvm {
typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse;
VRegPHIUse VRegPHIUseCount;
- PHIDefMap PHIDefs;
- PHIKillMap PHIKills;
// Defs of PHI sources which are implicit_def.
SmallPtrSet<MachineInstr*, 4> ImpDefs;
- // Lowered PHI nodes may be reused. We provide special DenseMap traits to
- // match PHI nodes with identical arguments.
- struct PHINodeTraits : public DenseMapInfo<MachineInstr*> {
- static unsigned getHashValue(const MachineInstr *PtrVal);
- static bool isEqual(const MachineInstr *LHS, const MachineInstr *RHS);
- };
-
// Map reusable lowered PHI node -> incoming join register.
- typedef DenseMap<MachineInstr*, unsigned, PHINodeTraits> LoweredPHIMap;
+ typedef DenseMap<MachineInstr*, unsigned,
+ MachineInstrExpressionTrait> LoweredPHIMap;
LoweredPHIMap LoweredPHIs;
};
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp
index f67eb79..5ea2941 100644
--- a/lib/CodeGen/Passes.cpp
+++ b/lib/CodeGen/Passes.cpp
@@ -34,7 +34,7 @@ static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
RegisterPassParser<RegisterRegAlloc> >
RegAlloc("regalloc",
cl::init(&createLinearScanRegisterAllocator),
- cl::desc("Register allocator to use: (default = linearscan)"));
+ cl::desc("Register allocator to use (default=linearscan)"));
//===---------------------------------------------------------------------===//
diff --git a/lib/CodeGen/PostRASchedulerList.cpp b/lib/CodeGen/PostRASchedulerList.cpp
index f43395f..424181c 100644
--- a/lib/CodeGen/PostRASchedulerList.cpp
+++ b/lib/CodeGen/PostRASchedulerList.cpp
@@ -460,6 +460,8 @@ void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) {
for (MachineBasicBlock::iterator I = MBB->end(), E = MBB->begin();
I != E; --Count) {
MachineInstr *MI = --I;
+ if (MI->isDebugValue())
+ continue;
// Update liveness. Registers that are defed but not used in this
// instruction are now dead. Mark register and all subregs as they
diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp
index e3df2e4..d7179b3 100644
--- a/lib/CodeGen/ProcessImplicitDefs.cpp
+++ b/lib/CodeGen/ProcessImplicitDefs.cpp
@@ -205,10 +205,9 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
// Process each use instruction once.
for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
UE = mri_->use_end(); UI != UE; ++UI) {
- MachineInstr *RMI = &*UI;
- MachineBasicBlock *RMBB = RMI->getParent();
- if (RMBB == MBB)
+ if (UI.getOperand().isUndef())
continue;
+ MachineInstr *RMI = &*UI;
if (ModInsts.insert(RMI))
RUses.push_back(RMI);
}
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 036f59a..138e711 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -175,9 +175,10 @@ void PEI::calculateCallsInformation(MachineFunction &Fn) {
MachineBasicBlock::iterator I = *i;
// If call frames are not being included as part of the stack frame, and
- // there is no dynamic allocation (therefore referencing frame slots off
- // sp), leave the pseudo ops alone. We'll eliminate them later.
- if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn))
+ // the target doesn't indicate otherwise, remove the call frame pseudos
+ // here. The sub/add sp instruction pairs are still inserted, but we don't
+ // need to track the SP adjustment for frame index elimination.
+ if (RegInfo->canSimplifyCallFramePseudos(Fn))
RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
}
}
@@ -476,8 +477,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
// Loop over all of the stack objects, assigning sequential addresses...
MachineFrameInfo *FFI = Fn.getFrameInfo();
- unsigned MaxAlign = 1;
-
// Start at the beginning of the local area.
// The Offset is the distance from the stack top in the direction
// of stack growth -- so it's always nonnegative.
@@ -517,9 +516,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
Offset += FFI->getObjectSize(i);
unsigned Align = FFI->getObjectAlignment(i);
- // If the alignment of this object is greater than that of the stack,
- // then increase the stack alignment to match.
- MaxAlign = std::max(MaxAlign, Align);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
@@ -529,9 +525,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;
for (int i = MaxCSFI; i >= MinCSFI ; --i) {
unsigned Align = FFI->getObjectAlignment(i);
- // If the alignment of this object is greater than that of the stack,
- // then increase the stack alignment to match.
- MaxAlign = std::max(MaxAlign, Align);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
@@ -540,6 +533,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
}
}
+ unsigned MaxAlign = FFI->getMaxAlignment();
+
// Make sure the special register scavenging spill slot is closest to the
// frame pointer if a frame pointer is required.
const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
@@ -605,11 +600,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
// Update frame info to pretend that this is part of the stack...
FFI->setStackSize(Offset - LocalAreaOffset);
-
- // Remember the required stack alignment in case targets need it to perform
- // dynamic stack alignment.
- if (MaxAlign > FFI->getMaxAlignment())
- FFI->setMaxAlignment(MaxAlign);
}
diff --git a/lib/CodeGen/PseudoSourceValue.cpp b/lib/CodeGen/PseudoSourceValue.cpp
index 7fb3e6e..5e86e5a 100644
--- a/lib/CodeGen/PseudoSourceValue.cpp
+++ b/lib/CodeGen/PseudoSourceValue.cpp
@@ -18,19 +18,38 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Mutex.h"
#include <map>
using namespace llvm;
-static ManagedStatic<PseudoSourceValue[4]> PSVs;
+namespace {
+struct PSVGlobalsTy {
+ // PseudoSourceValues are immutable so don't need locking.
+ const PseudoSourceValue PSVs[4];
+ sys::Mutex Lock; // Guards FSValues, but not the values inside it.
+ std::map<int, const PseudoSourceValue *> FSValues;
+
+ PSVGlobalsTy() : PSVs() {}
+ ~PSVGlobalsTy() {
+ for (std::map<int, const PseudoSourceValue *>::iterator
+ I = FSValues.begin(), E = FSValues.end(); I != E; ++I) {
+ delete I->second;
+ }
+ }
+};
+
+static ManagedStatic<PSVGlobalsTy> PSVGlobals;
+
+} // anonymous namespace
const PseudoSourceValue *PseudoSourceValue::getStack()
-{ return &(*PSVs)[0]; }
+{ return &PSVGlobals->PSVs[0]; }
const PseudoSourceValue *PseudoSourceValue::getGOT()
-{ return &(*PSVs)[1]; }
+{ return &PSVGlobals->PSVs[1]; }
const PseudoSourceValue *PseudoSourceValue::getJumpTable()
-{ return &(*PSVs)[2]; }
+{ return &PSVGlobals->PSVs[2]; }
const PseudoSourceValue *PseudoSourceValue::getConstantPool()
-{ return &(*PSVs)[3]; }
+{ return &PSVGlobals->PSVs[3]; }
static const char *const PSVNames[] = {
"Stack",
@@ -48,13 +67,13 @@ PseudoSourceValue::PseudoSourceValue(enum ValueTy Subclass) :
Subclass) {}
void PseudoSourceValue::printCustom(raw_ostream &O) const {
- O << PSVNames[this - *PSVs];
+ O << PSVNames[this - PSVGlobals->PSVs];
}
-static ManagedStatic<std::map<int, const PseudoSourceValue *> > FSValues;
-
const PseudoSourceValue *PseudoSourceValue::getFixedStack(int FI) {
- const PseudoSourceValue *&V = (*FSValues)[FI];
+ PSVGlobalsTy &PG = *PSVGlobals;
+ sys::ScopedLock locked(PG.Lock);
+ const PseudoSourceValue *&V = PG.FSValues[FI];
if (!V)
V = new FixedStackPseudoSourceValue(FI);
return V;
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index 8e44a57..5c5a394 100644
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -334,10 +334,6 @@ namespace {
SmallVector<unsigned, 256> &inactiveCounts,
bool SkipDGRegs);
- /// assignVirt2StackSlot - assigns this virtual register to a
- /// stack slot. returns the stack slot
- int assignVirt2StackSlot(unsigned virtReg);
-
void ComputeRelatedRegClasses();
template <typename ItTy>
diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp
index 4d2e3a3..04303cf 100644
--- a/lib/CodeGen/RegAllocLocal.cpp
+++ b/lib/CodeGen/RegAllocLocal.cpp
@@ -490,9 +490,12 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
// If the virtual register is already available, just update the instruction
// and return.
if (unsigned PR = getVirt2PhysRegMapSlot(VirtReg)) {
- MarkPhysRegRecentlyUsed(PR); // Already have this value available!
MI->getOperand(OpNum).setReg(PR); // Assign the input register
- getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum);
+ if (!MI->isDebugValue()) {
+ // Do not do these for DBG_VALUE as they can affect codegen.
+ MarkPhysRegRecentlyUsed(PR); // Already have this value available!
+ getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum);
+ }
return MI;
}
@@ -609,6 +612,8 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
DenseMap<unsigned, std::pair<MachineInstr*, unsigned> > LastUseDef;
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) {
+ if (I->isDebugValue())
+ continue;
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
MachineOperand& MO = I->getOperand(i);
// Uses don't trigger any flags, but we need to save
@@ -691,7 +696,13 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
bool usedOutsideBlock = isPhysReg ? false :
UsedInMultipleBlocks.test(MO.getReg() -
TargetRegisterInfo::FirstVirtualRegister);
- if (!isPhysReg && !usedOutsideBlock)
+ if (!isPhysReg && !usedOutsideBlock) {
+ // DBG_VALUE complicates this: if the only refs of a register outside
+ // this block are DBG_VALUE, we can't keep the reg live just for that,
+ // as it will cause the reg to be spilled at the end of this block when
+ // it wouldn't have been otherwise. Nullify the DBG_VALUEs when that
+ // happens.
+ bool UsedByDebugValueOnly = false;
for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
UE = MRI.reg_end(); UI != UE; ++UI)
// Two cases:
@@ -699,12 +710,26 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
// - used in the same block before it is defined (loop)
if (UI->getParent() != &MBB ||
(MO.isDef() && UI.getOperand().isUse() && precedes(&*UI, MI))) {
+ if (UI->isDebugValue()) {
+ UsedByDebugValueOnly = true;
+ continue;
+ }
+ // A non-DBG_VALUE use means we can leave DBG_VALUE uses alone.
UsedInMultipleBlocks.set(MO.getReg() -
TargetRegisterInfo::FirstVirtualRegister);
usedOutsideBlock = true;
+ UsedByDebugValueOnly = false;
break;
}
-
+ if (UsedByDebugValueOnly)
+ for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
+ UE = MRI.reg_end(); UI != UE; ++UI)
+ if (UI->isDebugValue() &&
+ (UI->getParent() != &MBB ||
+ (MO.isDef() && precedes(&*UI, MI))))
+ UI.getOperand().setReg(0U);
+ }
+
// Physical registers and those that are not live-out of the block
// are killed/dead at their last use/def within this block.
if (isPhysReg || !usedOutsideBlock) {
diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp
index 2701faf..81cfd8f 100644
--- a/lib/CodeGen/RegAllocPBQP.cpp
+++ b/lib/CodeGen/RegAllocPBQP.cpp
@@ -57,7 +57,7 @@
using namespace llvm;
static RegisterRegAlloc
-registerPBQPRepAlloc("pbqp", "PBQP register allocator.",
+registerPBQPRepAlloc("pbqp", "PBQP register allocator",
llvm::createPBQPRegisterAllocator);
static cl::opt<bool>
@@ -867,10 +867,6 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) {
// Find the vreg intervals in need of allocation.
findVRegIntervalsToAlloc();
- // If there aren't any then we're done here.
- if (vregIntervalsToAlloc.empty() && emptyVRegIntervals.empty())
- return true;
-
// If there are non-empty intervals allocate them using pbqp.
if (!vregIntervalsToAlloc.empty()) {
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp
index 56dd533..badf34e 100644
--- a/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -72,7 +72,7 @@ static const Value *getUnderlyingObjectFromInt(const Value *V) {
} else {
return V;
}
- assert(isa<IntegerType>(V->getType()) && "Unexpected operand type!");
+ assert(V->getType()->isIntegerTy() && "Unexpected operand type!");
} while (1);
}
@@ -87,7 +87,7 @@ static const Value *getUnderlyingObject(const Value *V) {
break;
const Value *O = getUnderlyingObjectFromInt(cast<User>(V)->getOperand(0));
// If that succeeded in finding a pointer, continue the search.
- if (!isa<PointerType>(O->getType()))
+ if (!O->getType()->isPointerTy())
break;
V = O;
} while (1);
diff --git a/lib/CodeGen/SelectionDAG/Android.mk b/lib/CodeGen/SelectionDAG/Android.mk
new file mode 100644
index 0000000..eb15a18
--- /dev/null
+++ b/lib/CodeGen/SelectionDAG/Android.mk
@@ -0,0 +1,48 @@
+LOCAL_PATH:= $(call my-dir)
+
+codegen_selectiondag_SRC_FILES := \
+ CallingConvLower.cpp \
+ DAGCombiner.cpp \
+ FastISel.cpp \
+ FunctionLoweringInfo.cpp \
+ InstrEmitter.cpp \
+ LegalizeDAG.cpp \
+ LegalizeFloatTypes.cpp \
+ LegalizeIntegerTypes.cpp \
+ LegalizeTypes.cpp \
+ LegalizeTypesGeneric.cpp \
+ LegalizeVectorOps.cpp \
+ LegalizeVectorTypes.cpp \
+ ScheduleDAGFast.cpp \
+ ScheduleDAGList.cpp \
+ ScheduleDAGRRList.cpp \
+ ScheduleDAGSDNodes.cpp \
+ SelectionDAG.cpp \
+ SelectionDAGBuilder.cpp \
+ SelectionDAGISel.cpp \
+ SelectionDAGPrinter.cpp \
+ TargetLowering.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(codegen_selectiondag_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMSelectionDAG
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(codegen_selectiondag_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMSelectionDAG
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 9189e71..3be6b43 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1064,7 +1064,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
if (VT.isInteger() && !VT.isVector()) {
APInt LHSZero, LHSOne;
APInt RHSZero, RHSOne;
- APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
+ APInt Mask = APInt::getAllOnesValue(VT.getScalarType().getSizeInBits());
DAG.ComputeMaskedBits(N0, Mask, LHSZero, LHSOne);
if (LHSZero.getBoolValue()) {
@@ -1136,7 +1136,7 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
// fold (addc a, b) -> (or a, b), CARRY_FALSE iff a and b share no bits.
APInt LHSZero, LHSOne;
APInt RHSZero, RHSOne;
- APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
+ APInt Mask = APInt::getAllOnesValue(VT.getScalarType().getSizeInBits());
DAG.ComputeMaskedBits(N0, Mask, LHSZero, LHSOne);
if (LHSZero.getBoolValue()) {
@@ -1758,7 +1758,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
EVT VT = N1.getValueType();
- unsigned BitWidth = VT.getSizeInBits();
+ unsigned BitWidth = VT.getScalarType().getSizeInBits();
// fold vector ops
if (VT.isVector()) {
@@ -1786,7 +1786,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
SDValue RAND = ReassociateOps(ISD::AND, N->getDebugLoc(), N0, N1);
if (RAND.getNode() != 0)
return RAND;
- // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF
+ // fold (and (or x, C), D) -> D if (C & D) == D
if (N1C && N0.getOpcode() == ISD::OR)
if (ConstantSDNode *ORI = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
if ((ORI->getAPIntValue() & N1C->getAPIntValue()) == N1C->getAPIntValue())
@@ -1872,16 +1872,17 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
EVT MemVT = LN0->getMemoryVT();
// If we zero all the possible extended bits, then we can turn this into
// a zextload if we are running before legalize or the operation is legal.
- unsigned BitWidth = N1.getValueSizeInBits();
+ unsigned BitWidth = N1.getValueType().getScalarType().getSizeInBits();
if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth,
- BitWidth - MemVT.getSizeInBits())) &&
+ BitWidth - MemVT.getScalarType().getSizeInBits())) &&
((!LegalOperations && !LN0->isVolatile()) ||
TLI.isLoadExtLegal(ISD::ZEXTLOAD, MemVT))) {
SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N0.getDebugLoc(), VT,
LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
AddToWorkList(N);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -1894,16 +1895,17 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
EVT MemVT = LN0->getMemoryVT();
// If we zero all the possible extended bits, then we can turn this into
// a zextload if we are running before legalize or the operation is legal.
- unsigned BitWidth = N1.getValueSizeInBits();
+ unsigned BitWidth = N1.getValueType().getScalarType().getSizeInBits();
if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth,
- BitWidth - MemVT.getSizeInBits())) &&
+ BitWidth - MemVT.getScalarType().getSizeInBits())) &&
((!LegalOperations && !LN0->isVolatile()) ||
TLI.isLoadExtLegal(ISD::ZEXTLOAD, MemVT))) {
SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N0.getDebugLoc(), VT,
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
AddToWorkList(N);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -1935,7 +1937,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), LoadResultTy,
LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- ExtVT, LN0->isVolatile(), LN0->getAlignment());
+ ExtVT, LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
AddToWorkList(N);
CombineTo(LN0, NewLoad, NewLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -1970,7 +1973,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), LoadResultTy,
LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- ExtVT, LN0->isVolatile(), Alignment);
+ ExtVT, LN0->isVolatile(), LN0->isNonTemporal(),
+ Alignment);
AddToWorkList(N);
CombineTo(LN0, Load, Load.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -2021,13 +2025,15 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
if (ROR.getNode() != 0)
return ROR;
// Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
+ // iff (c1 & c2) == 0.
if (N1C && N0.getOpcode() == ISD::AND && N0.getNode()->hasOneUse() &&
isa<ConstantSDNode>(N0.getOperand(1))) {
ConstantSDNode *C1 = cast<ConstantSDNode>(N0.getOperand(1));
- return DAG.getNode(ISD::AND, N->getDebugLoc(), VT,
- DAG.getNode(ISD::OR, N0.getDebugLoc(), VT,
- N0.getOperand(0), N1),
- DAG.FoldConstantArithmetic(ISD::OR, VT, N1C, C1));
+ if ((C1->getAPIntValue() & N1C->getAPIntValue()) != 0)
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT,
+ DAG.getNode(ISD::OR, N0.getDebugLoc(), VT,
+ N0.getOperand(0), N1),
+ DAG.FoldConstantArithmetic(ISD::OR, VT, N1C, C1));
}
// fold (or (setcc x), (setcc y)) -> (setcc (or x, y))
if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){
@@ -2750,7 +2756,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
if (N1C && N0.getOpcode() == ISD::CTLZ &&
N1C->getAPIntValue() == Log2_32(VT.getSizeInBits())) {
APInt KnownZero, KnownOne;
- APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
+ APInt Mask = APInt::getAllOnesValue(VT.getScalarType().getSizeInBits());
DAG.ComputeMaskedBits(N0.getOperand(0), Mask, KnownZero, KnownOne);
// If any of the input bits are KnownOne, then the input couldn't be all
@@ -3143,7 +3149,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
N0.getValueType(), ExtLoad);
@@ -3185,7 +3192,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
@@ -3315,7 +3323,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
N0.getValueType(), ExtLoad);
@@ -3357,7 +3366,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(),
@@ -3471,7 +3481,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
N0.getValueType(), ExtLoad);
@@ -3513,7 +3524,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
VT, LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
@@ -3636,10 +3648,11 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
SDValue Load = (ExtType == ISD::NON_EXTLOAD)
? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
- LN0->isVolatile(), NewAlign)
+ LN0->isVolatile(), LN0->isNonTemporal(), NewAlign)
: DAG.getExtLoad(ExtType, N0.getDebugLoc(), VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
- ExtVT, LN0->isVolatile(), NewAlign);
+ ExtVT, LN0->isVolatile(), LN0->isNonTemporal(),
+ NewAlign);
// Replace the old load's chain with the new load's chain.
WorkListRemover DeadNodes(*this);
@@ -3726,7 +3739,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -3742,7 +3756,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -3826,7 +3841,7 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, EVT VT) {
(!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT)))
return DAG.getLoad(VT, N->getDebugLoc(), LD1->getChain(),
LD1->getBasePtr(), LD1->getSrcValue(),
- LD1->getSrcValueOffset(), false, Align);
+ LD1->getSrcValueOffset(), false, false, Align);
}
return SDValue();
@@ -3896,7 +3911,8 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) {
SDValue Load = DAG.getLoad(VT, N->getDebugLoc(), LN0->getChain(),
LN0->getBasePtr(),
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- LN0->isVolatile(), OrigAlign);
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ OrigAlign);
AddToWorkList(N);
CombineTo(N0.getNode(),
DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(),
@@ -4492,7 +4508,8 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::FP_ROUND, N0.getDebugLoc(),
@@ -4640,7 +4657,8 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
DAG.DeleteNode(Trunc);
}
// Replace the uses of SRL with SETCC
- DAG.ReplaceAllUsesOfValueWith(N1, SetCC);
+ WorkListRemover DeadNodes(*this);
+ DAG.ReplaceAllUsesOfValueWith(N1, SetCC, &DeadNodes);
removeFromWorkList(N1.getNode());
DAG.DeleteNode(N1.getNode());
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -4648,6 +4666,56 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
}
}
}
+
+ // Transform br(xor(x, y)) -> br(x != y)
+ // Transform br(xor(xor(x,y), 1)) -> br (x == y)
+ if (N1.hasOneUse() && N1.getOpcode() == ISD::XOR) {
+ SDNode *TheXor = N1.getNode();
+ SDValue Op0 = TheXor->getOperand(0);
+ SDValue Op1 = TheXor->getOperand(1);
+ if (Op0.getOpcode() == Op1.getOpcode()) {
+ // Avoid missing important xor optimizations.
+ SDValue Tmp = visitXOR(TheXor);
+ if (Tmp.getNode()) {
+ DEBUG(dbgs() << "\nReplacing.8 ";
+ TheXor->dump(&DAG);
+ dbgs() << "\nWith: ";
+ Tmp.getNode()->dump(&DAG);
+ dbgs() << '\n');
+ WorkListRemover DeadNodes(*this);
+ DAG.ReplaceAllUsesOfValueWith(N1, Tmp, &DeadNodes);
+ removeFromWorkList(TheXor);
+ DAG.DeleteNode(TheXor);
+ return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
+ MVT::Other, Chain, Tmp, N2);
+ }
+ }
+
+ if (Op0.getOpcode() != ISD::SETCC && Op1.getOpcode() != ISD::SETCC) {
+ bool Equal = false;
+ if (ConstantSDNode *RHSCI = dyn_cast<ConstantSDNode>(Op0))
+ if (RHSCI->getAPIntValue() == 1 && Op0.hasOneUse() &&
+ Op0.getOpcode() == ISD::XOR) {
+ TheXor = Op0.getNode();
+ Equal = true;
+ }
+
+ EVT SetCCVT = N1.getValueType();
+ if (LegalTypes)
+ SetCCVT = TLI.getSetCCResultType(SetCCVT);
+ SDValue SetCC = DAG.getSetCC(TheXor->getDebugLoc(),
+ SetCCVT,
+ Op0, Op1,
+ Equal ? ISD::SETEQ : ISD::SETNE);
+ // Replace the uses of XOR with SETCC
+ WorkListRemover DeadNodes(*this);
+ DAG.ReplaceAllUsesOfValueWith(N1, SetCC, &DeadNodes);
+ removeFromWorkList(N1.getNode());
+ DAG.DeleteNode(N1.getNode());
+ return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
+ MVT::Other, Chain, SetCC, N2);
+ }
+ }
return SDValue();
}
@@ -4960,7 +5028,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
LD->getValueType(0),
Chain, Ptr, LD->getSrcValue(),
LD->getSrcValueOffset(), LD->getMemoryVT(),
- LD->isVolatile(), Align);
+ LD->isVolatile(), LD->isNonTemporal(), Align);
}
}
@@ -4997,7 +5065,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
assert(N->getValueType(2) == MVT::Other && "Malformed indexed loads?");
if (N->hasNUsesOfValue(0, 0) && N->hasNUsesOfValue(0, 1)) {
SDValue Undef = DAG.getUNDEF(N->getValueType(0));
- DEBUG(dbgs() << "\nReplacing.6 ";
+ DEBUG(dbgs() << "\nReplacing.7 ";
N->dump(&DAG);
dbgs() << "\nWith: ";
Undef.getNode()->dump(&DAG);
@@ -5042,7 +5110,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
ReplLoad = DAG.getLoad(N->getValueType(0), LD->getDebugLoc(),
BetterChain, Ptr,
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
} else {
ReplLoad = DAG.getExtLoad(LD->getExtensionType(), LD->getDebugLoc(),
LD->getValueType(0),
@@ -5050,6 +5119,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
LD->getSrcValueOffset(),
LD->getMemoryVT(),
LD->isVolatile(),
+ LD->isNonTemporal(),
LD->getAlignment());
}
@@ -5149,13 +5219,14 @@ SDValue DAGCombiner::ReduceLoadOpStoreWidth(SDNode *N) {
SDValue NewLD = DAG.getLoad(NewVT, N0.getDebugLoc(),
LD->getChain(), NewPtr,
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), NewAlign);
+ LD->isVolatile(), LD->isNonTemporal(),
+ NewAlign);
SDValue NewVal = DAG.getNode(Opc, Value.getDebugLoc(), NewVT, NewLD,
DAG.getConstant(NewImm, NewVT));
SDValue NewST = DAG.getStore(Chain, N->getDebugLoc(),
NewVal, NewPtr,
ST->getSrcValue(), ST->getSrcValueOffset(),
- false, NewAlign);
+ false, false, NewAlign);
AddToWorkList(NewPtr.getNode());
AddToWorkList(NewLD.getNode());
@@ -5184,7 +5255,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Value,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
- ST->isVolatile(), Align);
+ ST->isVolatile(), ST->isNonTemporal(), Align);
}
}
@@ -5201,7 +5272,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
TLI.isOperationLegalOrCustom(ISD::STORE, SVT)))
return DAG.getStore(Chain, N->getDebugLoc(), Value.getOperand(0),
Ptr, ST->getSrcValue(),
- ST->getSrcValueOffset(), ST->isVolatile(), OrigAlign);
+ ST->getSrcValueOffset(), ST->isVolatile(),
+ ST->isNonTemporal(), OrigAlign);
}
// Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr'
@@ -5227,7 +5299,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getStore(Chain, N->getDebugLoc(), Tmp,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
- ST->getAlignment());
+ ST->isNonTemporal(), ST->getAlignment());
}
break;
case MVT::f64:
@@ -5239,7 +5311,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getStore(Chain, N->getDebugLoc(), Tmp,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
- ST->getAlignment());
+ ST->isNonTemporal(), ST->getAlignment());
} else if (!ST->isVolatile() &&
TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) {
// Many FP stores are not made apparent until after legalize, e.g. for
@@ -5253,18 +5325,21 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
int SVOffset = ST->getSrcValueOffset();
unsigned Alignment = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
SDValue St0 = DAG.getStore(Chain, ST->getDebugLoc(), Lo,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(),
- isVolatile, ST->getAlignment());
+ isVolatile, isNonTemporal,
+ ST->getAlignment());
Ptr = DAG.getNode(ISD::ADD, N->getDebugLoc(), Ptr.getValueType(), Ptr,
DAG.getConstant(4, Ptr.getValueType()));
SVOffset += 4;
Alignment = MinAlign(Alignment, 4U);
SDValue St1 = DAG.getStore(Chain, ST->getDebugLoc(), Hi,
Ptr, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal,
+ Alignment);
return DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), MVT::Other,
St0, St1);
}
@@ -5286,12 +5361,13 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
if (ST->isTruncatingStore()) {
ReplStore = DAG.getTruncStore(BetterChain, N->getDebugLoc(), Value, Ptr,
ST->getSrcValue(),ST->getSrcValueOffset(),
- ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->getMemoryVT(), ST->isVolatile(),
+ ST->isNonTemporal(), ST->getAlignment());
} else {
ReplStore = DAG.getStore(BetterChain, N->getDebugLoc(), Value, Ptr,
ST->getSrcValue(), ST->getSrcValueOffset(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
}
// Create token to keep both nodes around.
@@ -5325,7 +5401,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Shorter,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
// Otherwise, see if we can simplify the operation with
// SimplifyDemandedBits, which only works if the value has a single use.
@@ -5358,7 +5435,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Value.getOperand(0),
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
}
return ReduceLoadOpStoreWidth(N);
@@ -5503,7 +5581,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
return DAG.getLoad(LVT, N->getDebugLoc(), LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- LN0->isVolatile(), Align);
+ LN0->isVolatile(), LN0->isNonTemporal(), Align);
}
return SDValue();
@@ -5883,6 +5961,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
LLD->getChain(),
Addr, 0, 0,
LLD->isVolatile(),
+ LLD->isNonTemporal(),
LLD->getAlignment());
} else {
Load = DAG.getExtLoad(LLD->getExtensionType(),
@@ -5891,6 +5970,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
LLD->getChain(), Addr, 0, 0,
LLD->getMemoryVT(),
LLD->isVolatile(),
+ LLD->isNonTemporal(),
LLD->getAlignment());
}
@@ -5998,7 +6078,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
CstOffset);
return DAG.getLoad(TV->getValueType(0), DL, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0, false,
- Alignment);
+ false, Alignment);
}
}
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 35ef5b7..1d76c7c 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -350,6 +350,34 @@ bool FastISel::SelectCall(User *I) {
(void)TargetSelectInstruction(cast<Instruction>(I));
return true;
}
+ case Intrinsic::dbg_value: {
+ // This requires target support, but right now X86 is the only Fast target.
+ DbgValueInst *DI = cast<DbgValueInst>(I);
+ const TargetInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
+ Value *V = DI->getValue();
+ if (!V) {
+ // Currently the optimizer can produce this; insert an undef to
+ // help debugging. Probably the optimizer should not do this.
+ BuildMI(MBB, DL, II).addReg(0U).addImm(DI->getOffset()).
+ addMetadata(DI->getVariable());
+ } else if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ BuildMI(MBB, DL, II).addImm(CI->getZExtValue()).addImm(DI->getOffset()).
+ addMetadata(DI->getVariable());
+ } else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
+ BuildMI(MBB, DL, II).addFPImm(CF).addImm(DI->getOffset()).
+ addMetadata(DI->getVariable());
+ } else if (unsigned Reg = lookUpRegForValue(V)) {
+ BuildMI(MBB, DL, II).addReg(Reg, RegState::Debug).addImm(DI->getOffset()).
+ addMetadata(DI->getVariable());
+ } else {
+ // We can't yet handle anything else here because it would require
+ // generating code, thus altering codegen because of debug info.
+ // Insert an undef so we can see what we dropped.
+ BuildMI(MBB, DL, II).addReg(0U).addImm(DI->getOffset()).
+ addMetadata(DI->getVariable());
+ }
+ return true;
+ }
case Intrinsic::eh_exception: {
EVT VT = TLI.getValueType(I->getType());
switch (TLI.getOperationAction(ISD::EXCEPTIONADDR, VT)) {
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 02fe85d..625de11 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -15,6 +15,7 @@
#define DEBUG_TYPE "instr-emitter"
#include "InstrEmitter.h"
+#include "SDDbgValue.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -497,6 +498,56 @@ InstrEmitter::EmitCopyToRegClassNode(SDNode *Node,
assert(isNew && "Node emitted out of order - early");
}
+/// EmitDbgValue - Generate any debug info that refers to this Node. Constant
+/// dbg_value is not handled here.
+void
+InstrEmitter::EmitDbgValue(SDNode *Node,
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ SDDbgValue *sd) {
+ if (!Node->getHasDebugValue())
+ return;
+ if (!sd)
+ return;
+ unsigned VReg = getVR(SDValue(sd->getSDNode(), sd->getResNo()), VRBaseMap);
+ const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
+ DebugLoc DL = sd->getDebugLoc();
+ MachineInstr *MI;
+ if (VReg) {
+ MI = BuildMI(*MF, DL, II).addReg(VReg, RegState::Debug).
+ addImm(sd->getOffset()).
+ addMetadata(sd->getMDPtr());
+ } else {
+ // Insert an Undef so we can see what we dropped.
+ MI = BuildMI(*MF, DL, II).addReg(0U).addImm(sd->getOffset()).
+ addMetadata(sd->getMDPtr());
+ }
+ MBB->insert(InsertPos, MI);
+}
+
+/// EmitDbgValue - Generate constant debug info. No SDNode is involved.
+void
+InstrEmitter::EmitDbgValue(SDDbgValue *sd) {
+ if (!sd)
+ return;
+ const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
+ DebugLoc DL = sd->getDebugLoc();
+ MachineInstr *MI;
+ Value *V = sd->getConst();
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()).
+ addImm(sd->getOffset()).
+ addMetadata(sd->getMDPtr());
+ } else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
+ MI = BuildMI(*MF, DL, II).addFPImm(CF).addImm(sd->getOffset()).
+ addMetadata(sd->getMDPtr());
+ } else {
+ // Insert an Undef so we can see what we dropped.
+ MI = BuildMI(*MF, DL, II).addReg(0U).addImm(sd->getOffset()).
+ addMetadata(sd->getMDPtr());
+ }
+ MBB->insert(InsertPos, MI);
+}
+
/// EmitNode - Generate machine code for a node and needed dependencies.
///
void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.h b/lib/CodeGen/SelectionDAG/InstrEmitter.h
index 91817e4..4fe9f19 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.h
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.h
@@ -23,6 +23,7 @@
namespace llvm {
class TargetInstrDesc;
+class SDDbgValue;
class InstrEmitter {
MachineFunction *MF;
@@ -97,6 +98,16 @@ public:
/// MachineInstr.
static unsigned CountOperands(SDNode *Node);
+ /// EmitDbgValue - Generate any debug info that refers to this Node. Constant
+ /// dbg_value is not handled here.
+ void EmitDbgValue(SDNode *Node,
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ SDDbgValue* sd);
+
+
+ /// EmitDbgValue - Generate a constant DBG_VALUE. No node is involved.
+ void EmitDbgValue(SDDbgValue* sd);
+
/// EmitNode - Generate machine code for a node and needed dependencies.
///
void EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 78e6e4e..f498263 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -377,9 +377,10 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
return DAG.getExtLoad(ISD::EXTLOAD, dl,
OrigVT, DAG.getEntryNode(),
CPIdx, PseudoSourceValue::getConstantPool(),
- 0, VT, false, Alignment);
+ 0, VT, false, false, Alignment);
return DAG.getLoad(OrigVT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0, false, Alignment);
+ PseudoSourceValue::getConstantPool(), 0, false, false,
+ Alignment);
}
/// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores.
@@ -402,7 +403,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// FIXME: Does not handle truncating floating point stores!
SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, intVT, Val);
return DAG.getStore(Chain, dl, Result, Ptr, ST->getSrcValue(),
- SVOffset, ST->isVolatile(), Alignment);
+ SVOffset, ST->isVolatile(), ST->isNonTemporal(),
+ Alignment);
} else {
// Do a (aligned) store to a stack slot, then copy from the stack slot
// to the final destination using (unaligned) integer loads and stores.
@@ -418,7 +420,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Perform the original store, only redirected to the stack slot.
SDValue Store = DAG.getTruncStore(Chain, dl,
- Val, StackPtr, NULL, 0, StoredVT);
+ Val, StackPtr, NULL, 0, StoredVT,
+ false, false, 0);
SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy());
SmallVector<SDValue, 8> Stores;
unsigned Offset = 0;
@@ -426,11 +429,12 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Do all but one copies using the full register width.
for (unsigned i = 1; i < NumRegs; i++) {
// Load one integer register's worth from the stack slot.
- SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0);
+ SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
// Store it to the final location. Remember the store.
Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr,
ST->getSrcValue(), SVOffset + Offset,
- ST->isVolatile(),
+ ST->isVolatile(), ST->isNonTemporal(),
MinAlign(ST->getAlignment(), Offset)));
// Increment the pointers.
Offset += RegBytes;
@@ -446,11 +450,12 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Load from the stack slot.
SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr,
- NULL, 0, MemVT);
+ NULL, 0, MemVT, false, false, 0);
Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr,
ST->getSrcValue(), SVOffset + Offset,
MemVT, ST->isVolatile(),
+ ST->isNonTemporal(),
MinAlign(ST->getAlignment(), Offset)));
// The order of the stores doesn't matter - say it with a TokenFactor.
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
@@ -474,13 +479,14 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
SDValue Store1, Store2;
Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr,
ST->getSrcValue(), SVOffset, NewStoredVT,
- ST->isVolatile(), Alignment);
+ ST->isVolatile(), ST->isNonTemporal(), Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Alignment = MinAlign(Alignment, IncrementSize);
Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr,
ST->getSrcValue(), SVOffset + IncrementSize,
- NewStoredVT, ST->isVolatile(), Alignment);
+ NewStoredVT, ST->isVolatile(), ST->isNonTemporal(),
+ Alignment);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
}
@@ -502,7 +508,7 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
// then bitconvert to floating point or vector.
SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset, LD->isVolatile(),
- LD->getAlignment());
+ LD->isNonTemporal(), LD->getAlignment());
SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, LoadedVT, newLoad);
if (VT.isFloatingPoint() && LoadedVT != VT)
Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result);
@@ -530,10 +536,11 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
// Load one integer register's worth from the original location.
SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset + Offset, LD->isVolatile(),
+ LD->isNonTemporal(),
MinAlign(LD->getAlignment(), Offset));
// Follow the load with a store to the stack slot. Remember the store.
Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr,
- NULL, 0));
+ NULL, 0, false, false, 0));
// Increment the pointers.
Offset += RegBytes;
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment);
@@ -546,12 +553,13 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr,
LD->getSrcValue(), SVOffset + Offset,
MemVT, LD->isVolatile(),
+ LD->isNonTemporal(),
MinAlign(LD->getAlignment(), Offset));
// Follow the load with a store to the stack slot. Remember the store.
// On big-endian machines this requires a truncating store to ensure
// that the bits end up in the right place.
Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr,
- NULL, 0, MemVT));
+ NULL, 0, MemVT, false, false, 0));
// The order of the stores doesn't matter - say it with a TokenFactor.
SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
@@ -559,7 +567,7 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
// Finally, perform the original load only redirected to the stack slot.
Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase,
- NULL, 0, LoadedVT);
+ NULL, 0, LoadedVT, false, false, 0);
// Callers expect a MERGE_VALUES node.
SDValue Ops[] = { Load, TF };
@@ -588,20 +596,22 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
SDValue Lo, Hi;
if (TLI.isLittleEndian()) {
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(),
- SVOffset, NewLoadedVT, LD->isVolatile(), Alignment);
+ SVOffset, NewLoadedVT, LD->isVolatile(),
+ LD->isNonTemporal(), Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
- MinAlign(Alignment, IncrementSize));
+ LD->isNonTemporal(), MinAlign(Alignment, IncrementSize));
} else {
Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(),
- SVOffset, NewLoadedVT, LD->isVolatile(), Alignment);
+ SVOffset, NewLoadedVT, LD->isVolatile(),
+ LD->isNonTemporal(), Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
- MinAlign(Alignment, IncrementSize));
+ LD->isNonTemporal(), MinAlign(Alignment, IncrementSize));
}
// aggregate the two parts
@@ -643,7 +653,8 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx,
// Store the vector.
SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0);
+ PseudoSourceValue::getFixedStack(SPFI), 0,
+ false, false, 0);
// Truncate or zero extend offset to target pointer type.
unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
@@ -654,10 +665,12 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx,
SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr);
// Store the scalar value.
Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2,
- PseudoSourceValue::getFixedStack(SPFI), 0, EltVT);
+ PseudoSourceValue::getFixedStack(SPFI), 0, EltVT,
+ false, false, 0);
// Load the updated vector.
return DAG.getLoad(VT, dl, Ch, StackPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0);
+ PseudoSourceValue::getFixedStack(SPFI), 0,
+ false, false, 0);
}
@@ -702,6 +715,7 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
int SVOffset = ST->getSrcValueOffset();
unsigned Alignment = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
DebugLoc dl = ST->getDebugLoc();
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) {
if (CFP->getValueType(0) == MVT::f32 &&
@@ -710,14 +724,14 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
bitcastToAPInt().zextOrTrunc(32),
MVT::i32);
return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal, Alignment);
} else if (CFP->getValueType(0) == MVT::f64) {
// If this target supports 64-bit registers, do a single 64-bit store.
if (getTypeAction(MVT::i64) == Legal) {
Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt().
zextOrTrunc(64), MVT::i64);
return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal, Alignment);
} else if (getTypeAction(MVT::i32) == Legal && !ST->isVolatile()) {
// Otherwise, if the target supports 32-bit registers, use 2 32-bit
// stores. If the target supports neither 32- nor 64-bits, this
@@ -728,11 +742,11 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
if (TLI.isBigEndian()) std::swap(Lo, Hi);
Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal, Alignment);
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(4));
Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
- isVolatile, MinAlign(Alignment, 4U));
+ isVolatile, isNonTemporal, MinAlign(Alignment, 4U));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
@@ -1108,7 +1122,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, dl, VT, Tmp1));
Tmp4 = LegalizeOp(Tmp1.getValue(1));
break;
@@ -1125,6 +1140,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
int SVOffset = LD->getSrcValueOffset();
unsigned Alignment = LD->getAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
if (SrcWidth != SrcVT.getStoreSizeInBits() &&
// Some targets pretend to have an i1 loading operation, and actually
@@ -1150,7 +1166,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0),
Tmp1, Tmp2, LD->getSrcValue(), SVOffset,
- NVT, isVolatile, Alignment);
+ NVT, isVolatile, isNonTemporal, Alignment);
Ch = Result.getValue(1); // The chain.
@@ -1187,7 +1203,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl,
Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
- Alignment);
+ isNonTemporal, Alignment);
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1195,7 +1211,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset + IncrementSize,
- ExtraVT, isVolatile,
+ ExtraVT, isVolatile, isNonTemporal,
MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
@@ -1215,7 +1231,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Load the top RoundWidth bits.
Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
- Alignment);
+ isNonTemporal, Alignment);
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1224,7 +1240,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl,
Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset + IncrementSize,
- ExtraVT, isVolatile,
+ ExtraVT, isVolatile, isNonTemporal,
MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
@@ -1284,7 +1300,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
(SrcVT == MVT::f64 && Node->getValueType(0) == MVT::f128)) {
SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
Result = DAG.getNode(ISD::FP_EXTEND, dl,
Node->getValueType(0), Load);
Tmp1 = LegalizeOp(Result); // Relegalize new nodes.
@@ -1297,7 +1314,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0),
Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(), SrcVT,
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
SDValue ValRes;
if (ExtType == ISD::SEXTLOAD)
ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl,
@@ -1325,6 +1343,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
int SVOffset = ST->getSrcValueOffset();
unsigned Alignment = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
if (!ST->isTruncatingStore()) {
if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) {
@@ -1361,7 +1380,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3);
Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2,
ST->getSrcValue(), SVOffset, isVolatile,
- Alignment);
+ isNonTemporal, Alignment);
break;
}
break;
@@ -1379,7 +1398,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
EVT NVT = EVT::getIntegerVT(*DAG.getContext(), StVT.getStoreSizeInBits());
Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT);
Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, NVT, isVolatile, Alignment);
+ SVOffset, NVT, isVolatile, isNonTemporal,
+ Alignment);
} else if (StWidth & (StWidth - 1)) {
// If not storing a power-of-2 number of bits, expand as two stores.
assert(!StVT.isVector() && "Unsupported truncstore!");
@@ -1399,7 +1419,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Store the bottom RoundWidth bits.
Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, RoundVT,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
// Store the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1409,6 +1429,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
DAG.getConstant(RoundWidth, TLI.getShiftAmountTy()));
Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(),
SVOffset + IncrementSize, ExtraVT, isVolatile,
+ isNonTemporal,
MinAlign(Alignment, IncrementSize));
} else {
// Big endian - avoid unaligned stores.
@@ -1417,7 +1438,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3,
DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy()));
Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(),
- SVOffset, RoundVT, isVolatile, Alignment);
+ SVOffset, RoundVT, isVolatile, isNonTemporal,
+ Alignment);
// Store the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1425,6 +1447,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
DAG.getIntPtrConstant(IncrementSize));
Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset + IncrementSize, ExtraVT, isVolatile,
+ isNonTemporal,
MinAlign(Alignment, IncrementSize));
}
@@ -1457,7 +1480,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
assert(isTypeLegal(StVT) && "Do not know how to expand this store!");
Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3);
Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal,
+ Alignment);
break;
}
}
@@ -1484,7 +1508,8 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
DebugLoc dl = Op.getDebugLoc();
// Store the value to a temporary stack slot, then LOAD the returned part.
SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType());
- SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0);
+ SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0,
+ false, false, 0);
// Add the offset to the index.
unsigned EltSize =
@@ -1500,10 +1525,12 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr);
if (Op.getValueType().isVector())
- return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0);
+ return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0,
+ false, false, 0);
else
return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr,
- NULL, 0, Vec.getValueType().getVectorElementType());
+ NULL, 0, Vec.getValueType().getVectorElementType(),
+ false, false, 0);
}
SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
@@ -1512,7 +1539,6 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
// the result as a vector.
// Create the stack frame object.
EVT VT = Node->getValueType(0);
- EVT OpVT = Node->getOperand(0).getValueType();
EVT EltVT = VT.getVectorElementType();
DebugLoc dl = Node->getDebugLoc();
SDValue FIPtr = DAG.CreateStackTemporary(VT);
@@ -1532,13 +1558,16 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
SDValue Idx = DAG.getConstant(Offset, FIPtr.getValueType());
Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx);
- // If EltVT smaller than OpVT, only store the bits necessary.
- if (!OpVT.isVector() && EltVT.bitsLT(OpVT)) {
+ // If the destination vector element type is narrower than the source
+ // element type, only store the bits necessary.
+ if (EltVT.bitsLT(Node->getOperand(i).getValueType().getScalarType())) {
Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl,
- Node->getOperand(i), Idx, SV, Offset, EltVT));
+ Node->getOperand(i), Idx, SV, Offset,
+ EltVT, false, false, 0));
} else
Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl,
- Node->getOperand(i), Idx, SV, Offset));
+ Node->getOperand(i), Idx, SV, Offset,
+ false, false, 0));
}
SDValue StoreChain;
@@ -1549,7 +1578,7 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
StoreChain = DAG.getEntryNode();
// Result is a load from the stack slot.
- return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0);
+ return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0, false, false, 0);
}
SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) {
@@ -1572,12 +1601,14 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) {
SDValue StackPtr = DAG.CreateStackTemporary(Tmp2.getValueType());
SDValue StorePtr = StackPtr, LoadPtr = StackPtr;
SDValue Ch =
- DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StorePtr, NULL, 0);
+ DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StorePtr, NULL, 0,
+ false, false, 0);
if (Tmp2.getValueType() == MVT::f64 && TLI.isLittleEndian())
LoadPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(),
LoadPtr, DAG.getIntPtrConstant(4));
SignBit = DAG.getExtLoad(ISD::SEXTLOAD, dl, TLI.getPointerTy(),
- Ch, LoadPtr, NULL, 0, MVT::i32);
+ Ch, LoadPtr, NULL, 0, MVT::i32,
+ false, false, 0);
}
SignBit =
DAG.getSetCC(dl, TLI.getSetCCResultType(SignBit.getValueType()),
@@ -1701,20 +1732,21 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
if (SrcSize > SlotSize)
Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr,
- SV, 0, SlotVT, false, SrcAlign);
+ SV, 0, SlotVT, false, false, SrcAlign);
else {
assert(SrcSize == SlotSize && "Invalid store");
Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr,
- SV, 0, false, SrcAlign);
+ SV, 0, false, false, SrcAlign);
}
// Result is a load from the stack slot.
if (SlotSize == DestSize)
- return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, DestAlign);
+ return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, false,
+ DestAlign);
assert(SlotSize < DestSize && "Unknown extension!");
return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, SV, 0, SlotVT,
- false, DestAlign);
+ false, false, DestAlign);
}
SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
@@ -1729,9 +1761,11 @@ SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), dl, Node->getOperand(0),
StackPtr,
PseudoSourceValue::getFixedStack(SPFI), 0,
- Node->getValueType(0).getVectorElementType());
+ Node->getValueType(0).getVectorElementType(),
+ false, false, 0);
return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0);
+ PseudoSourceValue::getFixedStack(SPFI), 0,
+ false, false, 0);
}
@@ -1805,7 +1839,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
- false, Alignment);
+ false, false, Alignment);
}
if (!MoreThanTwoValues) {
@@ -1865,8 +1899,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
0, TLI.getLibcallCallingConv(LC), false,
/*isReturnValueUsed=*/true,
- Callee, Args, DAG,
- Node->getDebugLoc(), DAG.GetOrdering(Node));
+ Callee, Args, DAG, Node->getDebugLoc());
// Legalize the call sequence, starting with the chain. This will advance
// the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
@@ -1943,13 +1976,16 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
}
// store the lo of the constructed double - based on integer input
SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl,
- Op0Mapped, Lo, NULL, 0);
+ Op0Mapped, Lo, NULL, 0,
+ false, false, 0);
// initial hi portion of constructed double
SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32);
// store the hi of the constructed double - biased exponent
- SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0);
+ SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0,
+ false, false, 0);
// load the constructed double
- SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0);
+ SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0,
+ false, false, 0);
// FP constant to bias correct the final result
SDValue Bias = DAG.getConstantFP(isSigned ?
BitsToDouble(0x4330000080000000ULL) :
@@ -1972,6 +2008,31 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
return Result;
}
assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
+
+ // Implementation of unsigned i64 to f64 following the algorithm in
+ // __floatundidf in compiler_rt. This implementation has the advantage
+ // of performing rounding correctly, both in the default rounding mode
+ // and in all alternate rounding modes.
+ // TODO: Generalize this for use with other types.
+ if (Op0.getValueType() == MVT::i64 && DestVT == MVT::f64) {
+ SDValue TwoP52 =
+ DAG.getConstant(UINT64_C(0x4330000000000000), MVT::i64);
+ SDValue TwoP84PlusTwoP52 =
+ DAG.getConstantFP(BitsToDouble(UINT64_C(0x4530000000100000)), MVT::f64);
+ SDValue TwoP84 =
+ DAG.getConstant(UINT64_C(0x4530000000000000), MVT::i64);
+
+ SDValue Lo = DAG.getZeroExtendInReg(Op0, dl, MVT::i32);
+ SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0,
+ DAG.getConstant(32, MVT::i64));
+ SDValue LoOr = DAG.getNode(ISD::OR, dl, MVT::i64, Lo, TwoP52);
+ SDValue HiOr = DAG.getNode(ISD::OR, dl, MVT::i64, Hi, TwoP84);
+ SDValue LoFlt = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, LoOr);
+ SDValue HiFlt = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, HiOr);
+ SDValue HiSub = DAG.getNode(ISD::FSUB, dl, MVT::f64, HiFlt, TwoP84PlusTwoP52);
+ return DAG.getNode(ISD::FADD, dl, MVT::f64, LoFlt, HiSub);
+ }
+
SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, dl, DestVT, Op0);
SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Op0.getValueType()),
@@ -2004,13 +2065,13 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
if (DestVT == MVT::f32)
FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
- false, Alignment);
+ false, false, Alignment);
else {
FudgeInReg =
LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT,
DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
- MVT::f32, false, Alignment));
+ MVT::f32, false, false, Alignment));
}
return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg);
@@ -2271,7 +2332,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
false, false, false, false, 0, CallingConv::C, false,
/*isReturnValueUsed=*/true,
DAG.getExternalSymbol("abort", TLI.getPointerTy()),
- Args, DAG, dl, DAG.GetOrdering(Node));
+ Args, DAG, dl);
Results.push_back(CallResult.second);
break;
}
@@ -2350,16 +2411,19 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
EVT VT = Node->getValueType(0);
Tmp1 = Node->getOperand(0);
Tmp2 = Node->getOperand(1);
- SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0);
+ SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0,
+ false, false, 0);
// Increment the pointer, VAList, to the next vaarg
Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList,
DAG.getConstant(TLI.getTargetData()->
getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())),
TLI.getPointerTy()));
// Store the incremented VAList to the legalized pointer
- Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0);
+ Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0,
+ false, false, 0);
// Load the actual argument out of the pointer VAList
- Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0));
+ Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0,
+ false, false, 0));
Results.push_back(Results[0].getValue(1));
break;
}
@@ -2369,8 +2433,9 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue();
const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue();
Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0),
- Node->getOperand(2), VS, 0);
- Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0);
+ Node->getOperand(2), VS, 0, false, false, 0);
+ Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0,
+ false, false, 0);
Results.push_back(Tmp1);
break;
}
@@ -2827,7 +2892,8 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8);
SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0, MemVT);
+ PseudoSourceValue::getJumpTable(), 0, MemVT,
+ false, false, 0);
Addr = LD;
if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) {
// For PIC, the sequence is:
diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 4f0fce7..35a7c7c 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -444,7 +444,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(),
NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
L->getSrcValue(), L->getSrcValueOffset(), NVT,
- L->isVolatile(), L->getAlignment());
+ L->isVolatile(), L->isNonTemporal(), L->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
@@ -456,8 +456,8 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
L->getMemoryVT(), L->getChain(),
L->getBasePtr(), L->getOffset(),
L->getSrcValue(), L->getSrcValueOffset(),
- L->getMemoryVT(),
- L->isVolatile(), L->getAlignment());
+ L->getMemoryVT(), L->isVolatile(),
+ L->isNonTemporal(), L->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
@@ -755,7 +755,8 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(),
ST->getSrcValue(), ST->getSrcValueOffset(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
}
@@ -1073,8 +1074,8 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr,
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->getMemoryVT(),
- LD->isVolatile(), LD->getAlignment());
+ LD->getMemoryVT(), LD->isVolatile(),
+ LD->isNonTemporal(), LD->getAlignment());
// Remember the chain.
Chain = Hi.getValue(1);
@@ -1382,6 +1383,6 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr,
ST->getSrcValue(), ST->getSrcValueOffset(),
- ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->getMemoryVT(), ST->isVolatile(),
+ ST->isNonTemporal(), ST->getAlignment());
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 9932cf4..81f28ad 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -359,7 +359,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT(), N->isVolatile(),
- N->getAlignment());
+ N->isNonTemporal(), N->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
@@ -873,6 +873,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ bool isNonTemporal = N->isNonTemporal();
DebugLoc dl = N->getDebugLoc();
SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value.
@@ -880,7 +881,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
// Truncate the value and store the result.
return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getSrcValue(),
SVOffset, N->getMemoryVT(),
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
}
SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
@@ -1079,8 +1080,8 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
SDValue Amt = N->getOperand(1);
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
EVT ShTy = Amt.getValueType();
- unsigned ShBits = ShTy.getSizeInBits();
- unsigned NVTBits = NVT.getSizeInBits();
+ unsigned ShBits = ShTy.getScalarType().getSizeInBits();
+ unsigned NVTBits = NVT.getScalarType().getSizeInBits();
assert(isPowerOf2_32(NVTBits) &&
"Expanded integer type size not a power of two!");
DebugLoc dl = N->getDebugLoc();
@@ -1500,6 +1501,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ bool isNonTemporal = N->isNonTemporal();
DebugLoc dl = N->getDebugLoc();
assert(NVT.isByteSized() && "Expanded type not byte sized!");
@@ -1508,7 +1510,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
EVT MemVT = N->getMemoryVT();
Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
- MemVT, isVolatile, Alignment);
+ MemVT, isVolatile, isNonTemporal, Alignment);
// Remember the chain.
Ch = Lo.getValue(1);
@@ -1530,7 +1532,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
unsigned ExcessBits =
N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
@@ -1542,7 +1544,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(),
SVOffset+IncrementSize, NEVT,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
@@ -1560,7 +1563,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
EVT::getIntegerVT(*DAG.getContext(),
MemVT.getSizeInBits() - ExcessBits),
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
// Increment the pointer to the other half.
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
@@ -1569,7 +1572,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, N->getSrcValue(),
SVOffset+IncrementSize,
EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
@@ -2212,6 +2216,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ bool isNonTemporal = N->isNonTemporal();
DebugLoc dl = N->getDebugLoc();
SDValue Lo, Hi;
@@ -2220,13 +2225,14 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
if (N->getMemoryVT().bitsLE(NVT)) {
GetExpandedInteger(N->getValue(), Lo, Hi);
return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- N->getMemoryVT(), isVolatile, Alignment);
+ N->getMemoryVT(), isVolatile, isNonTemporal,
+ Alignment);
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
GetExpandedInteger(N->getValue(), Lo, Hi);
Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
unsigned ExcessBits =
N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
@@ -2238,7 +2244,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
SVOffset+IncrementSize, NEVT,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
} else {
// Big-endian - high bits are at low addresses. Favor aligned stores at
@@ -2264,7 +2271,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
// Store both the high bits and maybe some of the low bits.
Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
- SVOffset, HiVT, isVolatile, Alignment);
+ SVOffset, HiVT, isVolatile, isNonTemporal,
+ Alignment);
// Increment the pointer to the other half.
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
@@ -2273,7 +2281,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(),
SVOffset+IncrementSize,
EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
}
@@ -2341,7 +2350,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
// FIXME: Avoid the extend by constructing the right constant pool?
SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(),
FudgePtr, NULL, 0, MVT::f32,
- false, Alignment);
+ false, false, Alignment);
return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge);
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index 37f36a3..f3e7ca4 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -871,9 +871,10 @@ SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op,
// the source and destination types.
SDValue StackPtr = DAG.CreateStackTemporary(Op.getValueType(), DestVT);
// Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0,
+ false, false, 0);
// Result is a load from the stack slot.
- return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0);
+ return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0, false, false, 0);
}
/// CustomLowerNode - Replace the node's results with custom code provided
@@ -1033,8 +1034,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, EVT RetVT,
TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
false, 0, TLI.getLibcallCallingConv(LC), false,
/*isReturnValueUsed=*/true,
- Callee, Args, DAG, dl,
- DAG.GetOrdering(DAG.getEntryNode().getNode()));
+ Callee, Args, DAG, dl);
return CallInfo.first;
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index a1b6ced..5e83b4b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -122,10 +122,11 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
// Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0,
+ false, false, 0);
// Load the first half from the stack slot.
- Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0);
+ Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0, false, false, 0);
// Increment the pointer to the other half.
unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
@@ -134,7 +135,7 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
// Load the second half from the stack slot.
Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, IncrementSize, false,
- MinAlign(Alignment, IncrementSize));
+ false, MinAlign(Alignment, IncrementSize));
// Handle endianness of the load.
if (TLI.isBigEndian())
@@ -205,11 +206,12 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
int SVOffset = LD->getSrcValueOffset();
unsigned Alignment = LD->getAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
assert(NVT.isByteSized() && "Expanded type not byte sized!");
Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits() / 8;
@@ -217,7 +219,8 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset+IncrementSize,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
@@ -383,6 +386,7 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
int SVOffset = St->getSrcValueOffset();
unsigned Alignment = St->getAlignment();
bool isVolatile = St->isVolatile();
+ bool isNonTemporal = St->isNonTemporal();
assert(NVT.isByteSized() && "Expanded type not byte sized!");
unsigned IncrementSize = NVT.getSizeInBits() / 8;
@@ -394,14 +398,15 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
std::swap(Lo, Hi);
Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
Hi = DAG.getStore(Chain, dl, Hi, Ptr, St->getSrcValue(),
SVOffset + IncrementSize,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index bf95bb5..8363c3a 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -172,7 +172,8 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
DAG.getUNDEF(N->getBasePtr().getValueType()),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT().getVectorElementType(),
- N->isVolatile(), N->getOriginalAlignment());
+ N->isVolatile(), N->isNonTemporal(),
+ N->getOriginalAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
@@ -366,11 +367,13 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
N->getBasePtr(),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT().getVectorElementType(),
- N->isVolatile(), N->getAlignment());
+ N->isVolatile(), N->isNonTemporal(),
+ N->getAlignment());
return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
- N->isVolatile(), N->getOriginalAlignment());
+ N->isVolatile(), N->isNonTemporal(),
+ N->getOriginalAlignment());
}
@@ -696,17 +699,20 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
EVT VecVT = Vec.getValueType();
EVT EltVT = VecVT.getVectorElementType();
SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0,
+ false, false, 0);
// Store the new element. This may be larger than the vector element type,
// so use a truncating store.
SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
unsigned Alignment =
TLI.getTargetData()->getPrefTypeAlignment(VecVT.getTypeForEVT(*DAG.getContext()));
- Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT);
+ Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT,
+ false, false, 0);
// Load the Lo part from the stack slot.
- Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0);
+ Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
// Increment the pointer to the other part.
unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8;
@@ -715,7 +721,7 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
// Load the Hi part from the stack slot.
Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, NULL, 0, false,
- MinAlign(Alignment, IncrementSize));
+ false, MinAlign(Alignment, IncrementSize));
}
void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo,
@@ -743,19 +749,20 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
EVT MemoryVT = LD->getMemoryVT();
unsigned Alignment = LD->getOriginalAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
EVT LoMemVT, HiMemVT;
GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT);
Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, LoVT, Ch, Ptr, Offset,
- SV, SVOffset, LoMemVT, isVolatile, Alignment);
+ SV, SVOffset, LoMemVT, isVolatile, isNonTemporal, Alignment);
unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, HiVT, Ch, Ptr, Offset,
- SV, SVOffset, HiMemVT, isVolatile, Alignment);
+ SV, SVOffset, HiMemVT, isVolatile, isNonTemporal, Alignment);
// Build a factor node to remember that this load is independent of the
// other one.
@@ -1086,12 +1093,13 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0,
+ false, false, 0);
// Load back the required element.
StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
return DAG.getExtLoad(ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr,
- SV, 0, EltVT);
+ SV, 0, EltVT, false, false, 0);
}
SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
@@ -1106,6 +1114,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
EVT MemoryVT = N->getMemoryVT();
unsigned Alignment = N->getOriginalAlignment();
bool isVol = N->isVolatile();
+ bool isNT = N->isNonTemporal();
SDValue Lo, Hi;
GetSplitVector(N->getOperand(1), Lo, Hi);
@@ -1116,10 +1125,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
if (isTruncating)
Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- LoMemVT, isVol, Alignment);
+ LoMemVT, isVol, isNT, Alignment);
else
Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- isVol, Alignment);
+ isVol, isNT, Alignment);
// Increment the pointer to the other half.
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
@@ -1128,10 +1137,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
if (isTruncating)
Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset,
- HiMemVT, isVol, Alignment);
+ HiMemVT, isVol, isNT, Alignment);
else
Hi = DAG.getStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset,
- isVol, Alignment);
+ isVol, isNT, Alignment);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
@@ -1242,10 +1251,96 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
// Binary op widening.
+ unsigned Opcode = N->getOpcode();
+ DebugLoc dl = N->getDebugLoc();
EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
- SDValue InOp1 = GetWidenedVector(N->getOperand(0));
- SDValue InOp2 = GetWidenedVector(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp1, InOp2);
+ EVT WidenEltVT = WidenVT.getVectorElementType();
+ EVT VT = WidenVT;
+ unsigned NumElts = VT.getVectorNumElements();
+ while (!TLI.isTypeLegal(VT) && NumElts != 1) {
+ NumElts = NumElts / 2;
+ VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
+ }
+
+ if (NumElts != 1 && !TLI.canOpTrap(N->getOpcode(), VT)) {
+ // Operation doesn't trap so just widen as normal.
+ SDValue InOp1 = GetWidenedVector(N->getOperand(0));
+ SDValue InOp2 = GetWidenedVector(N->getOperand(1));
+ return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2);
+ } else if (NumElts == 1) {
+ // No legal vector version so unroll the vector operation and then widen.
+ return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
+ } else {
+ // Since the operation can trap, apply operation on the original vector.
+ SDValue InOp1 = GetWidenedVector(N->getOperand(0));
+ SDValue InOp2 = GetWidenedVector(N->getOperand(1));
+ unsigned CurNumElts = N->getValueType(0).getVectorNumElements();
+
+ SmallVector<SDValue, 16> ConcatOps(CurNumElts);
+ unsigned ConcatEnd = 0; // Current ConcatOps index.
+ unsigned Idx = 0; // Current Idx into input vectors.
+ while (CurNumElts != 0) {
+ while (CurNumElts >= NumElts) {
+ SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1,
+ DAG.getIntPtrConstant(Idx));
+ SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp2,
+ DAG.getIntPtrConstant(Idx));
+ ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2);
+ Idx += NumElts;
+ CurNumElts -= NumElts;
+ }
+ EVT PrevVecVT = VT;
+ do {
+ NumElts = NumElts / 2;
+ VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
+ } while (!TLI.isTypeLegal(VT) && NumElts != 1);
+
+ if (NumElts == 1) {
+ // Since we are using concat vector, build a vector from the scalar ops.
+ SDValue VecOp = DAG.getUNDEF(PrevVecVT);
+ for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
+ SDValue EOp1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
+ InOp1, DAG.getIntPtrConstant(Idx));
+ SDValue EOp2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
+ InOp2, DAG.getIntPtrConstant(Idx));
+ VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, PrevVecVT, VecOp,
+ DAG.getNode(Opcode, dl, WidenEltVT, EOp1, EOp2),
+ DAG.getIntPtrConstant(i));
+ }
+ CurNumElts = 0;
+ ConcatOps[ConcatEnd++] = VecOp;
+ }
+ }
+
+ // Check to see if we have a single operation with the widen type.
+ if (ConcatEnd == 1) {
+ VT = ConcatOps[0].getValueType();
+ if (VT == WidenVT)
+ return ConcatOps[0];
+ }
+
+ // Rebuild vector to one with the widen type
+ Idx = ConcatEnd - 1;
+ while (Idx != 0) {
+ VT = ConcatOps[Idx--].getValueType();
+ while (Idx != 0 && ConcatOps[Idx].getValueType() == VT)
+ --Idx;
+ if (Idx != 0) {
+ VT = ConcatOps[Idx].getValueType();
+ ConcatOps[Idx+1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
+ &ConcatOps[Idx+1], ConcatEnd - Idx - 1);
+ ConcatEnd = Idx + 2;
+ }
+ }
+
+ unsigned NumOps = WidenVT.getVectorNumElements()/VT.getVectorNumElements();
+ if (NumOps != ConcatEnd ) {
+ SDValue UndefVal = DAG.getUNDEF(VT);
+ for (unsigned j = ConcatEnd; j < NumOps; ++j)
+ ConcatOps[j] = UndefVal;
+ }
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &ConcatOps[0], NumOps);
+ }
}
SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
@@ -2042,6 +2137,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
int SVOffset = LD->getSrcValueOffset();
unsigned Align = LD->getAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
const Value *SV = LD->getSrcValue();
int LdWidth = LdVT.getSizeInBits();
@@ -2052,7 +2148,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
EVT NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff);
int NewVTWidth = NewVT.getSizeInBits();
SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, SV, SVOffset,
- isVolatile, Align);
+ isVolatile, isNonTemporal, Align);
LdChain.push_back(LdOp.getValue(1));
// Check if we can load the element with one instruction
@@ -2099,7 +2195,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, SV,
SVOffset+Offset, isVolatile,
- MinAlign(Align, Increment));
+ isNonTemporal, MinAlign(Align, Increment));
LdChain.push_back(LdOp.getValue(1));
LdOps.push_back(LdOp);
@@ -2173,6 +2269,7 @@ DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVector<SDValue, 16>& LdChain,
int SVOffset = LD->getSrcValueOffset();
unsigned Align = LD->getAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
const Value *SV = LD->getSrcValue();
EVT EltVT = WidenVT.getVectorElementType();
@@ -2184,14 +2281,15 @@ DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVector<SDValue, 16>& LdChain,
SmallVector<SDValue, 16> Ops(WidenNumElts);
unsigned Increment = LdEltVT.getSizeInBits() / 8;
Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset,
- LdEltVT, isVolatile, Align);
+ LdEltVT, isVolatile, isNonTemporal, Align);
LdChain.push_back(Ops[0].getValue(1));
unsigned i = 0, Offset = Increment;
for (i=1; i < NumElts; ++i, Offset += Increment) {
SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
BasePtr, DAG.getIntPtrConstant(Offset));
Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV,
- SVOffset + Offset, LdEltVT, isVolatile, Align);
+ SVOffset + Offset, LdEltVT, isVolatile,
+ isNonTemporal, Align);
LdChain.push_back(Ops[i].getValue(1));
}
@@ -2215,6 +2313,7 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
int SVOffset = ST->getSrcValueOffset();
unsigned Align = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
SDValue ValOp = GetWidenedVector(ST->getValue());
DebugLoc dl = ST->getDebugLoc();
@@ -2240,6 +2339,7 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
DAG.getIntPtrConstant(Idx));
StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
SVOffset + Offset, isVolatile,
+ isNonTemporal,
MinAlign(Align, Offset)));
StWidth -= NewVTWidth;
Offset += Increment;
@@ -2258,8 +2358,8 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp,
DAG.getIntPtrConstant(Idx++));
StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
- SVOffset + Offset, isVolatile,
- MinAlign(Align, Offset)));
+ SVOffset + Offset, isVolatile,
+ isNonTemporal, MinAlign(Align, Offset)));
StWidth -= NewVTWidth;
Offset += Increment;
BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
@@ -2282,6 +2382,7 @@ DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVector<SDValue, 16>& StChain,
int SVOffset = ST->getSrcValueOffset();
unsigned Align = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
SDValue ValOp = GetWidenedVector(ST->getValue());
DebugLoc dl = ST->getDebugLoc();
@@ -2304,7 +2405,7 @@ DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVector<SDValue, 16>& StChain,
DAG.getIntPtrConstant(0));
StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV,
SVOffset, StEltVT,
- isVolatile, Align));
+ isVolatile, isNonTemporal, Align));
unsigned Offset = Increment;
for (unsigned i=1; i < NumElts; ++i, Offset += Increment) {
SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
@@ -2313,7 +2414,8 @@ DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVector<SDValue, 16>& StChain,
DAG.getIntPtrConstant(0));
StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV,
SVOffset + Offset, StEltVT,
- isVolatile, MinAlign(Align, Offset)));
+ isVolatile, isNonTemporal,
+ MinAlign(Align, Offset)));
}
}
diff --git a/lib/CodeGen/SelectionDAG/SDDbgValue.h b/lib/CodeGen/SelectionDAG/SDDbgValue.h
new file mode 100644
index 0000000..9e15fc9
--- /dev/null
+++ b/lib/CodeGen/SelectionDAG/SDDbgValue.h
@@ -0,0 +1,67 @@
+//===-- llvm/CodeGen/SDDbgValue.h - SD dbg_value handling--------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SDDbgValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SDDBGVALUE_H
+#define LLVM_CODEGEN_SDDBGVALUE_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DebugLoc.h"
+
+namespace llvm {
+
+class MDNode;
+class SDNode;
+class Value;
+
+/// SDDbgValue - Holds the information from a dbg_value node through SDISel.
+/// Either Const or Node is nonzero, but not both.
+/// We do not use SDValue here to avoid including its header.
+
+class SDDbgValue {
+ SDNode *Node; // valid for non-constants
+ unsigned ResNo; // valid for non-constants
+ Value *Const; // valid for constants
+ MDNode *mdPtr;
+ uint64_t Offset;
+ DebugLoc DL;
+public:
+ // Constructor for non-constants.
+ SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl) :
+ Node(N), ResNo(R), Const(0), mdPtr(mdP), Offset(off), DL(dl) {}
+
+ // Constructor for constants.
+ SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl) : Node(0),
+ ResNo(0), Const(C), mdPtr(mdP), Offset(off), DL(dl) {}
+
+ // Returns the MDNode pointer.
+ MDNode *getMDPtr() { return mdPtr; }
+
+ // Returns the SDNode* (valid for non-constants only).
+ SDNode *getSDNode() { assert (!Const); return Node; }
+
+ // Returns the ResNo (valid for non-constants only).
+ unsigned getResNo() { assert (!Const); return ResNo; }
+
+ // Returns the Value* for a constant (invalid for non-constants).
+ Value *getConst() { assert (!Node); return Const; }
+
+ // Returns the offset.
+ uint64_t getOffset() { return Offset; }
+
+ // Returns the DebugLoc.
+ DebugLoc getDebugLoc() { return DL; }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index b51c61b..06e7b8c 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -218,8 +218,20 @@ void ScheduleDAGSDNodes::BuildSchedUnits() {
// Check to see if the scheduler cares about latencies.
bool UnitLatencies = ForceUnitLatencies();
- for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
- E = DAG->allnodes_end(); NI != E; ++NI) {
+ // Add all nodes in depth first order.
+ SmallVector<SDNode*, 64> Worklist;
+ SmallPtrSet<SDNode*, 64> Visited;
+ Worklist.push_back(DAG->getRoot().getNode());
+ Visited.insert(DAG->getRoot().getNode());
+
+ while (!Worklist.empty()) {
+ SDNode *NI = Worklist.pop_back_val();
+
+ // Add all operands to the worklist unless they've already been added.
+ for (unsigned i = 0, e = NI->getNumOperands(); i != e; ++i)
+ if (Visited.insert(NI->getOperand(i).getNode()))
+ Worklist.push_back(NI->getOperand(i).getNode());
+
if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate.
continue;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6122a2a..746d4e2 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -468,18 +468,20 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {
}
/// encodeMemSDNodeFlags - Generic routine for computing a value for use in
-/// the CSE map that carries volatility, indexing mode, and
+/// the CSE map that carries volatility, temporalness, indexing mode, and
/// extension/truncation information.
///
static inline unsigned
-encodeMemSDNodeFlags(int ConvType, ISD::MemIndexedMode AM, bool isVolatile) {
+encodeMemSDNodeFlags(int ConvType, ISD::MemIndexedMode AM, bool isVolatile,
+ bool isNonTemporal) {
assert((ConvType & 3) == ConvType &&
"ConvType may not require more than 2 bits!");
assert((AM & 7) == AM &&
"AM may not require more than 3 bits!");
return ConvType |
(AM << 2) |
- (isVolatile << 5);
+ (isVolatile << 5) |
+ (isNonTemporal << 6);
}
//===----------------------------------------------------------------------===//
@@ -829,6 +831,7 @@ void SelectionDAG::clear() {
EntryNode.UseList = 0;
AllNodes.push_back(&EntryNode);
Root = getEntryNode();
+ delete Ordering;
Ordering = new SDNodeOrdering();
}
@@ -859,14 +862,14 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, DebugLoc DL, EVT VT) {
/// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
///
SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, EVT VT) {
- EVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT;
+ EVT EltVT = VT.getScalarType();
SDValue NegOne =
getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), VT);
return getNode(ISD::XOR, DL, VT, Val, NegOne);
}
SDValue SelectionDAG::getConstant(uint64_t Val, EVT VT, bool isT) {
- EVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT;
+ EVT EltVT = VT.getScalarType();
assert((EltVT.getSizeInBits() >= 64 ||
(uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
"getConstant with a uint64_t value that doesn't fit in the type!");
@@ -880,7 +883,7 @@ SDValue SelectionDAG::getConstant(const APInt &Val, EVT VT, bool isT) {
SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {
assert(VT.isInteger() && "Cannot create FP integer constant!");
- EVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT;
+ EVT EltVT = VT.getScalarType();
assert(Val.getBitWidth() == EltVT.getSizeInBits() &&
"APInt size does not match type size!");
@@ -923,8 +926,7 @@ SDValue SelectionDAG::getConstantFP(const APFloat& V, EVT VT, bool isTarget) {
SDValue SelectionDAG::getConstantFP(const ConstantFP& V, EVT VT, bool isTarget){
assert(VT.isFloatingPoint() && "Cannot create integer FP constant!");
- EVT EltVT =
- VT.isVector() ? VT.getVectorElementType() : VT;
+ EVT EltVT = VT.getScalarType();
// Do the map lookup using the actual bit pattern for the floating point
// value, so that we don't have problems with 0.0 comparing equal to -0.0, and
@@ -958,8 +960,7 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP& V, EVT VT, bool isTarget){
}
SDValue SelectionDAG::getConstantFP(double Val, EVT VT, bool isTarget) {
- EVT EltVT =
- VT.isVector() ? VT.getVectorElementType() : VT;
+ EVT EltVT = VT.getScalarType();
if (EltVT==MVT::f32)
return getConstantFP(APFloat((float)Val), VT, isTarget);
else
@@ -1344,7 +1345,7 @@ SDValue SelectionDAG::getBlockAddress(BlockAddress *BA, EVT VT,
}
SDValue SelectionDAG::getSrcValue(const Value *V) {
- assert((!V || isa<PointerType>(V->getType())) &&
+ assert((!V || V->getType()->isPointerTy()) &&
"SrcValue is not a pointer?");
FoldingSetNodeID ID;
@@ -2232,6 +2233,29 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op) const {
return false;
}
+bool SelectionDAG::isKnownNeverZero(SDValue Op) const {
+ // If the value is a constant, we can obviously see if it is a zero or not.
+ if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Op))
+ return !C->isZero();
+
+ // TODO: Recognize more cases here.
+
+ return false;
+}
+
+bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
+ // Check the obvious case.
+ if (A == B) return true;
+
+ // For for negative and positive zero.
+ if (const ConstantFPSDNode *CA = dyn_cast<ConstantFPSDNode>(A))
+ if (const ConstantFPSDNode *CB = dyn_cast<ConstantFPSDNode>(B))
+ if (CA->isZero() && CB->isZero()) return true;
+
+ // Otherwise they may not be equal.
+ return false;
+}
+
bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const {
GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op);
if (!GA) return false;
@@ -3080,8 +3104,7 @@ SDValue SelectionDAG::getStackArgumentTokenFactor(SDValue Chain) {
/// operand.
static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
DebugLoc dl) {
- unsigned NumBits = VT.isVector() ?
- VT.getVectorElementType().getSizeInBits() : VT.getSizeInBits();
+ unsigned NumBits = VT.getScalarType().getSizeInBits();
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Value)) {
APInt Val = APInt(NumBits, C->getZExtValue() & 255);
unsigned Shift = 8;
@@ -3185,7 +3208,7 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
bool isSrcConst = isa<ConstantSDNode>(Src);
EVT VT = TLI.getOptimalMemOpType(Size, Align, isSrcConst, isSrcStr, DAG);
bool AllowUnalign = TLI.allowsUnalignedMemoryAccesses(VT);
- if (VT != MVT::iAny) {
+ if (VT != MVT::Other) {
const Type *Ty = VT.getTypeForEVT(*DAG.getContext());
unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
// If source is a string constant, this will require an unaligned load.
@@ -3193,14 +3216,14 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
if (Dst.getOpcode() != ISD::FrameIndex) {
// Can't change destination alignment. It requires a unaligned store.
if (AllowUnalign)
- VT = MVT::iAny;
+ VT = MVT::Other;
} else {
int FI = cast<FrameIndexSDNode>(Dst)->getIndex();
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
if (MFI->isFixedObjectIndex(FI)) {
// Can't change destination alignment. It requires a unaligned store.
if (AllowUnalign)
- VT = MVT::iAny;
+ VT = MVT::Other;
} else {
// Give the stack frame object a larger alignment if needed.
if (MFI->getObjectAlignment(FI) < NewAlign)
@@ -3211,7 +3234,7 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
}
}
- if (VT == MVT::iAny) {
+ if (VT == MVT::Other) {
if (TLI.allowsUnalignedMemoryAccesses(MVT::i64)) {
VT = MVT::i64;
} else {
@@ -3299,7 +3322,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff);
Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, DstAlign);
+ DstSV, DstSVOff + DstOff, false, false, DstAlign);
} else {
// The type might not be legal for the target. This should only happen
// if the type is smaller than a legal type, as on PPC, so the right
@@ -3310,10 +3333,11 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
assert(NVT.bitsGE(VT));
Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, VT, false, Align);
+ SrcSV, SrcSVOff + SrcOff, VT, false, false, Align);
Store = DAG.getTruncStore(Chain, dl, Value,
- getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, VT, false, DstAlign);
+ getMemBasePlusOffset(Dst, DstOff, DAG),
+ DstSV, DstSVOff + DstOff, VT, false, false,
+ DstAlign);
}
OutChains.push_back(Store);
SrcOff += VTSize;
@@ -3358,7 +3382,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = DAG.getLoad(VT, dl, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, false, Align);
+ SrcSV, SrcSVOff + SrcOff, false, false, Align);
LoadValues.push_back(Value);
LoadChains.push_back(Value.getValue(1));
SrcOff += VTSize;
@@ -3373,7 +3397,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Store = DAG.getStore(Chain, dl, LoadValues[i],
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, DstAlign);
+ DstSV, DstSVOff + DstOff, false, false, DstAlign);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3408,7 +3432,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Value = getMemsetValue(Src, VT, DAG, dl);
SDValue Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff);
+ DstSV, DstSVOff + DstOff, false, false, 0);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3472,7 +3496,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
/*isReturnValueUsed=*/false,
getExternalSymbol(TLI.getLibcallName(RTLIB::MEMCPY),
TLI.getPointerTy()),
- Args, *this, dl, GetOrdering(Chain.getNode()));
+ Args, *this, dl);
return CallResult.second;
}
@@ -3521,7 +3545,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
/*isReturnValueUsed=*/false,
getExternalSymbol(TLI.getLibcallName(RTLIB::MEMMOVE),
TLI.getPointerTy()),
- Args, *this, dl, GetOrdering(Chain.getNode()));
+ Args, *this, dl);
return CallResult.second;
}
@@ -3580,7 +3604,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
/*isReturnValueUsed=*/false,
getExternalSymbol(TLI.getLibcallName(RTLIB::MEMSET),
TLI.getPointerTy()),
- Args, *this, dl, GetOrdering(Chain.getNode()));
+ Args, *this, dl);
return CallResult.second;
}
@@ -3788,7 +3812,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
ISD::LoadExtType ExtType, EVT VT, SDValue Chain,
SDValue Ptr, SDValue Offset,
const Value *SV, int SVOffset, EVT MemVT,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
if (Alignment == 0) // Ensure that codegen never sees alignment 0
Alignment = getEVTAlignment(VT);
@@ -3802,6 +3827,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
unsigned Flags = MachineMemOperand::MOLoad;
if (isVolatile)
Flags |= MachineMemOperand::MOVolatile;
+ if (isNonTemporal)
+ Flags |= MachineMemOperand::MONonTemporal;
MachineMemOperand *MMO =
MF.getMachineMemOperand(SV, Flags, SVOffset,
MemVT.getStoreSize(), Alignment);
@@ -3840,7 +3867,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
ID.AddInteger(MemVT.getRawBits());
- ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, MMO->isVolatile()));
+ ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, MMO->isVolatile(),
+ MMO->isNonTemporal()));
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {
cast<LoadSDNode>(E)->refineAlignment(MMO);
@@ -3856,20 +3884,22 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
SDValue SelectionDAG::getLoad(EVT VT, DebugLoc dl,
SDValue Chain, SDValue Ptr,
const Value *SV, int SVOffset,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
SDValue Undef = getUNDEF(Ptr.getValueType());
return getLoad(ISD::UNINDEXED, dl, ISD::NON_EXTLOAD, VT, Chain, Ptr, Undef,
- SV, SVOffset, VT, isVolatile, Alignment);
+ SV, SVOffset, VT, isVolatile, isNonTemporal, Alignment);
}
SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
SDValue Chain, SDValue Ptr,
const Value *SV,
int SVOffset, EVT MemVT,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
SDValue Undef = getUNDEF(Ptr.getValueType());
return getLoad(ISD::UNINDEXED, dl, ExtType, VT, Chain, Ptr, Undef,
- SV, SVOffset, MemVT, isVolatile, Alignment);
+ SV, SVOffset, MemVT, isVolatile, isNonTemporal, Alignment);
}
SDValue
@@ -3881,12 +3911,13 @@ SelectionDAG::getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
return getLoad(AM, dl, LD->getExtensionType(), OrigLoad.getValueType(),
LD->getChain(), Base, Offset, LD->getSrcValue(),
LD->getSrcValueOffset(), LD->getMemoryVT(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(), LD->getAlignment());
}
SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
SDValue Ptr, const Value *SV, int SVOffset,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
if (Alignment == 0) // Ensure that codegen never sees alignment 0
Alignment = getEVTAlignment(Val.getValueType());
@@ -3900,6 +3931,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
unsigned Flags = MachineMemOperand::MOStore;
if (isVolatile)
Flags |= MachineMemOperand::MOVolatile;
+ if (isNonTemporal)
+ Flags |= MachineMemOperand::MONonTemporal;
MachineMemOperand *MMO =
MF.getMachineMemOperand(SV, Flags, SVOffset,
Val.getValueType().getStoreSize(), Alignment);
@@ -3916,7 +3949,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
ID.AddInteger(VT.getRawBits());
- ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, MMO->isVolatile()));
+ ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, MMO->isVolatile(),
+ MMO->isNonTemporal()));
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {
cast<StoreSDNode>(E)->refineAlignment(MMO);
@@ -3932,7 +3966,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
SDValue Ptr, const Value *SV,
int SVOffset, EVT SVT,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
if (Alignment == 0) // Ensure that codegen never sees alignment 0
Alignment = getEVTAlignment(SVT);
@@ -3946,6 +3981,8 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
unsigned Flags = MachineMemOperand::MOStore;
if (isVolatile)
Flags |= MachineMemOperand::MOVolatile;
+ if (isNonTemporal)
+ Flags |= MachineMemOperand::MONonTemporal;
MachineMemOperand *MMO =
MF.getMachineMemOperand(SV, Flags, SVOffset, SVT.getStoreSize(), Alignment);
@@ -3976,7 +4013,8 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
ID.AddInteger(SVT.getRawBits());
- ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED, MMO->isVolatile()));
+ ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED, MMO->isVolatile(),
+ MMO->isNonTemporal()));
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {
cast<StoreSDNode>(E)->refineAlignment(MMO);
@@ -4535,91 +4573,13 @@ SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,
SDVTList VTs, const SDValue *Ops,
unsigned NumOps) {
- return MorphNodeTo(N, ~MachineOpc, VTs, Ops, NumOps);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT) {
- SDVTList VTs = getVTList(VT);
- return MorphNodeTo(N, Opc, VTs, 0, 0);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT, SDValue Op1) {
- SDVTList VTs = getVTList(VT);
- SDValue Ops[] = { Op1 };
- return MorphNodeTo(N, Opc, VTs, Ops, 1);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT, SDValue Op1,
- SDValue Op2) {
- SDVTList VTs = getVTList(VT);
- SDValue Ops[] = { Op1, Op2 };
- return MorphNodeTo(N, Opc, VTs, Ops, 2);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT, SDValue Op1,
- SDValue Op2, SDValue Op3) {
- SDVTList VTs = getVTList(VT);
- SDValue Ops[] = { Op1, Op2, Op3 };
- return MorphNodeTo(N, Opc, VTs, Ops, 3);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT, const SDValue *Ops,
- unsigned NumOps) {
- SDVTList VTs = getVTList(VT);
- return MorphNodeTo(N, Opc, VTs, Ops, NumOps);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT1, EVT VT2, const SDValue *Ops,
- unsigned NumOps) {
- SDVTList VTs = getVTList(VT1, VT2);
- return MorphNodeTo(N, Opc, VTs, Ops, NumOps);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT1, EVT VT2) {
- SDVTList VTs = getVTList(VT1, VT2);
- return MorphNodeTo(N, Opc, VTs, (SDValue *)0, 0);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT1, EVT VT2, EVT VT3,
- const SDValue *Ops, unsigned NumOps) {
- SDVTList VTs = getVTList(VT1, VT2, VT3);
- return MorphNodeTo(N, Opc, VTs, Ops, NumOps);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT1, EVT VT2,
- SDValue Op1) {
- SDVTList VTs = getVTList(VT1, VT2);
- SDValue Ops[] = { Op1 };
- return MorphNodeTo(N, Opc, VTs, Ops, 1);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT1, EVT VT2,
- SDValue Op1, SDValue Op2) {
- SDVTList VTs = getVTList(VT1, VT2);
- SDValue Ops[] = { Op1, Op2 };
- return MorphNodeTo(N, Opc, VTs, Ops, 2);
-}
-
-SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
- EVT VT1, EVT VT2,
- SDValue Op1, SDValue Op2,
- SDValue Op3) {
- SDVTList VTs = getVTList(VT1, VT2);
- SDValue Ops[] = { Op1, Op2, Op3 };
- return MorphNodeTo(N, Opc, VTs, Ops, 3);
+ N = MorphNodeTo(N, ~MachineOpc, VTs, Ops, NumOps);
+ // Reset the NodeID to -1.
+ N->setNodeId(-1);
+ return N;
}
-/// MorphNodeTo - These *mutate* the specified node to have the specified
+/// MorphNodeTo - This *mutates* the specified node to have the specified
/// return type, opcode, and operands.
///
/// Note that MorphNodeTo returns the resultant node. If there is already a
@@ -4695,12 +4655,14 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
// Delete any nodes that are still dead after adding the uses for the
// new operands.
- SmallVector<SDNode *, 16> DeadNodes;
- for (SmallPtrSet<SDNode *, 16>::iterator I = DeadNodeSet.begin(),
- E = DeadNodeSet.end(); I != E; ++I)
- if ((*I)->use_empty())
- DeadNodes.push_back(*I);
- RemoveDeadNodes(DeadNodes);
+ if (!DeadNodeSet.empty()) {
+ SmallVector<SDNode *, 16> DeadNodes;
+ for (SmallPtrSet<SDNode *, 16>::iterator I = DeadNodeSet.begin(),
+ E = DeadNodeSet.end(); I != E; ++I)
+ if ((*I)->use_empty())
+ DeadNodes.push_back(*I);
+ RemoveDeadNodes(DeadNodes);
+ }
if (IP)
CSEMap.InsertNode(N, IP); // Memoize the new node.
@@ -4907,6 +4869,43 @@ SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
return NULL;
}
+namespace {
+
+/// RAUWUpdateListener - Helper for ReplaceAllUsesWith - When the node
+/// pointed to by a use iterator is deleted, increment the use iterator
+/// so that it doesn't dangle.
+///
+/// This class also manages a "downlink" DAGUpdateListener, to forward
+/// messages to ReplaceAllUsesWith's callers.
+///
+class RAUWUpdateListener : public SelectionDAG::DAGUpdateListener {
+ SelectionDAG::DAGUpdateListener *DownLink;
+ SDNode::use_iterator &UI;
+ SDNode::use_iterator &UE;
+
+ virtual void NodeDeleted(SDNode *N, SDNode *E) {
+ // Increment the iterator as needed.
+ while (UI != UE && N == *UI)
+ ++UI;
+
+ // Then forward the message.
+ if (DownLink) DownLink->NodeDeleted(N, E);
+ }
+
+ virtual void NodeUpdated(SDNode *N) {
+ // Just forward the message.
+ if (DownLink) DownLink->NodeUpdated(N);
+ }
+
+public:
+ RAUWUpdateListener(SelectionDAG::DAGUpdateListener *dl,
+ SDNode::use_iterator &ui,
+ SDNode::use_iterator &ue)
+ : DownLink(dl), UI(ui), UE(ue) {}
+};
+
+}
+
/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG.
///
@@ -4927,6 +4926,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To,
// is replaced by To, we don't want to replace of all its users with To
// too. See PR3018 for more info.
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
+ RAUWUpdateListener Listener(UpdateListener, UI, UE);
while (UI != UE) {
SDNode *User = *UI;
@@ -4945,7 +4945,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To,
// Now that we have modified User, add it back to the CSE maps. If it
// already exists there, recursively merge the results together.
- AddModifiedNodeToCSEMaps(User, UpdateListener);
+ AddModifiedNodeToCSEMaps(User, &Listener);
}
}
@@ -4971,6 +4971,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,
// Iterate over just the existing users of From. See the comments in
// the ReplaceAllUsesWith above.
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
+ RAUWUpdateListener Listener(UpdateListener, UI, UE);
while (UI != UE) {
SDNode *User = *UI;
@@ -4989,7 +4990,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,
// Now that we have modified User, add it back to the CSE maps. If it
// already exists there, recursively merge the results together.
- AddModifiedNodeToCSEMaps(User, UpdateListener);
+ AddModifiedNodeToCSEMaps(User, &Listener);
}
}
@@ -5007,6 +5008,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
// Iterate over just the existing users of From. See the comments in
// the ReplaceAllUsesWith above.
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
+ RAUWUpdateListener Listener(UpdateListener, UI, UE);
while (UI != UE) {
SDNode *User = *UI;
@@ -5026,7 +5028,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
// Now that we have modified User, add it back to the CSE maps. If it
// already exists there, recursively merge the results together.
- AddModifiedNodeToCSEMaps(User, UpdateListener);
+ AddModifiedNodeToCSEMaps(User, &Listener);
}
}
@@ -5048,6 +5050,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
// the ReplaceAllUsesWith above.
SDNode::use_iterator UI = From.getNode()->use_begin(),
UE = From.getNode()->use_end();
+ RAUWUpdateListener Listener(UpdateListener, UI, UE);
while (UI != UE) {
SDNode *User = *UI;
bool UserRemovedFromCSEMaps = false;
@@ -5083,7 +5086,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
// Now that we have modified User, add it back to the CSE maps. If it
// already exists there, recursively merge the results together.
- AddModifiedNodeToCSEMaps(User, UpdateListener);
+ AddModifiedNodeToCSEMaps(User, &Listener);
}
}
@@ -5280,8 +5283,11 @@ GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA,
MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, EVT memvt,
MachineMemOperand *mmo)
: SDNode(Opc, dl, VTs), MemoryVT(memvt), MMO(mmo) {
- SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile());
+ SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile(),
+ MMO->isNonTemporal());
assert(isVolatile() == MMO->isVolatile() && "Volatile encoding error!");
+ assert(isNonTemporal() == MMO->isNonTemporal() &&
+ "Non-temporal encoding error!");
assert(memvt.getStoreSize() == MMO->getSize() && "Size mismatch!");
}
@@ -5290,7 +5296,8 @@ MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
MachineMemOperand *mmo)
: SDNode(Opc, dl, VTs, Ops, NumOps),
MemoryVT(memvt), MMO(mmo) {
- SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile());
+ SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile(),
+ MMO->isNonTemporal());
assert(isVolatile() == MMO->isVolatile() && "Volatile encoding error!");
assert(memvt.getStoreSize() == MMO->getSize() && "Size mismatch!");
}
@@ -5459,15 +5466,15 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
if (const TargetInstrInfo *TII = G->getTarget().getInstrInfo())
if (getMachineOpcode() < TII->getNumOpcodes())
return TII->get(getMachineOpcode()).getName();
- return "<<Unknown Machine Node>>";
+ return "<<Unknown Machine Node #" + utostr(getOpcode()) + ">>";
}
if (G) {
const TargetLowering &TLI = G->getTargetLoweringInfo();
const char *Name = TLI.getTargetNodeName(getOpcode());
if (Name) return Name;
- return "<<Unknown Target Node>>";
+ return "<<Unknown Target Node #" + utostr(getOpcode()) + ">>";
}
- return "<<Unknown Node>>";
+ return "<<Unknown Node #" + utostr(getOpcode()) + ">>";
#ifndef NDEBUG
case ISD::DELETED_NODE:
@@ -5904,6 +5911,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
if (G)
if (unsigned Order = G->GetOrdering(this))
OS << " [ORD=" << Order << ']';
+
+ if (getNodeId() != -1)
+ OS << " [ID=" << getNodeId() << ']';
}
void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const {
@@ -6292,31 +6302,37 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {
return true;
}
+#ifdef XDEBUG
static void checkForCyclesHelper(const SDNode *N,
- std::set<const SDNode *> &visited) {
- if (visited.find(N) != visited.end()) {
+ SmallPtrSet<const SDNode*, 32> &Visited,
+ SmallPtrSet<const SDNode*, 32> &Checked) {
+ // If this node has already been checked, don't check it again.
+ if (Checked.count(N))
+ return;
+
+ // If a node has already been visited on this depth-first walk, reject it as
+ // a cycle.
+ if (!Visited.insert(N)) {
dbgs() << "Offending node:\n";
N->dumprFull();
- assert(0 && "Detected cycle in SelectionDAG");
+ errs() << "Detected cycle in SelectionDAG\n";
+ abort();
}
-
- 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);
+
+ for(unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ checkForCyclesHelper(N->getOperand(i).getNode(), Visited, Checked);
+
+ Checked.insert(N);
+ Visited.erase(N);
}
+#endif
void llvm::checkForCycles(const llvm::SDNode *N) {
#ifdef XDEBUG
assert(N && "Checking nonexistant SDNode");
- std::set<const SDNode *> visited;
- checkForCyclesHelper(N, visited);
+ SmallPtrSet<const SDNode*, 32> visited;
+ SmallPtrSet<const SDNode*, 32> checked;
+ checkForCyclesHelper(N, visited, checked);
#endif
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index de17f90..05be9a1 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -155,7 +155,7 @@ namespace {
/// this value and returns the result as a ValueVTs value. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
- SDValue getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
+ SDValue getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
SDValue &Chain, SDValue *Flag) const;
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
@@ -163,14 +163,14 @@ namespace {
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
void getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
- unsigned Order, SDValue &Chain, SDValue *Flag) const;
+ SDValue &Chain, SDValue *Flag) const;
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
/// operand list. This adds the code marker, matching input operand index
/// (if applicable), and includes the number of values added into it.
void AddInlineAsmOperands(unsigned Code,
bool HasMatching, unsigned MatchingIdx,
- SelectionDAG &DAG, unsigned Order,
+ SelectionDAG &DAG,
std::vector<SDValue> &Ops) const;
};
}
@@ -180,7 +180,7 @@ namespace {
/// larger then ValueVT then AssertOp can be used to specify whether the extra
/// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT
/// (ISD::AssertSext).
-static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
+static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl,
const SDValue *Parts,
unsigned NumParts, EVT PartVT, EVT ValueVT,
ISD::NodeType AssertOp = ISD::DELETED_NODE) {
@@ -205,9 +205,9 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
EVT HalfVT = EVT::getIntegerVT(*DAG.getContext(), RoundBits/2);
if (RoundParts > 2) {
- Lo = getCopyFromParts(DAG, dl, Order, Parts, RoundParts / 2,
+ Lo = getCopyFromParts(DAG, dl, Parts, RoundParts / 2,
PartVT, HalfVT);
- Hi = getCopyFromParts(DAG, dl, Order, Parts + RoundParts / 2,
+ Hi = getCopyFromParts(DAG, dl, Parts + RoundParts / 2,
RoundParts / 2, PartVT, HalfVT);
} else {
Lo = DAG.getNode(ISD::BIT_CONVERT, dl, HalfVT, Parts[0]);
@@ -223,7 +223,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
// Assemble the trailing non-power-of-2 part.
unsigned OddParts = NumParts - RoundParts;
EVT OddVT = EVT::getIntegerVT(*DAG.getContext(), OddParts * PartBits);
- Hi = getCopyFromParts(DAG, dl, Order,
+ Hi = getCopyFromParts(DAG, dl,
Parts + RoundParts, OddParts, PartVT, OddVT);
// Combine the round and odd parts.
@@ -259,7 +259,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
// If the register was not expanded, truncate or copy the value,
// as appropriate.
for (unsigned i = 0; i != NumParts; ++i)
- Ops[i] = getCopyFromParts(DAG, dl, Order, &Parts[i], 1,
+ Ops[i] = getCopyFromParts(DAG, dl, &Parts[i], 1,
PartVT, IntermediateVT);
} else if (NumParts > 0) {
// If the intermediate type was expanded, build the intermediate
@@ -268,7 +268,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
"Must expand into a divisible number of parts!");
unsigned Factor = NumParts / NumIntermediates;
for (unsigned i = 0; i != NumIntermediates; ++i)
- Ops[i] = getCopyFromParts(DAG, dl, Order, &Parts[i * Factor], Factor,
+ Ops[i] = getCopyFromParts(DAG, dl, &Parts[i * Factor], Factor,
PartVT, IntermediateVT);
}
@@ -292,7 +292,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
assert(ValueVT.isFloatingPoint() && PartVT.isInteger() &&
!PartVT.isVector() && "Unexpected split");
EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), ValueVT.getSizeInBits());
- Val = getCopyFromParts(DAG, dl, Order, Parts, NumParts, PartVT, IntVT);
+ Val = getCopyFromParts(DAG, dl, Parts, NumParts, PartVT, IntVT);
}
}
@@ -349,7 +349,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
/// getCopyToParts - Create a series of nodes that contain the specified value
/// split into legal parts. If the parts contain more bits than Val, then, for
/// integers, ExtendKind can be used to specify how to generate the extra bits.
-static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
+static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl,
SDValue Val, SDValue *Parts, unsigned NumParts,
EVT PartVT,
ISD::NodeType ExtendKind = ISD::ANY_EXTEND) {
@@ -417,7 +417,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
SDValue OddVal = DAG.getNode(ISD::SRL, dl, ValueVT, Val,
DAG.getConstant(RoundBits,
TLI.getPointerTy()));
- getCopyToParts(DAG, dl, Order, OddVal, Parts + RoundParts,
+ getCopyToParts(DAG, dl, OddVal, Parts + RoundParts,
OddParts, PartVT);
if (TLI.isBigEndian())
@@ -514,7 +514,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
// If the register was not expanded, promote or copy the value,
// as appropriate.
for (unsigned i = 0; i != NumParts; ++i)
- getCopyToParts(DAG, dl, Order, Ops[i], &Parts[i], 1, PartVT);
+ getCopyToParts(DAG, dl, Ops[i], &Parts[i], 1, PartVT);
} else if (NumParts > 0) {
// If the intermediate type was expanded, split each the value into
// legal parts.
@@ -522,7 +522,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
"Must expand into a divisible number of parts!");
unsigned Factor = NumParts / NumIntermediates;
for (unsigned i = 0; i != NumIntermediates; ++i)
- getCopyToParts(DAG, dl, Order, Ops[i], &Parts[i*Factor], Factor, PartVT);
+ getCopyToParts(DAG, dl, Ops[i], &Parts[i*Factor], Factor, PartVT);
}
}
@@ -680,7 +680,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
getCurDebugLoc());
}
- if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType())) {
+ if (C->getType()->isStructTy() || C->getType()->isArrayTy()) {
assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
"Unknown struct or array constant!");
@@ -747,8 +747,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
RegsForValue RFV(*DAG.getContext(), TLI, InReg, V->getType());
SDValue Chain = DAG.getEntryNode();
- return RFV.getCopyFromRegs(DAG, getCurDebugLoc(),
- SDNodeOrder, Chain, NULL);
+ return RFV.getCopyFromRegs(DAG, getCurDebugLoc(), Chain, NULL);
}
/// Get the EVTs and ArgFlags collections that represent the legalized return
@@ -844,19 +843,17 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) {
Chains[i] =
DAG.getStore(Chain, getCurDebugLoc(),
SDValue(RetOp.getNode(), RetOp.getResNo() + i),
- Add, NULL, Offsets[i], false, 0);
+ Add, NULL, Offsets[i], false, false, 0);
}
Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
MVT::Other, &Chains[0], NumValues);
- } else {
- for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
- SmallVector<EVT, 4> ValueVTs;
- ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs);
- unsigned NumValues = ValueVTs.size();
- if (NumValues == 0) continue;
-
- SDValue RetOp = getValue(I.getOperand(i));
+ } else if (I.getNumOperands() != 0) {
+ SmallVector<EVT, 4> ValueVTs;
+ ComputeValueVTs(TLI, I.getOperand(0)->getType(), ValueVTs);
+ unsigned NumValues = ValueVTs.size();
+ if (NumValues) {
+ SDValue RetOp = getValue(I.getOperand(0));
for (unsigned j = 0, f = NumValues; j != f; ++j) {
EVT VT = ValueVTs[j];
@@ -881,7 +878,7 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) {
unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), VT);
EVT PartVT = TLI.getRegisterType(*DAG.getContext(), VT);
SmallVector<SDValue, 4> Parts(NumParts);
- getCopyToParts(DAG, getCurDebugLoc(), SDNodeOrder,
+ getCopyToParts(DAG, getCurDebugLoc(),
SDValue(RetOp.getNode(), RetOp.getResNo() + j),
&Parts[0], NumParts, PartVT, ExtendKind);
@@ -1973,7 +1970,7 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
if (Cases.size() >= 2)
// Must recompute end() each iteration because it may be
// invalidated by erase if we hold on to it
- for (CaseItr I = Cases.begin(), J = ++(Cases.begin()); J != Cases.end(); ) {
+ for (CaseItr TmpBegin = Cases.begin(), I = TmpBegin, J = ++TmpBegin; J != Cases.end(); ) {
const APInt& nextValue = cast<ConstantInt>(J->Low)->getValue();
const APInt& currentValue = cast<ConstantInt>(I->High)->getValue();
MachineBasicBlock* nextBB = J->BB;
@@ -2062,9 +2059,15 @@ void SelectionDAGBuilder::visitSwitch(SwitchInst &SI) {
}
void SelectionDAGBuilder::visitIndirectBr(IndirectBrInst &I) {
- // Update machine-CFG edges.
+ // Update machine-CFG edges with unique successors.
+ SmallVector<BasicBlock*, 32> succs;
+ succs.reserve(I.getNumSuccessors());
for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i)
- CurMBB->addSuccessor(FuncInfo.MBBMap[I.getSuccessor(i)]);
+ succs.push_back(I.getSuccessor(i));
+ array_pod_sort(succs.begin(), succs.end());
+ succs.erase(std::unique(succs.begin(), succs.end()), succs.end());
+ for (unsigned i = 0, e = succs.size(); i != e; ++i)
+ CurMBB->addSuccessor(FuncInfo.MBBMap[succs[i]]);
DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(),
MVT::Other, getControlRoot(),
@@ -2074,7 +2077,7 @@ void SelectionDAGBuilder::visitIndirectBr(IndirectBrInst &I) {
void SelectionDAGBuilder::visitFSub(User &I) {
// -0.0 - X --> fneg
const Type *Ty = I.getType();
- if (isa<VectorType>(Ty)) {
+ if (Ty->isVectorTy()) {
if (ConstantVector *CV = dyn_cast<ConstantVector>(I.getOperand(0))) {
const VectorType *DestTy = cast<VectorType>(I.getType());
const Type *ElTy = DestTy->getElementType();
@@ -2111,7 +2114,7 @@ void SelectionDAGBuilder::visitBinary(User &I, unsigned OpCode) {
void SelectionDAGBuilder::visitShift(User &I, unsigned Opcode) {
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
- if (!isa<VectorType>(I.getType()) &&
+ if (!I.getType()->isVectorTy() &&
Op2.getValueType() != TLI.getShiftAmountTy()) {
// If the operand is smaller than the shift count type, promote it.
EVT PTy = TLI.getPointerTy();
@@ -2699,7 +2702,9 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) {
SDValue Ptr = getValue(SV);
const Type *Ty = I.getType();
+
bool isVolatile = I.isVolatile();
+ bool isNonTemporal = I.getMetadata("nontemporal") != 0;
unsigned Alignment = I.getAlignment();
SmallVector<EVT, 4> ValueVTs;
@@ -2731,7 +2736,8 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) {
PtrVT, Ptr,
DAG.getConstant(Offsets[i], PtrVT));
SDValue L = DAG.getLoad(ValueVTs[i], getCurDebugLoc(), Root,
- A, SV, Offsets[i], isVolatile, Alignment);
+ A, SV, Offsets[i], isVolatile,
+ isNonTemporal, Alignment);
Values[i] = L;
Chains[i] = L.getValue(1);
@@ -2772,6 +2778,7 @@ void SelectionDAGBuilder::visitStore(StoreInst &I) {
SmallVector<SDValue, 4> Chains(NumValues);
EVT PtrVT = Ptr.getValueType();
bool isVolatile = I.isVolatile();
+ bool isNonTemporal = I.getMetadata("nontemporal") != 0;
unsigned Alignment = I.getAlignment();
for (unsigned i = 0; i != NumValues; ++i) {
@@ -2779,7 +2786,8 @@ void SelectionDAGBuilder::visitStore(StoreInst &I) {
DAG.getConstant(Offsets[i], PtrVT));
Chains[i] = DAG.getStore(Root, getCurDebugLoc(),
SDValue(Src.getNode(), Src.getResNo() + i),
- Add, PtrV, Offsets[i], isVolatile, Alignment);
+ Add, PtrV, Offsets[i], isVolatile,
+ isNonTemporal, Alignment);
}
DAG.setRoot(DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
@@ -2879,7 +2887,7 @@ void SelectionDAGBuilder::visitTargetIntrinsic(CallInst &I,
///
/// where Op is the hexidecimal representation of floating point value.
static SDValue
-GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl, unsigned Order) {
+GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl) {
SDValue t1 = DAG.getNode(ISD::AND, dl, MVT::i32, Op,
DAG.getConstant(0x007fffff, MVT::i32));
SDValue t2 = DAG.getNode(ISD::OR, dl, MVT::i32, t1,
@@ -2894,7 +2902,7 @@ GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl, unsigned Order) {
/// where Op is the hexidecimal representation of floating point value.
static SDValue
GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI,
- DebugLoc dl, unsigned Order) {
+ DebugLoc dl) {
SDValue t0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op,
DAG.getConstant(0x7f800000, MVT::i32));
SDValue t1 = DAG.getNode(ISD::SRL, dl, MVT::i32, t0,
@@ -3078,13 +3086,13 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
// Scale the exponent by log(2) [0.69314718f].
- SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
+ SDValue Exp = GetExponent(DAG, Op1, TLI, dl);
SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
getF32Constant(DAG, 0x3f317218));
// Get the significand and build it into a floating-point number with
// exponent of 1.
- SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder);
+ SDValue X = GetSignificand(DAG, Op1, dl);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3188,11 +3196,11 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
// Get the exponent.
- SDValue LogOfExponent = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
+ SDValue LogOfExponent = GetExponent(DAG, Op1, TLI, dl);
// Get the significand and build it into a floating-point number with
// exponent of 1.
- SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder);
+ SDValue X = GetSignificand(DAG, Op1, dl);
// Different possible minimax approximations of significand in
// floating-point for various degrees of accuracy over [1,2].
@@ -3297,13 +3305,13 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
// Scale the exponent by log10(2) [0.30102999f].
- SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
+ SDValue Exp = GetExponent(DAG, Op1, TLI, dl);
SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
getF32Constant(DAG, 0x3e9a209a));
// Get the significand and build it into a floating-point number with
// exponent of 1.
- SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder);
+ SDValue X = GetSignificand(DAG, Op1, dl);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -4058,7 +4066,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
// Store the stack protector onto the stack.
Res = DAG.getStore(getRoot(), getCurDebugLoc(), Src, FIN,
PseudoSourceValue::getFixedStack(FI),
- 0, true);
+ 0, true, false, 0);
setValue(&I, Res);
DAG.setRoot(Res);
return 0;
@@ -4276,8 +4284,8 @@ isInTailCallPosition(CallSite CS, Attributes CalleeRetAttr,
// Check for a truly no-op bitcast.
if (isa<BitCastInst>(U) &&
(U->getOperand(0)->getType() == U->getType() ||
- (isa<PointerType>(U->getOperand(0)->getType()) &&
- isa<PointerType>(U->getType()))))
+ (U->getOperand(0)->getType()->isPointerTy() &&
+ U->getType()->isPointerTy())))
continue;
// Otherwise it's not a true no-op.
return false;
@@ -4385,7 +4393,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
CS.getCallingConv(),
isTailCall,
!CS.getInstruction()->use_empty(),
- Callee, Args, DAG, getCurDebugLoc(), SDNodeOrder);
+ Callee, Args, DAG, getCurDebugLoc());
assert((isTailCall || Result.second.getNode()) &&
"Non-null chain expected with non-tail call!");
assert((Result.second.getNode() || !Result.first.getNode()) &&
@@ -4410,7 +4418,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
DemoteStackSlot,
DAG.getConstant(Offsets[i], PtrVT));
SDValue L = DAG.getLoad(OutVTs[i], getCurDebugLoc(), Result.second,
- Add, NULL, Offsets[i], false, 1);
+ Add, NULL, Offsets[i], false, false, 1);
Values[i] = L;
Chains[i] = L.getValue(1);
}
@@ -4433,7 +4441,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
unsigned NumRegs = TLI.getNumRegisters(RetTy->getContext(), VT);
SDValue ReturnValue =
- getCopyFromParts(DAG, getCurDebugLoc(), SDNodeOrder, &Values[CurReg], NumRegs,
+ getCopyFromParts(DAG, getCurDebugLoc(), &Values[CurReg], NumRegs,
RegisterVT, VT, AssertOp);
ReturnValues.push_back(ReturnValue);
CurReg += NumRegs;
@@ -4512,7 +4520,8 @@ static SDValue getMemCmpLoad(Value *PtrVal, MVT LoadVT, const Type *LoadTy,
SDValue Ptr = Builder.getValue(PtrVal);
SDValue LoadVal = Builder.DAG.getLoad(LoadVT, Builder.getCurDebugLoc(), Root,
Ptr, PtrVal /*SrcValue*/, 0/*SVOffset*/,
- false /*volatile*/, 1 /* align=1 */);
+ false /*volatile*/,
+ false /*nontemporal*/, 1 /* align=1 */);
if (!ConstantMemory)
Builder.PendingLoads.push_back(LoadVal.getValue(1));
@@ -4529,9 +4538,9 @@ bool SelectionDAGBuilder::visitMemCmpCall(CallInst &I) {
return false;
Value *LHS = I.getOperand(1), *RHS = I.getOperand(2);
- if (!isa<PointerType>(LHS->getType()) || !isa<PointerType>(RHS->getType()) ||
- !isa<IntegerType>(I.getOperand(3)->getType()) ||
- !isa<IntegerType>(I.getType()))
+ if (!LHS->getType()->isPointerTy() || !RHS->getType()->isPointerTy() ||
+ !I.getOperand(3)->getType()->isIntegerTy() ||
+ !I.getType()->isIntegerTy())
return false;
ConstantInt *Size = dyn_cast<ConstantInt>(I.getOperand(3));
@@ -4625,7 +4634,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
StringRef Name = F->getName();
if (Name == "copysign" || Name == "copysignf") {
if (I.getNumOperands() == 3 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.getType() == I.getOperand(2)->getType()) {
SDValue LHS = getValue(I.getOperand(1));
@@ -4636,7 +4645,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "fabs" || Name == "fabsf" || Name == "fabsl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType()) {
SDValue Tmp = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(),
@@ -4645,7 +4654,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "sin" || Name == "sinf" || Name == "sinl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getOperand(1));
@@ -4655,7 +4664,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "cos" || Name == "cosf" || Name == "cosl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getOperand(1));
@@ -4665,7 +4674,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getOperand(1));
@@ -4699,8 +4708,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
- unsigned Order, SDValue &Chain,
- SDValue *Flag) const {
+ SDValue &Chain, SDValue *Flag) const {
// Assemble the legal parts into the final values.
SmallVector<SDValue, 4> Values(ValueVTs.size());
SmallVector<SDValue, 8> Parts;
@@ -4765,7 +4773,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
Parts[i] = P;
}
- Values[Value] = getCopyFromParts(DAG, dl, Order, Parts.begin(),
+ Values[Value] = getCopyFromParts(DAG, dl, Parts.begin(),
NumRegs, RegisterVT, ValueVT);
Part += NumRegs;
Parts.clear();
@@ -4781,8 +4789,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
- unsigned Order, SDValue &Chain,
- SDValue *Flag) const {
+ SDValue &Chain, SDValue *Flag) const {
// Get the list of the values's legal parts.
unsigned NumRegs = Regs.size();
SmallVector<SDValue, 8> Parts(NumRegs);
@@ -4791,7 +4798,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
unsigned NumParts = TLI->getNumRegisters(*DAG.getContext(), ValueVT);
EVT RegisterVT = RegVTs[Value];
- getCopyToParts(DAG, dl, Order,
+ getCopyToParts(DAG, dl,
Val.getValue(Val.getResNo() + Value),
&Parts[Part], NumParts, RegisterVT);
Part += NumParts;
@@ -4832,7 +4839,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
/// values added into it.
void RegsForValue::AddInlineAsmOperands(unsigned Code,
bool HasMatching,unsigned MatchingIdx,
- SelectionDAG &DAG, unsigned Order,
+ SelectionDAG &DAG,
std::vector<SDValue> &Ops) const {
assert(Regs.size() < (1 << 13) && "Too many inline asm outputs!");
unsigned Flag = Code | (Regs.size() << 3);
@@ -5330,7 +5337,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align, false);
SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
Chain = DAG.getStore(Chain, getCurDebugLoc(),
- OpInfo.CallOperand, StackSlot, NULL, 0);
+ OpInfo.CallOperand, StackSlot, NULL, 0,
+ false, false, 0);
OpInfo.CallOperand = StackSlot;
}
@@ -5421,7 +5429,7 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
2 /* REGDEF */ ,
false,
0,
- DAG, SDNodeOrder,
+ DAG,
AsmNodeOperands);
break;
}
@@ -5469,10 +5477,10 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// Use the produced MatchedRegs object to
MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
- SDNodeOrder, Chain, &Flag);
+ Chain, &Flag);
MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/,
true, OpInfo.getMatchedOperand(),
- DAG, SDNodeOrder, AsmNodeOperands);
+ DAG, AsmNodeOperands);
break;
} else {
assert(((OpFlag & 7) == 4) && "Unknown matching constraint!");
@@ -5533,11 +5541,10 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
}
OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
- SDNodeOrder, Chain, &Flag);
+ Chain, &Flag);
OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, false, 0,
- DAG, SDNodeOrder,
- AsmNodeOperands);
+ DAG, AsmNodeOperands);
break;
}
case InlineAsm::isClobber: {
@@ -5545,7 +5552,7 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// allocator is aware that the physreg got clobbered.
if (!OpInfo.AssignedRegs.Regs.empty())
OpInfo.AssignedRegs.AddInlineAsmOperands(6 /* EARLYCLOBBER REGDEF */,
- false, 0, DAG, SDNodeOrder,
+ false, 0, DAG,
AsmNodeOperands);
break;
}
@@ -5565,7 +5572,7 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// and set it as the value of the call.
if (!RetValRegs.Regs.empty()) {
SDValue Val = RetValRegs.getCopyFromRegs(DAG, getCurDebugLoc(),
- SDNodeOrder, Chain, &Flag);
+ Chain, &Flag);
// FIXME: Why don't we do this for inline asms with MRVs?
if (CS.getType()->isSingleValueType() && CS.getType()->isSized()) {
@@ -5605,7 +5612,7 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
RegsForValue &OutRegs = IndirectStoresToEmit[i].first;
Value *Ptr = IndirectStoresToEmit[i].second;
SDValue OutVal = OutRegs.getCopyFromRegs(DAG, getCurDebugLoc(),
- SDNodeOrder, Chain, &Flag);
+ Chain, &Flag);
StoresToEmit.push_back(std::make_pair(OutVal, Ptr));
}
@@ -5616,7 +5623,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
SDValue Val = DAG.getStore(Chain, getCurDebugLoc(),
StoresToEmit[i].first,
getValue(StoresToEmit[i].second),
- StoresToEmit[i].second, 0);
+ StoresToEmit[i].second, 0,
+ false, false, 0);
OutChains.push_back(Val);
}
@@ -5669,8 +5677,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
CallingConv::ID CallConv, bool isTailCall,
bool isReturnValueUsed,
SDValue Callee,
- ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl,
- unsigned Order) {
+ ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl) {
// Handle all of the outgoing arguments.
SmallVector<ISD::OutputArg, 32> Outs;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -5721,7 +5728,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
else if (Args[i].isZExt)
ExtendKind = ISD::ZERO_EXTEND;
- getCopyToParts(DAG, dl, Order, Op, &Parts[0], NumParts,
+ getCopyToParts(DAG, dl, Op, &Parts[0], NumParts,
PartVT, ExtendKind);
for (unsigned j = 0; j != NumParts; ++j) {
@@ -5800,7 +5807,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
EVT RegisterVT = getRegisterType(RetTy->getContext(), VT);
unsigned NumRegs = getNumRegisters(RetTy->getContext(), VT);
- ReturnValues.push_back(getCopyFromParts(DAG, dl, Order, &InVals[CurReg],
+ ReturnValues.push_back(getCopyFromParts(DAG, dl, &InVals[CurReg],
NumRegs, RegisterVT, VT,
AssertOp));
CurReg += NumRegs;
@@ -5840,7 +5847,7 @@ void SelectionDAGBuilder::CopyValueToVirtualRegister(Value *V, unsigned Reg) {
RegsForValue RFV(V->getContext(), TLI, Reg, V->getType());
SDValue Chain = DAG.getEntryNode();
- RFV.getCopyToRegs(Op, DAG, getCurDebugLoc(), SDNodeOrder, Chain, 0);
+ RFV.getCopyToRegs(Op, DAG, getCurDebugLoc(), Chain, 0);
PendingExports.push_back(Chain);
}
@@ -5966,7 +5973,7 @@ void SelectionDAGISel::LowerArguments(BasicBlock *LLVMBB) {
EVT VT = ValueVTs[0];
EVT RegVT = TLI.getRegisterType(*CurDAG->getContext(), VT);
ISD::NodeType AssertOp = ISD::DELETED_NODE;
- SDValue ArgValue = getCopyFromParts(DAG, dl, 0, &InVals[0], 1,
+ SDValue ArgValue = getCopyFromParts(DAG, dl, &InVals[0], 1,
RegVT, VT, AssertOp);
MachineFunction& MF = SDB->DAG.getMachineFunction();
@@ -6000,7 +6007,7 @@ void SelectionDAGISel::LowerArguments(BasicBlock *LLVMBB) {
else if (F.paramHasAttr(Idx, Attribute::ZExt))
AssertOp = ISD::AssertZext;
- ArgValues.push_back(getCopyFromParts(DAG, dl, 0, &InVals[i],
+ ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i],
NumParts, PartVT, VT,
AssertOp));
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index da2e6e4..05f9f1f 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -56,9 +56,12 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/Statistic.h"
#include <algorithm>
using namespace llvm;
+STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
+
static cl::opt<bool>
EnableFastISelVerbose("fast-isel-verbose", cl::Hidden,
cl::desc("Enable verbose messages in the \"fast\" "
@@ -723,9 +726,9 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
// code to the MachineBasicBlock.
if (TimePassesIsEnabled) {
NamedRegionTimer T("Instruction Selection", GroupName);
- InstructionSelect();
+ DoInstructionSelection();
} else {
- InstructionSelect();
+ DoInstructionSelection();
}
DEBUG(dbgs() << "Selected selection DAG:\n");
@@ -765,6 +768,66 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
DEBUG(BB->dump());
}
+void SelectionDAGISel::DoInstructionSelection() {
+ DEBUG(errs() << "===== Instruction selection begins:\n");
+
+ PreprocessISelDAG();
+
+ // Select target instructions for the DAG.
+ {
+ // Number all nodes with a topological order and set DAGSize.
+ DAGSize = CurDAG->AssignTopologicalOrder();
+
+ // Create a dummy node (which is not added to allnodes), that adds
+ // a reference to the root node, preventing it from being deleted,
+ // and tracking any changes of the root.
+ HandleSDNode Dummy(CurDAG->getRoot());
+ ISelPosition = SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode());
+ ++ISelPosition;
+
+ // The AllNodes list is now topological-sorted. Visit the
+ // nodes by starting at the end of the list (the root of the
+ // graph) and preceding back toward the beginning (the entry
+ // node).
+ while (ISelPosition != CurDAG->allnodes_begin()) {
+ SDNode *Node = --ISelPosition;
+ // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes,
+ // but there are currently some corner cases that it misses. Also, this
+ // makes it theoretically possible to disable the DAGCombiner.
+ if (Node->use_empty())
+ continue;
+
+ SDNode *ResNode = Select(Node);
+
+ // FIXME: This is pretty gross. 'Select' should be changed to not return
+ // anything at all and this code should be nuked with a tactical strike.
+
+ // If node should not be replaced, continue with the next one.
+ if (ResNode == Node || Node->getOpcode() == ISD::DELETED_NODE)
+ continue;
+ // Replace node.
+ if (ResNode)
+ ReplaceUses(Node, ResNode);
+
+ // If after the replacement this node is not used any more,
+ // remove this dead node.
+ if (Node->use_empty()) { // Don't delete EntryToken, etc.
+ ISelUpdater ISU(ISelPosition);
+ CurDAG->RemoveDeadNode(Node, &ISU);
+ }
+ }
+
+ CurDAG->setRoot(Dummy.getValue());
+ }
+ DEBUG(errs() << "===== Instruction selection ends:\n");
+
+ PostprocessISelDAG();
+
+ // FIXME: This shouldn't be needed, remove it.
+ CurDAG->RemoveDeadNodes();
+}
+
+
void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
MachineFunction &MF,
MachineModuleInfo *MMI,
@@ -870,6 +933,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
// feed PHI nodes in successor blocks.
if (isa<TerminatorInst>(BI))
if (!HandlePHINodesInSuccessorBlocksFast(LLVMBB, FastIS)) {
+ ++NumFastIselFailures;
ResetDebugLoc(SDB, FastIS);
if (EnableFastISelVerbose || EnableFastISelAbort) {
dbgs() << "FastISel miss: ";
@@ -894,6 +958,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
// Then handle certain instructions as single-LLVM-Instruction blocks.
if (isa<CallInst>(BI)) {
+ ++NumFastIselFailures;
if (EnableFastISelVerbose || EnableFastISelAbort) {
dbgs() << "FastISel missed call: ";
BI->dump();
@@ -923,6 +988,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
// Otherwise, give up on FastISel for the rest of the block.
// For now, be a little lenient about non-branch terminators.
if (!isa<TerminatorInst>(BI) || isa<BranchInst>(BI)) {
+ ++NumFastIselFailures;
if (EnableFastISelVerbose || EnableFastISelAbort) {
dbgs() << "FastISel miss: ";
BI->dump();
@@ -972,6 +1038,8 @@ SelectionDAGISel::FinishBasicBlock() {
MachineInstr *PHI = SDB->PHINodesToUpdate[i].first;
assert(PHI->isPHI() &&
"This is not a machine PHI node that we are updating!");
+ if (!BB->isSuccessor(PHI->getParent()))
+ continue;
PHI->addOperand(MachineOperand::CreateReg(SDB->PHINodesToUpdate[i].second,
false));
PHI->addOperand(MachineOperand::CreateMBB(BB));
@@ -1316,13 +1384,29 @@ static SDNode *findFlagUse(SDNode *N) {
/// This function recursively traverses up the operand chain, ignoring
/// certain nodes.
static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
- SDNode *Root,
- SmallPtrSet<SDNode*, 16> &Visited) {
- if (Use->getNodeId() < Def->getNodeId() ||
- !Visited.insert(Use))
+ SDNode *Root, SmallPtrSet<SDNode*, 16> &Visited,
+ bool IgnoreChains) {
+ // The NodeID's are given uniques ID's where a node ID is guaranteed to be
+ // greater than all of its (recursive) operands. If we scan to a point where
+ // 'use' is smaller than the node we're scanning for, then we know we will
+ // never find it.
+ //
+ // The Use may be -1 (unassigned) if it is a newly allocated node. This can
+ // happen because we scan down to newly selected nodes in the case of flag
+ // uses.
+ if ((Use->getNodeId() < Def->getNodeId() && Use->getNodeId() != -1))
+ return false;
+
+ // Don't revisit nodes if we already scanned it and didn't fail, we know we
+ // won't fail if we scan it again.
+ if (!Visited.insert(Use))
return false;
for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {
+ // Ignore chain uses, they are validated by HandleMergeInputChains.
+ if (Use->getOperand(i).getValueType() == MVT::Other && IgnoreChains)
+ continue;
+
SDNode *N = Use->getOperand(i).getNode();
if (N == Def) {
if (Use == ImmedUse || Use == Root)
@@ -1332,32 +1416,24 @@ static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
}
// Traverse up the operand chain.
- if (findNonImmUse(N, Def, ImmedUse, Root, Visited))
+ if (findNonImmUse(N, Def, ImmedUse, Root, Visited, IgnoreChains))
return true;
}
return false;
}
-/// isNonImmUse - Start searching from Root up the DAG to check is Def can
-/// be reached. Return true if that's the case. However, ignore direct uses
-/// by ImmedUse (which would be U in the example illustrated in
-/// IsLegalAndProfitableToFold) and by Root (which can happen in the store
-/// case).
-/// FIXME: to be really generic, we should allow direct use by any node
-/// that is being folded. But realisticly since we only fold loads which
-/// have one non-chain use, we only need to watch out for load/op/store
-/// and load/op/cmp case where the root (store / cmp) may reach the load via
-/// its chain operand.
-static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) {
- SmallPtrSet<SDNode*, 16> Visited;
- return findNonImmUse(Root, Def, ImmedUse, Root, Visited);
+/// IsProfitableToFold - Returns true if it's profitable to fold the specific
+/// operand node N of U during instruction selection that starts at Root.
+bool SelectionDAGISel::IsProfitableToFold(SDValue N, SDNode *U,
+ SDNode *Root) const {
+ if (OptLevel == CodeGenOpt::None) return false;
+ return N.hasOneUse();
}
-/// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
-/// U can be folded during instruction selection that starts at Root and
-/// folding N is profitable.
-bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+/// IsLegalToFold - Returns true if the specific operand node N of
+/// U can be folded during instruction selection that starts at Root.
+bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
+ bool IgnoreChains) const {
if (OptLevel == CodeGenOpt::None) return false;
// If Root use can somehow reach N through a path that that doesn't contain
@@ -1402,6 +1478,8 @@ bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
// Fold. But since Fold and FU are flagged together, this will create
// a cycle in the scheduling graph.
+ // If the node has flags, walk down the graph to the "lowest" node in the
+ // flagged set.
EVT VT = Root->getValueType(Root->getNumValues()-1);
while (VT == MVT::Flag) {
SDNode *FU = findFlagUse(Root);
@@ -1409,9 +1487,17 @@ bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
break;
Root = FU;
VT = Root->getValueType(Root->getNumValues()-1);
+
+ // If our query node has a flag result with a use, we've walked up it. If
+ // the user (which has already been selected) has a chain or indirectly uses
+ // the chain, our WalkChainUsers predicate will not consider it. Because of
+ // this, we cannot ignore chains in this predicate.
+ IgnoreChains = false;
}
+
- return !isNonImmUse(Root, N, U);
+ SmallPtrSet<SDNode*, 16> Visited;
+ return !findNonImmUse(Root, N.getNode(), U, Root, Visited, IgnoreChains);
}
SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
@@ -1423,6 +1509,7 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
VTs.push_back(MVT::Flag);
SDValue New = CurDAG->getNode(ISD::INLINEASM, N->getDebugLoc(),
VTs, &Ops[0], Ops.size());
+ New->setNodeId(-1);
return New.getNode();
}
@@ -1438,25 +1525,1219 @@ SDNode *SelectionDAGISel::Select_EH_LABEL(SDNode *N) {
MVT::Other, Tmp, Chain);
}
+/// GetVBR - decode a vbr encoding whose top bit is set.
+ALWAYS_INLINE static uint64_t
+GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
+ assert(Val >= 128 && "Not a VBR");
+ Val &= 127; // Remove first vbr bit.
+
+ unsigned Shift = 7;
+ uint64_t NextBits;
+ do {
+ NextBits = MatcherTable[Idx++];
+ Val |= (NextBits&127) << Shift;
+ Shift += 7;
+ } while (NextBits & 128);
+
+ return Val;
+}
+
+
+/// UpdateChainsAndFlags - When a match is complete, this method updates uses of
+/// interior flag and chain results to use the new flag and chain results.
+void SelectionDAGISel::
+UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
+ const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+ SDValue InputFlag,
+ const SmallVectorImpl<SDNode*> &FlagResultNodesMatched,
+ bool isMorphNodeTo) {
+ SmallVector<SDNode*, 4> NowDeadNodes;
+
+ ISelUpdater ISU(ISelPosition);
+
+ // Now that all the normal results are replaced, we replace the chain and
+ // flag results if present.
+ if (!ChainNodesMatched.empty()) {
+ assert(InputChain.getNode() != 0 &&
+ "Matched input chains but didn't produce a chain");
+ // Loop over all of the nodes we matched that produced a chain result.
+ // Replace all the chain results with the final chain we ended up with.
+ for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
+ SDNode *ChainNode = ChainNodesMatched[i];
+
+ // If this node was already deleted, don't look at it.
+ if (ChainNode->getOpcode() == ISD::DELETED_NODE)
+ continue;
+
+ // Don't replace the results of the root node if we're doing a
+ // MorphNodeTo.
+ if (ChainNode == NodeToMatch && isMorphNodeTo)
+ continue;
+
+ SDValue ChainVal = SDValue(ChainNode, ChainNode->getNumValues()-1);
+ if (ChainVal.getValueType() == MVT::Flag)
+ ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2);
+ assert(ChainVal.getValueType() == MVT::Other && "Not a chain?");
+ CurDAG->ReplaceAllUsesOfValueWith(ChainVal, InputChain, &ISU);
+
+ // If the node became dead, delete it.
+ if (ChainNode->use_empty())
+ NowDeadNodes.push_back(ChainNode);
+ }
+ }
+
+ // If the result produces a flag, update any flag results in the matched
+ // pattern with the flag result.
+ if (InputFlag.getNode() != 0) {
+ // Handle any interior nodes explicitly marked.
+ for (unsigned i = 0, e = FlagResultNodesMatched.size(); i != e; ++i) {
+ SDNode *FRN = FlagResultNodesMatched[i];
+
+ // If this node was already deleted, don't look at it.
+ if (FRN->getOpcode() == ISD::DELETED_NODE)
+ continue;
+
+ assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag &&
+ "Doesn't have a flag result");
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1),
+ InputFlag, &ISU);
+
+ // If the node became dead, delete it.
+ if (FRN->use_empty())
+ NowDeadNodes.push_back(FRN);
+ }
+ }
+
+ if (!NowDeadNodes.empty())
+ CurDAG->RemoveDeadNodes(NowDeadNodes, &ISU);
+
+ DEBUG(errs() << "ISEL: Match complete!\n");
+}
+
+enum ChainResult {
+ CR_Simple,
+ CR_InducesCycle,
+ CR_LeadsToInteriorNode
+};
+
+/// WalkChainUsers - Walk down the users of the specified chained node that is
+/// part of the pattern we're matching, looking at all of the users we find.
+/// This determines whether something is an interior node, whether we have a
+/// non-pattern node in between two pattern nodes (which prevent folding because
+/// it would induce a cycle) and whether we have a TokenFactor node sandwiched
+/// between pattern nodes (in which case the TF becomes part of the pattern).
+///
+/// The walk we do here is guaranteed to be small because we quickly get down to
+/// already selected nodes "below" us.
+static ChainResult
+WalkChainUsers(SDNode *ChainedNode,
+ SmallVectorImpl<SDNode*> &ChainedNodesInPattern,
+ SmallVectorImpl<SDNode*> &InteriorChainedNodes) {
+ ChainResult Result = CR_Simple;
+
+ for (SDNode::use_iterator UI = ChainedNode->use_begin(),
+ E = ChainedNode->use_end(); UI != E; ++UI) {
+ // Make sure the use is of the chain, not some other value we produce.
+ if (UI.getUse().getValueType() != MVT::Other) continue;
+
+ SDNode *User = *UI;
+
+ // If we see an already-selected machine node, then we've gone beyond the
+ // pattern that we're selecting down into the already selected chunk of the
+ // DAG.
+ if (User->isMachineOpcode() ||
+ User->getOpcode() == ISD::HANDLENODE) // Root of the graph.
+ continue;
+
+ if (User->getOpcode() == ISD::CopyToReg ||
+ User->getOpcode() == ISD::CopyFromReg ||
+ User->getOpcode() == ISD::INLINEASM) {
+ // If their node ID got reset to -1 then they've already been selected.
+ // Treat them like a MachineOpcode.
+ if (User->getNodeId() == -1)
+ continue;
+ }
+
+ // If we have a TokenFactor, we handle it specially.
+ if (User->getOpcode() != ISD::TokenFactor) {
+ // If the node isn't a token factor and isn't part of our pattern, then it
+ // must be a random chained node in between two nodes we're selecting.
+ // This happens when we have something like:
+ // x = load ptr
+ // call
+ // y = x+4
+ // store y -> ptr
+ // Because we structurally match the load/store as a read/modify/write,
+ // but the call is chained between them. We cannot fold in this case
+ // because it would induce a cycle in the graph.
+ if (!std::count(ChainedNodesInPattern.begin(),
+ ChainedNodesInPattern.end(), User))
+ return CR_InducesCycle;
+
+ // Otherwise we found a node that is part of our pattern. For example in:
+ // x = load ptr
+ // y = x+4
+ // store y -> ptr
+ // This would happen when we're scanning down from the load and see the
+ // store as a user. Record that there is a use of ChainedNode that is
+ // part of the pattern and keep scanning uses.
+ Result = CR_LeadsToInteriorNode;
+ InteriorChainedNodes.push_back(User);
+ continue;
+ }
+
+ // If we found a TokenFactor, there are two cases to consider: first if the
+ // TokenFactor is just hanging "below" the pattern we're matching (i.e. no
+ // uses of the TF are in our pattern) we just want to ignore it. Second,
+ // the TokenFactor can be sandwiched in between two chained nodes, like so:
+ // [Load chain]
+ // ^
+ // |
+ // [Load]
+ // ^ ^
+ // | \ DAG's like cheese
+ // / \ do you?
+ // / |
+ // [TokenFactor] [Op]
+ // ^ ^
+ // | |
+ // \ /
+ // \ /
+ // [Store]
+ //
+ // In this case, the TokenFactor becomes part of our match and we rewrite it
+ // as a new TokenFactor.
+ //
+ // To distinguish these two cases, do a recursive walk down the uses.
+ switch (WalkChainUsers(User, ChainedNodesInPattern, InteriorChainedNodes)) {
+ case CR_Simple:
+ // If the uses of the TokenFactor are just already-selected nodes, ignore
+ // it, it is "below" our pattern.
+ continue;
+ case CR_InducesCycle:
+ // If the uses of the TokenFactor lead to nodes that are not part of our
+ // pattern that are not selected, folding would turn this into a cycle,
+ // bail out now.
+ return CR_InducesCycle;
+ case CR_LeadsToInteriorNode:
+ break; // Otherwise, keep processing.
+ }
+
+ // Okay, we know we're in the interesting interior case. The TokenFactor
+ // is now going to be considered part of the pattern so that we rewrite its
+ // uses (it may have uses that are not part of the pattern) with the
+ // ultimate chain result of the generated code. We will also add its chain
+ // inputs as inputs to the ultimate TokenFactor we create.
+ Result = CR_LeadsToInteriorNode;
+ ChainedNodesInPattern.push_back(User);
+ InteriorChainedNodes.push_back(User);
+ continue;
+ }
+
+ return Result;
+}
+
+/// HandleMergeInputChains - This implements the OPC_EmitMergeInputChains
+/// operation for when the pattern matched at least one node with a chains. The
+/// input vector contains a list of all of the chained nodes that we match. We
+/// must determine if this is a valid thing to cover (i.e. matching it won't
+/// induce cycles in the DAG) and if so, creating a TokenFactor node. that will
+/// be used as the input node chain for the generated nodes.
+static SDValue
+HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched,
+ SelectionDAG *CurDAG) {
+ // Walk all of the chained nodes we've matched, recursively scanning down the
+ // users of the chain result. This adds any TokenFactor nodes that are caught
+ // in between chained nodes to the chained and interior nodes list.
+ SmallVector<SDNode*, 3> InteriorChainedNodes;
+ for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
+ if (WalkChainUsers(ChainNodesMatched[i], ChainNodesMatched,
+ InteriorChainedNodes) == CR_InducesCycle)
+ return SDValue(); // Would induce a cycle.
+ }
+
+ // Okay, we have walked all the matched nodes and collected TokenFactor nodes
+ // that we are interested in. Form our input TokenFactor node.
+ SmallVector<SDValue, 3> InputChains;
+ for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
+ // Add the input chain of this node to the InputChains list (which will be
+ // the operands of the generated TokenFactor) if it's not an interior node.
+ SDNode *N = ChainNodesMatched[i];
+ if (N->getOpcode() != ISD::TokenFactor) {
+ if (std::count(InteriorChainedNodes.begin(),InteriorChainedNodes.end(),N))
+ continue;
+
+ // Otherwise, add the input chain.
+ SDValue InChain = ChainNodesMatched[i]->getOperand(0);
+ assert(InChain.getValueType() == MVT::Other && "Not a chain");
+ InputChains.push_back(InChain);
+ continue;
+ }
+
+ // If we have a token factor, we want to add all inputs of the token factor
+ // that are not part of the pattern we're matching.
+ for (unsigned op = 0, e = N->getNumOperands(); op != e; ++op) {
+ if (!std::count(ChainNodesMatched.begin(), ChainNodesMatched.end(),
+ N->getOperand(op).getNode()))
+ InputChains.push_back(N->getOperand(op));
+ }
+ }
+
+ SDValue Res;
+ if (InputChains.size() == 1)
+ return InputChains[0];
+ return CurDAG->getNode(ISD::TokenFactor, ChainNodesMatched[0]->getDebugLoc(),
+ MVT::Other, &InputChains[0], InputChains.size());
+}
+
+/// MorphNode - Handle morphing a node in place for the selector.
+SDNode *SelectionDAGISel::
+MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,
+ const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo) {
+ // It is possible we're using MorphNodeTo to replace a node with no
+ // normal results with one that has a normal result (or we could be
+ // adding a chain) and the input could have flags and chains as well.
+ // In this case we need to shifting the operands down.
+ // FIXME: This is a horrible hack and broken in obscure cases, no worse
+ // than the old isel though. We should sink this into MorphNodeTo.
+ int OldFlagResultNo = -1, OldChainResultNo = -1;
+
+ unsigned NTMNumResults = Node->getNumValues();
+ if (Node->getValueType(NTMNumResults-1) == MVT::Flag) {
+ OldFlagResultNo = NTMNumResults-1;
+ if (NTMNumResults != 1 &&
+ Node->getValueType(NTMNumResults-2) == MVT::Other)
+ OldChainResultNo = NTMNumResults-2;
+ } else if (Node->getValueType(NTMNumResults-1) == MVT::Other)
+ OldChainResultNo = NTMNumResults-1;
+
+ // Call the underlying SelectionDAG routine to do the transmogrification. Note
+ // that this deletes operands of the old node that become dead.
+ SDNode *Res = CurDAG->MorphNodeTo(Node, ~TargetOpc, VTList, Ops, NumOps);
+
+ // MorphNodeTo can operate in two ways: if an existing node with the
+ // specified operands exists, it can just return it. Otherwise, it
+ // updates the node in place to have the requested operands.
+ if (Res == Node) {
+ // If we updated the node in place, reset the node ID. To the isel,
+ // this should be just like a newly allocated machine node.
+ Res->setNodeId(-1);
+ }
+
+ unsigned ResNumResults = Res->getNumValues();
+ // Move the flag if needed.
+ if ((EmitNodeInfo & OPFL_FlagOutput) && OldFlagResultNo != -1 &&
+ (unsigned)OldFlagResultNo != ResNumResults-1)
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldFlagResultNo),
+ SDValue(Res, ResNumResults-1));
+
+ if ((EmitNodeInfo & OPFL_FlagOutput) != 0)
+ --ResNumResults;
+
+ // Move the chain reference if needed.
+ if ((EmitNodeInfo & OPFL_Chain) && OldChainResultNo != -1 &&
+ (unsigned)OldChainResultNo != ResNumResults-1)
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldChainResultNo),
+ SDValue(Res, ResNumResults-1));
+
+ // Otherwise, no replacement happened because the node already exists. Replace
+ // Uses of the old node with the new one.
+ if (Res != Node)
+ CurDAG->ReplaceAllUsesWith(Node, Res);
+
+ return Res;
+}
+
+/// CheckPatternPredicate - Implements OP_CheckPatternPredicate.
+ALWAYS_INLINE static bool
+CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N, const SmallVectorImpl<SDValue> &RecordedNodes) {
+ // Accept if it is exactly the same as a previously recorded node.
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ return N == RecordedNodes[RecNo];
+}
+
+/// CheckPatternPredicate - Implements OP_CheckPatternPredicate.
+ALWAYS_INLINE static bool
+CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SelectionDAGISel &SDISel) {
+ return SDISel.CheckPatternPredicate(MatcherTable[MatcherIndex++]);
+}
+
+/// CheckNodePredicate - Implements OP_CheckNodePredicate.
+ALWAYS_INLINE static bool
+CheckNodePredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SelectionDAGISel &SDISel, SDNode *N) {
+ return SDISel.CheckNodePredicate(N, MatcherTable[MatcherIndex++]);
+}
+
+ALWAYS_INLINE static bool
+CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDNode *N) {
+ return N->getOpcode() == MatcherTable[MatcherIndex++];
+}
+
+ALWAYS_INLINE static bool
+CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N, const TargetLowering &TLI) {
+ MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ if (N.getValueType() == VT) return true;
+
+ // Handle the case when VT is iPTR.
+ return VT == MVT::iPTR && N.getValueType() == TLI.getPointerTy();
+}
+
+ALWAYS_INLINE static bool
+CheckChildType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N, const TargetLowering &TLI,
+ unsigned ChildNo) {
+ if (ChildNo >= N.getNumOperands())
+ return false; // Match fails if out of range child #.
+ return ::CheckType(MatcherTable, MatcherIndex, N.getOperand(ChildNo), TLI);
+}
+
+
+ALWAYS_INLINE static bool
+CheckCondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N) {
+ return cast<CondCodeSDNode>(N)->get() ==
+ (ISD::CondCode)MatcherTable[MatcherIndex++];
+}
+
+ALWAYS_INLINE static bool
+CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N, const TargetLowering &TLI) {
+ MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ if (cast<VTSDNode>(N)->getVT() == VT)
+ return true;
+
+ // Handle the case when VT is iPTR.
+ return VT == MVT::iPTR && cast<VTSDNode>(N)->getVT() == TLI.getPointerTy();
+}
+
+ALWAYS_INLINE static bool
+CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N) {
+ int64_t Val = MatcherTable[MatcherIndex++];
+ if (Val & 128)
+ Val = GetVBR(Val, MatcherTable, MatcherIndex);
+
+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(N);
+ return C != 0 && C->getSExtValue() == Val;
+}
+
+ALWAYS_INLINE static bool
+CheckAndImm(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N, SelectionDAGISel &SDISel) {
+ int64_t Val = MatcherTable[MatcherIndex++];
+ if (Val & 128)
+ Val = GetVBR(Val, MatcherTable, MatcherIndex);
+
+ if (N->getOpcode() != ISD::AND) return false;
+
+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ return C != 0 && SDISel.CheckAndMask(N.getOperand(0), C, Val);
+}
+
+ALWAYS_INLINE static bool
+CheckOrImm(const unsigned char *MatcherTable, unsigned &MatcherIndex,
+ SDValue N, SelectionDAGISel &SDISel) {
+ int64_t Val = MatcherTable[MatcherIndex++];
+ if (Val & 128)
+ Val = GetVBR(Val, MatcherTable, MatcherIndex);
+
+ if (N->getOpcode() != ISD::OR) return false;
+
+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ return C != 0 && SDISel.CheckOrMask(N.getOperand(0), C, Val);
+}
+
+/// IsPredicateKnownToFail - If we know how and can do so without pushing a
+/// scope, evaluate the current node. If the current predicate is known to
+/// fail, set Result=true and return anything. If the current predicate is
+/// known to pass, set Result=false and return the MatcherIndex to continue
+/// with. If the current predicate is unknown, set Result=false and return the
+/// MatcherIndex to continue with.
+static unsigned IsPredicateKnownToFail(const unsigned char *Table,
+ unsigned Index, SDValue N,
+ bool &Result, SelectionDAGISel &SDISel,
+ SmallVectorImpl<SDValue> &RecordedNodes){
+ switch (Table[Index++]) {
+ default:
+ Result = false;
+ return Index-1; // Could not evaluate this predicate.
+ case SelectionDAGISel::OPC_CheckSame:
+ Result = !::CheckSame(Table, Index, N, RecordedNodes);
+ return Index;
+ case SelectionDAGISel::OPC_CheckPatternPredicate:
+ Result = !::CheckPatternPredicate(Table, Index, SDISel);
+ return Index;
+ case SelectionDAGISel::OPC_CheckPredicate:
+ Result = !::CheckNodePredicate(Table, Index, SDISel, N.getNode());
+ return Index;
+ case SelectionDAGISel::OPC_CheckOpcode:
+ Result = !::CheckOpcode(Table, Index, N.getNode());
+ return Index;
+ case SelectionDAGISel::OPC_CheckType:
+ Result = !::CheckType(Table, Index, N, SDISel.TLI);
+ return Index;
+ case SelectionDAGISel::OPC_CheckChild0Type:
+ case SelectionDAGISel::OPC_CheckChild1Type:
+ case SelectionDAGISel::OPC_CheckChild2Type:
+ case SelectionDAGISel::OPC_CheckChild3Type:
+ case SelectionDAGISel::OPC_CheckChild4Type:
+ case SelectionDAGISel::OPC_CheckChild5Type:
+ case SelectionDAGISel::OPC_CheckChild6Type:
+ case SelectionDAGISel::OPC_CheckChild7Type:
+ Result = !::CheckChildType(Table, Index, N, SDISel.TLI,
+ Table[Index-1] - SelectionDAGISel::OPC_CheckChild0Type);
+ return Index;
+ case SelectionDAGISel::OPC_CheckCondCode:
+ Result = !::CheckCondCode(Table, Index, N);
+ return Index;
+ case SelectionDAGISel::OPC_CheckValueType:
+ Result = !::CheckValueType(Table, Index, N, SDISel.TLI);
+ return Index;
+ case SelectionDAGISel::OPC_CheckInteger:
+ Result = !::CheckInteger(Table, Index, N);
+ return Index;
+ case SelectionDAGISel::OPC_CheckAndImm:
+ Result = !::CheckAndImm(Table, Index, N, SDISel);
+ return Index;
+ case SelectionDAGISel::OPC_CheckOrImm:
+ Result = !::CheckOrImm(Table, Index, N, SDISel);
+ return Index;
+ }
+}
+
+
+struct MatchScope {
+ /// FailIndex - If this match fails, this is the index to continue with.
+ unsigned FailIndex;
+
+ /// NodeStack - The node stack when the scope was formed.
+ SmallVector<SDValue, 4> NodeStack;
+
+ /// NumRecordedNodes - The number of recorded nodes when the scope was formed.
+ unsigned NumRecordedNodes;
+
+ /// NumMatchedMemRefs - The number of matched memref entries.
+ unsigned NumMatchedMemRefs;
+
+ /// InputChain/InputFlag - The current chain/flag
+ SDValue InputChain, InputFlag;
+
+ /// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty.
+ bool HasChainNodesMatched, HasFlagResultNodesMatched;
+};
+
+SDNode *SelectionDAGISel::
+SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
+ unsigned TableSize) {
+ // FIXME: Should these even be selected? Handle these cases in the caller?
+ switch (NodeToMatch->getOpcode()) {
+ default:
+ break;
+ case ISD::EntryToken: // These nodes remain the same.
+ case ISD::BasicBlock:
+ case ISD::Register:
+ case ISD::HANDLENODE:
+ case ISD::TargetConstant:
+ case ISD::TargetConstantFP:
+ case ISD::TargetConstantPool:
+ case ISD::TargetFrameIndex:
+ case ISD::TargetExternalSymbol:
+ case ISD::TargetBlockAddress:
+ case ISD::TargetJumpTable:
+ case ISD::TargetGlobalTLSAddress:
+ case ISD::TargetGlobalAddress:
+ case ISD::TokenFactor:
+ case ISD::CopyFromReg:
+ case ISD::CopyToReg:
+ NodeToMatch->setNodeId(-1); // Mark selected.
+ return 0;
+ case ISD::AssertSext:
+ case ISD::AssertZext:
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, 0),
+ NodeToMatch->getOperand(0));
+ return 0;
+ case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch);
+ case ISD::EH_LABEL: return Select_EH_LABEL(NodeToMatch);
+ case ISD::UNDEF: return Select_UNDEF(NodeToMatch);
+ }
+
+ assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");
+
+ // Set up the node stack with NodeToMatch as the only node on the stack.
+ SmallVector<SDValue, 8> NodeStack;
+ SDValue N = SDValue(NodeToMatch, 0);
+ NodeStack.push_back(N);
+
+ // MatchScopes - Scopes used when matching, if a match failure happens, this
+ // indicates where to continue checking.
+ SmallVector<MatchScope, 8> MatchScopes;
+
+ // RecordedNodes - This is the set of nodes that have been recorded by the
+ // state machine.
+ SmallVector<SDValue, 8> RecordedNodes;
+
+ // MatchedMemRefs - This is the set of MemRef's we've seen in the input
+ // pattern.
+ SmallVector<MachineMemOperand*, 2> MatchedMemRefs;
+
+ // These are the current input chain and flag for use when generating nodes.
+ // Various Emit operations change these. For example, emitting a copytoreg
+ // uses and updates these.
+ SDValue InputChain, InputFlag;
+
+ // ChainNodesMatched - If a pattern matches nodes that have input/output
+ // chains, the OPC_EmitMergeInputChains operation is emitted which indicates
+ // which ones they are. The result is captured into this list so that we can
+ // update the chain results when the pattern is complete.
+ SmallVector<SDNode*, 3> ChainNodesMatched;
+ SmallVector<SDNode*, 3> FlagResultNodesMatched;
+
+ DEBUG(errs() << "ISEL: Starting pattern match on root node: ";
+ NodeToMatch->dump(CurDAG);
+ errs() << '\n');
+
+ // Determine where to start the interpreter. Normally we start at opcode #0,
+ // but if the state machine starts with an OPC_SwitchOpcode, then we
+ // accelerate the first lookup (which is guaranteed to be hot) with the
+ // OpcodeOffset table.
+ unsigned MatcherIndex = 0;
+
+ if (!OpcodeOffset.empty()) {
+ // Already computed the OpcodeOffset table, just index into it.
+ if (N.getOpcode() < OpcodeOffset.size())
+ MatcherIndex = OpcodeOffset[N.getOpcode()];
+ DEBUG(errs() << " Initial Opcode index to " << MatcherIndex << "\n");
+
+ } else if (MatcherTable[0] == OPC_SwitchOpcode) {
+ // Otherwise, the table isn't computed, but the state machine does start
+ // with an OPC_SwitchOpcode instruction. Populate the table now, since this
+ // is the first time we're selecting an instruction.
+ unsigned Idx = 1;
+ while (1) {
+ // Get the size of this case.
+ unsigned CaseSize = MatcherTable[Idx++];
+ if (CaseSize & 128)
+ CaseSize = GetVBR(CaseSize, MatcherTable, Idx);
+ if (CaseSize == 0) break;
+
+ // Get the opcode, add the index to the table.
+ unsigned Opc = MatcherTable[Idx++];
+ if (Opc >= OpcodeOffset.size())
+ OpcodeOffset.resize((Opc+1)*2);
+ OpcodeOffset[Opc] = Idx;
+ Idx += CaseSize;
+ }
+
+ // Okay, do the lookup for the first opcode.
+ if (N.getOpcode() < OpcodeOffset.size())
+ MatcherIndex = OpcodeOffset[N.getOpcode()];
+ }
+
+ while (1) {
+ assert(MatcherIndex < TableSize && "Invalid index");
+ BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++];
+ switch (Opcode) {
+ case OPC_Scope: {
+ // Okay, the semantics of this operation are that we should push a scope
+ // then evaluate the first child. However, pushing a scope only to have
+ // the first check fail (which then pops it) is inefficient. If we can
+ // determine immediately that the first check (or first several) will
+ // immediately fail, don't even bother pushing a scope for them.
+ unsigned FailIndex;
+
+ while (1) {
+ unsigned NumToSkip = MatcherTable[MatcherIndex++];
+ if (NumToSkip & 128)
+ NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex);
+ // Found the end of the scope with no match.
+ if (NumToSkip == 0) {
+ FailIndex = 0;
+ break;
+ }
+
+ FailIndex = MatcherIndex+NumToSkip;
+
+ // If we can't evaluate this predicate without pushing a scope (e.g. if
+ // it is a 'MoveParent') or if the predicate succeeds on this node, we
+ // push the scope and evaluate the full predicate chain.
+ bool Result;
+ MatcherIndex = IsPredicateKnownToFail(MatcherTable, MatcherIndex, N,
+ Result, *this, RecordedNodes);
+ if (!Result)
+ break;
+
+ DEBUG(errs() << " Skipped scope entry at index " << MatcherIndex
+ << " continuing at " << FailIndex << "\n");
+
+
+ // Otherwise, we know that this case of the Scope is guaranteed to fail,
+ // move to the next case.
+ MatcherIndex = FailIndex;
+ }
+
+ // If the whole scope failed to match, bail.
+ if (FailIndex == 0) break;
+
+ // Push a MatchScope which indicates where to go if the first child fails
+ // to match.
+ MatchScope NewEntry;
+ NewEntry.FailIndex = FailIndex;
+ NewEntry.NodeStack.append(NodeStack.begin(), NodeStack.end());
+ NewEntry.NumRecordedNodes = RecordedNodes.size();
+ NewEntry.NumMatchedMemRefs = MatchedMemRefs.size();
+ NewEntry.InputChain = InputChain;
+ NewEntry.InputFlag = InputFlag;
+ NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty();
+ NewEntry.HasFlagResultNodesMatched = !FlagResultNodesMatched.empty();
+ MatchScopes.push_back(NewEntry);
+ continue;
+ }
+ case OPC_RecordNode:
+ // Remember this node, it may end up being an operand in the pattern.
+ RecordedNodes.push_back(N);
+ continue;
+
+ case OPC_RecordChild0: case OPC_RecordChild1:
+ case OPC_RecordChild2: case OPC_RecordChild3:
+ case OPC_RecordChild4: case OPC_RecordChild5:
+ case OPC_RecordChild6: case OPC_RecordChild7: {
+ unsigned ChildNo = Opcode-OPC_RecordChild0;
+ if (ChildNo >= N.getNumOperands())
+ break; // Match fails if out of range child #.
+
+ RecordedNodes.push_back(N->getOperand(ChildNo));
+ continue;
+ }
+ case OPC_RecordMemRef:
+ MatchedMemRefs.push_back(cast<MemSDNode>(N)->getMemOperand());
+ continue;
+
+ case OPC_CaptureFlagInput:
+ // If the current node has an input flag, capture it in InputFlag.
+ if (N->getNumOperands() != 0 &&
+ N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag)
+ InputFlag = N->getOperand(N->getNumOperands()-1);
+ continue;
+
+ case OPC_MoveChild: {
+ unsigned ChildNo = MatcherTable[MatcherIndex++];
+ if (ChildNo >= N.getNumOperands())
+ break; // Match fails if out of range child #.
+ N = N.getOperand(ChildNo);
+ NodeStack.push_back(N);
+ continue;
+ }
+
+ case OPC_MoveParent:
+ // Pop the current node off the NodeStack.
+ NodeStack.pop_back();
+ assert(!NodeStack.empty() && "Node stack imbalance!");
+ N = NodeStack.back();
+ continue;
+
+ case OPC_CheckSame:
+ if (!::CheckSame(MatcherTable, MatcherIndex, N, RecordedNodes)) break;
+ continue;
+ case OPC_CheckPatternPredicate:
+ if (!::CheckPatternPredicate(MatcherTable, MatcherIndex, *this)) break;
+ continue;
+ case OPC_CheckPredicate:
+ if (!::CheckNodePredicate(MatcherTable, MatcherIndex, *this,
+ N.getNode()))
+ break;
+ continue;
+ case OPC_CheckComplexPat: {
+ unsigned CPNum = MatcherTable[MatcherIndex++];
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckComplexPat");
+ if (!CheckComplexPattern(NodeToMatch, RecordedNodes[RecNo], CPNum,
+ RecordedNodes))
+ break;
+ continue;
+ }
+ case OPC_CheckOpcode:
+ if (!::CheckOpcode(MatcherTable, MatcherIndex, N.getNode())) break;
+ continue;
+
+ case OPC_CheckType:
+ if (!::CheckType(MatcherTable, MatcherIndex, N, TLI)) break;
+ continue;
+
+ case OPC_SwitchOpcode: {
+ unsigned CurNodeOpcode = N.getOpcode();
+ unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart;
+ unsigned CaseSize;
+ while (1) {
+ // Get the size of this case.
+ CaseSize = MatcherTable[MatcherIndex++];
+ if (CaseSize & 128)
+ CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex);
+ if (CaseSize == 0) break;
+
+ // If the opcode matches, then we will execute this case.
+ if (CurNodeOpcode == MatcherTable[MatcherIndex++])
+ break;
+
+ // Otherwise, skip over this case.
+ MatcherIndex += CaseSize;
+ }
+
+ // If no cases matched, bail out.
+ if (CaseSize == 0) break;
+
+ // Otherwise, execute the case we found.
+ DEBUG(errs() << " OpcodeSwitch from " << SwitchStart
+ << " to " << MatcherIndex << "\n");
+ continue;
+ }
+
+ case OPC_SwitchType: {
+ MVT::SimpleValueType CurNodeVT = N.getValueType().getSimpleVT().SimpleTy;
+ unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart;
+ unsigned CaseSize;
+ while (1) {
+ // Get the size of this case.
+ CaseSize = MatcherTable[MatcherIndex++];
+ if (CaseSize & 128)
+ CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex);
+ if (CaseSize == 0) break;
+
+ MVT::SimpleValueType CaseVT =
+ (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ if (CaseVT == MVT::iPTR)
+ CaseVT = TLI.getPointerTy().SimpleTy;
+
+ // If the VT matches, then we will execute this case.
+ if (CurNodeVT == CaseVT)
+ break;
+
+ // Otherwise, skip over this case.
+ MatcherIndex += CaseSize;
+ }
+
+ // If no cases matched, bail out.
+ if (CaseSize == 0) break;
+
+ // Otherwise, execute the case we found.
+ DEBUG(errs() << " TypeSwitch[" << EVT(CurNodeVT).getEVTString()
+ << "] from " << SwitchStart << " to " << MatcherIndex<<'\n');
+ continue;
+ }
+ case OPC_CheckChild0Type: case OPC_CheckChild1Type:
+ case OPC_CheckChild2Type: case OPC_CheckChild3Type:
+ case OPC_CheckChild4Type: case OPC_CheckChild5Type:
+ case OPC_CheckChild6Type: case OPC_CheckChild7Type:
+ if (!::CheckChildType(MatcherTable, MatcherIndex, N, TLI,
+ Opcode-OPC_CheckChild0Type))
+ break;
+ continue;
+ case OPC_CheckCondCode:
+ if (!::CheckCondCode(MatcherTable, MatcherIndex, N)) break;
+ continue;
+ case OPC_CheckValueType:
+ if (!::CheckValueType(MatcherTable, MatcherIndex, N, TLI)) break;
+ continue;
+ case OPC_CheckInteger:
+ if (!::CheckInteger(MatcherTable, MatcherIndex, N)) break;
+ continue;
+ case OPC_CheckAndImm:
+ if (!::CheckAndImm(MatcherTable, MatcherIndex, N, *this)) break;
+ continue;
+ case OPC_CheckOrImm:
+ if (!::CheckOrImm(MatcherTable, MatcherIndex, N, *this)) break;
+ continue;
+
+ case OPC_CheckFoldableChainNode: {
+ assert(NodeStack.size() != 1 && "No parent node");
+ // Verify that all intermediate nodes between the root and this one have
+ // a single use.
+ bool HasMultipleUses = false;
+ for (unsigned i = 1, e = NodeStack.size()-1; i != e; ++i)
+ if (!NodeStack[i].hasOneUse()) {
+ HasMultipleUses = true;
+ break;
+ }
+ if (HasMultipleUses) break;
+
+ // Check to see that the target thinks this is profitable to fold and that
+ // we can fold it without inducing cycles in the graph.
+ if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(),
+ NodeToMatch) ||
+ !IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(),
+ NodeToMatch, true/*We validate our own chains*/))
+ break;
+
+ continue;
+ }
+ case OPC_EmitInteger: {
+ MVT::SimpleValueType VT =
+ (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ int64_t Val = MatcherTable[MatcherIndex++];
+ if (Val & 128)
+ Val = GetVBR(Val, MatcherTable, MatcherIndex);
+ RecordedNodes.push_back(CurDAG->getTargetConstant(Val, VT));
+ continue;
+ }
+ case OPC_EmitRegister: {
+ MVT::SimpleValueType VT =
+ (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ unsigned RegNo = MatcherTable[MatcherIndex++];
+ RecordedNodes.push_back(CurDAG->getRegister(RegNo, VT));
+ continue;
+ }
+
+ case OPC_EmitConvertToTarget: {
+ // Convert from IMM/FPIMM to target version.
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ SDValue Imm = RecordedNodes[RecNo];
+
+ if (Imm->getOpcode() == ISD::Constant) {
+ int64_t Val = cast<ConstantSDNode>(Imm)->getZExtValue();
+ Imm = CurDAG->getTargetConstant(Val, Imm.getValueType());
+ } else if (Imm->getOpcode() == ISD::ConstantFP) {
+ const ConstantFP *Val=cast<ConstantFPSDNode>(Imm)->getConstantFPValue();
+ Imm = CurDAG->getTargetConstantFP(*Val, Imm.getValueType());
+ }
+
+ RecordedNodes.push_back(Imm);
+ continue;
+ }
+
+ case OPC_EmitMergeInputChains: {
+ assert(InputChain.getNode() == 0 &&
+ "EmitMergeInputChains should be the first chain producing node");
+ // This node gets a list of nodes we matched in the input that have
+ // chains. We want to token factor all of the input chains to these nodes
+ // together. However, if any of the input chains is actually one of the
+ // nodes matched in this pattern, then we have an intra-match reference.
+ // Ignore these because the newly token factored chain should not refer to
+ // the old nodes.
+ unsigned NumChains = MatcherTable[MatcherIndex++];
+ assert(NumChains != 0 && "Can't TF zero chains");
+
+ assert(ChainNodesMatched.empty() &&
+ "Should only have one EmitMergeInputChains per match");
+
+ // Read all of the chained nodes.
+ for (unsigned i = 0; i != NumChains; ++i) {
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
+
+ // FIXME: What if other value results of the node have uses not matched
+ // by this pattern?
+ if (ChainNodesMatched.back() != NodeToMatch &&
+ !RecordedNodes[RecNo].hasOneUse()) {
+ ChainNodesMatched.clear();
+ break;
+ }
+ }
+
+ // If the inner loop broke out, the match fails.
+ if (ChainNodesMatched.empty())
+ break;
+
+ // Merge the input chains if they are not intra-pattern references.
+ InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG);
+
+ if (InputChain.getNode() == 0)
+ break; // Failed to merge.
+
+ continue;
+ }
+
+ case OPC_EmitCopyToReg: {
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ unsigned DestPhysReg = MatcherTable[MatcherIndex++];
+
+ if (InputChain.getNode() == 0)
+ InputChain = CurDAG->getEntryNode();
+
+ InputChain = CurDAG->getCopyToReg(InputChain, NodeToMatch->getDebugLoc(),
+ DestPhysReg, RecordedNodes[RecNo],
+ InputFlag);
+
+ InputFlag = InputChain.getValue(1);
+ continue;
+ }
+
+ case OPC_EmitNodeXForm: {
+ unsigned XFormNo = MatcherTable[MatcherIndex++];
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ RecordedNodes.push_back(RunSDNodeXForm(RecordedNodes[RecNo], XFormNo));
+ continue;
+ }
+
+ case OPC_EmitNode:
+ case OPC_MorphNodeTo: {
+ uint16_t TargetOpc = MatcherTable[MatcherIndex++];
+ TargetOpc |= (unsigned short)MatcherTable[MatcherIndex++] << 8;
+ unsigned EmitNodeInfo = MatcherTable[MatcherIndex++];
+ // Get the result VT list.
+ unsigned NumVTs = MatcherTable[MatcherIndex++];
+ SmallVector<EVT, 4> VTs;
+ for (unsigned i = 0; i != NumVTs; ++i) {
+ MVT::SimpleValueType VT =
+ (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ if (VT == MVT::iPTR) VT = TLI.getPointerTy().SimpleTy;
+ VTs.push_back(VT);
+ }
+
+ if (EmitNodeInfo & OPFL_Chain)
+ VTs.push_back(MVT::Other);
+ if (EmitNodeInfo & OPFL_FlagOutput)
+ VTs.push_back(MVT::Flag);
+
+ // This is hot code, so optimize the two most common cases of 1 and 2
+ // results.
+ SDVTList VTList;
+ if (VTs.size() == 1)
+ VTList = CurDAG->getVTList(VTs[0]);
+ else if (VTs.size() == 2)
+ VTList = CurDAG->getVTList(VTs[0], VTs[1]);
+ else
+ VTList = CurDAG->getVTList(VTs.data(), VTs.size());
+
+ // Get the operand list.
+ unsigned NumOps = MatcherTable[MatcherIndex++];
+ SmallVector<SDValue, 8> Ops;
+ for (unsigned i = 0; i != NumOps; ++i) {
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ if (RecNo & 128)
+ RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex);
+
+ assert(RecNo < RecordedNodes.size() && "Invalid EmitNode");
+ Ops.push_back(RecordedNodes[RecNo]);
+ }
+
+ // If there are variadic operands to add, handle them now.
+ if (EmitNodeInfo & OPFL_VariadicInfo) {
+ // Determine the start index to copy from.
+ unsigned FirstOpToCopy = getNumFixedFromVariadicInfo(EmitNodeInfo);
+ FirstOpToCopy += (EmitNodeInfo & OPFL_Chain) ? 1 : 0;
+ assert(NodeToMatch->getNumOperands() >= FirstOpToCopy &&
+ "Invalid variadic node");
+ // Copy all of the variadic operands, not including a potential flag
+ // input.
+ for (unsigned i = FirstOpToCopy, e = NodeToMatch->getNumOperands();
+ i != e; ++i) {
+ SDValue V = NodeToMatch->getOperand(i);
+ if (V.getValueType() == MVT::Flag) break;
+ Ops.push_back(V);
+ }
+ }
+
+ // If this has chain/flag inputs, add them.
+ if (EmitNodeInfo & OPFL_Chain)
+ Ops.push_back(InputChain);
+ if ((EmitNodeInfo & OPFL_FlagInput) && InputFlag.getNode() != 0)
+ Ops.push_back(InputFlag);
+
+ // Create the node.
+ SDNode *Res = 0;
+ if (Opcode != OPC_MorphNodeTo) {
+ // If this is a normal EmitNode command, just create the new node and
+ // add the results to the RecordedNodes list.
+ Res = CurDAG->getMachineNode(TargetOpc, NodeToMatch->getDebugLoc(),
+ VTList, Ops.data(), Ops.size());
+
+ // Add all the non-flag/non-chain results to the RecordedNodes list.
+ for (unsigned i = 0, e = VTs.size(); i != e; ++i) {
+ if (VTs[i] == MVT::Other || VTs[i] == MVT::Flag) break;
+ RecordedNodes.push_back(SDValue(Res, i));
+ }
+
+ } else {
+ Res = MorphNode(NodeToMatch, TargetOpc, VTList, Ops.data(), Ops.size(),
+ EmitNodeInfo);
+ }
+
+ // If the node had chain/flag results, update our notion of the current
+ // chain and flag.
+ if (EmitNodeInfo & OPFL_FlagOutput) {
+ InputFlag = SDValue(Res, VTs.size()-1);
+ if (EmitNodeInfo & OPFL_Chain)
+ InputChain = SDValue(Res, VTs.size()-2);
+ } else if (EmitNodeInfo & OPFL_Chain)
+ InputChain = SDValue(Res, VTs.size()-1);
+
+ // If the OPFL_MemRefs flag is set on this node, slap all of the
+ // accumulated memrefs onto it.
+ //
+ // FIXME: This is vastly incorrect for patterns with multiple outputs
+ // instructions that access memory and for ComplexPatterns that match
+ // loads.
+ if (EmitNodeInfo & OPFL_MemRefs) {
+ MachineSDNode::mmo_iterator MemRefs =
+ MF->allocateMemRefsArray(MatchedMemRefs.size());
+ std::copy(MatchedMemRefs.begin(), MatchedMemRefs.end(), MemRefs);
+ cast<MachineSDNode>(Res)
+ ->setMemRefs(MemRefs, MemRefs + MatchedMemRefs.size());
+ }
+
+ DEBUG(errs() << " "
+ << (Opcode == OPC_MorphNodeTo ? "Morphed" : "Created")
+ << " node: "; Res->dump(CurDAG); errs() << "\n");
+
+ // If this was a MorphNodeTo then we're completely done!
+ if (Opcode == OPC_MorphNodeTo) {
+ // Update chain and flag uses.
+ UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched,
+ InputFlag, FlagResultNodesMatched, true);
+ return Res;
+ }
+
+ continue;
+ }
+
+ case OPC_MarkFlagResults: {
+ unsigned NumNodes = MatcherTable[MatcherIndex++];
+
+ // Read and remember all the flag-result nodes.
+ for (unsigned i = 0; i != NumNodes; ++i) {
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ if (RecNo & 128)
+ RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex);
+
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ FlagResultNodesMatched.push_back(RecordedNodes[RecNo].getNode());
+ }
+ continue;
+ }
+
+ case OPC_CompleteMatch: {
+ // The match has been completed, and any new nodes (if any) have been
+ // created. Patch up references to the matched dag to use the newly
+ // created nodes.
+ unsigned NumResults = MatcherTable[MatcherIndex++];
+
+ for (unsigned i = 0; i != NumResults; ++i) {
+ unsigned ResSlot = MatcherTable[MatcherIndex++];
+ if (ResSlot & 128)
+ ResSlot = GetVBR(ResSlot, MatcherTable, MatcherIndex);
+
+ assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame");
+ SDValue Res = RecordedNodes[ResSlot];
+
+ // FIXME2: Eliminate this horrible hack by fixing the 'Gen' program
+ // after (parallel) on input patterns are removed. This would also
+ // allow us to stop encoding #results in OPC_CompleteMatch's table
+ // entry.
+ if (NodeToMatch->getNumValues() <= i ||
+ NodeToMatch->getValueType(i) == MVT::Other ||
+ NodeToMatch->getValueType(i) == MVT::Flag)
+ break;
+ assert((NodeToMatch->getValueType(i) == Res.getValueType() ||
+ NodeToMatch->getValueType(i) == MVT::iPTR ||
+ Res.getValueType() == MVT::iPTR ||
+ NodeToMatch->getValueType(i).getSizeInBits() ==
+ Res.getValueType().getSizeInBits()) &&
+ "invalid replacement");
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, i), Res);
+ }
+
+ // If the root node defines a flag, add it to the flag nodes to update
+ // list.
+ if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == MVT::Flag)
+ FlagResultNodesMatched.push_back(NodeToMatch);
+
+ // Update chain and flag uses.
+ UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched,
+ InputFlag, FlagResultNodesMatched, false);
+
+ assert(NodeToMatch->use_empty() &&
+ "Didn't replace all uses of the node?");
+
+ // FIXME: We just return here, which interacts correctly with SelectRoot
+ // above. We should fix this to not return an SDNode* anymore.
+ return 0;
+ }
+ }
+
+ // If the code reached this point, then the match failed. See if there is
+ // another child to try in the current 'Scope', otherwise pop it until we
+ // find a case to check.
+ while (1) {
+ if (MatchScopes.empty()) {
+ CannotYetSelect(NodeToMatch);
+ return 0;
+ }
+
+ // Restore the interpreter state back to the point where the scope was
+ // formed.
+ MatchScope &LastScope = MatchScopes.back();
+ RecordedNodes.resize(LastScope.NumRecordedNodes);
+ NodeStack.clear();
+ NodeStack.append(LastScope.NodeStack.begin(), LastScope.NodeStack.end());
+ N = NodeStack.back();
+
+ DEBUG(errs() << " Match failed at index " << MatcherIndex
+ << " continuing at " << LastScope.FailIndex << "\n");
+
+ if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size())
+ MatchedMemRefs.resize(LastScope.NumMatchedMemRefs);
+ MatcherIndex = LastScope.FailIndex;
+
+ InputChain = LastScope.InputChain;
+ InputFlag = LastScope.InputFlag;
+ if (!LastScope.HasChainNodesMatched)
+ ChainNodesMatched.clear();
+ if (!LastScope.HasFlagResultNodesMatched)
+ FlagResultNodesMatched.clear();
+
+ // Check to see what the offset is at the new MatcherIndex. If it is zero
+ // we have reached the end of this scope, otherwise we have another child
+ // in the current scope to try.
+ unsigned NumToSkip = MatcherTable[MatcherIndex++];
+ if (NumToSkip & 128)
+ NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex);
+
+ // If we have another child in this scope to match, update FailIndex and
+ // try it.
+ if (NumToSkip != 0) {
+ LastScope.FailIndex = MatcherIndex+NumToSkip;
+ break;
+ }
+
+ // End of this scope, pop it and try the next child in the containing
+ // scope.
+ MatchScopes.pop_back();
+ }
+ }
+}
+
+
+
void SelectionDAGISel::CannotYetSelect(SDNode *N) {
std::string msg;
raw_string_ostream Msg(msg);
Msg << "Cannot yet select: ";
- N->printrFull(Msg, CurDAG);
+
+ if (N->getOpcode() != ISD::INTRINSIC_W_CHAIN &&
+ N->getOpcode() != ISD::INTRINSIC_WO_CHAIN &&
+ N->getOpcode() != ISD::INTRINSIC_VOID) {
+ N->printrFull(Msg, CurDAG);
+ } else {
+ bool HasInputChain = N->getOperand(0).getValueType() == MVT::Other;
+ unsigned iid =
+ cast<ConstantSDNode>(N->getOperand(HasInputChain))->getZExtValue();
+ if (iid < Intrinsic::num_intrinsics)
+ Msg << "intrinsic %" << Intrinsic::getName((Intrinsic::ID)iid);
+ else if (const TargetIntrinsicInfo *TII = TM.getIntrinsicInfo())
+ Msg << "target intrinsic %" << TII->getName(iid);
+ else
+ Msg << "unknown intrinsic #" << iid;
+ }
llvm_report_error(Msg.str());
}
-void SelectionDAGISel::CannotYetSelectIntrinsic(SDNode *N) {
- dbgs() << "Cannot yet select: ";
- unsigned iid =
- cast<ConstantSDNode>(N->getOperand(N->getOperand(0).getValueType() ==
- MVT::Other))->getZExtValue();
- if (iid < Intrinsic::num_intrinsics)
- llvm_report_error("Cannot yet select: intrinsic %" +
- Intrinsic::getName((Intrinsic::ID)iid));
- else if (const TargetIntrinsicInfo *tii = TM.getIntrinsicInfo())
- llvm_report_error(Twine("Cannot yet select: target intrinsic %") +
- tii->getName(iid));
-}
-
char SelectionDAGISel::ID = 0;
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index d74ec7e..8d0d884 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include <ctype.h>
using namespace llvm;
namespace llvm {
@@ -540,6 +541,24 @@ TargetLowering::~TargetLowering() {
delete &TLOF;
}
+/// canOpTrap - Returns true if the operation can trap for the value type.
+/// VT must be a legal type.
+bool TargetLowering::canOpTrap(unsigned Op, EVT VT) const {
+ assert(isTypeLegal(VT));
+ switch (Op) {
+ default:
+ return false;
+ case ISD::FDIV:
+ case ISD::FREM:
+ case ISD::SDIV:
+ case ISD::UDIV:
+ case ISD::SREM:
+ case ISD::UREM:
+ return true;
+ }
+}
+
+
static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
unsigned &NumIntermediates,
EVT &RegisterVT,
@@ -1423,8 +1442,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
case ISD::TRUNCATE: {
// Simplify the input, using demanded bit information, and compute the known
// zero/one bits live out.
+ unsigned OperandBitWidth =
+ Op.getOperand(0).getValueType().getScalarType().getSizeInBits();
APInt TruncMask = NewMask;
- TruncMask.zext(Op.getOperand(0).getValueSizeInBits());
+ TruncMask.zext(OperandBitWidth);
if (SimplifyDemandedBits(Op.getOperand(0), TruncMask,
KnownZero, KnownOne, TLO, Depth+1))
return true;
@@ -1435,15 +1456,14 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// on the known demanded bits.
if (Op.getOperand(0).getNode()->hasOneUse()) {
SDValue In = Op.getOperand(0);
- unsigned InBitWidth = In.getValueSizeInBits();
switch (In.getOpcode()) {
default: break;
case ISD::SRL:
// Shrink SRL by a constant if none of the high bits shifted in are
// demanded.
if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(In.getOperand(1))){
- APInt HighBits = APInt::getHighBitsSet(InBitWidth,
- InBitWidth - BitWidth);
+ APInt HighBits = APInt::getHighBitsSet(OperandBitWidth,
+ OperandBitWidth - BitWidth);
HighBits = HighBits.lshr(ShAmt->getZExtValue());
HighBits.trunc(BitWidth);
@@ -1589,7 +1609,7 @@ static bool ValueHasExactlyOneBitSet(SDValue Val, const SelectionDAG &DAG) {
// Fall back to ComputeMaskedBits to catch other known cases.
EVT OpVT = Val.getValueType();
- unsigned BitWidth = OpVT.getSizeInBits();
+ unsigned BitWidth = OpVT.getScalarType().getSizeInBits();
APInt Mask = APInt::getAllOnesValue(BitWidth);
APInt KnownZero, KnownOne;
DAG.ComputeMaskedBits(Val, Mask, KnownZero, KnownOne);
@@ -1698,7 +1718,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
SDValue NewLoad = DAG.getLoad(newVT, dl, Lod->getChain(), Ptr,
Lod->getSrcValue(),
Lod->getSrcValueOffset() + bestOffset,
- false, NewAlign);
+ false, false, NewAlign);
return DAG.getSetCC(dl, VT,
DAG.getNode(ISD::AND, dl, newVT, NewLoad,
DAG.getConstant(bestMask.trunc(bestWidth),
@@ -1757,7 +1777,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
break; // todo, be more careful with signed comparisons
}
} else if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
- (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
+ (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
EVT ExtSrcTy = cast<VTSDNode>(N0.getOperand(1))->getVT();
unsigned ExtSrcTyBits = ExtSrcTy.getSizeInBits();
EVT ExtDstTy = N0.getValueType();
@@ -1791,22 +1811,21 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
Cond);
} else if ((N1C->isNullValue() || N1C->getAPIntValue() == 1) &&
(Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
-
// SETCC (SETCC), [0|1], [EQ|NE] -> SETCC
- if (N0.getOpcode() == ISD::SETCC) {
+ if (N0.getOpcode() == ISD::SETCC &&
+ isTypeLegal(VT) && VT.bitsLE(N0.getValueType())) {
bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (N1C->getAPIntValue() != 1);
if (TrueWhenTrue)
- return N0;
-
+ return DAG.getNode(ISD::TRUNCATE, dl, VT, N0);
// Invert the condition.
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
CC = ISD::getSetCCInverse(CC,
N0.getOperand(0).getValueType().isInteger());
return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
}
-
+
if ((N0.getOpcode() == ISD::XOR ||
- (N0.getOpcode() == ISD::AND &&
+ (N0.getOpcode() == ISD::AND &&
N0.getOperand(0).getOpcode() == ISD::XOR &&
N0.getOperand(1) == N0.getOperand(0).getOperand(1))) &&
isa<ConstantSDNode>(N0.getOperand(1)) &&
@@ -1829,9 +1848,36 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
N0.getOperand(0).getOperand(0),
N0.getOperand(1));
}
+
return DAG.getSetCC(dl, VT, Val, N1,
Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
}
+ } else if (N1C->getAPIntValue() == 1 &&
+ (VT == MVT::i1 ||
+ getBooleanContents() == ZeroOrOneBooleanContent)) {
+ SDValue Op0 = N0;
+ if (Op0.getOpcode() == ISD::TRUNCATE)
+ Op0 = Op0.getOperand(0);
+
+ if ((Op0.getOpcode() == ISD::XOR) &&
+ Op0.getOperand(0).getOpcode() == ISD::SETCC &&
+ Op0.getOperand(1).getOpcode() == ISD::SETCC) {
+ // (xor (setcc), (setcc)) == / != 1 -> (setcc) != / == (setcc)
+ Cond = (Cond == ISD::SETEQ) ? ISD::SETNE : ISD::SETEQ;
+ return DAG.getSetCC(dl, VT, Op0.getOperand(0), Op0.getOperand(1),
+ Cond);
+ } else if (Op0.getOpcode() == ISD::AND &&
+ isa<ConstantSDNode>(Op0.getOperand(1)) &&
+ cast<ConstantSDNode>(Op0.getOperand(1))->getAPIntValue() == 1) {
+ // If this is (X&1) == / != 1, normalize it to (X&1) != / == 0.
+ if (Op0.getValueType() != VT)
+ Op0 = DAG.getNode(ISD::AND, dl, VT,
+ DAG.getNode(ISD::TRUNCATE, dl, VT, Op0.getOperand(0)),
+ DAG.getConstant(1, VT));
+ return DAG.getSetCC(dl, VT, Op0,
+ DAG.getConstant(0, Op0.getValueType()),
+ Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
+ }
}
}
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 1d9bda4..ce72b2f 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -662,7 +662,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
if (!tii_->isTriviallyReMaterializable(DefMI, AA))
return false;
bool SawStore = false;
- if (!DefMI->isSafeToMove(tii_, SawStore, AA))
+ if (!DefMI->isSafeToMove(tii_, AA, SawStore))
return false;
if (TID.getNumDefs() != 1)
return false;
@@ -702,7 +702,8 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
for (const unsigned* SR = tri_->getSubRegisters(DstReg); *SR; ++SR) {
if (!li_->hasInterval(*SR))
continue;
- DLR = li_->getInterval(*SR).getLiveRangeContaining(DefIdx);
+ const LiveRange *DLR =
+ li_->getInterval(*SR).getLiveRangeContaining(DefIdx);
if (DLR && DLR->valno->getCopy() == CopyMI)
DLR->valno->setCopy(0);
}
@@ -741,9 +742,21 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
NewMI->addOperand(MO);
if (MO.isDef() && li_->hasInterval(MO.getReg())) {
unsigned Reg = MO.getReg();
- DLR = li_->getInterval(Reg).getLiveRangeContaining(DefIdx);
+ const LiveRange *DLR =
+ li_->getInterval(Reg).getLiveRangeContaining(DefIdx);
if (DLR && DLR->valno->getCopy() == CopyMI)
DLR->valno->setCopy(0);
+ // Handle subregs as well
+ if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ for (const unsigned* SR = tri_->getSubRegisters(Reg); *SR; ++SR) {
+ if (!li_->hasInterval(*SR))
+ continue;
+ const LiveRange *DLR =
+ li_->getInterval(*SR).getLiveRangeContaining(DefIdx);
+ if (DLR && DLR->valno->getCopy() == CopyMI)
+ DLR->valno->setCopy(0);
+ }
+ }
}
}
@@ -752,6 +765,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
CopyMI->eraseFromParent();
ReMatCopies.insert(CopyMI);
ReMatDefs.insert(DefMI);
+ DEBUG(dbgs() << "Remat: " << *NewMI);
++NumReMats;
return true;
}
@@ -771,11 +785,16 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
SubIdx = 0;
}
+ // Copy the register use-list before traversing it. We may be adding operands
+ // and invalidating pointers.
+ SmallVector<std::pair<MachineInstr*, unsigned>, 32> reglist;
for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg),
- E = mri_->reg_end(); I != E; ) {
- MachineOperand &O = I.getOperand();
- MachineInstr *UseMI = &*I;
- ++I;
+ E = mri_->reg_end(); I != E; ++I)
+ reglist.push_back(std::make_pair(&*I, I.getOperandNo()));
+
+ for (unsigned N=0; N != reglist.size(); ++N) {
+ MachineInstr *UseMI = reglist[N].first;
+ MachineOperand &O = UseMI->getOperand(reglist[N].second);
unsigned OldSubIdx = O.getSubReg();
if (DstIsPhys) {
unsigned UseDstReg = DstReg;
@@ -796,6 +815,19 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
O.setReg(UseDstReg);
O.setSubReg(0);
+ if (OldSubIdx) {
+ // Def and kill of subregister of a virtual register actually defs and
+ // kills the whole register. Add imp-defs and imp-kills as needed.
+ if (O.isDef()) {
+ if(O.isDead())
+ UseMI->addRegisterDead(DstReg, tri_, true);
+ else
+ UseMI->addRegisterDefined(DstReg, tri_);
+ } else if (!O.isUndef() &&
+ (O.isKill() ||
+ UseMI->isRegTiedToDefOperand(&O-&UseMI->getOperand(0))))
+ UseMI->addRegisterKilled(DstReg, tri_, true);
+ }
continue;
}
@@ -1148,12 +1180,14 @@ SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned LargeReg,
LiveInterval &SmallInt = li_->getInterval(SmallReg);
unsigned LargeSize = li_->getApproximateInstructionCount(LargeInt);
unsigned SmallSize = li_->getApproximateInstructionCount(SmallInt);
- if (SmallSize > Threshold || LargeSize > Threshold)
- if ((float)std::distance(mri_->use_nodbg_begin(SmallReg),
- mri_->use_nodbg_end()) / SmallSize <
- (float)std::distance(mri_->use_nodbg_begin(LargeReg),
- mri_->use_nodbg_end()) / LargeSize)
+ if (LargeSize > Threshold) {
+ unsigned SmallUses = std::distance(mri_->use_nodbg_begin(SmallReg),
+ mri_->use_nodbg_end());
+ unsigned LargeUses = std::distance(mri_->use_nodbg_begin(LargeReg),
+ mri_->use_nodbg_end());
+ if (SmallUses*LargeSize < LargeUses*SmallSize)
return false;
+ }
return true;
}
@@ -1173,6 +1207,8 @@ SimpleRegisterCoalescing::HasIncompatibleSubRegDefUse(MachineInstr *CopyMI,
for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(VirtReg),
E = mri_->reg_end(); I != E; ++I) {
MachineOperand &O = I.getOperand();
+ if (O.isDebug())
+ continue;
MachineInstr *MI = &*I;
if (MI == CopyMI || JoinedCopies.count(MI))
continue;
@@ -1559,7 +1595,10 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
(isExtSubReg || DstRC->isASubClass()) &&
!isWinToJoinCrossClass(LargeReg, SmallReg,
allocatableRCRegs_[NewRC].count())) {
- DEBUG(dbgs() << "\tSrc/Dest are different register classes.\n");
+ DEBUG(dbgs() << "\tSrc/Dest are different register classes: "
+ << SrcRC->getName() << "/"
+ << DstRC->getName() << " -> "
+ << NewRC->getName() << ".\n");
// Allow the coalescer to try again in case either side gets coalesced to
// a physical register that's compatible with the other side. e.g.
// r1024 = MOV32to32_ r1025
@@ -1680,6 +1719,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
(AdjustCopiesBackFrom(SrcInt, DstInt, CopyMI) ||
RemoveCopyByCommutingDef(SrcInt, DstInt, CopyMI))) {
JoinedCopies.insert(CopyMI);
+ DEBUG(dbgs() << "Trivial!\n");
return true;
}
@@ -1839,7 +1879,7 @@ static unsigned ComputeUltimateVN(VNInfo *VNI,
// If the VN has already been computed, just return it.
if (ThisValNoAssignments[VN] >= 0)
return ThisValNoAssignments[VN];
-// assert(ThisValNoAssignments[VN] != -2 && "Cyclic case?");
+ assert(ThisValNoAssignments[VN] != -2 && "Cyclic value numbers");
// If this val is not a copy from the other val, then it must be a new value
// number in the destination.
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index 8d4d1b2..059e8d6 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -44,7 +44,6 @@ namespace {
const Type *FunctionContextTy;
Constant *RegisterFn;
Constant *UnregisterFn;
- Constant *ResumeFn;
Constant *BuiltinSetjmpFn;
Constant *FrameAddrFn;
Constant *LSDAAddrFn;
@@ -67,8 +66,8 @@ namespace {
}
private:
- void markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
- Value *CallSite,
+ void insertCallSiteStore(Instruction *I, int Number, Value *CallSite);
+ void markInvokeCallSite(InvokeInst *II, int InvokeNo, Value *CallSite,
SwitchInst *CatchSwitch);
void splitLiveRangesLiveAcrossInvokes(SmallVector<InvokeInst*,16> &Invokes);
bool insertSjLjEHSupport(Function &F);
@@ -107,11 +106,6 @@ bool SjLjEHPass::doInitialization(Module &M) {
Type::getVoidTy(M.getContext()),
PointerType::getUnqual(FunctionContextTy),
(Type *)0);
- ResumeFn =
- M.getOrInsertFunction("_Unwind_SjLj_Resume",
- Type::getVoidTy(M.getContext()),
- VoidPtrTy,
- (Type *)0);
FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress);
BuiltinSetjmpFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setjmp);
LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda);
@@ -123,12 +117,22 @@ bool SjLjEHPass::doInitialization(Module &M) {
return true;
}
+/// insertCallSiteStore - Insert a store of the call-site value to the
+/// function context
+void SjLjEHPass::insertCallSiteStore(Instruction *I, int Number,
+ Value *CallSite) {
+ ConstantInt *CallSiteNoC = ConstantInt::get(Type::getInt32Ty(I->getContext()),
+ Number);
+ // Insert a store of the call-site number
+ new StoreInst(CallSiteNoC, CallSite, true, I); // volatile
+}
+
/// markInvokeCallSite - Insert code to mark the call_site for this invoke
-void SjLjEHPass::markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
+void SjLjEHPass::markInvokeCallSite(InvokeInst *II, int InvokeNo,
Value *CallSite,
SwitchInst *CatchSwitch) {
ConstantInt *CallSiteNoC= ConstantInt::get(Type::getInt32Ty(II->getContext()),
- InvokeNo);
+ InvokeNo);
// The runtime comes back to the dispatcher with the call_site - 1 in
// the context. Odd, but there it is.
ConstantInt *SwitchValC = ConstantInt::get(Type::getInt32Ty(II->getContext()),
@@ -145,8 +149,11 @@ void SjLjEHPass::markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
}
}
- // Insert a store of the invoke num before the invoke
- new StoreInst(CallSiteNoC, CallSite, true, II); // volatile
+ // Insert the store of the call site value
+ insertCallSiteStore(II, InvokeNo, CallSite);
+
+ // Record the call site value for the back end so it stays associated with
+ // the invoke.
CallInst::Create(CallSiteFn, CallSiteNoC, "", II);
// Add a switch case to our unwind block.
@@ -272,8 +279,8 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
SmallVector<InvokeInst*,16> Invokes;
// Look through the terminators of the basic blocks to find invokes, returns
- // and unwinds
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ // and unwinds.
+ for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
// Remember all return instructions in case we insert an invoke into this
// function.
@@ -283,6 +290,7 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
} else if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
Unwinds.push_back(UI);
}
+ }
// If we don't have any invokes or unwinds, there's nothing to do.
if (Unwinds.empty() && Invokes.empty()) return false;
@@ -478,24 +486,21 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
for (unsigned i = 0, e = Invokes.size(); i != e; ++i)
markInvokeCallSite(Invokes[i], i+1, CallSite, DispatchSwitch);
- // The front end has likely added calls to _Unwind_Resume. We need
- // to find those calls and mark the call_site as -1 immediately prior.
- // resume is a noreturn function, so any block that has a call to it
- // should end in an 'unreachable' instruction with the call immediately
- // prior. That's how we'll search.
- // ??? There's got to be a better way. this is fugly.
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
- if ((dyn_cast<UnreachableInst>(BB->getTerminator()))) {
- BasicBlock::iterator I = BB->getTerminator();
- // Check the previous instruction and see if it's a resume call
- if (I == BB->begin()) continue;
- if (CallInst *CI = dyn_cast<CallInst>(--I)) {
- if (CI->getCalledFunction() == ResumeFn) {
- Value *NegativeOne = Constant::getAllOnesValue(Int32Ty);
- new StoreInst(NegativeOne, CallSite, true, I); // volatile
- }
+ // Mark call instructions that aren't nounwind as no-action
+ // (call_site == -1). Skip the entry block, as prior to then, no function
+ // context has been created for this function and any unexpected exceptions
+ // thrown will go directly to the caller's context, which is what we want
+ // anyway, so no need to do anything here.
+ for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) {
+ for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I)
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ // Ignore calls to the EH builtins (eh.selector, eh.exception)
+ Constant *Callee = CI->getCalledFunction();
+ if (Callee != SelectorFn && Callee != ExceptionFn
+ && !CI->doesNotThrow())
+ insertCallSiteStore(CI, -1, CallSite);
}
- }
+ }
// Replace all unwinds with a branch to the unwind handler.
// ??? Should this ever happen with sjlj exceptions?
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp
index 48bb5af..8a6a727 100644
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -113,7 +113,7 @@ bool StackProtector::RequiresStackProtector() const {
if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) {
// We apparently only care about character arrays.
- if (!AT->getElementType()->isInteger(8))
+ if (!AT->getElementType()->isIntegerTy(8))
continue;
// If an array has more than SSPBufferSize bytes of allocated space,
diff --git a/lib/CodeGen/TailDuplication.cpp b/lib/CodeGen/TailDuplication.cpp
index 9ab4058..3223e53 100644
--- a/lib/CodeGen/TailDuplication.cpp
+++ b/lib/CodeGen/TailDuplication.cpp
@@ -403,26 +403,45 @@ TailDuplicatePass::UpdateSuccessorsPHIs(MachineBasicBlock *FromBB, bool isDead,
II->RemoveOperand(i);
}
}
- II->RemoveOperand(Idx+1);
- II->RemoveOperand(Idx);
- }
+ } else
+ Idx = 0;
+
+ // If Idx is set, the operands at Idx and Idx+1 must be removed.
+ // We reuse the location to avoid expensive RemoveOperand calls.
+
DenseMap<unsigned,AvailableValsTy>::iterator LI=SSAUpdateVals.find(Reg);
if (LI != SSAUpdateVals.end()) {
// This register is defined in the tail block.
for (unsigned j = 0, ee = LI->second.size(); j != ee; ++j) {
MachineBasicBlock *SrcBB = LI->second[j].first;
unsigned SrcReg = LI->second[j].second;
- II->addOperand(MachineOperand::CreateReg(SrcReg, false));
- II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ if (Idx != 0) {
+ II->getOperand(Idx).setReg(SrcReg);
+ II->getOperand(Idx+1).setMBB(SrcBB);
+ Idx = 0;
+ } else {
+ II->addOperand(MachineOperand::CreateReg(SrcReg, false));
+ II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ }
}
} else {
// Live in tail block, must also be live in predecessors.
for (unsigned j = 0, ee = TDBBs.size(); j != ee; ++j) {
MachineBasicBlock *SrcBB = TDBBs[j];
- II->addOperand(MachineOperand::CreateReg(Reg, false));
- II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ if (Idx != 0) {
+ II->getOperand(Idx).setReg(Reg);
+ II->getOperand(Idx+1).setMBB(SrcBB);
+ Idx = 0;
+ } else {
+ II->addOperand(MachineOperand::CreateReg(Reg, false));
+ II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ }
}
}
+ if (Idx != 0) {
+ II->RemoveOperand(Idx+1);
+ II->RemoveOperand(Idx);
+ }
}
}
}
diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp
index a0fccab..e9e998f 100644
--- a/lib/CodeGen/TargetInstrInfoImpl.cpp
+++ b/lib/CodeGen/TargetInstrInfoImpl.cpp
@@ -150,6 +150,11 @@ void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
MBB.insert(I, MI);
}
+bool TargetInstrInfoImpl::produceSameValue(const MachineInstr *MI0,
+ const MachineInstr *MI1) const {
+ return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
+}
+
MachineInstr *TargetInstrInfoImpl::duplicate(MachineInstr *Orig,
MachineFunction &MF) const {
assert(!Orig->getDesc().isNotDuplicable() &&
@@ -157,37 +162,6 @@ MachineInstr *TargetInstrInfoImpl::duplicate(MachineInstr *Orig,
return MF.CloneMachineInstr(Orig);
}
-bool
-TargetInstrInfoImpl::isIdentical(const MachineInstr *MI,
- const MachineInstr *Other,
- const MachineRegisterInfo *MRI) const {
- if (MI->getOpcode() != Other->getOpcode() ||
- MI->getNumOperands() != Other->getNumOperands())
- return false;
-
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
- const MachineOperand &OMO = Other->getOperand(i);
- if (MO.isReg() && MO.isDef()) {
- assert(OMO.isReg() && OMO.isDef());
- unsigned Reg = MO.getReg();
- if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
- if (Reg != OMO.getReg())
- return false;
- } else if (MRI->getRegClass(MO.getReg()) !=
- MRI->getRegClass(OMO.getReg()))
- return false;
-
- continue;
- }
-
- if (!MO.isIdenticalTo(OMO))
- return false;
- }
-
- return true;
-}
-
unsigned
TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const {
unsigned FnSize = 0;
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
new file mode 100644
index 0000000..d127f53
--- /dev/null
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -0,0 +1,902 @@
+//===-- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#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/Dwarf.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace llvm;
+using namespace dwarf;
+
+//===----------------------------------------------------------------------===//
+// ELF
+//===----------------------------------------------------------------------===//
+typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
+
+TargetLoweringObjectFileELF::~TargetLoweringObjectFileELF() {
+ // If we have the section uniquing map, free it.
+ delete (ELFUniqueMapTy*)UniquingMap;
+}
+
+const MCSection *TargetLoweringObjectFileELF::
+getELFSection(StringRef Section, unsigned Type, unsigned Flags,
+ SectionKind Kind, bool IsExplicit) const {
+ if (UniquingMap == 0)
+ UniquingMap = new ELFUniqueMapTy();
+ ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)UniquingMap;
+
+ // Do the lookup, if we have a hit, return it.
+ const MCSectionELF *&Entry = Map[Section];
+ if (Entry) return Entry;
+
+ return Entry = MCSectionELF::Create(Section, Type, Flags, Kind, IsExplicit,
+ getContext());
+}
+
+void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
+ const TargetMachine &TM) {
+ if (UniquingMap != 0)
+ ((ELFUniqueMapTy*)UniquingMap)->clear();
+ TargetLoweringObjectFile::Initialize(Ctx, TM);
+
+ BSSSection =
+ getELFSection(".bss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getBSS());
+
+ TextSection =
+ getELFSection(".text", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC,
+ SectionKind::getText());
+
+ DataSection =
+ getELFSection(".data", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getDataRel());
+
+ ReadOnlySection =
+ getELFSection(".rodata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC,
+ SectionKind::getReadOnly());
+
+ TLSDataSection =
+ getELFSection(".tdata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
+ MCSectionELF::SHF_WRITE, SectionKind::getThreadData());
+
+ TLSBSSSection =
+ getELFSection(".tbss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
+ MCSectionELF::SHF_WRITE, SectionKind::getThreadBSS());
+
+ DataRelSection =
+ getELFSection(".data.rel", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ DataRelLocalSection =
+ getELFSection(".data.rel.local", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRelLocal());
+
+ DataRelROSection =
+ getELFSection(".data.rel.ro", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getReadOnlyWithRel());
+
+ DataRelROLocalSection =
+ getELFSection(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getReadOnlyWithRelLocal());
+
+ MergeableConst4Section =
+ getELFSection(".rodata.cst4", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst4());
+
+ MergeableConst8Section =
+ getELFSection(".rodata.cst8", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst8());
+
+ MergeableConst16Section =
+ getELFSection(".rodata.cst16", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst16());
+
+ StaticCtorSection =
+ getELFSection(".ctors", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ StaticDtorSection =
+ getELFSection(".dtors", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ // Exception Handling Sections.
+
+ // FIXME: We're emitting LSDA info into a readonly section on ELF, even though
+ // it contains relocatable pointers. In PIC mode, this is probably a big
+ // runtime hit for C++ apps. Either the contents of the LSDA need to be
+ // adjusted or this should be a data section.
+ LSDASection =
+ getELFSection(".gcc_except_table", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
+ EHFrameSection =
+ getELFSection(".eh_frame", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ // Debug Info Sections.
+ DwarfAbbrevSection =
+ getELFSection(".debug_abbrev", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfInfoSection =
+ getELFSection(".debug_info", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfLineSection =
+ getELFSection(".debug_line", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfFrameSection =
+ getELFSection(".debug_frame", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ getELFSection(".debug_pubnames", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfPubTypesSection =
+ getELFSection(".debug_pubtypes", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfStrSection =
+ getELFSection(".debug_str", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfLocSection =
+ getELFSection(".debug_loc", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfARangesSection =
+ getELFSection(".debug_aranges", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfRangesSection =
+ getELFSection(".debug_ranges", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfMacroInfoSection =
+ getELFSection(".debug_macinfo", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+}
+
+
+static SectionKind
+getELFKindForNamedSection(StringRef Name, SectionKind K) {
+ if (Name.empty() || Name[0] != '.') return K;
+
+ // Some lame default implementation based on some magic section names.
+ 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 (Name == ".tdata" ||
+ Name.startswith(".tdata.") ||
+ Name.startswith(".gnu.linkonce.td.") ||
+ Name.startswith(".llvm.linkonce.td."))
+ return SectionKind::getThreadData();
+
+ if (Name == ".tbss" ||
+ Name.startswith(".tbss.") ||
+ Name.startswith(".gnu.linkonce.tb.") ||
+ Name.startswith(".llvm.linkonce.tb."))
+ return SectionKind::getThreadBSS();
+
+ return K;
+}
+
+
+static unsigned getELFSectionType(StringRef Name, SectionKind K) {
+
+ if (Name == ".init_array")
+ return MCSectionELF::SHT_INIT_ARRAY;
+
+ if (Name == ".fini_array")
+ return MCSectionELF::SHT_FINI_ARRAY;
+
+ if (Name == ".preinit_array")
+ return MCSectionELF::SHT_PREINIT_ARRAY;
+
+ if (K.isBSS() || K.isThreadBSS())
+ return MCSectionELF::SHT_NOBITS;
+
+ return MCSectionELF::SHT_PROGBITS;
+}
+
+
+static unsigned
+getELFSectionFlags(SectionKind K) {
+ unsigned Flags = 0;
+
+ if (!K.isMetadata())
+ Flags |= MCSectionELF::SHF_ALLOC;
+
+ if (K.isText())
+ Flags |= MCSectionELF::SHF_EXECINSTR;
+
+ if (K.isWriteable())
+ Flags |= MCSectionELF::SHF_WRITE;
+
+ if (K.isThreadLocal())
+ Flags |= MCSectionELF::SHF_TLS;
+
+ // K.isMergeableConst() is left out to honour PR4650
+ if (K.isMergeableCString() || K.isMergeableConst4() ||
+ K.isMergeableConst8() || K.isMergeableConst16())
+ Flags |= MCSectionELF::SHF_MERGE;
+
+ if (K.isMergeableCString())
+ Flags |= MCSectionELF::SHF_STRINGS;
+
+ return Flags;
+}
+
+
+const MCSection *TargetLoweringObjectFileELF::
+getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ StringRef SectionName = GV->getSection();
+
+ // Infer section flags from the section name if we can.
+ Kind = getELFKindForNamedSection(SectionName, Kind);
+
+ return getELFSection(SectionName,
+ getELFSectionType(SectionName, Kind),
+ getELFSectionFlags(Kind), Kind, true);
+}
+
+static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
+ if (Kind.isText()) return ".gnu.linkonce.t.";
+ if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
+
+ if (Kind.isThreadData()) return ".gnu.linkonce.td.";
+ if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
+
+ if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
+ if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
+ if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
+ if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
+
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return ".gnu.linkonce.d.rel.ro.";
+}
+
+const MCSection *TargetLoweringObjectFileELF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+
+ // 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() && !Kind.isCommon() && !Kind.isBSS()) {
+ const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
+ SmallString<128> Name;
+ Name.append(Prefix, Prefix+strlen(Prefix));
+ Mang->getNameWithPrefix(Name, GV, false);
+ return getELFSection(Name.str(), getELFSectionType(Name.str(), Kind),
+ getELFSectionFlags(Kind), Kind);
+ }
+
+ if (Kind.isText()) return TextSection;
+
+ if (Kind.isMergeable1ByteCString() ||
+ Kind.isMergeable2ByteCString() ||
+ Kind.isMergeable4ByteCString()) {
+
+ // We also need alignment here.
+ // FIXME: this is getting the alignment of the character, not the
+ // alignment of the global!
+ unsigned Align =
+ TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
+
+ const char *SizeSpec = ".rodata.str1.";
+ if (Kind.isMergeable2ByteCString())
+ SizeSpec = ".rodata.str2.";
+ else if (Kind.isMergeable4ByteCString())
+ SizeSpec = ".rodata.str4.";
+ else
+ assert(Kind.isMergeable1ByteCString() && "unknown string width");
+
+
+ std::string Name = SizeSpec + utostr(Align);
+ return getELFSection(Name, MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC |
+ MCSectionELF::SHF_MERGE |
+ MCSectionELF::SHF_STRINGS,
+ Kind);
+ }
+
+ if (Kind.isMergeableConst()) {
+ if (Kind.isMergeableConst4() && MergeableConst4Section)
+ return MergeableConst4Section;
+ if (Kind.isMergeableConst8() && MergeableConst8Section)
+ return MergeableConst8Section;
+ if (Kind.isMergeableConst16() && MergeableConst16Section)
+ return MergeableConst16Section;
+ return ReadOnlySection; // .const
+ }
+
+ if (Kind.isReadOnly()) return ReadOnlySection;
+
+ if (Kind.isThreadData()) return TLSDataSection;
+ if (Kind.isThreadBSS()) return TLSBSSSection;
+
+ // 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;
+ if (Kind.isDataRel()) return DataRelSection;
+ if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return DataRelROSection;
+}
+
+/// getSectionForConstant - Given a mergeable constant with the
+/// specified size and relocation information, return a section that it
+/// should be placed in.
+const MCSection *TargetLoweringObjectFileELF::
+getSectionForConstant(SectionKind Kind) const {
+ if (Kind.isMergeableConst4() && MergeableConst4Section)
+ return MergeableConst4Section;
+ if (Kind.isMergeableConst8() && MergeableConst8Section)
+ return MergeableConst8Section;
+ if (Kind.isMergeableConst16() && MergeableConst16Section)
+ return MergeableConst16Section;
+ if (Kind.isReadOnly())
+ return ReadOnlySection;
+
+ if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return DataRelROSection;
+}
+
+const MCExpr *TargetLoweringObjectFileELF::
+getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const {
+
+ if (Encoding & dwarf::DW_EH_PE_indirect) {
+ MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
+
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, GV, true);
+ Name += ".DW.stub";
+
+ // Add information about the stub reference to ELFMMI so that the stub
+ // gets emitted by the asmprinter.
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = ELFMMI.getGVStubEntry(Sym);
+ if (StubSym == 0) {
+ Name.clear();
+ Mang->getNameWithPrefix(Name, GV, false);
+ StubSym = getContext().GetOrCreateSymbol(Name.str());
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfReference(Sym, MMI,
+ Encoding & ~dwarf::DW_EH_PE_indirect);
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
+}
+
+//===----------------------------------------------------------------------===//
+// MachO
+//===----------------------------------------------------------------------===//
+
+typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
+
+TargetLoweringObjectFileMachO::~TargetLoweringObjectFileMachO() {
+ // If we have the MachO uniquing map, free it.
+ delete (MachOUniqueMapTy*)UniquingMap;
+}
+
+
+const MCSectionMachO *TargetLoweringObjectFileMachO::
+getMachOSection(StringRef Segment, 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 (UniquingMap == 0)
+ UniquingMap = new MachOUniqueMapTy();
+ MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)UniquingMap;
+
+ // 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()];
+ if (Entry) return Entry;
+
+ // Otherwise, return a new section.
+ return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
+ Reserved2, Kind, getContext());
+}
+
+
+void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
+ const TargetMachine &TM) {
+ if (UniquingMap != 0)
+ ((MachOUniqueMapTy*)UniquingMap)->clear();
+ TargetLoweringObjectFile::Initialize(Ctx, TM);
+
+ TextSection // .text
+ = getMachOSection("__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ SectionKind::getText());
+ DataSection // .data
+ = getMachOSection("__DATA", "__data", 0, SectionKind::getDataRel());
+
+ CStringSection // .cstring
+ = getMachOSection("__TEXT", "__cstring", MCSectionMachO::S_CSTRING_LITERALS,
+ SectionKind::getMergeable1ByteCString());
+ UStringSection
+ = getMachOSection("__TEXT","__ustring", 0,
+ SectionKind::getMergeable2ByteCString());
+ FourByteConstantSection // .literal4
+ = getMachOSection("__TEXT", "__literal4", MCSectionMachO::S_4BYTE_LITERALS,
+ SectionKind::getMergeableConst4());
+ EightByteConstantSection // .literal8
+ = getMachOSection("__TEXT", "__literal8", MCSectionMachO::S_8BYTE_LITERALS,
+ SectionKind::getMergeableConst8());
+
+ // ld_classic doesn't support .literal16 in 32-bit mode, and ld64 falls back
+ // to using it in -static mode.
+ SixteenByteConstantSection = 0;
+ if (TM.getRelocationModel() != Reloc::Static &&
+ TM.getTargetData()->getPointerSize() == 32)
+ SixteenByteConstantSection = // .literal16
+ getMachOSection("__TEXT", "__literal16",MCSectionMachO::S_16BYTE_LITERALS,
+ SectionKind::getMergeableConst16());
+
+ ReadOnlySection // .const
+ = getMachOSection("__TEXT", "__const", 0, SectionKind::getReadOnly());
+
+ TextCoalSection
+ = getMachOSection("__TEXT", "__textcoal_nt",
+ MCSectionMachO::S_COALESCED |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ SectionKind::getText());
+ ConstTextCoalSection
+ = getMachOSection("__TEXT", "__const_coal", MCSectionMachO::S_COALESCED,
+ SectionKind::getText());
+ ConstDataCoalSection
+ = getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED,
+ SectionKind::getText());
+ ConstDataSection // .const_data
+ = getMachOSection("__DATA", "__const", 0,
+ SectionKind::getReadOnlyWithRel());
+ 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",
+ MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
+ SectionKind::getMetadata());
+ NonLazySymbolPointerSection
+ = getMachOSection("__DATA", "__nl_symbol_ptr",
+ MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
+ SectionKind::getMetadata());
+
+ if (TM.getRelocationModel() == Reloc::Static) {
+ StaticCtorSection
+ = getMachOSection("__TEXT", "__constructor", 0,SectionKind::getDataRel());
+ StaticDtorSection
+ = getMachOSection("__TEXT", "__destructor", 0, SectionKind::getDataRel());
+ } else {
+ StaticCtorSection
+ = getMachOSection("__DATA", "__mod_init_func",
+ MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
+ SectionKind::getDataRel());
+ StaticDtorSection
+ = getMachOSection("__DATA", "__mod_term_func",
+ MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
+ SectionKind::getDataRel());
+ }
+
+ // Exception Handling.
+ LSDASection = getMachOSection("__DATA", "__gcc_except_tab", 0,
+ SectionKind::getDataRel());
+ EHFrameSection =
+ getMachOSection("__TEXT", "__eh_frame",
+ MCSectionMachO::S_COALESCED |
+ MCSectionMachO::S_ATTR_NO_TOC |
+ MCSectionMachO::S_ATTR_STRIP_STATIC_SYMS |
+ MCSectionMachO::S_ATTR_LIVE_SUPPORT,
+ SectionKind::getReadOnly());
+
+ // Debug Information.
+ DwarfAbbrevSection =
+ getMachOSection("__DWARF", "__debug_abbrev", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfInfoSection =
+ getMachOSection("__DWARF", "__debug_info", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfLineSection =
+ getMachOSection("__DWARF", "__debug_line", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfFrameSection =
+ getMachOSection("__DWARF", "__debug_frame", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ getMachOSection("__DWARF", "__debug_pubnames", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfPubTypesSection =
+ getMachOSection("__DWARF", "__debug_pubtypes", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfStrSection =
+ getMachOSection("__DWARF", "__debug_str", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfLocSection =
+ getMachOSection("__DWARF", "__debug_loc", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfARangesSection =
+ getMachOSection("__DWARF", "__debug_aranges", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfRangesSection =
+ getMachOSection("__DWARF", "__debug_ranges", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfMacroInfoSection =
+ getMachOSection("__DWARF", "__debug_macinfo", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfDebugInlineSection =
+ getMachOSection("__DWARF", "__debug_inlined", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+}
+
+const MCSection *TargetLoweringObjectFileMachO::
+getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ // Parse the section specifier and create it if valid.
+ StringRef Segment, Section;
+ unsigned TAA, StubSize;
+ std::string ErrorCode =
+ MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section,
+ TAA, StubSize);
+ if (!ErrorCode.empty()) {
+ // If invalid, report the error with llvm_report_error.
+ llvm_report_error("Global variable '" + GV->getNameStr() +
+ "' has an invalid section specifier '" + GV->getSection()+
+ "': " + ErrorCode + ".");
+ // Fall back to dropping it into the data section.
+ return DataSection;
+ }
+
+ // Get the section.
+ const MCSectionMachO *S =
+ getMachOSection(Segment, Section, TAA, StubSize, Kind);
+
+ // Okay, now that we got the section, verify that the TAA & StubSize agree.
+ // If the user declared multiple globals with different section flags, we need
+ // to reject it here.
+ if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
+ // If invalid, report the error with llvm_report_error.
+ llvm_report_error("Global variable '" + GV->getNameStr() +
+ "' section type or attributes does not match previous"
+ " section specifier");
+ }
+
+ return S;
+}
+
+const MCSection *TargetLoweringObjectFileMachO::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
+
+ if (Kind.isText())
+ return GV->isWeakForLinker() ? TextCoalSection : TextSection;
+
+ // If this is weak/linkonce, put this in a coalescable section, either in text
+ // or data depending on if it is writable.
+ if (GV->isWeakForLinker()) {
+ if (Kind.isReadOnly())
+ return ConstTextCoalSection;
+ return DataCoalSection;
+ }
+
+ // FIXME: Alignment check should be handled by section classifier.
+ if (Kind.isMergeable1ByteCString() &&
+ TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
+ return CStringSection;
+
+ // Do not put 16-bit arrays in the UString section if they have an
+ // externally visible label, this runs into issues with certain linker
+ // versions.
+ if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() &&
+ TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
+ return UStringSection;
+
+ if (Kind.isMergeableConst()) {
+ if (Kind.isMergeableConst4())
+ return FourByteConstantSection;
+ if (Kind.isMergeableConst8())
+ return EightByteConstantSection;
+ if (Kind.isMergeableConst16() && SixteenByteConstantSection)
+ return SixteenByteConstantSection;
+ }
+
+ // Otherwise, if it is readonly, but not something we can specially optimize,
+ // just drop it in .const.
+ if (Kind.isReadOnly())
+ return ReadOnlySection;
+
+ // If this is marked const, put it into a const section. But if the dynamic
+ // linker needs to write to it, put it in the data segment.
+ 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;
+}
+
+const MCSection *
+TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const {
+ // If this constant requires a relocation, we have to put it in the data
+ // segment, not in the text segment.
+ if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
+ return ConstDataSection;
+
+ if (Kind.isMergeableConst4())
+ return FourByteConstantSection;
+ if (Kind.isMergeableConst8())
+ return EightByteConstantSection;
+ if (Kind.isMergeableConst16() && SixteenByteConstantSection)
+ return SixteenByteConstantSection;
+ return ReadOnlySection; // .const
+}
+
+/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively decide
+/// not to emit the UsedDirective for some symbols in llvm.used.
+// FIXME: REMOVE this (rdar://7071300)
+bool TargetLoweringObjectFileMachO::
+shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
+ /// On Darwin, internally linked data beginning with "L" or "l" does not have
+ /// the directive emitted (this occurs in ObjC metadata).
+ if (!GV) return false;
+
+ // Check whether the mangled name has the "Private" or "LinkerPrivate" prefix.
+ if (GV->hasLocalLinkage() && !isa<Function>(GV)) {
+ // 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.
+ SmallString<64> Name;
+ Mang->getNameWithPrefix(Name, GV, false);
+ if (Name[0] == 'L' || Name[0] == 'l')
+ return false;
+ }
+
+ return true;
+}
+
+const MCExpr *TargetLoweringObjectFileMachO::
+getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const {
+ // The mach-o version of this method defaults to returning a stub reference.
+
+ if (Encoding & DW_EH_PE_indirect) {
+ MachineModuleInfoMachO &MachOMMI =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>();
+
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, GV, true);
+ Name += "$non_lazy_ptr";
+
+ // Add information about the stub reference to MachOMMI so that the stub
+ // gets emitted by the asmprinter.
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = MachOMMI.getGVStubEntry(Sym);
+ if (StubSym == 0) {
+ Name.clear();
+ Mang->getNameWithPrefix(Name, GV, false);
+ StubSym = getContext().GetOrCreateSymbol(Name.str());
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfReference(Sym, MMI,
+ Encoding & ~dwarf::DW_EH_PE_indirect);
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
+}
+
+unsigned TargetLoweringObjectFileMachO::getPersonalityEncoding() const {
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned TargetLoweringObjectFileMachO::getLSDAEncoding() const {
+ return DW_EH_PE_pcrel;
+}
+
+unsigned TargetLoweringObjectFileMachO::getFDEEncoding() const {
+ return DW_EH_PE_pcrel;
+}
+
+unsigned TargetLoweringObjectFileMachO::getTTypeEncoding() const {
+ return DW_EH_PE_absptr;
+}
+
+//===----------------------------------------------------------------------===//
+// COFF
+//===----------------------------------------------------------------------===//
+
+typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
+
+TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
+ delete (COFFUniqueMapTy*)UniquingMap;
+}
+
+
+const MCSection *TargetLoweringObjectFileCOFF::
+getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
+ // Create the map if it doesn't already exist.
+ if (UniquingMap == 0)
+ UniquingMap = new MachOUniqueMapTy();
+ COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap;
+
+ // Do the lookup, if we have a hit, return it.
+ const MCSectionCOFF *&Entry = Map[Name];
+ if (Entry) return Entry;
+
+ return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext());
+}
+
+void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
+ const TargetMachine &TM) {
+ if (UniquingMap != 0)
+ ((COFFUniqueMapTy*)UniquingMap)->clear();
+ TargetLoweringObjectFile::Initialize(Ctx, TM);
+ TextSection = getCOFFSection("\t.text", true, SectionKind::getText());
+ DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel());
+ StaticCtorSection =
+ getCOFFSection(".ctors", false, SectionKind::getDataRel());
+ StaticDtorSection =
+ getCOFFSection(".dtors", false, SectionKind::getDataRel());
+
+ // FIXME: We're emitting LSDA info into a readonly section on COFF, even
+ // though it contains relocatable pointers. In PIC mode, this is probably a
+ // big runtime hit for C++ apps. Either the contents of the LSDA need to be
+ // adjusted or this should be a data section.
+ LSDASection =
+ getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly());
+ EHFrameSection =
+ getCOFFSection(".eh_frame", false, SectionKind::getDataRel());
+
+ // Debug info.
+ // FIXME: Don't use 'directive' mode here.
+ DwarfAbbrevSection =
+ getCOFFSection("\t.section\t.debug_abbrev,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfInfoSection =
+ getCOFFSection("\t.section\t.debug_info,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfLineSection =
+ getCOFFSection("\t.section\t.debug_line,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfFrameSection =
+ getCOFFSection("\t.section\t.debug_frame,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ getCOFFSection("\t.section\t.debug_pubnames,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfPubTypesSection =
+ getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfStrSection =
+ getCOFFSection("\t.section\t.debug_str,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfLocSection =
+ getCOFFSection("\t.section\t.debug_loc,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfARangesSection =
+ getCOFFSection("\t.section\t.debug_aranges,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfRangesSection =
+ getCOFFSection("\t.section\t.debug_ranges,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfMacroInfoSection =
+ getCOFFSection("\t.section\t.debug_macinfo,\"dr\"",
+ true, SectionKind::getMetadata());
+}
+
+const MCSection *TargetLoweringObjectFileCOFF::
+getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ return getCOFFSection(GV->getSection(), false, Kind);
+}
+
+static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
+ if (Kind.isText())
+ return ".text$linkonce";
+ if (Kind.isWriteable())
+ return ".data$linkonce";
+ return ".rdata$linkonce";
+}
+
+
+const MCSection *TargetLoweringObjectFileCOFF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ assert(!Kind.isThreadLocal() && "Doesn't support TLS");
+
+ // 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()) {
+ const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
+ SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
+ Mang->getNameWithPrefix(Name, GV, false);
+ return getCOFFSection(Name.str(), false, Kind);
+ }
+
+ if (Kind.isText())
+ return getTextSection();
+
+ return getDataSection();
+}
+
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp
index 6c7c1a1..c840b39 100644
--- a/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -160,7 +160,7 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB,
MachineBasicBlock::iterator OldPos) {
// Check if it's safe to move this instruction.
bool SeenStore = true; // Be conservative.
- if (!MI->isSafeToMove(TII, SeenStore, AA))
+ if (!MI->isSafeToMove(TII, AA, SeenStore))
return false;
unsigned DefReg = 0;
@@ -213,6 +213,9 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB,
unsigned NumVisited = 0;
for (MachineBasicBlock::iterator I = llvm::next(OldPos); I != KillPos; ++I) {
MachineInstr *OtherMI = I;
+ // DBG_VALUE cannot be counted against the limit.
+ if (OtherMI->isDebugValue())
+ continue;
if (NumVisited > 30) // FIXME: Arbitrary limit to reduce compile time cost.
return false;
++NumVisited;
@@ -451,13 +454,10 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB,
const TargetInstrInfo *TII,
bool &IsCopy,
unsigned &DstReg, bool &IsDstPhys) {
- MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg);
- if (UI == MRI->use_end())
- return 0;
- MachineInstr &UseMI = *UI;
- if (++UI != MRI->use_end())
- // More than one use.
+ if (!MRI->hasOneNonDBGUse(Reg))
+ // None or more than one use.
return 0;
+ MachineInstr &UseMI = *MRI->use_nodbg_begin(Reg);
if (UseMI.getParent() != MBB)
return 0;
unsigned SrcReg;
@@ -923,6 +923,10 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end();
mi != me; ) {
MachineBasicBlock::iterator nmi = llvm::next(mi);
+ if (mi->isDebugValue()) {
+ mi = nmi;
+ continue;
+ }
const TargetInstrDesc &TID = mi->getDesc();
bool FirstTied = true;
@@ -1021,7 +1025,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
// copying it.
if (DefMI &&
DefMI->getDesc().isAsCheapAsAMove() &&
- DefMI->isSafeToReMat(TII, regB, AA) &&
+ DefMI->isSafeToReMat(TII, AA, regB) &&
isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist)){
DEBUG(dbgs() << "2addr: REMATTING : " << *DefMI << "\n");
unsigned regASubIdx = mi->getOperand(DstIdx).getSubReg();
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index 5956b61..ed02696 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -261,19 +261,21 @@ bool VirtRegMap::FindUnusedRegisters(LiveIntervals* LIs) {
void VirtRegMap::print(raw_ostream &OS, const Module* M) const {
const TargetRegisterInfo* TRI = MF->getTarget().getRegisterInfo();
+ const MachineRegisterInfo &MRI = MF->getRegInfo();
OS << "********** REGISTER MAP **********\n";
for (unsigned i = TargetRegisterInfo::FirstVirtualRegister,
e = MF->getRegInfo().getLastVirtReg(); i <= e; ++i) {
if (Virt2PhysMap[i] != (unsigned)VirtRegMap::NO_PHYS_REG)
OS << "[reg" << i << " -> " << TRI->getName(Virt2PhysMap[i])
- << "]\n";
+ << "] " << MRI.getRegClass(i)->getName() << "\n";
}
for (unsigned i = TargetRegisterInfo::FirstVirtualRegister,
e = MF->getRegInfo().getLastVirtReg(); i <= e; ++i)
if (Virt2StackSlotMap[i] != VirtRegMap::NO_STACK_SLOT)
- OS << "[reg" << i << " -> fi#" << Virt2StackSlotMap[i] << "]\n";
+ OS << "[reg" << i << " -> fi#" << Virt2StackSlotMap[i]
+ << "] " << MRI.getRegClass(i)->getName() << "\n";
OS << '\n';
}
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index ce62594..7aa0a91 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -46,7 +46,7 @@ namespace {
static cl::opt<RewriterName>
RewriterOpt("rewriter",
- cl::desc("Rewriter to use: (default: local)"),
+ cl::desc("Rewriter to use (default=local)"),
cl::Prefix,
cl::values(clEnumVal(local, "local rewriter"),
clEnumVal(trivial, "trivial rewriter"),
@@ -62,6 +62,7 @@ VirtRegRewriter::~VirtRegRewriter() {}
/// substitutePhysReg - Replace virtual register in MachineOperand with a
/// physical register. Do the right thing with the sub-register index.
+/// Note that operands may be added, so the MO reference is no longer valid.
static void substitutePhysReg(MachineOperand &MO, unsigned Reg,
const TargetRegisterInfo &TRI) {
if (unsigned SubIdx = MO.getSubReg()) {
@@ -123,14 +124,15 @@ struct TrivialRewriter : public VirtRegRewriter {
continue;
unsigned pReg = VRM.getPhys(reg);
mri->setPhysRegUsed(pReg);
- for (MachineRegisterInfo::reg_iterator regItr = mri->reg_begin(reg),
- regEnd = mri->reg_end(); regItr != regEnd;) {
- MachineOperand &mop = regItr.getOperand();
- assert(mop.isReg() && mop.getReg() == reg && "reg_iterator broken?");
- ++regItr;
- substitutePhysReg(mop, pReg, *tri);
- changed = true;
- }
+ // Copy the register use-list before traversing it.
+ SmallVector<std::pair<MachineInstr*, unsigned>, 32> reglist;
+ for (MachineRegisterInfo::reg_iterator I = mri->reg_begin(reg),
+ E = mri->reg_end(); I != E; ++I)
+ reglist.push_back(std::make_pair(&*I, I.getOperandNo()));
+ for (unsigned N=0; N != reglist.size(); ++N)
+ substitutePhysReg(reglist[N].first->getOperand(reglist[N].second),
+ pReg, *tri);
+ changed |= !reglist.empty();
}
}
@@ -1850,19 +1852,18 @@ private:
KilledMIRegs.clear();
for (unsigned j = 0, e = VirtUseOps.size(); j != e; ++j) {
unsigned i = VirtUseOps[j];
- MachineOperand &MO = MI.getOperand(i);
- unsigned VirtReg = MO.getReg();
+ unsigned VirtReg = MI.getOperand(i).getReg();
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Not a virtual register?");
- unsigned SubIdx = MO.getSubReg();
+ unsigned SubIdx = MI.getOperand(i).getSubReg();
if (VRM.isAssignedReg(VirtReg)) {
// This virtual register was assigned a physreg!
unsigned Phys = VRM.getPhys(VirtReg);
RegInfo->setPhysRegUsed(Phys);
- if (MO.isDef())
+ if (MI.getOperand(i).isDef())
ReusedOperands.markClobbered(Phys);
- substitutePhysReg(MO, Phys, *TRI);
+ substitutePhysReg(MI.getOperand(i), Phys, *TRI);
if (VRM.isImplicitlyDefined(VirtReg))
// FIXME: Is this needed?
BuildMI(MBB, &MI, MI.getDebugLoc(),
@@ -1871,10 +1872,10 @@ private:
}
// This virtual register is now known to be a spilled value.
- if (!MO.isUse())
+ if (!MI.getOperand(i).isUse())
continue; // Handle defs in the loop below (handle use&def here though)
- bool AvoidReload = MO.isUndef();
+ bool AvoidReload = MI.getOperand(i).isUndef();
// Check if it is defined by an implicit def. It should not be spilled.
// Note, this is for correctness reason. e.g.
// 8 %reg1024<def> = IMPLICIT_DEF
diff --git a/lib/CompilerDriver/Action.cpp b/lib/CompilerDriver/Action.cpp
index 7bcd30a..9d07811 100644
--- a/lib/CompilerDriver/Action.cpp
+++ b/lib/CompilerDriver/Action.cpp
@@ -15,6 +15,7 @@
#include "llvm/CompilerDriver/BuiltinOptions.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SystemUtils.h"
#include "llvm/System/Program.h"
#include "llvm/System/TimeValue.h"
@@ -24,13 +25,23 @@
using namespace llvm;
using namespace llvmc;
+namespace llvmc {
+
+extern int Main(int argc, char** argv);
+extern const char* ProgramName;
+
+}
+
namespace {
int ExecuteProgram(const std::string& name,
const StrVector& args) {
sys::Path prog = sys::Program::FindProgramByName(name);
- if (prog.isEmpty())
- throw std::runtime_error("Can't find program '" + name + "'");
+ if (prog.isEmpty()) {
+ prog = FindExecutable(name, ProgramName, (void *)(intptr_t)&Main);
+ if (prog.isEmpty())
+ throw std::runtime_error("Can't find program '" + name + "'");
+ }
if (!prog.canExecute())
throw std::runtime_error("Program '" + name + "' is not executable.");
diff --git a/lib/CompilerDriver/CompilationGraph.cpp b/lib/CompilerDriver/CompilationGraph.cpp
index 524607b..7d1c7fe 100644
--- a/lib/CompilerDriver/CompilationGraph.cpp
+++ b/lib/CompilerDriver/CompilationGraph.cpp
@@ -34,7 +34,8 @@ namespace llvmc {
const std::string& LanguageMap::GetLanguage(const sys::Path& File) const {
StringRef suf = File.getSuffix();
- LanguageMap::const_iterator Lang = this->find(suf);
+ LanguageMap::const_iterator Lang =
+ this->find(suf.empty() ? "*empty*" : suf);
if (Lang == this->end())
throw std::runtime_error("File '" + File.str() +
"' has unknown suffix '" + suf.str() + '\'');
@@ -313,7 +314,7 @@ int CompilationGraph::Build (const sys::Path& TempDir,
JoinTool* JT = &dynamic_cast<JoinTool&>(*CurNode->ToolPtr.getPtr());
// Are there any files in the join list?
- if (JT->JoinListEmpty())
+ if (JT->JoinListEmpty() && !(JT->WorksOnEmpty() && InputFilenames.empty()))
continue;
Action CurAction = JT->GenerateAction(CurNode->HasChildren(),
diff --git a/lib/CompilerDriver/Main.cpp b/lib/CompilerDriver/Main.cpp
index 3a3487a..b5e507d 100644
--- a/lib/CompilerDriver/Main.cpp
+++ b/lib/CompilerDriver/Main.cpp
@@ -100,7 +100,8 @@ int Main(int argc, char** argv) {
ProgramName = argv[0];
cl::ParseCommandLineOptions
- (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
+ (argc, argv, "LLVM Compiler Driver (Work In Progress)",
+ /* ReadResponseFiles = */ false);
PluginLoader Plugins;
Plugins.RunInitialization(langMap, graph);
@@ -126,10 +127,6 @@ int Main(int argc, char** argv) {
return 0;
}
- if (InputFilenames.empty()) {
- throw std::runtime_error("no input files");
- }
-
if (Time) {
GlobalTimeLog = new std::stringstream;
GlobalTimeLog->precision(2);
diff --git a/lib/CompilerDriver/Tool.cpp b/lib/CompilerDriver/Tool.cpp
index 9f4ab49..5e558ca 100644
--- a/lib/CompilerDriver/Tool.cpp
+++ b/lib/CompilerDriver/Tool.cpp
@@ -17,6 +17,8 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/System/Path.h"
+#include <algorithm>
+
using namespace llvm;
using namespace llvmc;
@@ -71,3 +73,22 @@ sys::Path Tool::OutFilename(const sys::Path& In,
}
return Out;
}
+
+namespace {
+ template <class A, class B>
+ bool CompareFirst (std::pair<A,B> p1, std::pair<A,B> p2) {
+ return std::less<A>()(p1.first, p2.first);
+ }
+}
+
+StrVector Tool::SortArgs(ArgsVector& Args) const {
+ StrVector Out;
+
+ // HACK: this won't be needed when we'll migrate away from CommandLine.
+ std::stable_sort(Args.begin(), Args.end(), &CompareFirst<unsigned, std::string>);
+ for (ArgsVector::iterator B = Args.begin(), E = Args.end(); B != E; ++B) {
+ Out.push_back(B->second);
+ }
+
+ return Out;
+}
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 3e684e1..b2e2a04 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -339,12 +339,12 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn,
}
// FALLS THROUGH
case 1:
- if (!FTy->getParamType(0)->isInteger(32)) {
+ if (!FTy->getParamType(0)->isIntegerTy(32)) {
llvm_report_error("Invalid type for first argument of main() supplied");
}
// FALLS THROUGH
case 0:
- if (!isa<IntegerType>(FTy->getReturnType()) &&
+ if (!FTy->getReturnType()->isIntegerTy() &&
!FTy->getReturnType()->isVoidTy()) {
llvm_report_error("Invalid return type of main() supplied");
}
@@ -599,22 +599,22 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
switch (Op0->getType()->getTypeID()) {
default: llvm_unreachable("Invalid bitcast operand");
case Type::IntegerTyID:
- assert(DestTy->isFloatingPoint() && "invalid bitcast");
+ assert(DestTy->isFloatingPointTy() && "invalid bitcast");
if (DestTy->isFloatTy())
GV.FloatVal = GV.IntVal.bitsToFloat();
else if (DestTy->isDoubleTy())
GV.DoubleVal = GV.IntVal.bitsToDouble();
break;
case Type::FloatTyID:
- assert(DestTy->isInteger(32) && "Invalid bitcast");
+ assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
GV.IntVal.floatToBits(GV.FloatVal);
break;
case Type::DoubleTyID:
- assert(DestTy->isInteger(64) && "Invalid bitcast");
+ assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
GV.IntVal.doubleToBits(GV.DoubleVal);
break;
case Type::PointerTyID:
- assert(isa<PointerType>(DestTy) && "Invalid bitcast");
+ assert(DestTy->isPointerTy() && "Invalid bitcast");
break; // getConstantValue(Op0) above already converted it
}
return GV;
diff --git a/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
index 141cb27..c7495d4 100644
--- a/lib/ExecutionEngine/ExecutionEngineBindings.cpp
+++ b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
@@ -87,11 +87,11 @@ void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
/*===-- Operations on execution engines -----------------------------------===*/
-LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
- LLVMModuleProviderRef MP,
- char **OutError) {
+LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
+ LLVMModuleRef M,
+ char **OutError) {
std::string Error;
- EngineBuilder builder(unwrap(MP));
+ EngineBuilder builder(unwrap(M));
builder.setEngineKind(EngineKind::Either)
.setErrorStr(&Error);
if (ExecutionEngine *EE = builder.create()){
@@ -102,11 +102,11 @@ LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
return 1;
}
-LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
- LLVMModuleProviderRef MP,
- char **OutError) {
+LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
+ LLVMModuleRef M,
+ char **OutError) {
std::string Error;
- EngineBuilder builder(unwrap(MP));
+ EngineBuilder builder(unwrap(M));
builder.setEngineKind(EngineKind::Interpreter)
.setErrorStr(&Error);
if (ExecutionEngine *Interp = builder.create()) {
@@ -117,12 +117,12 @@ LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
return 1;
}
-LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
- LLVMModuleProviderRef MP,
- unsigned OptLevel,
- char **OutError) {
+LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
+ LLVMModuleRef M,
+ unsigned OptLevel,
+ char **OutError) {
std::string Error;
- EngineBuilder builder(unwrap(MP));
+ EngineBuilder builder(unwrap(M));
builder.setEngineKind(EngineKind::JIT)
.setErrorStr(&Error)
.setOptLevel((CodeGenOpt::Level)OptLevel);
@@ -134,6 +134,35 @@ LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
return 1;
}
+LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
+ LLVMModuleProviderRef MP,
+ char **OutError) {
+ /* The module provider is now actually a module. */
+ return LLVMCreateExecutionEngineForModule(OutEE,
+ reinterpret_cast<LLVMModuleRef>(MP),
+ OutError);
+}
+
+LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
+ LLVMModuleProviderRef MP,
+ char **OutError) {
+ /* The module provider is now actually a module. */
+ return LLVMCreateInterpreterForModule(OutInterp,
+ reinterpret_cast<LLVMModuleRef>(MP),
+ OutError);
+}
+
+LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
+ LLVMModuleProviderRef MP,
+ unsigned OptLevel,
+ char **OutError) {
+ /* The module provider is now actually a module. */
+ return LLVMCreateJITCompilerForModule(OutJIT,
+ reinterpret_cast<LLVMModuleRef>(MP),
+ OptLevel, OutError);
+}
+
+
void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
delete unwrap(EE);
}
@@ -173,17 +202,29 @@ void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
unwrap(EE)->freeMachineCodeForFunction(unwrap<Function>(F));
}
+void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
+ unwrap(EE)->addModule(unwrap(M));
+}
+
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP){
- unwrap(EE)->addModule(unwrap(MP));
+ /* The module provider is now actually a module. */
+ LLVMAddModule(EE, reinterpret_cast<LLVMModuleRef>(MP));
+}
+
+LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
+ LLVMModuleRef *OutMod, char **OutError) {
+ Module *Mod = unwrap(M);
+ unwrap(EE)->removeModule(Mod);
+ *OutMod = wrap(Mod);
+ return 0;
}
LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
LLVMModuleProviderRef MP,
LLVMModuleRef *OutMod, char **OutError) {
- Module *M = unwrap(MP);
- unwrap(EE)->removeModule(M);
- *OutMod = wrap(M);
- return 0;
+ /* The module provider is now actually a module. */
+ return LLVMRemoveModule(EE, reinterpret_cast<LLVMModuleRef>(MP), OutMod,
+ OutError);
}
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 73f5558..a2aad5a 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -591,7 +591,7 @@ void Interpreter::popStackAndReturnValueToCaller(const Type *RetTy,
ECStack.pop_back();
if (ECStack.empty()) { // Finished main. Put result into exit code...
- if (RetTy && RetTy->isInteger()) { // Nonvoid return type?
+ if (RetTy && RetTy->isIntegerTy()) { // Nonvoid return type?
ExitValue = Result; // Capture the exit value of the program
} else {
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
@@ -761,7 +761,7 @@ void Interpreter::visitAllocaInst(AllocaInst &I) {
GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
gep_type_iterator E,
ExecutionContext &SF) {
- assert(isa<PointerType>(Ptr->getType()) &&
+ assert(Ptr->getType()->isPointerTy() &&
"Cannot getElementOffset of a nonpointer type!");
uint64_t Total = 0;
@@ -979,7 +979,7 @@ GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, const Type *DstTy,
const Type *SrcTy = SrcVal->getType();
uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(SrcTy->isFloatingPoint() && "Invalid FPToUI instruction");
+ assert(SrcTy->isFloatingPointTy() && "Invalid FPToUI instruction");
if (SrcTy->getTypeID() == Type::FloatTyID)
Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
@@ -993,7 +993,7 @@ GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, const Type *DstTy,
const Type *SrcTy = SrcVal->getType();
uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(SrcTy->isFloatingPoint() && "Invalid FPToSI instruction");
+ assert(SrcTy->isFloatingPointTy() && "Invalid FPToSI instruction");
if (SrcTy->getTypeID() == Type::FloatTyID)
Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
@@ -1005,7 +1005,7 @@ GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, const Type *DstTy,
GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF) {
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(DstTy->isFloatingPoint() && "Invalid UIToFP instruction");
+ assert(DstTy->isFloatingPointTy() && "Invalid UIToFP instruction");
if (DstTy->getTypeID() == Type::FloatTyID)
Dest.FloatVal = APIntOps::RoundAPIntToFloat(Src.IntVal);
@@ -1017,7 +1017,7 @@ GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, const Type *DstTy,
GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF) {
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(DstTy->isFloatingPoint() && "Invalid SIToFP instruction");
+ assert(DstTy->isFloatingPointTy() && "Invalid SIToFP instruction");
if (DstTy->getTypeID() == Type::FloatTyID)
Dest.FloatVal = APIntOps::RoundSignedAPIntToFloat(Src.IntVal);
@@ -1031,7 +1031,7 @@ GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF) {
uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(isa<PointerType>(SrcVal->getType()) && "Invalid PtrToInt instruction");
+ assert(SrcVal->getType()->isPointerTy() && "Invalid PtrToInt instruction");
Dest.IntVal = APInt(DBitWidth, (intptr_t) Src.PointerVal);
return Dest;
@@ -1040,7 +1040,7 @@ GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, const Type *DstTy,
GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF) {
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(isa<PointerType>(DstTy) && "Invalid PtrToInt instruction");
+ assert(DstTy->isPointerTy() && "Invalid PtrToInt instruction");
uint32_t PtrSize = TD.getPointerSizeInBits();
if (PtrSize != Src.IntVal.getBitWidth())
@@ -1055,27 +1055,27 @@ GenericValue Interpreter::executeBitCastInst(Value *SrcVal, const Type *DstTy,
const Type *SrcTy = SrcVal->getType();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- if (isa<PointerType>(DstTy)) {
- assert(isa<PointerType>(SrcTy) && "Invalid BitCast");
+ if (DstTy->isPointerTy()) {
+ assert(SrcTy->isPointerTy() && "Invalid BitCast");
Dest.PointerVal = Src.PointerVal;
- } else if (DstTy->isInteger()) {
+ } else if (DstTy->isIntegerTy()) {
if (SrcTy->isFloatTy()) {
Dest.IntVal.zext(sizeof(Src.FloatVal) * CHAR_BIT);
Dest.IntVal.floatToBits(Src.FloatVal);
} else if (SrcTy->isDoubleTy()) {
Dest.IntVal.zext(sizeof(Src.DoubleVal) * CHAR_BIT);
Dest.IntVal.doubleToBits(Src.DoubleVal);
- } else if (SrcTy->isInteger()) {
+ } else if (SrcTy->isIntegerTy()) {
Dest.IntVal = Src.IntVal;
} else
llvm_unreachable("Invalid BitCast");
} else if (DstTy->isFloatTy()) {
- if (SrcTy->isInteger())
+ if (SrcTy->isIntegerTy())
Dest.FloatVal = Src.IntVal.bitsToFloat();
else
Dest.FloatVal = Src.FloatVal;
} else if (DstTy->isDoubleTy()) {
- if (SrcTy->isInteger())
+ if (SrcTy->isIntegerTy())
Dest.DoubleVal = Src.IntVal.bitsToDouble();
else
Dest.DoubleVal = Src.DoubleVal;
diff --git a/lib/ExecutionEngine/JIT/Android.mk b/lib/ExecutionEngine/JIT/Android.mk
new file mode 100644
index 0000000..1c7e27f
--- /dev/null
+++ b/lib/ExecutionEngine/JIT/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ Intercept.cpp \
+ JIT.cpp \
+ JITDebugRegisterer.cpp \
+ JITDwarfEmitter.cpp \
+ JITEmitter.cpp \
+ JITMemoryManager.cpp \
+ OProfileJITEventListener.cpp \
+ TargetSelect.cpp
+
+LOCAL_MODULE:= libLLVMJIT
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ JITMemoryManager.cpp
+
+LOCAL_MODULE:= libLLVMJIT
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index 616a66e..dd74d73 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -18,6 +18,7 @@
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/GenericValue.h"
@@ -27,6 +28,7 @@
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/System/DynamicLibrary.h"
#include "llvm/Config/config.h"
@@ -237,9 +239,53 @@ ExecutionEngine *JIT::createJIT(Module *M,
}
}
+namespace {
+/// This class supports the global getPointerToNamedFunction(), which allows
+/// bugpoint or gdb users to search for a function by name without any context.
+class JitPool {
+ SmallPtrSet<JIT*, 1> JITs; // Optimize for process containing just 1 JIT.
+ mutable sys::Mutex Lock;
+public:
+ void Add(JIT *jit) {
+ MutexGuard guard(Lock);
+ JITs.insert(jit);
+ }
+ void Remove(JIT *jit) {
+ MutexGuard guard(Lock);
+ JITs.erase(jit);
+ }
+ void *getPointerToNamedFunction(const char *Name) const {
+ MutexGuard guard(Lock);
+ assert(JITs.size() != 0 && "No Jit registered");
+ //search function in every instance of JIT
+ for (SmallPtrSet<JIT*, 1>::const_iterator Jit = JITs.begin(),
+ end = JITs.end();
+ Jit != end; ++Jit) {
+ if (Function *F = (*Jit)->FindFunctionNamed(Name))
+ return (*Jit)->getPointerToFunction(F);
+ }
+ // The function is not available : fallback on the first created (will
+ // search in symbol of the current program/library)
+ return (*JITs.begin())->getPointerToNamedFunction(Name);
+ }
+};
+ManagedStatic<JitPool> AllJits;
+}
+extern "C" {
+ // getPointerToNamedFunction - This function is used as a global wrapper to
+ // JIT::getPointerToNamedFunction for the purpose of resolving symbols when
+ // bugpoint is debugging the JIT. In that scenario, we are loading an .so and
+ // need to resolve function(s) that are being mis-codegenerated, so we need to
+ // resolve their addresses at runtime, and this is the way to do it.
+ void *getPointerToNamedFunction(const char *Name) {
+ return AllJits->getPointerToNamedFunction(Name);
+ }
+}
+
JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode)
- : ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode) {
+ : ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode),
+ isAlreadyCodeGenerating(false) {
setTargetData(TM.getTargetData());
jitstate = new JITState(M);
@@ -247,6 +293,9 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
// Initialize JCE
JCE = createEmitter(*this, JMM, TM);
+ // Register in global list of all JITs.
+ AllJits->Add(this);
+
// Add target data
MutexGuard locked(lock);
FunctionPassManager &PM = jitstate->getPM(locked);
@@ -281,6 +330,7 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
}
JIT::~JIT() {
+ AllJits->Remove(this);
delete jitstate;
delete JCE;
delete &TM;
@@ -361,12 +411,12 @@ GenericValue JIT::runFunction(Function *F,
// Handle some common cases first. These cases correspond to common `main'
// prototypes.
- if (RetTy->isInteger(32) || RetTy->isVoidTy()) {
+ if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
switch (ArgValues.size()) {
case 3:
- if (FTy->getParamType(0)->isInteger(32) &&
- isa<PointerType>(FTy->getParamType(1)) &&
- isa<PointerType>(FTy->getParamType(2))) {
+ if (FTy->getParamType(0)->isIntegerTy(32) &&
+ FTy->getParamType(1)->isPointerTy() &&
+ FTy->getParamType(2)->isPointerTy()) {
int (*PF)(int, char **, const char **) =
(int(*)(int, char **, const char **))(intptr_t)FPtr;
@@ -379,8 +429,8 @@ GenericValue JIT::runFunction(Function *F,
}
break;
case 2:
- if (FTy->getParamType(0)->isInteger(32) &&
- isa<PointerType>(FTy->getParamType(1))) {
+ if (FTy->getParamType(0)->isIntegerTy(32) &&
+ FTy->getParamType(1)->isPointerTy()) {
int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
// Call the function.
@@ -392,7 +442,7 @@ GenericValue JIT::runFunction(Function *F,
break;
case 1:
if (FTy->getNumParams() == 1 &&
- FTy->getParamType(0)->isInteger(32)) {
+ FTy->getParamType(0)->isIntegerTy(32)) {
GenericValue rv;
int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
@@ -503,8 +553,12 @@ GenericValue JIT::runFunction(Function *F,
else
ReturnInst::Create(F->getContext(), StubBB); // Just return void.
- // Finally, return the value returned by our nullary stub function.
- return runFunction(Stub, std::vector<GenericValue>());
+ // Finally, call our nullary stub function.
+ GenericValue Result = runFunction(Stub, std::vector<GenericValue>());
+ // Erase it, since no other function can have a reference to it.
+ Stub->eraseFromParent();
+ // And return the result.
+ return Result;
}
void JIT::RegisterJITEventListener(JITEventListener *L) {
@@ -570,7 +624,6 @@ void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) {
}
void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) {
- static bool isAlreadyCodeGenerating = false;
assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!");
// JIT the function
diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h
index bb8f851..edae719 100644
--- a/lib/ExecutionEngine/JIT/JIT.h
+++ b/lib/ExecutionEngine/JIT/JIT.h
@@ -61,6 +61,10 @@ class JIT : public ExecutionEngine {
/// should be set to true. Doing so breaks freeMachineCodeForFunction.
bool AllocateGVsWithCode;
+ /// True while the JIT is generating code. Used to assert against recursive
+ /// entry.
+ bool isAlreadyCodeGenerating;
+
JITState *jitstate;
JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
index c1051a9..946351b 100644
--- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
@@ -522,7 +522,11 @@ JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
}
- JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+ // LSDA encoding: This must match the encoding used in EmitEHFrame ()
+ if (PointerSize == 4)
+ JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+ else
+ JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8);
JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
} else {
JCE->emitULEB128Bytes(1);
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index 34a9938..783ebb4 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -37,6 +37,7 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
@@ -57,7 +58,6 @@ using namespace llvm;
STATISTIC(NumBytes, "Number of bytes of machine code compiled");
STATISTIC(NumRelos, "Number of relocations applied");
STATISTIC(NumRetries, "Number of retries with more memory");
-static JIT *TheJIT = 0;
// A declaration may stop being a declaration once it's fully read from bitcode.
@@ -109,9 +109,13 @@ namespace {
/// particular GlobalVariable so that we can reuse them if necessary.
GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
+ /// Instance of the JIT this ResolverState serves.
+ JIT *TheJIT;
+
public:
- JITResolverState() : FunctionToLazyStubMap(this),
- FunctionToCallSitesMap(this) {}
+ JITResolverState(JIT *jit) : FunctionToLazyStubMap(this),
+ FunctionToCallSitesMap(this),
+ TheJIT(jit) {}
FunctionToLazyStubMapTy& getFunctionToLazyStubMap(
const MutexGuard& locked) {
@@ -152,53 +156,18 @@ namespace {
// was no stub. This function uses the call-site->function map to find a
// relevant function, but asserts that only stubs and not other call sites
// will be passed in.
- Function *EraseStub(const MutexGuard &locked, void *Stub) {
- CallSiteToFunctionMapTy::iterator C2F_I =
- CallSiteToFunctionMap.find(Stub);
- if (C2F_I == CallSiteToFunctionMap.end()) {
- // Not a stub.
- return NULL;
- }
-
- Function *const F = C2F_I->second;
-#ifndef NDEBUG
- void *RealStub = FunctionToLazyStubMap.lookup(F);
- assert(RealStub == Stub &&
- "Call-site that wasn't a stub pass in to EraseStub");
-#endif
- FunctionToLazyStubMap.erase(F);
- CallSiteToFunctionMap.erase(C2F_I);
-
- // Remove the stub from the function->call-sites map, and remove the whole
- // entry from the map if that was the last call site.
- FunctionToCallSitesMapTy::iterator F2C_I = FunctionToCallSitesMap.find(F);
- assert(F2C_I != FunctionToCallSitesMap.end() &&
- "FunctionToCallSitesMap broken");
- bool Erased = F2C_I->second.erase(Stub);
- (void)Erased;
- assert(Erased && "FunctionToCallSitesMap broken");
- if (F2C_I->second.empty())
- FunctionToCallSitesMap.erase(F2C_I);
-
- return F;
- }
+ Function *EraseStub(const MutexGuard &locked, void *Stub);
- void EraseAllCallSites(const MutexGuard &locked, Function *F) {
+ void EraseAllCallSitesFor(const MutexGuard &locked, Function *F) {
assert(locked.holds(TheJIT->lock));
- EraseAllCallSitesPrelocked(F);
- }
- void EraseAllCallSitesPrelocked(Function *F) {
- FunctionToCallSitesMapTy::iterator F2C = FunctionToCallSitesMap.find(F);
- if (F2C == FunctionToCallSitesMap.end())
- return;
- for (SmallPtrSet<void*, 1>::const_iterator I = F2C->second.begin(),
- E = F2C->second.end(); I != E; ++I) {
- bool Erased = CallSiteToFunctionMap.erase(*I);
- (void)Erased;
- assert(Erased && "Missing call site->function mapping");
- }
- FunctionToCallSitesMap.erase(F2C);
+ EraseAllCallSitesForPrelocked(F);
}
+ void EraseAllCallSitesForPrelocked(Function *F);
+
+ // Erases _all_ call sites regardless of their function. This is used to
+ // unregister the stub addresses from the StubToResolverMap in
+ // ~JITResolver().
+ void EraseAllCallSitesPrelocked();
};
/// JITResolver - Keep track of, and resolve, call sites for functions that
@@ -227,19 +196,16 @@ namespace {
JITEmitter &JE;
- static JITResolver *TheJITResolver;
- public:
- explicit JITResolver(JIT &jit, JITEmitter &je) : nextGOTIndex(0), JE(je) {
- TheJIT = &jit;
+ /// Instance of JIT corresponding to this Resolver.
+ JIT *TheJIT;
+ public:
+ explicit JITResolver(JIT &jit, JITEmitter &je)
+ : state(&jit), nextGOTIndex(0), JE(je), TheJIT(&jit) {
LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn);
- assert(TheJITResolver == 0 && "Multiple JIT resolvers?");
- TheJITResolver = this;
}
- ~JITResolver() {
- TheJITResolver = 0;
- }
+ ~JITResolver();
/// getLazyFunctionStubIfAvailable - This returns a pointer to a function's
/// lazy-compilation stub if it has already been created.
@@ -260,8 +226,6 @@ namespace {
void getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
SmallVectorImpl<void*> &Ptrs);
- GlobalValue *invalidateStub(void *Stub);
-
/// getGOTIndexForAddress - Return a new or existing index in the GOT for
/// an address. This function only manages slots, it does not manage the
/// contents of the slots or the memory associated with the GOT.
@@ -273,6 +237,55 @@ namespace {
static void *JITCompilerFn(void *Stub);
};
+ class StubToResolverMapTy {
+ /// Map a stub address to a specific instance of a JITResolver so that
+ /// lazily-compiled functions can find the right resolver to use.
+ ///
+ /// Guarded by Lock.
+ std::map<void*, JITResolver*> Map;
+
+ /// Guards Map from concurrent accesses.
+ mutable sys::Mutex Lock;
+
+ public:
+ /// Registers a Stub to be resolved by Resolver.
+ void RegisterStubResolver(void *Stub, JITResolver *Resolver) {
+ MutexGuard guard(Lock);
+ Map.insert(std::make_pair(Stub, Resolver));
+ }
+ /// Unregisters the Stub when it's invalidated.
+ void UnregisterStubResolver(void *Stub) {
+ MutexGuard guard(Lock);
+ Map.erase(Stub);
+ }
+ /// Returns the JITResolver instance that owns the Stub.
+ JITResolver *getResolverFromStub(void *Stub) const {
+ MutexGuard guard(Lock);
+ // The address given to us for the stub may not be exactly right, it might
+ // be a little bit after the stub. As such, use upper_bound to find it.
+ // This is the same trick as in LookupFunctionFromCallSite from
+ // JITResolverState.
+ std::map<void*, JITResolver*>::const_iterator I = Map.upper_bound(Stub);
+ assert(I != Map.begin() && "This is not a known stub!");
+ --I;
+ return I->second;
+ }
+ /// True if any stubs refer to the given resolver. Only used in an assert().
+ /// O(N)
+ bool ResolverHasStubs(JITResolver* Resolver) const {
+ MutexGuard guard(Lock);
+ for (std::map<void*, JITResolver*>::const_iterator I = Map.begin(),
+ E = Map.end(); I != E; ++I) {
+ if (I->second == Resolver)
+ return true;
+ }
+ return false;
+ }
+ };
+ /// This needs to be static so that a lazy call stub can access it with no
+ /// context except the address of the stub.
+ ManagedStatic<StubToResolverMapTy> StubToResolverMap;
+
/// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is
/// used to output functions to memory for execution.
class JITEmitter : public JITCodeEmitter {
@@ -333,9 +346,6 @@ namespace {
/// MMI - Machine module info for exception informations
MachineModuleInfo* MMI;
- // GVSet - a set to keep track of which globals have been seen
- SmallPtrSet<const GlobalVariable*, 8> GVSet;
-
// CurFn - The llvm function being emitted. Only valid during
// finishFunction().
const Function *CurFn;
@@ -359,22 +369,15 @@ namespace {
ValueMap<const Function *, EmittedCode,
EmittedFunctionConfig> EmittedFunctions;
- // CurFnStubUses - For a given Function, a vector of stubs that it
- // references. This facilitates the JIT detecting that a stub is no
- // longer used, so that it may be deallocated.
- DenseMap<AssertingVH<const Function>, SmallVector<void*, 1> > CurFnStubUses;
-
- // StubFnRefs - For a given pointer to a stub, a set of Functions which
- // reference the stub. When the count of a stub's references drops to zero,
- // the stub is unused.
- DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
-
DILocation PrevDLT;
+ /// Instance of the JIT
+ JIT *TheJIT;
+
public:
JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
: SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0),
- EmittedFunctions(this), PrevDLT(NULL) {
+ EmittedFunctions(this), PrevDLT(NULL), TheJIT(&jit) {
MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
if (jit.getJITInfo().needsGOT()) {
MemMgr->AllocateGOT();
@@ -454,11 +457,6 @@ namespace {
/// function body.
void deallocateMemForFunction(const Function *F);
- /// AddStubToCurrentFunction - Mark the current function being JIT'd as
- /// using the stub at the specified address. Allows
- /// deallocateMemForFunction to also remove stubs no longer referenced.
- void AddStubToCurrentFunction(void *Stub);
-
virtual void processDebugLoc(DebugLoc DL, bool BeforePrintingInsn);
virtual void emitLabel(uint64_t LabelID) {
@@ -489,16 +487,86 @@ namespace {
bool MayNeedFarStub);
void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference);
unsigned addSizeOfGlobal(const GlobalVariable *GV, unsigned Size);
- unsigned addSizeOfGlobalsInConstantVal(const Constant *C, unsigned Size);
- unsigned addSizeOfGlobalsInInitializer(const Constant *Init, unsigned Size);
+ unsigned addSizeOfGlobalsInConstantVal(
+ const Constant *C, unsigned Size,
+ SmallPtrSet<const GlobalVariable*, 8> &SeenGlobals,
+ SmallVectorImpl<const GlobalVariable*> &Worklist);
+ unsigned addSizeOfGlobalsInInitializer(
+ const Constant *Init, unsigned Size,
+ SmallPtrSet<const GlobalVariable*, 8> &SeenGlobals,
+ SmallVectorImpl<const GlobalVariable*> &Worklist);
unsigned GetSizeOfGlobalsInBytes(MachineFunction &MF);
};
}
-JITResolver *JITResolver::TheJITResolver = 0;
-
void CallSiteValueMapConfig::onDelete(JITResolverState *JRS, Function *F) {
- JRS->EraseAllCallSitesPrelocked(F);
+ JRS->EraseAllCallSitesForPrelocked(F);
+}
+
+Function *JITResolverState::EraseStub(const MutexGuard &locked, void *Stub) {
+ CallSiteToFunctionMapTy::iterator C2F_I =
+ CallSiteToFunctionMap.find(Stub);
+ if (C2F_I == CallSiteToFunctionMap.end()) {
+ // Not a stub.
+ return NULL;
+ }
+
+ StubToResolverMap->UnregisterStubResolver(Stub);
+
+ Function *const F = C2F_I->second;
+#ifndef NDEBUG
+ void *RealStub = FunctionToLazyStubMap.lookup(F);
+ assert(RealStub == Stub &&
+ "Call-site that wasn't a stub passed in to EraseStub");
+#endif
+ FunctionToLazyStubMap.erase(F);
+ CallSiteToFunctionMap.erase(C2F_I);
+
+ // Remove the stub from the function->call-sites map, and remove the whole
+ // entry from the map if that was the last call site.
+ FunctionToCallSitesMapTy::iterator F2C_I = FunctionToCallSitesMap.find(F);
+ assert(F2C_I != FunctionToCallSitesMap.end() &&
+ "FunctionToCallSitesMap broken");
+ bool Erased = F2C_I->second.erase(Stub);
+ (void)Erased;
+ assert(Erased && "FunctionToCallSitesMap broken");
+ if (F2C_I->second.empty())
+ FunctionToCallSitesMap.erase(F2C_I);
+
+ return F;
+}
+
+void JITResolverState::EraseAllCallSitesForPrelocked(Function *F) {
+ FunctionToCallSitesMapTy::iterator F2C = FunctionToCallSitesMap.find(F);
+ if (F2C == FunctionToCallSitesMap.end())
+ return;
+ StubToResolverMapTy &S2RMap = *StubToResolverMap;
+ for (SmallPtrSet<void*, 1>::const_iterator I = F2C->second.begin(),
+ E = F2C->second.end(); I != E; ++I) {
+ S2RMap.UnregisterStubResolver(*I);
+ bool Erased = CallSiteToFunctionMap.erase(*I);
+ (void)Erased;
+ assert(Erased && "Missing call site->function mapping");
+ }
+ FunctionToCallSitesMap.erase(F2C);
+}
+
+void JITResolverState::EraseAllCallSitesPrelocked() {
+ StubToResolverMapTy &S2RMap = *StubToResolverMap;
+ for (CallSiteToFunctionMapTy::const_iterator
+ I = CallSiteToFunctionMap.begin(),
+ E = CallSiteToFunctionMap.end(); I != E; ++I) {
+ S2RMap.UnregisterStubResolver(I->first);
+ }
+ CallSiteToFunctionMap.clear();
+ FunctionToCallSitesMap.clear();
+}
+
+JITResolver::~JITResolver() {
+ // No need to lock because we're in the destructor, and state isn't shared.
+ state.EraseAllCallSitesPrelocked();
+ assert(!StubToResolverMap->ResolverHasStubs(this) &&
+ "Resolver destroyed with stubs still alive.");
}
/// getLazyFunctionStubIfAvailable - This returns a pointer to a function stub
@@ -551,16 +619,22 @@ void *JITResolver::getLazyFunctionStub(Function *F) {
DEBUG(dbgs() << "JIT: Lazy stub emitted at [" << Stub << "] for function '"
<< F->getName() << "'\n");
- // Finally, keep track of the stub-to-Function mapping so that the
- // JITCompilerFn knows which function to compile!
- state.AddCallSite(locked, Stub, F);
-
- // If we are JIT'ing non-lazily but need to call a function that does not
- // exist yet, add it to the JIT's work list so that we can fill in the stub
- // address later.
- if (!Actual && !TheJIT->isCompilingLazily())
- if (!isNonGhostDeclaration(F) && !F->hasAvailableExternallyLinkage())
- TheJIT->addPendingFunction(F);
+ if (TheJIT->isCompilingLazily()) {
+ // Register this JITResolver as the one corresponding to this call site so
+ // JITCompilerFn will be able to find it.
+ StubToResolverMap->RegisterStubResolver(Stub, this);
+
+ // Finally, keep track of the stub-to-Function mapping so that the
+ // JITCompilerFn knows which function to compile!
+ state.AddCallSite(locked, Stub, F);
+ } else if (!Actual) {
+ // If we are JIT'ing non-lazily but need to call a function that does not
+ // exist yet, add it to the JIT's work list so that we can fill in the
+ // stub address later.
+ assert(!isNonGhostDeclaration(F) && !F->hasAvailableExternallyLinkage() &&
+ "'Actual' should have been set above.");
+ TheJIT->addPendingFunction(F);
+ }
return Stub;
}
@@ -634,44 +708,12 @@ void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
}
}
-GlobalValue *JITResolver::invalidateStub(void *Stub) {
- MutexGuard locked(TheJIT->lock);
-
- GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked);
-
- // Look up the cheap way first, to see if it's a function stub we are
- // invalidating. If so, remove it from both the forward and reverse maps.
- if (Function *F = state.EraseStub(locked, Stub)) {
- return F;
- }
-
- // Otherwise, it might be an indirect symbol stub. Find it and remove it.
- for (GlobalToIndirectSymMapTy::iterator i = GM.begin(), e = GM.end();
- i != e; ++i) {
- if (i->second != Stub)
- continue;
- GlobalValue *GV = i->first;
- GM.erase(i);
- return GV;
- }
-
- // Lastly, check to see if it's in the ExternalFnToStubMap.
- for (std::map<void *, void *>::iterator i = ExternalFnToStubMap.begin(),
- e = ExternalFnToStubMap.end(); i != e; ++i) {
- if (i->second != Stub)
- continue;
- ExternalFnToStubMap.erase(i);
- break;
- }
-
- return 0;
-}
-
/// JITCompilerFn - This function is called when a lazy compilation stub has
/// been entered. It looks up which function this stub corresponds to, compiles
/// it if necessary, then returns the resultant function pointer.
void *JITResolver::JITCompilerFn(void *Stub) {
- JITResolver &JR = *TheJITResolver;
+ JITResolver *JR = StubToResolverMap->getResolverFromStub(Stub);
+ assert(JR && "Unable to find the corresponding JITResolver to the call site");
Function* F = 0;
void* ActualPtr = 0;
@@ -680,24 +722,24 @@ void *JITResolver::JITCompilerFn(void *Stub) {
// Only lock for getting the Function. The call getPointerToFunction made
// in this function might trigger function materializing, which requires
// JIT lock to be unlocked.
- MutexGuard locked(TheJIT->lock);
+ MutexGuard locked(JR->TheJIT->lock);
// The address given to us for the stub may not be exactly right, it might
// be a little bit after the stub. As such, use upper_bound to find it.
pair<void*, Function*> I =
- JR.state.LookupFunctionFromCallSite(locked, Stub);
+ JR->state.LookupFunctionFromCallSite(locked, Stub);
F = I.second;
ActualPtr = I.first;
}
// If we have already code generated the function, just return the address.
- void *Result = TheJIT->getPointerToGlobalIfAvailable(F);
+ void *Result = JR->TheJIT->getPointerToGlobalIfAvailable(F);
if (!Result) {
// Otherwise we don't have it, do lazy compilation now.
// If lazy compilation is disabled, emit a useful error message and abort.
- if (!TheJIT->isCompilingLazily()) {
+ if (!JR->TheJIT->isCompilingLazily()) {
llvm_report_error("LLVM JIT requested to do lazy compilation of function '"
+ F->getName() + "' when lazy compiles are disabled!");
}
@@ -706,11 +748,11 @@ void *JITResolver::JITCompilerFn(void *Stub) {
<< "' In stub ptr = " << Stub << " actual ptr = "
<< ActualPtr << "\n");
- Result = TheJIT->getPointerToFunction(F);
+ Result = JR->TheJIT->getPointerToFunction(F);
}
// Reacquire the lock to update the GOT map.
- MutexGuard locked(TheJIT->lock);
+ MutexGuard locked(JR->TheJIT->lock);
// We might like to remove the call site from the CallSiteToFunction map, but
// we can't do that! Multiple threads could be stuck, waiting to acquire the
@@ -725,8 +767,8 @@ void *JITResolver::JITCompilerFn(void *Stub) {
// if they see it still using the stub address.
// Note: this is done so the Resolver doesn't have to manage GOT memory
// Do this without allocating map space if the target isn't using a GOT
- if(JR.revGOTMap.find(Stub) != JR.revGOTMap.end())
- JR.revGOTMap[Result] = JR.revGOTMap[Stub];
+ if(JR->revGOTMap.find(Stub) != JR->revGOTMap.end())
+ JR->revGOTMap[Result] = JR->revGOTMap[Stub];
return Result;
}
@@ -751,7 +793,6 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
// that we're returning the same address for the function as any previous
// call. TODO: Yes, this is wrong. The lazy stub isn't guaranteed to be
// close enough to call.
- AddStubToCurrentFunction(FnStub);
return FnStub;
}
@@ -768,18 +809,10 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
return TheJIT->getPointerToFunction(F);
}
- // Otherwise, we may need a to emit a stub, and, conservatively, we
- // always do so.
- void *StubAddr = Resolver.getLazyFunctionStub(F);
-
- // Add the stub to the current function's list of referenced stubs, so we can
- // deallocate them if the current function is ever freed. It's possible to
- // return null from getLazyFunctionStub in the case of a weak extern that
- // fails to resolve.
- if (StubAddr)
- AddStubToCurrentFunction(StubAddr);
-
- return StubAddr;
+ // Otherwise, we may need a to emit a stub, and, conservatively, we always do
+ // so. Note that it's possible to return null from getLazyFunctionStub in the
+ // case of a weak extern that fails to resolve.
+ return Resolver.getLazyFunctionStub(F);
}
void *JITEmitter::getPointerToGVIndirectSym(GlobalValue *V, void *Reference) {
@@ -787,24 +820,9 @@ void *JITEmitter::getPointerToGVIndirectSym(GlobalValue *V, void *Reference) {
// resolved address.
void *GVAddress = getPointerToGlobal(V, Reference, false);
void *StubAddr = Resolver.getGlobalValueIndirectSym(V, GVAddress);
-
- // Add the stub to the current function's list of referenced stubs, so we can
- // deallocate them if the current function is ever freed.
- AddStubToCurrentFunction(StubAddr);
-
return StubAddr;
}
-void JITEmitter::AddStubToCurrentFunction(void *StubAddr) {
- assert(CurFn && "Stub added to current function, but current function is 0!");
-
- SmallVectorImpl<void*> &StubsUsed = CurFnStubUses[CurFn];
- StubsUsed.push_back(StubAddr);
-
- SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[StubAddr];
- FnRefs.insert(CurFn);
-}
-
void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) {
if (!DL.isUnknown()) {
DILocation CurDLT = EmissionDetails.MF->getDILocation(DL);
@@ -839,7 +857,7 @@ static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP,
return Size;
}
-static unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI) {
+static unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI, JIT *jit) {
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty()) return 0;
@@ -847,7 +865,7 @@ static unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI) {
for (unsigned i = 0, e = JT.size(); i != e; ++i)
NumEntries += JT[i].MBBs.size();
- return NumEntries * MJTI->getEntrySize(*TheJIT->getTargetData());
+ return NumEntries * MJTI->getEntrySize(*jit->getTargetData());
}
static uintptr_t RoundUpToAlign(uintptr_t Size, unsigned Alignment) {
@@ -876,11 +894,14 @@ unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) {
}
/// addSizeOfGlobalsInConstantVal - find any globals that we haven't seen yet
-/// but are referenced from the constant; put them in GVSet and add their
-/// size into the running total Size.
-
-unsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant *C,
- unsigned Size) {
+/// but are referenced from the constant; put them in SeenGlobals and the
+/// Worklist, and add their size into the running total Size.
+
+unsigned JITEmitter::addSizeOfGlobalsInConstantVal(
+ const Constant *C,
+ unsigned Size,
+ SmallPtrSet<const GlobalVariable*, 8> &SeenGlobals,
+ SmallVectorImpl<const GlobalVariable*> &Worklist) {
// If its undefined, return the garbage.
if (isa<UndefValue>(C))
return Size;
@@ -902,7 +923,7 @@ unsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant *C,
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast: {
- Size = addSizeOfGlobalsInConstantVal(Op0, Size);
+ Size = addSizeOfGlobalsInConstantVal(Op0, Size, SeenGlobals, Worklist);
break;
}
case Instruction::Add:
@@ -918,8 +939,9 @@ unsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant *C,
case Instruction::And:
case Instruction::Or:
case Instruction::Xor: {
- Size = addSizeOfGlobalsInConstantVal(Op0, Size);
- Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size);
+ Size = addSizeOfGlobalsInConstantVal(Op0, Size, SeenGlobals, Worklist);
+ Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size,
+ SeenGlobals, Worklist);
break;
}
default: {
@@ -933,8 +955,10 @@ unsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant *C,
if (C->getType()->getTypeID() == Type::PointerTyID)
if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C))
- if (GVSet.insert(GV))
+ if (SeenGlobals.insert(GV)) {
+ Worklist.push_back(GV);
Size = addSizeOfGlobal(GV, Size);
+ }
return Size;
}
@@ -942,15 +966,18 @@ unsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant *C,
/// addSizeOfGLobalsInInitializer - handle any globals that we haven't seen yet
/// but are referenced from the given initializer.
-unsigned JITEmitter::addSizeOfGlobalsInInitializer(const Constant *Init,
- unsigned Size) {
+unsigned JITEmitter::addSizeOfGlobalsInInitializer(
+ const Constant *Init,
+ unsigned Size,
+ SmallPtrSet<const GlobalVariable*, 8> &SeenGlobals,
+ SmallVectorImpl<const GlobalVariable*> &Worklist) {
if (!isa<UndefValue>(Init) &&
!isa<ConstantVector>(Init) &&
!isa<ConstantAggregateZero>(Init) &&
!isa<ConstantArray>(Init) &&
!isa<ConstantStruct>(Init) &&
Init->getType()->isFirstClassType())
- Size = addSizeOfGlobalsInConstantVal(Init, Size);
+ Size = addSizeOfGlobalsInConstantVal(Init, Size, SeenGlobals, Worklist);
return Size;
}
@@ -961,7 +988,7 @@ unsigned JITEmitter::addSizeOfGlobalsInInitializer(const Constant *Init,
unsigned JITEmitter::GetSizeOfGlobalsInBytes(MachineFunction &MF) {
unsigned Size = 0;
- GVSet.clear();
+ SmallPtrSet<const GlobalVariable*, 8> SeenGlobals;
for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
MBB != E; ++MBB) {
@@ -985,7 +1012,7 @@ unsigned JITEmitter::GetSizeOfGlobalsInBytes(MachineFunction &MF) {
// assuming the addresses of the new globals in this module
// start at 0 (or something) and adjusting them after codegen
// complete. Another possibility is to grab a marker bit in GV.
- if (GVSet.insert(GV))
+ if (SeenGlobals.insert(GV))
// A variable as yet unseen. Add in its size.
Size = addSizeOfGlobal(GV, Size);
}
@@ -994,12 +1021,14 @@ unsigned JITEmitter::GetSizeOfGlobalsInBytes(MachineFunction &MF) {
}
DEBUG(dbgs() << "JIT: About to look through initializers\n");
// Look for more globals that are referenced only from initializers.
- // GVSet.end is computed each time because the set can grow as we go.
- for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin();
- I != GVSet.end(); I++) {
- const GlobalVariable* GV = *I;
+ SmallVector<const GlobalVariable*, 8> Worklist(
+ SeenGlobals.begin(), SeenGlobals.end());
+ while (!Worklist.empty()) {
+ const GlobalVariable* GV = Worklist.back();
+ Worklist.pop_back();
if (GV->hasInitializer())
- Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size);
+ Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size,
+ SeenGlobals, Worklist);
}
return Size;
@@ -1032,7 +1061,7 @@ void JITEmitter::startFunction(MachineFunction &F) {
MJTI->getEntryAlignment(*TheJIT->getTargetData()));
// Add the jump table size
- ActualSize += GetJumpTableSizeInBytes(MJTI);
+ ActualSize += GetJumpTableSizeInBytes(MJTI, TheJIT);
}
// Add the alignment for the function
@@ -1301,40 +1330,6 @@ void JITEmitter::deallocateMemForFunction(const Function *F) {
if (JITEmitDebugInfo) {
DR->UnregisterFunction(F);
}
-
- // If the function did not reference any stubs, return.
- if (CurFnStubUses.find(F) == CurFnStubUses.end())
- return;
-
- // For each referenced stub, erase the reference to this function, and then
- // erase the list of referenced stubs.
- SmallVectorImpl<void *> &StubList = CurFnStubUses[F];
- for (unsigned i = 0, e = StubList.size(); i != e; ++i) {
- void *Stub = StubList[i];
-
- // If we already invalidated this stub for this function, continue.
- if (StubFnRefs.count(Stub) == 0)
- continue;
-
- SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub];
- FnRefs.erase(F);
-
- // If this function was the last reference to the stub, invalidate the stub
- // in the JITResolver. Were there a memory manager deallocateStub routine,
- // we could call that at this point too.
- if (FnRefs.empty()) {
- DEBUG(dbgs() << "\nJIT: Invalidated Stub at [" << Stub << "]\n");
- StubFnRefs.erase(Stub);
-
- // Invalidate the stub. If it is a GV stub, update the JIT's global
- // mapping for that GV to zero.
- GlobalValue *GV = Resolver.invalidateStub(Stub);
- if (GV) {
- TheJIT->updateGlobalMapping(GV, 0);
- }
- }
- }
- CurFnStubUses.erase(F);
}
@@ -1552,19 +1547,6 @@ JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM,
return new JITEmitter(jit, JMM, tm);
}
-// getPointerToNamedFunction - This function is used as a global wrapper to
-// JIT::getPointerToNamedFunction for the purpose of resolving symbols when
-// bugpoint is debugging the JIT. In that scenario, we are loading an .so and
-// need to resolve function(s) that are being mis-codegenerated, so we need to
-// resolve their addresses at runtime, and this is the way to do it.
-extern "C" {
- void *getPointerToNamedFunction(const char *Name) {
- if (Function *F = TheJIT->FindFunctionNamed(Name))
- return TheJIT->getPointerToFunction(F);
- return TheJIT->getPointerToNamedFunction(Name);
- }
-}
-
// getPointerToFunctionOrStub - If the specified function has been
// code-gen'd, return a pointer to the function. If not, compile it, or use
// a stub to implement lazy compilation if available.
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 7f441b0..8487c83 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -159,7 +159,7 @@ static bool RecursiveResolveTypesI(const Type *DstTy, const Type *SrcTy,
if (DstTy == SrcTy) return false; // If already equal, noop
// If we found our opaque type, resolve it now!
- if (isa<OpaqueType>(DstTy) || isa<OpaqueType>(SrcTy))
+ if (DstTy->isOpaqueTy() || SrcTy->isOpaqueTy())
return ResolveTypes(DstTy, SrcTy);
// Two types cannot be resolved together if they are of different primitive
diff --git a/lib/MC/Android.mk b/lib/MC/Android.mk
new file mode 100644
index 0000000..dac5a54
--- /dev/null
+++ b/lib/MC/Android.mk
@@ -0,0 +1,45 @@
+LOCAL_PATH:= $(call my-dir)
+
+mc_SRC_FILES := \
+ MCAsmInfo.cpp \
+ MCAsmInfoCOFF.cpp \
+ MCAsmInfoDarwin.cpp \
+ MCAsmStreamer.cpp \
+ MCAssembler.cpp \
+ MCCodeEmitter.cpp \
+ MCContext.cpp \
+ MCDisassembler.cpp \
+ MCExpr.cpp \
+ MCInst.cpp \
+ MCInstPrinter.cpp \
+ MCMachOStreamer.cpp \
+ MCNullStreamer.cpp \
+ MCSection.cpp \
+ MCSectionELF.cpp \
+ MCSectionMachO.cpp \
+ MCStreamer.cpp \
+ MCSymbol.cpp \
+ MCValue.cpp \
+ TargetAsmBackend.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mc_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMMC
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mc_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMMC
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index 9ead33b..4cf71dc 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -18,4 +18,5 @@ add_llvm_library(LLVMMC
MCStreamer.cpp
MCSymbol.cpp
MCValue.cpp
+ TargetAsmBackend.cpp
)
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 828377f..1b66900 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
+#include <ctype.h>
using namespace llvm;
namespace {
@@ -134,6 +135,9 @@ public:
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0);
+
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0);
@@ -513,6 +517,13 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
EmitEOL();
}
+void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit) {
+ // Emit with a text fill value.
+ EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
+ 1, MaxBytesToEmit);
+}
+
void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
// FIXME: Verify that Offset is associated with the current section.
@@ -552,7 +563,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
MCFixup &F = Fixups[i];
- MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind());
+ const MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind());
for (unsigned j = 0; j != Info.TargetSize; ++j) {
unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
@@ -599,7 +610,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
MCFixup &F = Fixups[i];
- MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind());
+ const MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind());
OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
<< ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
}
@@ -617,6 +628,12 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
raw_ostream &OS = GetCommentOS();
OS << "<MCInst #" << Inst.getOpcode();
+ StringRef InstName;
+ if (InstPrinter)
+ InstName = InstPrinter->getOpcodeName(Inst.getOpcode());
+ if (!InstName.empty())
+ OS << ' ' << InstName;
+
for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
OS << "\n ";
Inst.getOperand(i).print(OS, &MAI);
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index bdc886b..96227db 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -16,11 +16,17 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MachO.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
+
+// FIXME: Gross.
+#include "../Target/X86/X86FixupKinds.h"
+
#include <vector>
using namespace llvm;
@@ -36,6 +42,8 @@ STATISTIC(EmittedFragments, "Number of emitted assembler fragments");
static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
MachObjectWriter &MOW);
+static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW);
+
/// isVirtualSection - Check if this is a section which does not actually exist
/// in the object file.
static bool isVirtualSection(const MCSection &Section) {
@@ -45,6 +53,30 @@ static bool isVirtualSection(const MCSection &Section) {
return (Type == MCSectionMachO::S_ZEROFILL);
}
+static unsigned getFixupKindLog2Size(unsigned Kind) {
+ switch (Kind) {
+ default: llvm_unreachable("invalid fixup kind!");
+ case X86::reloc_pcrel_1byte:
+ case FK_Data_1: return 0;
+ case FK_Data_2: return 1;
+ case X86::reloc_pcrel_4byte:
+ case X86::reloc_riprel_4byte:
+ case FK_Data_4: return 2;
+ case FK_Data_8: return 3;
+ }
+}
+
+static bool isFixupKindPCRel(unsigned Kind) {
+ switch (Kind) {
+ default:
+ return false;
+ case X86::reloc_pcrel_1byte:
+ case X86::reloc_pcrel_4byte:
+ case X86::reloc_riprel_4byte:
+ return true;
+ }
+}
+
class MachObjectWriter {
// See <mach-o/loader.h>.
enum {
@@ -402,13 +434,14 @@ public:
uint32_t Word0;
uint32_t Word1;
};
- void ComputeScatteredRelocationInfo(MCAssembler &Asm,
- MCSectionData::Fixup &Fixup,
+ void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment,
+ MCAsmFixup &Fixup,
const MCValue &Target,
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
- uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
+ uint32_t Address = Fragment.getOffset() + Fixup.Offset;
unsigned IsPCRel = 0;
+ unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned Type = RIT_Vanilla;
// See <reloc.h>.
@@ -424,11 +457,12 @@ public:
Value2 = SD->getFragment()->getAddress() + SD->getOffset();
}
- unsigned Log2Size = Log2_32(Fixup.Size);
- assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
-
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value - Value2 + Target.getConstant();
+ if (isFixupKindPCRel(Fixup.Kind)) {
+ Fixup.FixedValue -= Address;
+ IsPCRel = 1;
+ }
MachRelocationEntry MRE;
MRE.Word0 = ((Address << 0) |
@@ -453,8 +487,8 @@ public:
}
}
- void ComputeRelocationInfo(MCAssembler &Asm,
- MCSectionData::Fixup &Fixup,
+ void ComputeRelocationInfo(MCAssembler &Asm, MCDataFragment &Fragment,
+ MCAsmFixup &Fixup,
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
MCValue Target;
@@ -466,19 +500,22 @@ public:
if (Target.getSymB() ||
(Target.getSymA() && !Target.getSymA()->isUndefined() &&
Target.getConstant()))
- return ComputeScatteredRelocationInfo(Asm, Fixup, Target,
+ return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
SymbolMap, Relocs);
// See <reloc.h>.
- uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
+ uint32_t Address = Fragment.getOffset() + Fixup.Offset;
uint32_t Value = 0;
unsigned Index = 0;
unsigned IsPCRel = 0;
+ unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned IsExtern = 0;
unsigned Type = 0;
if (Target.isAbsolute()) { // constant
// SymbolNum of 0 indicates the absolute section.
+ //
+ // FIXME: When is this generated?
Type = RIT_Vanilla;
Value = 0;
llvm_unreachable("FIXME: Not yet implemented!");
@@ -495,10 +532,11 @@ public:
//
// FIXME: O(N)
Index = 1;
- for (MCAssembler::iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it, ++Index)
+ MCAssembler::iterator it = Asm.begin(), ie = Asm.end();
+ for (; it != ie; ++it, ++Index)
if (&*it == SD->getFragment()->getParent())
break;
+ assert(it != ie && "Unable to find section index!");
Value = SD->getFragment()->getAddress() + SD->getOffset();
}
@@ -508,8 +546,10 @@ public:
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value + Target.getConstant();
- unsigned Log2Size = Log2_32(Fixup.Size);
- assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
+ if (isFixupKindPCRel(Fixup.Kind)) {
+ Fixup.FixedValue -= Address;
+ IsPCRel = 1;
+ }
// struct relocation_info (8 bytes)
MachRelocationEntry MRE;
@@ -766,17 +806,20 @@ public:
// is written.
std::vector<MachRelocationEntry> RelocInfos;
uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
- for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie;
- ++it) {
+ for (MCAssembler::iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
MCSectionData &SD = *it;
// The assembler writes relocations in the reverse order they were seen.
//
// FIXME: It is probably more complicated than this.
unsigned NumRelocsStart = RelocInfos.size();
- for (unsigned i = 0, e = SD.fixup_size(); i != e; ++i)
- ComputeRelocationInfo(Asm, SD.getFixups()[e - i - 1], SymbolMap,
- RelocInfos);
+ for (MCSectionData::reverse_iterator it2 = SD.rbegin(),
+ ie2 = SD.rend(); it2 != ie2; ++it2)
+ if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2))
+ for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i)
+ ComputeRelocationInfo(Asm, *DF, DF->getFixups()[e - i - 1],
+ SymbolMap, RelocInfos);
unsigned NumRelocs = RelocInfos.size() - NumRelocsStart;
uint64_t SectionStart = SectionDataStart + SD.getAddress();
@@ -871,6 +914,16 @@ public:
OS << StringTable.str();
}
}
+
+ void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) {
+ unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind);
+
+ // FIXME: Endianness assumption.
+ assert(Fixup.Offset + Size <= DF.getContents().size() &&
+ "Invalid fixup offset!");
+ for (unsigned i = 0; i != Size; ++i)
+ DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8));
+ }
};
/* *** */
@@ -905,35 +958,12 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
Address(~UINT64_C(0)),
Size(~UINT64_C(0)),
FileSize(~UINT64_C(0)),
- LastFixupLookup(~0),
HasInstructions(false)
{
if (A)
A->getSectionList().push_back(this);
}
-const MCSectionData::Fixup *
-MCSectionData::LookupFixup(const MCFragment *Fragment, uint64_t Offset) const {
- // Use a one level cache to turn the common case of accessing the fixups in
- // order into O(1) instead of O(N).
- unsigned i = LastFixupLookup, Count = Fixups.size(), End = Fixups.size();
- if (i >= End)
- i = 0;
- while (Count--) {
- const Fixup &F = Fixups[i];
- if (F.Fragment == Fragment && F.Offset == Offset) {
- LastFixupLookup = i;
- return &F;
- }
-
- ++i;
- if (i == End)
- i = 0;
- }
-
- return 0;
-}
-
/* *** */
MCSymbolData::MCSymbolData() : Symbol(0) {}
@@ -980,31 +1010,10 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
}
case MCFragment::FT_Data:
+ case MCFragment::FT_Fill:
F.setFileSize(F.getMaxFileSize());
break;
- case MCFragment::FT_Fill: {
- MCFillFragment &FF = cast<MCFillFragment>(F);
-
- F.setFileSize(F.getMaxFileSize());
-
- MCValue Target;
- if (!FF.getValue().EvaluateAsRelocatable(Target))
- llvm_report_error("expected relocatable expression");
-
- // If the fill value is constant, thats it.
- if (Target.isAbsolute())
- break;
-
- // Otherwise, add fixups for the values.
- for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
- MCSectionData::Fixup Fix(F, i * FF.getValueSize(),
- FF.getValue(),FF.getValueSize());
- SD.getFixups().push_back(Fix);
- }
- break;
- }
-
case MCFragment::FT_Org: {
MCOrgFragment &OF = cast<MCOrgFragment>(F);
@@ -1051,6 +1060,64 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
SD.setFileSize(Address - SD.getAddress());
}
+/// WriteNopData - Write optimal nops to the output file for the \arg Count
+/// bytes. This returns the number of bytes written. It may return 0 if
+/// the \arg Count is more than the maximum optimal nops.
+///
+/// FIXME this is X86 32-bit specific and should move to a better place.
+static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) {
+ static const uint8_t Nops[16][16] = {
+ // nop
+ {0x90},
+ // xchg %ax,%ax
+ {0x66, 0x90},
+ // nopl (%[re]ax)
+ {0x0f, 0x1f, 0x00},
+ // nopl 0(%[re]ax)
+ {0x0f, 0x1f, 0x40, 0x00},
+ // nopl 0(%[re]ax,%[re]ax,1)
+ {0x0f, 0x1f, 0x44, 0x00, 0x00},
+ // nopw 0(%[re]ax,%[re]ax,1)
+ {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
+ // nopl 0L(%[re]ax)
+ {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
+ // nopl 0L(%[re]ax,%[re]ax,1)
+ {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ // nopw 0L(%[re]ax,%[re]ax,1)
+ {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ // nopw %cs:0L(%[re]ax,%[re]ax,1)
+ {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ // nopl 0(%[re]ax,%[re]ax,1)
+ // nopw 0(%[re]ax,%[re]ax,1)
+ {0x0f, 0x1f, 0x44, 0x00, 0x00,
+ 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
+ // nopw 0(%[re]ax,%[re]ax,1)
+ // nopw 0(%[re]ax,%[re]ax,1)
+ {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
+ 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
+ // nopw 0(%[re]ax,%[re]ax,1)
+ // nopl 0L(%[re]ax) */
+ {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
+ 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
+ // nopl 0L(%[re]ax)
+ // nopl 0L(%[re]ax)
+ {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
+ // nopl 0L(%[re]ax)
+ // nopl 0L(%[re]ax,%[re]ax,1)
+ {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}
+ };
+
+ if (Count > 15)
+ return 0;
+
+ for (uint64_t i = 0; i < Count; i++)
+ MOW.Write8 (uint8_t(Nops[Count - 1][i]));
+
+ return Count;
+}
+
/// WriteFileData - Write the \arg F data to the output file.
static void WriteFileData(raw_ostream &OS, const MCFragment &F,
MachObjectWriter &MOW) {
@@ -1074,6 +1141,14 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
"' is not a divisor of padding size '" +
Twine(AF.getFileSize()) + "'");
+ // See if we are aligning with nops, and if so do that first to try to fill
+ // the Count bytes. Then if that did not fill any bytes or there are any
+ // bytes left to fill use the the Value and ValueSize to fill the rest.
+ if (AF.getEmitNops()) {
+ uint64_t NopByteCount = WriteNopData(Count, MOW);
+ Count -= NopByteCount;
+ }
+
for (uint64_t i = 0; i != Count; ++i) {
switch (AF.getValueSize()) {
default:
@@ -1087,39 +1162,30 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
break;
}
- case MCFragment::FT_Data:
+ case MCFragment::FT_Data: {
+ MCDataFragment &DF = cast<MCDataFragment>(F);
+
+ // Apply the fixups.
+ //
+ // FIXME: Move elsewhere.
+ for (MCDataFragment::const_fixup_iterator it = DF.fixup_begin(),
+ ie = DF.fixup_end(); it != ie; ++it)
+ MOW.ApplyFixup(*it, DF);
+
OS << cast<MCDataFragment>(F).getContents().str();
break;
+ }
case MCFragment::FT_Fill: {
MCFillFragment &FF = cast<MCFillFragment>(F);
-
- int64_t Value = 0;
-
- MCValue Target;
- if (!FF.getValue().EvaluateAsRelocatable(Target))
- llvm_report_error("expected relocatable expression");
-
- if (Target.isAbsolute())
- Value = Target.getConstant();
for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
- if (!Target.isAbsolute()) {
- // Find the fixup.
- //
- // FIXME: Find a better way to write in the fixes.
- const MCSectionData::Fixup *Fixup =
- F.getParent()->LookupFixup(&F, i * FF.getValueSize());
- assert(Fixup && "Missing fixup for fill value!");
- Value = Fixup->FixedValue;
- }
-
switch (FF.getValueSize()) {
default:
assert(0 && "Invalid size!");
- case 1: MOW.Write8 (uint8_t (Value)); break;
- case 2: MOW.Write16(uint16_t(Value)); break;
- case 4: MOW.Write32(uint32_t(Value)); break;
- case 8: MOW.Write64(uint64_t(Value)); break;
+ case 1: MOW.Write8 (uint8_t (FF.getValue())); break;
+ case 2: MOW.Write16(uint16_t(FF.getValue())); break;
+ case 4: MOW.Write32(uint32_t(FF.getValue())); break;
+ case 8: MOW.Write64(uint64_t(FF.getValue())); break;
}
}
break;
@@ -1167,6 +1233,10 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
}
void MCAssembler::Finish() {
+ DEBUG_WITH_TYPE("mc-dump", {
+ llvm::errs() << "assembler backend - pre-layout\n--\n";
+ dump(); });
+
// Layout the concrete sections and fragments.
uint64_t Address = 0;
MCSectionData *Prev = 0;
@@ -1205,9 +1275,149 @@ void MCAssembler::Finish() {
Address += SD.getSize();
}
+ DEBUG_WITH_TYPE("mc-dump", {
+ llvm::errs() << "assembler backend - post-layout\n--\n";
+ dump(); });
+
// Write the object file.
MachObjectWriter MOW(OS);
MOW.WriteObject(*this);
OS.flush();
}
+
+
+// Debugging methods
+
+namespace llvm {
+
+raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) {
+ OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value
+ << " Kind:" << AF.Kind << ">";
+ return OS;
+}
+
+}
+
+void MCFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCFragment " << (void*) this << " Offset:" << Offset
+ << " FileSize:" << FileSize;
+
+ OS << ">";
+}
+
+void MCAlignFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCAlignFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Alignment:" << getAlignment()
+ << " Value:" << getValue() << " ValueSize:" << getValueSize()
+ << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">";
+}
+
+void MCDataFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCDataFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Contents:[";
+ for (unsigned i = 0, e = getContents().size(); i != e; ++i) {
+ if (i) OS << ",";
+ OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
+ }
+ OS << "] (" << getContents().size() << " bytes)";
+
+ if (!getFixups().empty()) {
+ OS << ",\n ";
+ OS << " Fixups:[";
+ for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
+ if (it != fixup_begin()) OS << ",\n ";
+ OS << *it;
+ }
+ OS << "]";
+ }
+
+ OS << ">";
+}
+
+void MCFillFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCFillFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Value:" << getValue() << " ValueSize:" << getValueSize()
+ << " Count:" << getCount() << ">";
+}
+
+void MCOrgFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCOrgFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Offset:" << getOffset() << " Value:" << getValue() << ">";
+}
+
+void MCZeroFillFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCZeroFillFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Size:" << getSize() << " Alignment:" << getAlignment() << ">";
+}
+
+void MCSectionData::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCSectionData";
+ OS << " Alignment:" << getAlignment() << " Address:" << Address
+ << " Size:" << Size << " FileSize:" << FileSize
+ << " Fragments:[";
+ for (iterator it = begin(), ie = end(); it != ie; ++it) {
+ if (it != begin()) OS << ",\n ";
+ it->dump();
+ }
+ OS << "]>";
+}
+
+void MCSymbolData::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCSymbolData Symbol:" << getSymbol()
+ << " Fragment:" << getFragment() << " Offset:" << getOffset()
+ << " Flags:" << getFlags() << " Index:" << getIndex();
+ if (isCommon())
+ OS << " (common, size:" << getCommonSize()
+ << " align: " << getCommonAlignment() << ")";
+ if (isExternal())
+ OS << " (external)";
+ if (isPrivateExtern())
+ OS << " (private extern)";
+ OS << ">";
+}
+
+void MCAssembler::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCAssembler\n";
+ OS << " Sections:[";
+ for (iterator it = begin(), ie = end(); it != ie; ++it) {
+ if (it != begin()) OS << ",\n ";
+ it->dump();
+ }
+ OS << "],\n";
+ OS << " Symbols:[";
+
+ for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
+ if (it != symbol_begin()) OS << ",\n ";
+ it->dump();
+ }
+ OS << "]>\n";
+}
diff --git a/lib/MC/MCCodeEmitter.cpp b/lib/MC/MCCodeEmitter.cpp
index c122763..accb06c 100644
--- a/lib/MC/MCCodeEmitter.cpp
+++ b/lib/MC/MCCodeEmitter.cpp
@@ -16,3 +16,15 @@ MCCodeEmitter::MCCodeEmitter() {
MCCodeEmitter::~MCCodeEmitter() {
}
+
+const MCFixupKindInfo &MCCodeEmitter::getFixupKindInfo(MCFixupKind Kind) const {
+ static const MCFixupKindInfo Builtins[] = {
+ { "FK_Data_1", 0, 8 },
+ { "FK_Data_2", 0, 16 },
+ { "FK_Data_4", 0, 32 },
+ { "FK_Data_8", 0, 64 }
+ };
+
+ assert(Kind <= 3 && "Unknown fixup kind");
+ return Builtins[Kind];
+}
diff --git a/lib/MC/MCInstPrinter.cpp b/lib/MC/MCInstPrinter.cpp
index e90c03c..92a7154 100644
--- a/lib/MC/MCInstPrinter.cpp
+++ b/lib/MC/MCInstPrinter.cpp
@@ -8,7 +8,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/ADT/StringRef.h"
using namespace llvm;
MCInstPrinter::~MCInstPrinter() {
}
+
+/// getOpcodeName - Return the name of the specified opcode enum (e.g.
+/// "MOV32ri") or empty if we can't resolve it.
+StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
+ return "";
+}
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 99a819f..a7a8a5d 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -137,6 +137,8 @@ public:
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0);
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0);
@@ -333,7 +335,22 @@ void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size,
unsigned AddrSpace) {
- new MCFillFragment(*AddValueSymbols(Value), Size, 1, CurSectionData);
+ MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
+ if (!DF)
+ DF = new MCDataFragment(CurSectionData);
+
+ // Avoid fixups when possible.
+ int64_t AbsValue;
+ if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
+ // FIXME: Endianness assumption.
+ for (unsigned i = 0; i != Size; ++i)
+ DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
+ } else {
+ DF->getFixups().push_back(MCAsmFixup(DF->getContents().size(),
+ *AddValueSymbols(Value),
+ MCFixup::getKindForSize(Size)));
+ DF->getContents().resize(DF->getContents().size() + Size, 0);
+ }
}
void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
@@ -342,7 +359,20 @@ void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
if (MaxBytesToEmit == 0)
MaxBytesToEmit = ByteAlignment;
new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
- CurSectionData);
+ false /* EmitNops */, CurSectionData);
+
+ // Update the maximum alignment on the current section if necessary.
+ if (ByteAlignment > CurSectionData->getAlignment())
+ CurSectionData->setAlignment(ByteAlignment);
+}
+
+void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit) {
+ if (MaxBytesToEmit == 0)
+ MaxBytesToEmit = ByteAlignment;
+ // FIXME the 0x90 is the default x86 1 byte nop opcode.
+ new MCAlignFragment(ByteAlignment, 0x90, 1, MaxBytesToEmit,
+ true /* EmitNops */, CurSectionData);
// Update the maximum alignment on the current section if necessary.
if (ByteAlignment > CurSectionData->getAlignment())
@@ -365,12 +395,23 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
CurSectionData->setHasInstructions(true);
- // FIXME: Relocations!
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
Emitter->EncodeInstruction(Inst, VecOS, Fixups);
- EmitBytes(VecOS.str(), 0);
+ VecOS.flush();
+
+ // Add the fixups and data.
+ MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
+ if (!DF)
+ DF = new MCDataFragment(CurSectionData);
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ MCFixup &F = Fixups[i];
+ DF->getFixups().push_back(MCAsmFixup(DF->getContents().size()+F.getOffset(),
+ *F.getValue(),
+ F.getKind()));
+ }
+ DF->getContents().append(Code.begin(), Code.end());
}
void MCMachOStreamer::Finish() {
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index 46e9ebf..ab61799 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -55,6 +55,9 @@ namespace {
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) {}
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0) {}
+
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0) {}
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index d5bc396..6185c30 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -146,7 +146,7 @@ bool AsmParser::Run() {
// FIXME: Target hook & command line option for initial section.
Out.SwitchSection(getMachOSection("__TEXT", "__text",
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, SectionKind()));
+ 0, SectionKind::getText()));
// Prime the lexer.
@@ -325,9 +325,17 @@ bool AsmParser::ParseExpression(const MCExpr *&Res) {
/// expr ::= primaryexpr
///
bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+ // Parse the expression.
Res = 0;
- return ParsePrimaryExpr(Res, EndLoc) ||
- ParseBinOpRHS(1, Res, EndLoc);
+ if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
+ return true;
+
+ // Try to constant fold it up front, if possible.
+ int64_t Value;
+ if (Res->EvaluateAsAbsolute(Value))
+ Res = MCConstantExpr::Create(Value, getContext());
+
+ return false;
}
bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
@@ -906,8 +914,10 @@ bool AsmParser::ParseDirectiveDarwinSection() {
return Error(Loc, ErrorStr.c_str());
// FIXME: Arch specific.
+ bool isText = Segment == "__TEXT"; // FIXME: Hack.
Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
- SectionKind()));
+ isText ? SectionKind::getText()
+ : SectionKind::getDataRel()));
return false;
}
@@ -921,8 +931,10 @@ bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
Lex();
// FIXME: Arch specific.
+ bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
- SectionKind()));
+ isText ? SectionKind::getText()
+ : SectionKind::getDataRel()));
// Set the implicit alignment, if any.
//
@@ -1229,8 +1241,14 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
}
}
- // FIXME: Target specific behavior about how the "extra" bytes are filled.
- Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
+ // FIXME: hard code the parser to use EmitCodeAlignment for text when using
+ // the TextAlignFillValue.
+ if(Out.getCurrentSection()->getKind().isText() &&
+ Lexer.getMAI().getTextAlignFillValue() == FillExpr)
+ Out.EmitCodeAlignment(Alignment, MaxBytesToFill);
+ else
+ // FIXME: Target specific behavior about how the "extra" bytes are filled.
+ Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
return false;
}
@@ -1354,7 +1372,7 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
if (IsLocal) {
Out.EmitZerofill(getMachOSection("__DATA", "__bss",
MCSectionMachO::S_ZEROFILL, 0,
- SectionKind()),
+ SectionKind::getBSS()),
Sym, Size, 1 << Pow2Alignment);
return false;
}
@@ -1390,7 +1408,7 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
// Create the zerofill section but no symbol
Out.EmitZerofill(getMachOSection(Segment, Section,
MCSectionMachO::S_ZEROFILL, 0,
- SectionKind()));
+ SectionKind::getBSS()));
return false;
}
@@ -1448,7 +1466,7 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
// FIXME: Arch specific.
Out.EmitZerofill(getMachOSection(Segment, Section,
MCSectionMachO::S_ZEROFILL, 0,
- SectionKind()),
+ SectionKind::getBSS()),
Sym, Size, 1 << Pow2Alignment);
return false;
diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp
index 6cc67a2..370aad1 100644
--- a/lib/MC/MCSectionMachO.cpp
+++ b/lib/MC/MCSectionMachO.cpp
@@ -10,6 +10,7 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/raw_ostream.h"
+#include <ctype.h>
using namespace llvm;
/// SectionTypeDescriptors - These are strings that describe the various section
diff --git a/lib/MC/TargetAsmBackend.cpp b/lib/MC/TargetAsmBackend.cpp
new file mode 100644
index 0000000..918d272
--- /dev/null
+++ b/lib/MC/TargetAsmBackend.cpp
@@ -0,0 +1,19 @@
+//===-- TargetAsmBackend.cpp - Target Assembly Backend ---------------------==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetAsmBackend.h"
+using namespace llvm;
+
+TargetAsmBackend::TargetAsmBackend(const Target &T)
+ : TheTarget(T)
+{
+}
+
+TargetAsmBackend::~TargetAsmBackend() {
+}
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 1e6d22f..8f860a6 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include <limits.h>
#include <cstring>
using namespace llvm;
@@ -625,17 +626,58 @@ APFloat::copySignificand(const APFloat &rhs)
/* Make this number a NaN, with an arbitrary but deterministic value
for the significand. If double or longer, this is a signalling NaN,
which may not be ideal. If float, this is QNaN(0). */
-void
-APFloat::makeNaN(unsigned type)
+void APFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill)
{
category = fcNaN;
- // FIXME: Add double and long double support for QNaN(0).
- if (semantics->precision == 24 && semantics->maxExponent == 127) {
- type |= 0x7fc00000U;
- type &= ~0x80000000U;
- } else
- type = ~0U;
- APInt::tcSet(significandParts(), type, partCount());
+ sign = Negative;
+
+ integerPart *significand = significandParts();
+ unsigned numParts = partCount();
+
+ // Set the significand bits to the fill.
+ if (!fill || fill->getNumWords() < numParts)
+ APInt::tcSet(significand, 0, numParts);
+ if (fill) {
+ APInt::tcAssign(significand, fill->getRawData(),
+ std::min(fill->getNumWords(), numParts));
+
+ // Zero out the excess bits of the significand.
+ unsigned bitsToPreserve = semantics->precision - 1;
+ unsigned part = bitsToPreserve / 64;
+ bitsToPreserve %= 64;
+ significand[part] &= ((1ULL << bitsToPreserve) - 1);
+ for (part++; part != numParts; ++part)
+ significand[part] = 0;
+ }
+
+ unsigned QNaNBit = semantics->precision - 2;
+
+ if (SNaN) {
+ // We always have to clear the QNaN bit to make it an SNaN.
+ APInt::tcClearBit(significand, QNaNBit);
+
+ // If there are no bits set in the payload, we have to set
+ // *something* to make it a NaN instead of an infinity;
+ // conventionally, this is the next bit down from the QNaN bit.
+ if (APInt::tcIsZero(significand, numParts))
+ APInt::tcSetBit(significand, QNaNBit - 1);
+ } else {
+ // We always have to set the QNaN bit to make it a QNaN.
+ APInt::tcSetBit(significand, QNaNBit);
+ }
+
+ // For x87 extended precision, we want to make a NaN, not a
+ // pseudo-NaN. Maybe we should expose the ability to make
+ // pseudo-NaNs?
+ if (semantics == &APFloat::x87DoubleExtended)
+ APInt::tcSetBit(significand, QNaNBit + 1);
+}
+
+APFloat APFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
+ const APInt *fill) {
+ APFloat value(Sem, uninitialized);
+ value.makeNaN(SNaN, Negative, fill);
+ return value;
}
APFloat &
@@ -700,9 +742,14 @@ APFloat::APFloat(const fltSemantics &ourSemantics) {
sign = false;
}
+APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
+ assertArithmeticOK(ourSemantics);
+ // Allocates storage if necessary but does not initialize it.
+ initialize(&ourSemantics);
+}
APFloat::APFloat(const fltSemantics &ourSemantics,
- fltCategory ourCategory, bool negative, unsigned type)
+ fltCategory ourCategory, bool negative)
{
assertArithmeticOK(ourSemantics);
initialize(&ourSemantics);
@@ -711,7 +758,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics,
if (category == fcNormal)
category = fcZero;
else if (ourCategory == fcNaN)
- makeNaN(type);
+ makeNaN();
}
APFloat::APFloat(const fltSemantics &ourSemantics, const StringRef& text)
@@ -2345,11 +2392,24 @@ APFloat::convertFromDecimalString(const StringRef &str, roundingMode rounding_mo
if (decDigitValue(*D.firstSigDigit) >= 10U) {
category = fcZero;
fs = opOK;
- } else if ((D.normalizedExponent + 1) * 28738
- <= 8651 * (semantics->minExponent - (int) semantics->precision)) {
+
+ /* Check whether the normalized exponent is high enough to overflow
+ max during the log-rebasing in the max-exponent check below. */
+ } else if (D.normalizedExponent - 1 > INT_MAX / 42039) {
+ fs = handleOverflow(rounding_mode);
+
+ /* If it wasn't, then it also wasn't high enough to overflow max
+ during the log-rebasing in the min-exponent check. Check that it
+ won't overflow min in either check, then perform the min-exponent
+ check. */
+ } else if (D.normalizedExponent - 1 < INT_MIN / 42039 ||
+ (D.normalizedExponent + 1) * 28738 <=
+ 8651 * (semantics->minExponent - (int) semantics->precision)) {
/* Underflow to zero and round. */
zeroSignificand();
fs = normalize(rounding_mode, lfLessThanHalf);
+
+ /* We can finally safely perform the max-exponent check. */
} else if ((D.normalizedExponent - 1) * 42039
>= 12655 * semantics->maxExponent) {
/* Overflow and round. */
@@ -3306,7 +3366,7 @@ namespace {
void APFloat::toString(SmallVectorImpl<char> &Str,
unsigned FormatPrecision,
- unsigned FormatMaxPadding) {
+ unsigned FormatMaxPadding) const {
switch (category) {
case fcInfinity:
if (isNegative())
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 3bce3f3..6a6384a 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -2344,13 +2344,21 @@ APInt::tcExtractBit(const integerPart *parts, unsigned int bit)
& ((integerPart) 1 << bit % integerPartWidth)) != 0;
}
-/* Set the given bit of a bignum. */
+/* Set the given bit of a bignum. */
void
APInt::tcSetBit(integerPart *parts, unsigned int bit)
{
parts[bit / integerPartWidth] |= (integerPart) 1 << (bit % integerPartWidth);
}
+/* Clears the given bit of a bignum. */
+void
+APInt::tcClearBit(integerPart *parts, unsigned int bit)
+{
+ parts[bit / integerPartWidth] &=
+ ~((integerPart) 1 << (bit % integerPartWidth));
+}
+
/* Returns the bit number of the least significant set bit of a
number. If the input number has no bits set -1U is returned. */
unsigned int
diff --git a/lib/Support/Android.mk b/lib/Support/Android.mk
new file mode 100644
index 0000000..e972753
--- /dev/null
+++ b/lib/Support/Android.mk
@@ -0,0 +1,72 @@
+LOCAL_PATH:= $(call my-dir)
+
+support_SRC_FILES := \
+ APFloat.cpp \
+ APInt.cpp \
+ APSInt.cpp \
+ Allocator.cpp \
+ CommandLine.cpp \
+ ConstantRange.cpp \
+ Debug.cpp \
+ DeltaAlgorithm.cpp \
+ Dwarf.cpp \
+ ErrorHandling.cpp \
+ FileUtilities.cpp \
+ FoldingSet.cpp \
+ FormattedStream.cpp \
+ GraphWriter.cpp \
+ IsInf.cpp \
+ IsNAN.cpp \
+ ManagedStatic.cpp \
+ MemoryBuffer.cpp \
+ MemoryObject.cpp \
+ PluginLoader.cpp \
+ PrettyStackTrace.cpp \
+ Regex.cpp \
+ SlowOperationInformer.cpp \
+ SmallPtrSet.cpp \
+ SmallVector.cpp \
+ SourceMgr.cpp \
+ Statistic.cpp \
+ StringExtras.cpp \
+ StringMap.cpp \
+ StringPool.cpp \
+ StringRef.cpp \
+ SystemUtils.cpp \
+ TargetRegistry.cpp \
+ Timer.cpp \
+ Triple.cpp \
+ Twine.cpp \
+ circular_raw_ostream.cpp \
+ raw_os_ostream.cpp \
+ raw_ostream.cpp \
+ regcomp.c \
+ regerror.c \
+ regexec.c \
+ regfree.c \
+ regstrlcpy.c
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+# FIXME: This only requires RTTI because tblgen uses it. Fix that.
+REQUIRES_RTTI := 1
+
+LOCAL_SRC_FILES := $(support_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMSupport
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(support_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMSupport
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 961dc1f..2ab4103 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -650,7 +650,7 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
if (Handler == 0) {
if (SinkOpts.empty()) {
errs() << ProgramName << ": Unknown command line argument '"
- << argv[i] << "'. Try: '" << argv[0] << " --help'\n";
+ << argv[i] << "'. Try: '" << argv[0] << " -help'\n";
ErrorParsing = true;
} else {
for (SmallVectorImpl<Option*>::iterator I = SinkOpts.begin(),
@@ -673,7 +673,7 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
errs() << ProgramName
<< ": Not enough positional command line arguments specified!\n"
<< "Must specify at least " << NumPositionalRequired
- << " positional arguments: See: " << argv[0] << " --help\n";
+ << " positional arguments: See: " << argv[0] << " -help\n";
ErrorParsing = true;
} else if (!HasUnlimitedPositionals
@@ -681,7 +681,7 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
errs() << ProgramName
<< ": Too many positional arguments specified!\n"
<< "Can specify at most " << PositionalOpts.size()
- << " positional arguments: See: " << argv[0] << " --help\n";
+ << " positional arguments: See: " << argv[0] << " -help\n";
ErrorParsing = true;
} else if (ConsumeAfterOpt == 0) {
@@ -1029,7 +1029,7 @@ void generic_parser_base::printOptionInfo(const Option &O,
//===----------------------------------------------------------------------===//
-// --help and --help-hidden option implementation
+// -help and -help-hidden option implementation
//
static int OptNameCompare(const void *LHS, const void *RHS) {
@@ -1134,7 +1134,7 @@ static HelpPrinter NormalPrinter(false);
static HelpPrinter HiddenPrinter(true);
static cl::opt<HelpPrinter, true, parser<bool> >
-HOp("help", cl::desc("Display available options (--help-hidden for more)"),
+HOp("help", cl::desc("Display available options (-help-hidden for more)"),
cl::location(NormalPrinter), cl::ValueDisallowed);
static cl::opt<HelpPrinter, true, parser<bool> >
@@ -1222,8 +1222,8 @@ void cl::PrintHelpMessage() {
// NormalPrinter variable is a HelpPrinter and the help gets printed when
// its operator= is invoked. That's because the "normal" usages of the
// help printer is to be assigned true/false depending on whether the
- // --help option was given or not. Since we're circumventing that we have
- // to make it look like --help was given, so we assign true.
+ // -help option was given or not. Since we're circumventing that we have
+ // to make it look like -help was given, so we assign true.
NormalPrinter = true;
}
diff --git a/lib/Support/FormattedStream.cpp b/lib/Support/FormattedStream.cpp
index 9ab3666..c72b5a1 100644
--- a/lib/Support/FormattedStream.cpp
+++ b/lib/Support/FormattedStream.cpp
@@ -56,15 +56,14 @@ void formatted_raw_ostream::ComputeColumn(const char *Ptr, size_t Size) {
/// PadToColumn - Align the output to some column number.
///
/// \param NewCol - The column to move to.
-/// \param MinPad - The minimum space to give after the most recent
-/// I/O, even if the current column + minpad > newcol.
///
-void formatted_raw_ostream::PadToColumn(unsigned NewCol) {
+formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) {
// Figure out what's in the buffer and add it to the column count.
ComputeColumn(getBufferStart(), GetNumBytesInBuffer());
// Output spaces until we reach the desired column.
indent(std::max(int(NewCol - ColumnScanned), 1));
+ return *this;
}
void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) {
diff --git a/lib/Support/GraphWriter.cpp b/lib/Support/GraphWriter.cpp
index c8bca6e..ec84f9b 100644
--- a/lib/Support/GraphWriter.cpp
+++ b/lib/Support/GraphWriter.cpp
@@ -137,7 +137,7 @@ void llvm::DisplayGraph(const sys::Path &Filename, bool wait,
args.clear();
args.push_back(gv.c_str());
args.push_back(PSFilename.c_str());
- args.push_back("-spartan");
+ args.push_back("--spartan");
args.push_back(0);
ErrMsg.clear();
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 9253b01..eb046d0 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -174,7 +174,8 @@ MemoryBuffer *MemoryBuffer::getFile(StringRef Filename, std::string *ErrStr,
#ifdef O_BINARY
OpenFlags |= O_BINARY; // Open input file in binary mode on win32.
#endif
- int FD = ::open(Filename.str().c_str(), O_RDONLY|OpenFlags);
+ SmallString<256> PathBuf(Filename.begin(), Filename.end());
+ int FD = ::open(PathBuf.c_str(), O_RDONLY|OpenFlags);
if (FD == -1) {
if (ErrStr) *ErrStr = strerror(errno);
return 0;
diff --git a/lib/Support/Regex.cpp b/lib/Support/Regex.cpp
index 618ca05..a7631de 100644
--- a/lib/Support/Regex.cpp
+++ b/lib/Support/Regex.cpp
@@ -90,3 +90,79 @@ bool Regex::match(const StringRef &String, SmallVectorImpl<StringRef> *Matches){
return true;
}
+
+std::string Regex::sub(StringRef Repl, StringRef String,
+ std::string *Error) {
+ SmallVector<StringRef, 8> Matches;
+
+ // Reset error, if given.
+ if (Error && !Error->empty()) *Error = "";
+
+ // Return the input if there was no match.
+ if (!match(String, &Matches))
+ return String;
+
+ // Otherwise splice in the replacement string, starting with the prefix before
+ // the match.
+ std::string Res(String.begin(), Matches[0].begin());
+
+ // Then the replacement string, honoring possible substitutions.
+ while (!Repl.empty()) {
+ // Skip to the next escape.
+ std::pair<StringRef, StringRef> Split = Repl.split('\\');
+
+ // Add the skipped substring.
+ Res += Split.first;
+
+ // Check for terminimation and trailing backslash.
+ if (Split.second.empty()) {
+ if (Repl.size() != Split.first.size() &&
+ Error && Error->empty())
+ *Error = "replacement string contained trailing backslash";
+ break;
+ }
+
+ // Otherwise update the replacement string and interpret escapes.
+ Repl = Split.second;
+
+ // FIXME: We should have a StringExtras function for mapping C99 escapes.
+ switch (Repl[0]) {
+ // Treat all unrecognized characters as self-quoting.
+ default:
+ Res += Repl[0];
+ Repl = Repl.substr(1);
+ break;
+
+ // Single character escapes.
+ case 't':
+ Res += '\t';
+ Repl = Repl.substr(1);
+ break;
+ case 'n':
+ Res += '\n';
+ Repl = Repl.substr(1);
+ break;
+
+ // Decimal escapes are backreferences.
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ // Extract the backreference number.
+ StringRef Ref = Repl.slice(0, Repl.find_first_not_of("0123456789"));
+ Repl = Repl.substr(Ref.size());
+
+ unsigned RefValue;
+ if (!Ref.getAsInteger(10, RefValue) &&
+ RefValue < Matches.size())
+ Res += Matches[RefValue];
+ else if (Error && Error->empty())
+ *Error = "invalid backreference string '" + Ref.str() + "'";
+ break;
+ }
+ }
+ }
+
+ // And finally the suffix.
+ Res += StringRef(Matches[0].end(), String.end() - Matches[0].end());
+
+ return Res;
+}
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index ae2640b..2b262dc 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/APInt.h"
using namespace llvm;
@@ -172,23 +173,28 @@ size_t StringRef::count(StringRef Str) const {
return Count;
}
+static unsigned GetAutoSenseRadix(StringRef &Str) {
+ if (Str.startswith("0x")) {
+ Str = Str.substr(2);
+ return 16;
+ } else if (Str.startswith("0b")) {
+ Str = Str.substr(2);
+ return 2;
+ } else if (Str.startswith("0")) {
+ return 8;
+ } else {
+ return 10;
+ }
+}
+
+
/// GetAsUnsignedInteger - Workhorse method that converts a integer character
/// sequence of radix up to 36 to an unsigned long long value.
static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix,
unsigned long long &Result) {
// Autosense radix if not specified.
- if (Radix == 0) {
- if (Str.startswith("0x")) {
- Str = Str.substr(2);
- Radix = 16;
- } else if (Str.startswith("0b")) {
- Str = Str.substr(2);
- Radix = 2;
- } else if (Str.startswith("0"))
- Radix = 8;
- else
- Radix = 10;
- }
+ if (Radix == 0)
+ Radix = GetAutoSenseRadix(Str);
// Empty strings (after the radix autosense) are invalid.
if (Str.empty()) return true;
@@ -272,3 +278,78 @@ bool StringRef::getAsInteger(unsigned Radix, unsigned &Result) const {
Result = Val;
return false;
}
+
+bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
+ StringRef Str = *this;
+
+ // Autosense radix if not specified.
+ if (Radix == 0)
+ Radix = GetAutoSenseRadix(Str);
+
+ assert(Radix > 1 && Radix <= 36);
+
+ // Empty strings (after the radix autosense) are invalid.
+ if (Str.empty()) return true;
+
+ // Skip leading zeroes. This can be a significant improvement if
+ // it means we don't need > 64 bits.
+ while (!Str.empty() && Str.front() == '0')
+ Str = Str.substr(1);
+
+ // If it was nothing but zeroes....
+ if (Str.empty()) {
+ Result = APInt(64, 0);
+ return false;
+ }
+
+ // (Over-)estimate the required number of bits.
+ unsigned Log2Radix = 0;
+ while ((1U << Log2Radix) < Radix) Log2Radix++;
+ bool IsPowerOf2Radix = ((1U << Log2Radix) == Radix);
+
+ unsigned BitWidth = Log2Radix * Str.size();
+ if (BitWidth < Result.getBitWidth())
+ BitWidth = Result.getBitWidth(); // don't shrink the result
+ else
+ Result.zext(BitWidth);
+
+ APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix
+ if (!IsPowerOf2Radix) {
+ // These must have the same bit-width as Result.
+ RadixAP = APInt(BitWidth, Radix);
+ CharAP = APInt(BitWidth, 0);
+ }
+
+ // Parse all the bytes of the string given this radix.
+ Result = 0;
+ while (!Str.empty()) {
+ unsigned CharVal;
+ if (Str[0] >= '0' && Str[0] <= '9')
+ CharVal = Str[0]-'0';
+ else if (Str[0] >= 'a' && Str[0] <= 'z')
+ CharVal = Str[0]-'a'+10;
+ else if (Str[0] >= 'A' && Str[0] <= 'Z')
+ CharVal = Str[0]-'A'+10;
+ else
+ return true;
+
+ // If the parsed value is larger than the integer radix, the string is
+ // invalid.
+ if (CharVal >= Radix)
+ return true;
+
+ // Add in this character.
+ if (IsPowerOf2Radix) {
+ Result <<= Log2Radix;
+ Result |= CharVal;
+ } else {
+ Result *= RadixAP;
+ CharAP = CharVal;
+ Result += CharAP;
+ }
+
+ Str = Str.substr(1);
+ }
+
+ return false;
+}
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index 5a76184..61bf0a7 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -40,6 +40,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case x86: return "i386";
case x86_64: return "x86_64";
case xcore: return "xcore";
+ case mblaze: return "mblaze";
}
return "<invalid>";
@@ -62,6 +63,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case ppc64:
case ppc: return "ppc";
+ case mblaze: return "mblaze";
+
case sparcv9:
case sparc: return "sparc";
@@ -127,6 +130,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return ppc64;
if (Name == "ppc")
return ppc;
+ if (Name == "mblaze")
+ return mblaze;
if (Name == "sparc")
return sparc;
if (Name == "sparcv9")
@@ -198,6 +203,8 @@ const char *Triple::getArchNameForAssembler() {
return "ppc";
if (Str == "powerpc64")
return "ppc64";
+ if (Str == "mblaze" || Str == "microblaze")
+ return "mblaze";
if (Str == "arm")
return "arm";
if (Str == "armv4t" || Str == "thumbv4t")
@@ -234,6 +241,8 @@ void Triple::Parse() const {
Arch = ppc;
else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
Arch = ppc64;
+ else if (ArchName == "mblaze")
+ Arch = mblaze;
else if (ArchName == "arm" ||
ArchName.startswith("armv") ||
ArchName == "xscale")
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index af6dc7c..071c924 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -368,6 +368,7 @@ void format_object_base::home() {
/// if no error occurred.
raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
unsigned Flags) : pos(0) {
+ assert(Filename != 0 && "Filename is null");
// Verify that we don't have both "append" and "excl".
assert((!(Flags & F_Excl) || !(Flags & F_Append)) &&
"Cannot specify both 'excl' and 'append' file creation flags!");
@@ -574,12 +575,18 @@ void raw_svector_ostream::resync() {
}
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!");
-
- // We don't need to copy the bytes, just commit the bytes to the
- // SmallVector.
- OS.set_size(OS.size() + Size);
+ // If we're writing bytes from the end of the buffer into the smallvector, we
+ // don't need to copy the bytes, just commit the bytes because they are
+ // already in the right place.
+ if (Ptr == OS.end()) {
+ assert(OS.size() + Size <= OS.capacity() && "Invalid write_impl() call!");
+ OS.set_size(OS.size() + Size);
+ } else {
+ assert(GetNumBytesInBuffer() == 0 &&
+ "Should be writing from buffer if some bytes in it");
+ // Otherwise, do copy the bytes.
+ OS.append(Ptr, Ptr+Size);
+ }
// Grow the vector if necessary.
if (OS.capacity() - OS.size() < 64)
diff --git a/lib/System/Android.mk b/lib/System/Android.mk
new file mode 100644
index 0000000..3f11fc7
--- /dev/null
+++ b/lib/System/Android.mk
@@ -0,0 +1,46 @@
+LOCAL_PATH:= $(call my-dir)
+
+system_SRC_FILES := \
+ Alarm.cpp \
+ Atomic.cpp \
+ Disassembler.cpp \
+ Errno.cpp \
+ Host.cpp \
+ IncludeFile.cpp \
+ Memory.cpp \
+ Mutex.cpp \
+ Path.cpp \
+ Process.cpp \
+ Program.cpp \
+ RWMutex.cpp \
+ Signals.cpp \
+ ThreadLocal.cpp \
+ Threading.cpp \
+ TimeValue.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+REQUIRES_RTTI := 1
+
+LOCAL_SRC_FILES := $(system_SRC_FILES)
+LOCAL_CFLAGS += -march=i686
+
+LOCAL_MODULE:= libLLVMSystem
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+REQUIRES_RTTI := 1
+
+LOCAL_SRC_FILES := $(system_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMSystem
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/System/Unix/Host.inc b/lib/System/Unix/Host.inc
index c76d6a4..5b11876 100644
--- a/lib/System/Unix/Host.inc
+++ b/lib/System/Unix/Host.inc
@@ -21,6 +21,7 @@
#include "Unix.h"
#include <sys/utsname.h>
#include <string>
+#include <ctype.h>
using namespace llvm;
diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc
index e8c2806..c10498a 100644
--- a/lib/System/Unix/Program.inc
+++ b/lib/System/Unix/Program.inc
@@ -126,7 +126,7 @@ static void TimeOutHandler(int Sig) {
static void SetMemoryLimits (unsigned size)
{
-#if HAVE_SYS_RESOURCE_H
+#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
struct rlimit r;
__typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc
index 676e1e5..c8ec68a 100644
--- a/lib/System/Unix/Signals.inc
+++ b/lib/System/Unix/Signals.inc
@@ -52,7 +52,16 @@ static const int *const IntSigsEnd =
// KillSigs - Signals that are synchronous with the program that will cause it
// to die.
static const int KillSigs[] = {
- SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
+ SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV
+#ifdef SIGSYS
+ , SIGSYS
+#endif
+#ifdef SIGXCPU
+ , SIGXCPU
+#endif
+#ifdef SIGXFSZ
+ , SIGXFSZ
+#endif
#ifdef SIGEMT
, SIGEMT
#endif
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 6fe7c2c..8e537d8 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -643,6 +643,13 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
DebugLoc DL = DebugLoc::getUnknownLoc();
if (I != MBB.end()) DL = I->getDebugLoc();
+ // tGPR is used sometimes in ARM instructions that need to avoid using
+ // certain registers. Just treat it as GPR here.
+ if (DestRC == ARM::tGPRRegisterClass)
+ DestRC = ARM::GPRRegisterClass;
+ if (SrcRC == ARM::tGPRRegisterClass)
+ SrcRC = ARM::GPRRegisterClass;
+
if (DestRC != SrcRC) {
if (DestRC->getSize() != SrcRC->getSize())
return false;
@@ -697,6 +704,11 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
MFI.getObjectSize(FI),
Align);
+ // tGPR is used sometimes in ARM instructions that need to avoid using
+ // certain registers. Just treat it as GPR here.
+ if (RC == ARM::tGPRRegisterClass)
+ RC = ARM::GPRRegisterClass;
+
if (RC == ARM::GPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
.addReg(SrcReg, getKillRegState(isKill))
@@ -745,6 +757,11 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
MFI.getObjectSize(FI),
Align);
+ // tGPR is used sometimes in ARM instructions that need to avoid using
+ // certain registers. Just treat it as GPR here.
+ if (RC == ARM::tGPRRegisterClass)
+ RC = ARM::GPRRegisterClass;
+
if (RC == ARM::GPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
.addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO));
@@ -1020,9 +1037,8 @@ ARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const {
return MI;
}
-bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0,
- const MachineInstr *MI1,
- const MachineRegisterInfo *MRI) const {
+bool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
+ const MachineInstr *MI1) const {
int Opcode = MI0->getOpcode();
if (Opcode == ARM::t2LDRpci ||
Opcode == ARM::t2LDRpci_pic ||
@@ -1051,7 +1067,7 @@ bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0,
return ACPV0->hasSameValue(ACPV1);
}
- return TargetInstrInfoImpl::isIdentical(MI0, MI1, MRI);
+ return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
}
/// getInstrPredicate - If instruction is predicated, returns its predicate
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h
index 0d9d4a7..0194231 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -289,8 +289,8 @@ public:
MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const;
- virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other,
- const MachineRegisterInfo *MRI) const;
+ virtual bool produceSameValue(const MachineInstr *MI0,
+ const MachineInstr *MI1) const;
};
static inline
@@ -332,7 +332,7 @@ bool isJumpTableBranchOpcode(int Opc) {
static inline
bool isIndirectBranchOpcode(int Opc) {
- return Opc == ARM::BRIND || Opc == ARM::tBRIND;
+ return Opc == ARM::BRIND || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
}
/// getInstrPredicate - If instruction is predicated, returns its predicate
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index cb0bd1d..577c363 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -513,7 +513,7 @@ cannotEliminateFrame(const MachineFunction &MF) const {
}
/// estimateStackSize - Estimate and return the size of the frame.
-static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
+static unsigned estimateStackSize(MachineFunction &MF) {
const MachineFrameInfo *FFI = MF.getFrameInfo();
int Offset = 0;
for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
@@ -583,14 +583,6 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
SmallVector<unsigned, 4> UnspilledCS2GPRs;
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
-
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- if (RealignStack) {
- MachineFrameInfo *MFI = MF.getFrameInfo();
- MFI->calculateMaxStackAlignment();
- }
-
// Spill R4 if Thumb2 function requires stack realignment - it will be used as
// scratch register.
// FIXME: It will be better just to find spare register here.
@@ -679,8 +671,16 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
}
}
+ // If any of the stack slot references may be out of range of an immediate
+ // offset, make sure a register (or a spill slot) is available for the
+ // register scavenger. Note that if we're indexing off the frame pointer, the
+ // effective stack size is 4 bytes larger since the FP points to the stack
+ // slot of the previous FP.
+ bool BigStack = RS &&
+ estimateStackSize(MF) + (hasFP(MF) ? 4 : 0) >= estimateRSStackSizeLimit(MF);
+
bool ExtraCSSpill = false;
- if (!CanEliminateFrame || cannotEliminateFrame(MF)) {
+ if (BigStack || !CanEliminateFrame || cannotEliminateFrame(MF)) {
AFI->setHasStackFrame(true);
// If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
@@ -735,51 +735,43 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
// callee-saved register or reserve a special spill slot to facilitate
// register scavenging. Thumb1 needs a spill slot for stack pointer
// adjustments also, even when the frame itself is small.
- if (RS && !ExtraCSSpill) {
- MachineFrameInfo *MFI = MF.getFrameInfo();
- // If any of the stack slot references may be out of range of an
- // immediate offset, make sure a register (or a spill slot) is
- // available for the register scavenger. Note that if we're indexing
- // off the frame pointer, the effective stack size is 4 bytes larger
- // since the FP points to the stack slot of the previous FP.
- if (estimateStackSize(MF, MFI) + (hasFP(MF) ? 4 : 0)
- >= estimateRSStackSizeLimit(MF)) {
- // If any non-reserved CS register isn't spilled, just spill one or two
- // extra. That should take care of it!
- unsigned NumExtras = TargetAlign / 4;
- SmallVector<unsigned, 2> Extras;
- while (NumExtras && !UnspilledCS1GPRs.empty()) {
- unsigned Reg = UnspilledCS1GPRs.back();
- UnspilledCS1GPRs.pop_back();
+ if (BigStack && !ExtraCSSpill) {
+ // If any non-reserved CS register isn't spilled, just spill one or two
+ // extra. That should take care of it!
+ unsigned NumExtras = TargetAlign / 4;
+ SmallVector<unsigned, 2> Extras;
+ while (NumExtras && !UnspilledCS1GPRs.empty()) {
+ unsigned Reg = UnspilledCS1GPRs.back();
+ UnspilledCS1GPRs.pop_back();
+ if (!isReservedReg(MF, Reg)) {
+ Extras.push_back(Reg);
+ NumExtras--;
+ }
+ }
+ // For non-Thumb1 functions, also check for hi-reg CS registers
+ if (!AFI->isThumb1OnlyFunction()) {
+ while (NumExtras && !UnspilledCS2GPRs.empty()) {
+ unsigned Reg = UnspilledCS2GPRs.back();
+ UnspilledCS2GPRs.pop_back();
if (!isReservedReg(MF, Reg)) {
Extras.push_back(Reg);
NumExtras--;
}
}
- // For non-Thumb1 functions, also check for hi-reg CS registers
- if (!AFI->isThumb1OnlyFunction()) {
- while (NumExtras && !UnspilledCS2GPRs.empty()) {
- unsigned Reg = UnspilledCS2GPRs.back();
- UnspilledCS2GPRs.pop_back();
- if (!isReservedReg(MF, Reg)) {
- Extras.push_back(Reg);
- NumExtras--;
- }
- }
- }
- if (Extras.size() && NumExtras == 0) {
- for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
- MF.getRegInfo().setPhysRegUsed(Extras[i]);
- AFI->setCSRegisterIsSpilled(Extras[i]);
- }
- } else if (!AFI->isThumb1OnlyFunction()) {
- // note: Thumb1 functions spill to R12, not the stack.
- // Reserve a slot closest to SP or frame pointer.
- const TargetRegisterClass *RC = ARM::GPRRegisterClass;
- RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
- RC->getAlignment(),
- false));
+ }
+ if (Extras.size() && NumExtras == 0) {
+ for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
+ MF.getRegInfo().setPhysRegUsed(Extras[i]);
+ AFI->setCSRegisterIsSpilled(Extras[i]);
}
+ } else if (!AFI->isThumb1OnlyFunction()) {
+ // note: Thumb1 functions spill to R12, not the stack. Reserve a slot
+ // closest to SP or frame pointer.
+ const TargetRegisterClass *RC = ARM::GPRRegisterClass;
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
+ RC->getAlignment(),
+ false));
}
}
}
@@ -1093,6 +1085,15 @@ hasReservedCallFrame(MachineFunction &MF) const {
return !MF.getFrameInfo()->hasVarSizedObjects();
}
+// canSimplifyCallFramePseudos - If there is a reserved call frame, the
+// call frame pseudos can be simplified. Unlike most targets, having a FP
+// is not sufficient here since we still may reference some objects via SP
+// even when FP is available in Thumb2 mode.
+bool ARMBaseRegisterInfo::
+canSimplifyCallFramePseudos(MachineFunction &MF) const {
+ return hasReservedCallFrame(MF) || MF.getFrameInfo()->hasVarSizedObjects();
+}
+
static void
emitSPUpdate(bool isARM,
MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
@@ -1127,13 +1128,14 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert(!AFI->isThumb1OnlyFunction() &&
- "This eliminateCallFramePseudoInstr does not suppor Thumb1!");
+ "This eliminateCallFramePseudoInstr does not support Thumb1!");
bool isARM = !AFI->isThumbFunction();
// Replace the pseudo instruction with a new instruction...
unsigned Opc = Old->getOpcode();
- ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm();
- // FIXME: Thumb2 version of ADJCALLSTACKUP and ADJCALLSTACKDOWN?
+ int PIdx = Old->findFirstPredOperandIdx();
+ ARMCC::CondCodes Pred = (PIdx == -1)
+ ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
// Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
unsigned PredReg = Old->getOperand(2).getReg();
@@ -1157,7 +1159,6 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
- const MachineFrameInfo *MFI = MF.getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert(!AFI->isThumb1OnlyFunction() &&
"This eliminateFrameIndex does not support Thumb1!");
@@ -1168,12 +1169,12 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
int FrameIndex = MI.getOperand(i).getIndex();
- int Offset = MFI->getObjectOffset(FrameIndex) + MFI->getStackSize() + SPAdj;
unsigned FrameReg;
- Offset = getFrameIndexReference(MF, FrameIndex, FrameReg);
+ int Offset = getFrameIndexReference(MF, FrameIndex, FrameReg);
if (FrameReg != ARM::SP)
SPAdj = 0;
+ Offset += SPAdj;
// Modify MI as necessary to handle as much of 'Offset' as possible
bool Done = false;
@@ -1264,7 +1265,7 @@ emitPrologue(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert(!AFI->isThumb1OnlyFunction() &&
- "This emitPrologue does not suppor Thumb1!");
+ "This emitPrologue does not support Thumb1!");
bool isARM = !AFI->isThumbFunction();
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
unsigned NumBytes = MFI->getStackSize();
@@ -1349,7 +1350,9 @@ emitPrologue(MachineFunction &MF) const {
unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
- AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
+ if (STI.isTargetDarwin() || hasFP(MF))
+ AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
+ NumBytes);
AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
@@ -1425,7 +1428,7 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert(!AFI->isThumb1OnlyFunction() &&
- "This emitEpilogue does not suppor Thumb1!");
+ "This emitEpilogue does not support Thumb1!");
bool isARM = !AFI->isThumbFunction();
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h
index 33ba21d..64f6ff1 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -138,6 +138,7 @@ public:
virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const;
virtual bool hasReservedCallFrame(MachineFunction &MF) const;
+ virtual bool canSimplifyCallFramePseudos(MachineFunction &MF) const;
virtual void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index bd703f4..21c6cb3 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -86,6 +86,7 @@ namespace {
void emitWordLE(unsigned Binary);
void emitDWordLE(uint64_t Binary);
void emitConstPoolInstruction(const MachineInstr &MI);
+ void emitMOVi32immInstruction(const MachineInstr &MI);
void emitMOVi2piecesInstruction(const MachineInstr &MI);
void emitLEApcrelJTInstruction(const MachineInstr &MI);
void emitPseudoMoveInstruction(const MachineInstr &MI);
@@ -143,6 +144,15 @@ namespace {
return getMachineOpValue(MI, MI.getOperand(OpIdx));
}
+ /// getMovi32Value - Return binary encoding of operand for movw/movt. If the
+ /// machine operand requires relocation, record the relocation and return zero.
+ unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO,
+ unsigned Reloc);
+ unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx,
+ unsigned Reloc) {
+ return getMovi32Value(MI, MI.getOperand(OpIdx), Reloc);
+ }
+
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
///
unsigned getShiftOp(unsigned Imm) const ;
@@ -214,6 +224,54 @@ unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
return 0;
}
+/// getMovi32Value - Return binary encoding of operand for movw/movt. If the
+/// machine operand requires relocation, record the relocation and return zero.
+unsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI,
+ const MachineOperand &MO,
+ unsigned Reloc) {
+ assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw))
+ && "Relocation to this function should be for movt or movw");
+ switch(MO.getType()) {
+ case MachineOperand::MO_Register:
+ return ARMRegisterInfo::getRegisterNumbering(MO.getReg());
+ break;
+
+ case MachineOperand::MO_Immediate:
+ return static_cast<unsigned>(MO.getImm());
+ break;
+
+ case MachineOperand::MO_FPImmediate:
+ return static_cast<unsigned>(
+ MO.getFPImm()->getValueAPF().bitcastToAPInt().getLimitedValue());
+ break;
+
+ case MachineOperand::MO_MachineBasicBlock:
+ emitMachineBasicBlock(MO.getMBB(), Reloc);
+ break;
+
+ case MachineOperand::MO_ConstantPoolIndex:
+ emitConstPoolAddress(MO.getIndex(), Reloc);
+ break;
+
+ case MachineOperand::MO_JumpTableIndex:
+ emitJumpTableAddress(MO.getIndex(), Reloc);
+ break;
+
+ case MachineOperand::MO_ExternalSymbol:
+ emitExternalSymbolAddress(MO.getSymbolName(), Reloc);
+ break;
+
+ case MachineOperand::MO_GlobalAddress:
+ emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
+ break;
+
+ default:
+ llvm_unreachable("Unsupported immediate operand type for movw/movt");
+ break;
+ }
+ return 0;
+}
+
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
@@ -433,6 +491,41 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
}
}
+void ARMCodeEmitter::emitMOVi32immInstruction(const MachineInstr &MI) {
+ const MachineOperand &MO0 = MI.getOperand(0);
+ const MachineOperand &MO1 = MI.getOperand(1);
+
+ unsigned Lo16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movw) & 0xFFFF;
+
+ // Emit the 'mov' instruction.
+ unsigned Binary = 0x30 << 20; // mov: Insts{27-20} = 0b00110000
+
+ // Set the conditional execution predicate.
+ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+ // Encode Rd.
+ Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
+
+ // Encode imm.
+ Binary |= Lo16 & 0xFFF;
+ Binary |= ((Lo16 >> 12) & 0xF) << 16; // imm4:imm12, Insts[19-16] = imm4, Insts[11-0] = imm12
+ emitWordLE(Binary);
+
+ unsigned Hi16 = (getMovi32Value(MI, MO1, ARM::reloc_arm_movt) >> 16) & 0xFFFF;
+ // Emit the 'mov' instruction.
+ Binary = 0x34 << 20; // movt: Insts[27-20] = 0b00110100
+
+ // Set the conditional execution predicate.
+ Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+ // Encode Rd.
+ Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
+
+ Binary |= Hi16 & 0xFFF;
+ Binary |= ((Hi16 >> 12) & 0xF) << 16;
+ emitWordLE(Binary);
+}
+
void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
const MachineOperand &MO0 = MI.getOperand(0);
const MachineOperand &MO1 = MI.getOperand(1);
@@ -552,7 +645,6 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
switch (Opcode) {
default:
llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
- // FIXME: Add support for MOVimm32.
case TargetOpcode::INLINEASM: {
// We allow inline assembler nodes with empty bodies - they can
// implicitly define registers, which is ok for JIT.
@@ -599,6 +691,11 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
emitMiscLoadStoreInstruction(MI, ARM::PC);
break;
}
+
+ case ARM::MOVi32imm:
+ emitMOVi32immInstruction(MI);
+ break;
+
case ARM::MOVi2pieces:
// Two instructions to materialize a constant.
emitMOVi2piecesInstruction(MI);
@@ -1138,7 +1235,7 @@ void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
- if (TID.Opcode == ARM::BX_RET)
+ if (TID.Opcode == ARM::BX_RET || TID.Opcode == ARM::MOVPCLR)
// The return register is LR.
Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR);
else
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index a458269..013e00a 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -65,7 +65,7 @@ public:
}
SDNode *Select(SDNode *N);
- virtual void InstructionSelect();
+
bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A,
SDValue &B, SDValue &C);
bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base,
@@ -201,11 +201,6 @@ static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) {
}
-void ARMDAGToDAGISel::InstructionSelect() {
- SelectRoot(*CurDAG);
- CurDAG->RemoveDeadNodes();
-}
-
bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op,
SDValue N,
SDValue &BaseReg,
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 614e684..6a2c6bb 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -294,6 +294,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setTargetDAGCombine(ISD::SIGN_EXTEND);
setTargetDAGCombine(ISD::ZERO_EXTEND);
setTargetDAGCombine(ISD::ANY_EXTEND);
+ setTargetDAGCombine(ISD::SELECT_CC);
}
computeRegisterProperties();
@@ -544,6 +545,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::VZIP: return "ARMISD::VZIP";
case ARMISD::VUZP: return "ARMISD::VUZP";
case ARMISD::VTRN: return "ARMISD::VTRN";
+ case ARMISD::FMAX: return "ARMISD::FMAX";
+ case ARMISD::FMIN: return "ARMISD::FMIN";
}
}
@@ -863,7 +866,8 @@ ARMTargetLowering::LowerMemOpCallTo(SDValue Chain,
return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl);
}
return DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), LocMemOffset);
+ PseudoSourceValue::getStack(), LocMemOffset,
+ false, false, 0);
}
void ARMTargetLowering::PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG,
@@ -920,7 +924,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// These operations are automatically eliminated by the prolog/epilog pass
Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
- SDValue StackPtr = DAG.getRegister(ARM::SP, MVT::i32);
+ SDValue StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy());
RegsToPassVector RegsToPass;
SmallVector<SDValue, 8> MemOpChains;
@@ -969,8 +973,6 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
VA, ArgLocs[++i], StackPtr, MemOpChains, Flags);
} else {
assert(VA.isMemLoc());
- if (StackPtr.getNode() == 0)
- StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy());
MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Op1,
dl, DAG, VA, Flags));
@@ -983,8 +985,6 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
} else {
assert(VA.isMemLoc());
- if (StackPtr.getNode() == 0)
- StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy());
MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg,
dl, DAG, VA, Flags));
@@ -1031,7 +1031,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
Callee = DAG.getLoad(getPointerTy(), dl,
DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
getPointerTy(), Callee, PICLabel);
@@ -1052,7 +1053,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
Callee = DAG.getLoad(getPointerTy(), dl,
DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
getPointerTy(), Callee, PICLabel);
@@ -1238,7 +1240,8 @@ SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
}
CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
if (RelocM == Reloc::Static)
return Result;
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
@@ -1261,7 +1264,8 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Argument.getValue(1);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
@@ -1278,8 +1282,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
LowerCallTo(Chain, (const Type *) Type::getInt32Ty(*DAG.getContext()),
false, false, false, false,
0, CallingConv::C, false, /*isReturnValueUsed=*/true,
- DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl,
- DAG.GetOrdering(Chain.getNode()));
+ DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl);
return CallResult.first;
}
@@ -1308,21 +1311,24 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
Chain = Offset.getValue(1);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
} else {
// local exec model
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, "tpoff");
Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
}
// The address of the thread local variable is the add of the thread
@@ -1358,13 +1364,15 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Result.getValue(1);
SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT);
Result = DAG.getNode(ISD::ADD, dl, PtrVT, Result, GOT);
if (!UseGOTOFF)
Result = DAG.getLoad(PtrVT, dl, Chain, Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0,
+ false, false, 0);
return Result;
} else {
// If we have T2 ops, we can materialize the address directly via movt/movw
@@ -1376,7 +1384,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4);
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
}
}
}
@@ -1403,7 +1412,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Result.getValue(1);
if (RelocM == Reloc::PIC_) {
@@ -1413,7 +1423,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
if (Subtarget->GVIsIndirectSymbol(GV, RelocM))
Result = DAG.getLoad(PtrVT, dl, Chain, Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0,
+ false, false, 0);
return Result;
}
@@ -1434,7 +1445,8 @@ SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op,
SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
}
@@ -1467,7 +1479,8 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result =
DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Result.getValue(1);
if (RelocM == Reloc::PIC_) {
@@ -1515,7 +1528,8 @@ static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
SDValue
@@ -1592,7 +1606,8 @@ ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
// Create load node to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
ArgValue2 = DAG.getLoad(MVT::i32, dl, Root, FIN,
- PseudoSourceValue::getFixedStack(FI), 0);
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
} else {
Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
@@ -1707,7 +1722,8 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
// Create load nodes to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0));
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0));
}
}
@@ -1745,7 +1761,8 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
unsigned VReg = MF.addLiveIn(GPRArgRegs[NumGPRs], RC);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
- PseudoSourceValue::getFixedStack(VarArgsFrameIndex), 0);
+ PseudoSourceValue::getFixedStack(VarArgsFrameIndex), 0,
+ false, false, 0);
MemOps.push_back(Store);
FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(), FIN,
DAG.getConstant(4, getPointerTy()));
@@ -1939,13 +1956,14 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) {
}
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
Addr = DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0);
+ PseudoSourceValue::getJumpTable(), 0,
+ false, false, 0);
Chain = Addr.getValue(1);
Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, Table);
return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId);
} else {
Addr = DAG.getLoad(PTy, dl, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0);
+ PseudoSourceValue::getJumpTable(), 0, false, false, 0);
Chain = Addr.getValue(1);
return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId);
}
@@ -1993,7 +2011,8 @@ SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
? ARM::R7 : ARM::R11;
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
while (Depth--)
- FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
+ FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0,
+ false, false, 0);
return FrameAddr;
}
@@ -2038,7 +2057,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
- SrcSV, SrcSVOff + SrcOff);
+ SrcSV, SrcSVOff + SrcOff, false, false, 0);
TFOps[i] = Loads[i].getValue(1);
SrcOff += VTSize;
}
@@ -2047,9 +2066,9 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
for (i = 0;
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
- DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
- DAG.getConstant(DstOff, MVT::i32)),
- DstSV, DstSVOff + DstOff);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
+ DAG.getConstant(DstOff, MVT::i32)),
+ DstSV, DstSVOff + DstOff, false, false, 0);
DstOff += VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
@@ -2075,7 +2094,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
- SrcSV, SrcSVOff + SrcOff);
+ SrcSV, SrcSVOff + SrcOff, false, false, 0);
TFOps[i] = Loads[i].getValue(1);
++i;
SrcOff += VTSize;
@@ -2097,7 +2116,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
DAG.getConstant(DstOff, MVT::i32)),
- DstSV, DstSVOff + DstOff);
+ DstSV, DstSVOff + DstOff, false, false, 0);
++i;
DstOff += VTSize;
BytesLeft -= VTSize;
@@ -3835,23 +3854,106 @@ static SDValue PerformExtendCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+/// PerformSELECT_CCCombine - Target-specific DAG combining for ISD::SELECT_CC
+/// to match f32 max/min patterns to use NEON vmax/vmin instructions.
+static SDValue PerformSELECT_CCCombine(SDNode *N, SelectionDAG &DAG,
+ const ARMSubtarget *ST) {
+ // If the target supports NEON, try to use vmax/vmin instructions for f32
+ // selects like "x < y ? x : y". Unless the FiniteOnlyFPMath option is set,
+ // be careful about NaNs: NEON's vmax/vmin return NaN if either operand is
+ // a NaN; only do the transformation when it matches that behavior.
+
+ // For now only do this when using NEON for FP operations; if using VFP, it
+ // is not obvious that the benefit outweighs the cost of switching to the
+ // NEON pipeline.
+ if (!ST->hasNEON() || !ST->useNEONForSinglePrecisionFP() ||
+ N->getValueType(0) != MVT::f32)
+ return SDValue();
+
+ SDValue CondLHS = N->getOperand(0);
+ SDValue CondRHS = N->getOperand(1);
+ SDValue LHS = N->getOperand(2);
+ SDValue RHS = N->getOperand(3);
+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
+
+ unsigned Opcode = 0;
+ bool IsReversed;
+ if (DAG.isEqualTo(LHS, CondLHS) && DAG.isEqualTo(RHS, CondRHS)) {
+ IsReversed = false; // x CC y ? x : y
+ } else if (DAG.isEqualTo(LHS, CondRHS) && DAG.isEqualTo(RHS, CondLHS)) {
+ IsReversed = true ; // x CC y ? y : x
+ } else {
+ return SDValue();
+ }
+
+ bool IsUnordered;
+ switch (CC) {
+ default: break;
+ case ISD::SETOLT:
+ case ISD::SETOLE:
+ case ISD::SETLT:
+ case ISD::SETLE:
+ case ISD::SETULT:
+ case ISD::SETULE:
+ // If LHS is NaN, an ordered comparison will be false and the result will
+ // be the RHS, but vmin(NaN, RHS) = NaN. Avoid this by checking that LHS
+ // != NaN. Likewise, for unordered comparisons, check for RHS != NaN.
+ IsUnordered = (CC == ISD::SETULT || CC == ISD::SETULE);
+ if (!DAG.isKnownNeverNaN(IsUnordered ? RHS : LHS))
+ break;
+ // For less-than-or-equal comparisons, "+0 <= -0" will be true but vmin
+ // will return -0, so vmin can only be used for unsafe math or if one of
+ // the operands is known to be nonzero.
+ if ((CC == ISD::SETLE || CC == ISD::SETOLE || CC == ISD::SETULE) &&
+ !UnsafeFPMath &&
+ !(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS)))
+ break;
+ Opcode = IsReversed ? ARMISD::FMAX : ARMISD::FMIN;
+ break;
+
+ case ISD::SETOGT:
+ case ISD::SETOGE:
+ case ISD::SETGT:
+ case ISD::SETGE:
+ case ISD::SETUGT:
+ case ISD::SETUGE:
+ // If LHS is NaN, an ordered comparison will be false and the result will
+ // be the RHS, but vmax(NaN, RHS) = NaN. Avoid this by checking that LHS
+ // != NaN. Likewise, for unordered comparisons, check for RHS != NaN.
+ IsUnordered = (CC == ISD::SETUGT || CC == ISD::SETUGE);
+ if (!DAG.isKnownNeverNaN(IsUnordered ? RHS : LHS))
+ break;
+ // For greater-than-or-equal comparisons, "-0 >= +0" will be true but vmax
+ // will return +0, so vmax can only be used for unsafe math or if one of
+ // the operands is known to be nonzero.
+ if ((CC == ISD::SETGE || CC == ISD::SETOGE || CC == ISD::SETUGE) &&
+ !UnsafeFPMath &&
+ !(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS)))
+ break;
+ Opcode = IsReversed ? ARMISD::FMIN : ARMISD::FMAX;
+ break;
+ }
+
+ if (!Opcode)
+ return SDValue();
+ return DAG.getNode(Opcode, N->getDebugLoc(), N->getValueType(0), LHS, RHS);
+}
+
SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
switch (N->getOpcode()) {
default: break;
- case ISD::ADD: return PerformADDCombine(N, DCI);
- case ISD::SUB: return PerformSUBCombine(N, DCI);
+ case ISD::ADD: return PerformADDCombine(N, DCI);
+ case ISD::SUB: return PerformSUBCombine(N, DCI);
case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI);
- case ISD::INTRINSIC_WO_CHAIN:
- return PerformIntrinsicCombine(N, DCI.DAG);
+ case ISD::INTRINSIC_WO_CHAIN: return PerformIntrinsicCombine(N, DCI.DAG);
case ISD::SHL:
case ISD::SRA:
- case ISD::SRL:
- return PerformShiftCombine(N, DCI.DAG, Subtarget);
+ case ISD::SRL: return PerformShiftCombine(N, DCI.DAG, Subtarget);
case ISD::SIGN_EXTEND:
case ISD::ZERO_EXTEND:
- case ISD::ANY_EXTEND:
- return PerformExtendCombine(N, DCI.DAG, Subtarget);
+ case ISD::ANY_EXTEND: return PerformExtendCombine(N, DCI.DAG, Subtarget);
+ case ISD::SELECT_CC: return PerformSELECT_CCCombine(N, DCI.DAG, Subtarget);
}
return SDValue();
}
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index 3c5df45..f8f8adc 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -131,7 +131,11 @@ namespace llvm {
VREV16, // reverse elements within 16-bit halfwords
VZIP, // zip (interleave)
VUZP, // unzip (deinterleave)
- VTRN // transpose
+ VTRN, // transpose
+
+ // Floating-point max and min:
+ FMAX,
+ FMIN
};
}
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 169eeed..76595fa 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -56,6 +56,9 @@ def NEONGetLnFrm : Format<25>;
def NEONSetLnFrm : Format<26>;
def NEONDupFrm : Format<27>;
+def MiscFrm : Format<29>;
+def ThumbMiscFrm : Format<30>;
+
// Misc flags.
// the instruction has a Rn register operand.
@@ -705,6 +708,20 @@ class AI3ldsbpr<dag oops, dag iops, Format f, InstrItinClass itin,
let Inst{24} = 1; // P bit
let Inst{27-25} = 0b000;
}
+class AI3lddpr<dag oops, dag iops, Format f, InstrItinClass itin,
+ string opc, string asm, string cstr, list<dag> pattern>
+ : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
+ opc, asm, cstr, pattern> {
+ let Inst{4} = 1;
+ let Inst{5} = 0; // H bit
+ let Inst{6} = 1; // S bit
+ let Inst{7} = 1;
+ let Inst{20} = 0; // L bit
+ let Inst{21} = 1; // W bit
+ let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
+}
+
// Pre-indexed stores
class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin,
@@ -720,6 +737,19 @@ class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin,
let Inst{24} = 1; // P bit
let Inst{27-25} = 0b000;
}
+class AI3stdpr<dag oops, dag iops, Format f, InstrItinClass itin,
+ string opc, string asm, string cstr, list<dag> pattern>
+ : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin,
+ opc, asm, cstr, pattern> {
+ let Inst{4} = 1;
+ let Inst{5} = 1; // H bit
+ let Inst{6} = 1; // S bit
+ let Inst{7} = 1;
+ let Inst{20} = 0; // L bit
+ let Inst{21} = 1; // W bit
+ let Inst{24} = 1; // P bit
+ let Inst{27-25} = 0b000;
+}
// Post-indexed loads
class AI3ldhpo<dag oops, dag iops, Format f, InstrItinClass itin,
@@ -731,7 +761,7 @@ class AI3ldhpo<dag oops, dag iops, Format f, InstrItinClass itin,
let Inst{6} = 0; // S bit
let Inst{7} = 1;
let Inst{20} = 1; // L bit
- let Inst{21} = 1; // W bit
+ let Inst{21} = 0; // W bit
let Inst{24} = 0; // P bit
let Inst{27-25} = 0b000;
}
@@ -744,7 +774,7 @@ class AI3ldshpo<dag oops, dag iops, Format f, InstrItinClass itin,
let Inst{6} = 1; // S bit
let Inst{7} = 1;
let Inst{20} = 1; // L bit
- let Inst{21} = 1; // W bit
+ let Inst{21} = 0; // W bit
let Inst{24} = 0; // P bit
let Inst{27-25} = 0b000;
}
@@ -757,7 +787,20 @@ class AI3ldsbpo<dag oops, dag iops, Format f, InstrItinClass itin,
let Inst{6} = 1; // S bit
let Inst{7} = 1;
let Inst{20} = 1; // L bit
- let Inst{21} = 1; // W bit
+ let Inst{21} = 0; // W bit
+ let Inst{24} = 0; // P bit
+ let Inst{27-25} = 0b000;
+}
+class AI3lddpo<dag oops, dag iops, Format f, InstrItinClass itin,
+ string opc, string asm, string cstr, list<dag> pattern>
+ : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
+ opc, asm, cstr, pattern> {
+ let Inst{4} = 1;
+ let Inst{5} = 0; // H bit
+ let Inst{6} = 1; // S bit
+ let Inst{7} = 1;
+ let Inst{20} = 0; // L bit
+ let Inst{21} = 0; // W bit
let Inst{24} = 0; // P bit
let Inst{27-25} = 0b000;
}
@@ -772,7 +815,20 @@ class AI3sthpo<dag oops, dag iops, Format f, InstrItinClass itin,
let Inst{6} = 0; // S bit
let Inst{7} = 1;
let Inst{20} = 0; // L bit
- let Inst{21} = 1; // W bit
+ let Inst{21} = 0; // W bit
+ let Inst{24} = 0; // P bit
+ let Inst{27-25} = 0b000;
+}
+class AI3stdpo<dag oops, dag iops, Format f, InstrItinClass itin,
+ string opc, string asm, string cstr, list<dag> pattern>
+ : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin,
+ opc, asm, cstr, pattern> {
+ let Inst{4} = 1;
+ let Inst{5} = 1; // H bit
+ let Inst{6} = 1; // S bit
+ let Inst{7} = 1;
+ let Inst{20} = 0; // L bit
+ let Inst{21} = 0; // W bit
let Inst{24} = 0; // P bit
let Inst{27-25} = 0b000;
}
@@ -1147,6 +1203,19 @@ class T2Iidxldst<bit signed, bits<2> opcod, bit load, bit pre,
let Inst{8} = 1; // The W bit.
}
+// Helper class for disassembly only
+// A6.3.16 & A6.3.17
+// T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
+class T2I_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, dag iops,
+ InstrItinClass itin, string opc, string asm, list<dag> pattern>
+ : T2I<oops, iops, itin, opc, asm, pattern> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-24} = 0b011;
+ let Inst{23} = long;
+ let Inst{22-20} = op22_20;
+ let Inst{7-4} = op7_4;
+}
+
// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
list<Predicate> Predicates = [IsThumb1Only, HasV5T];
@@ -1324,6 +1393,15 @@ class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
let Inst{4} = 0;
}
+// VFP conversion between floating-point and fixed-point
+class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
+ dag oops, dag iops, InstrItinClass itin, string opc, string asm,
+ list<dag> pattern>
+ : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
+ // size (fixed-point number): sx == 0 ? 16 : 32
+ let Inst{7} = op5; // sx
+}
+
// VFP conversion instructions, if no NEON
class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
dag oops, dag iops, InstrItinClass itin,
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 852c74e..3812aba 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -113,6 +113,8 @@ def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
//===----------------------------------------------------------------------===//
// ARM Instruction Predicate Definitions.
//
+def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
+def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
@@ -130,8 +132,6 @@ def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
def IsARM : Predicate<"!Subtarget->isThumb()">;
def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
-def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">;
-def CarryDefIsUsed : Predicate<"N->hasAnyUseOfValue(1)">;
// FIXME: Eventually this will be just "hasV6T2Ops".
def UseMovt : Predicate<"Subtarget->useMovt()">;
@@ -176,7 +176,7 @@ def imm16_31 : PatLeaf<(i32 imm), [{
return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
}]>;
-def so_imm_neg :
+def so_imm_neg :
PatLeaf<(imm), [{
return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
}], so_imm_neg_XFORM>;
@@ -194,7 +194,7 @@ def sext_16_node : PatLeaf<(i32 GPR:$a), [{
/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
/// e.g., 0xf000ffff
def bf_inv_mask_imm : Operand<i32>,
- PatLeaf<(imm), [{
+ PatLeaf<(imm), [{
uint32_t v = (uint32_t)N->getZExtValue();
if (v == 0xffffffff)
return 0;
@@ -227,7 +227,7 @@ def lo16AllZero : PatLeaf<(i32 imm), [{
return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
}], hi16>;
-/// imm0_65535 predicate - True if the 32-bit immediate is in the range
+/// imm0_65535 predicate - True if the 32-bit immediate is in the range
/// [0.65535].
def imm0_65535 : PatLeaf<(i32 imm), [{
return (uint32_t)N->getZExtValue() < 65536;
@@ -236,6 +236,21 @@ def imm0_65535 : PatLeaf<(i32 imm), [{
class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
+/// adde and sube predicates - True based on whether the carry flag output
+/// will be needed or not.
+def adde_dead_carry :
+ PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
+ [{return !N->hasAnyUseOfValue(1);}]>;
+def sube_dead_carry :
+ PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
+ [{return !N->hasAnyUseOfValue(1);}]>;
+def adde_live_carry :
+ PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS),
+ [{return N->hasAnyUseOfValue(1);}]>;
+def sube_live_carry :
+ PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS),
+ [{return N->hasAnyUseOfValue(1);}]>;
+
//===----------------------------------------------------------------------===//
// Operand Definitions.
//
@@ -501,6 +516,22 @@ multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
}
}
+multiclass AI_unary_rrot_np<bits<8> opcod, string opc> {
+ def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src),
+ IIC_iUNAr, opc, "\t$dst, $src",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{11-10} = 0b00;
+ let Inst{19-16} = 0b1111;
+ }
+ def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot),
+ IIC_iUNAsi, opc, "\t$dst, $src, ror $rot",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{19-16} = 0b1111;
+ }
+}
+
/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
/// register and one whose operand is a register rotated by 8/16/24.
multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
@@ -510,13 +541,29 @@ multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
Requires<[IsARM, HasV6]> {
let Inst{11-10} = 0b00;
}
- def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
+ def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
+ i32imm:$rot),
IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
[(set GPR:$dst, (opnode GPR:$LHS,
(rotr GPR:$RHS, rot_imm:$rot)))]>,
Requires<[IsARM, HasV6]>;
}
+// For disassembly only.
+multiclass AI_bin_rrot_np<bits<8> opcod, string opc> {
+ def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
+ IIC_iALUr, opc, "\t$dst, $LHS, $RHS",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{11-10} = 0b00;
+ }
+ def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS,
+ i32imm:$rot),
+ IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]>;
+}
+
/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
let Uses = [CPSR] in {
multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
@@ -524,13 +571,13 @@ multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b",
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
- Requires<[IsARM, CarryDefIsUnused]> {
+ Requires<[IsARM]> {
let Inst{25} = 1;
}
def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b",
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
- Requires<[IsARM, CarryDefIsUnused]> {
+ Requires<[IsARM]> {
let isCommutable = Commutable;
let Inst{11-4} = 0b00000000;
let Inst{25} = 0;
@@ -538,7 +585,7 @@ multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b",
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
- Requires<[IsARM, CarryDefIsUnused]> {
+ Requires<[IsARM]> {
let Inst{25} = 0;
}
}
@@ -549,16 +596,14 @@ multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
- Requires<[IsARM, CarryDefIsUsed]> {
- let Defs = [CPSR];
+ Requires<[IsARM]> {
let Inst{20} = 1;
let Inst{25} = 1;
}
def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
- Requires<[IsARM, CarryDefIsUsed]> {
- let Defs = [CPSR];
+ Requires<[IsARM]> {
let Inst{11-4} = 0b00000000;
let Inst{20} = 1;
let Inst{25} = 0;
@@ -566,8 +611,7 @@ multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
- Requires<[IsARM, CarryDefIsUsed]> {
- let Defs = [CPSR];
+ Requires<[IsARM]> {
let Inst{20} = 1;
let Inst{25} = 0;
}
@@ -593,18 +637,153 @@ PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
i32imm:$size), NoItinerary,
"${instid:label} ${cpidx:cpentry}", []>;
-let Defs = [SP], Uses = [SP] in {
+// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
+// from removing one half of the matched pairs. That breaks PEI, which assumes
+// these will always be in pairs, and asserts if it finds otherwise. Better way?
+let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
def ADJCALLSTACKUP :
PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
"@ ADJCALLSTACKUP $amt1",
[(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
-def ADJCALLSTACKDOWN :
+def ADJCALLSTACKDOWN :
PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
"@ ADJCALLSTACKDOWN $amt",
[(ARMcallseq_start timm:$amt)]>;
}
+def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000000;
+}
+
+def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000001;
+}
+
+def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000010;
+}
+
+def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000011;
+}
+
+def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel",
+ "\t$dst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{27-20} = 0b01101000;
+ let Inst{7-4} = 0b1011;
+}
+
+def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000100;
+}
+
+// The i32imm operand $val can be used by a debugger to store more information
+// about the breakpoint.
+def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{27-20} = 0b00010010;
+ let Inst{7-4} = 0b0111;
+}
+
+// Change Processor State is a system instruction -- for disassembly only.
+// The singleton $opt operand contains the following information:
+// opt{4-0} = mode from Inst{4-0}
+// opt{5} = changemode from Inst{17}
+// opt{8-6} = AIF from Inst{8-6}
+// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
+def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{27-20} = 0b00010000;
+ let Inst{16} = 0;
+ let Inst{5} = 0;
+}
+
+// Preload signals the memory system of possible future data/instruction access.
+// These are for disassembly only.
+multiclass APreLoad<bit data, bit read, string opc> {
+
+ def i : AXI<(outs), (ins GPR:$base, i32imm:$imm), MiscFrm, NoItinerary,
+ !strconcat(opc, "\t[$base, $imm]"), []> {
+ let Inst{31-26} = 0b111101;
+ let Inst{25} = 0; // 0 for immediate form
+ let Inst{24} = data;
+ let Inst{22} = read;
+ let Inst{21-20} = 0b01;
+ }
+
+ def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
+ !strconcat(opc, "\t$addr"), []> {
+ let Inst{31-26} = 0b111101;
+ let Inst{25} = 1; // 1 for register form
+ let Inst{24} = data;
+ let Inst{22} = read;
+ let Inst{21-20} = 0b01;
+ let Inst{4} = 0;
+ }
+}
+
+defm PLD : APreLoad<1, 1, "pld">;
+defm PLDW : APreLoad<1, 0, "pldw">;
+defm PLI : APreLoad<0, 1, "pli">;
+
+def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{27-20} = 0b00010000;
+ let Inst{16} = 1;
+ let Inst{9} = 1;
+ let Inst{7-4} = 0b0000;
+}
+
+def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{27-20} = 0b00010000;
+ let Inst{16} = 1;
+ let Inst{9} = 0;
+ let Inst{7-4} = 0b0000;
+}
+
+def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV7]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-4} = 0b1111;
+}
+
+// A5.4 Permanently UNDEFINED instructions.
+def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{27-25} = 0b011;
+ let Inst{24-20} = 0b11111;
+ let Inst{7-5} = 0b111;
+ let Inst{4} = 0b1;
+}
+
// Address computation and loads and stores in PIC mode.
let isNotDuplicable = 1 in {
def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
@@ -665,7 +844,7 @@ def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
"(${label}_${id}-(",
"${:private}PCRELL${:uid}+8))\n"),
!strconcat("${:private}PCRELL${:uid}:\n\t",
- "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
+ "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
[]> {
let Inst{25} = 1;
}
@@ -674,24 +853,50 @@ def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
// Control Flow Instructions.
//
-let isReturn = 1, isTerminator = 1, isBarrier = 1 in
- def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
- "bx", "\tlr", [(ARMretflag)]> {
- let Inst{3-0} = 0b1110;
- let Inst{7-4} = 0b0001;
- let Inst{19-8} = 0b111111111111;
- let Inst{27-20} = 0b00010010;
+let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
+ // ARMV4T and above
+ def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
+ "bx", "\tlr", [(ARMretflag)]>,
+ Requires<[IsARM, HasV4T]> {
+ let Inst{3-0} = 0b1110;
+ let Inst{7-4} = 0b0001;
+ let Inst{19-8} = 0b111111111111;
+ let Inst{27-20} = 0b00010010;
+ }
+
+ // ARMV4 only
+ def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
+ "mov", "\tpc, lr", [(ARMretflag)]>,
+ Requires<[IsARM, NoV4T]> {
+ let Inst{11-0} = 0b000000001110;
+ let Inst{15-12} = 0b1111;
+ let Inst{19-16} = 0b0000;
+ let Inst{27-20} = 0b00011010;
+ }
}
// Indirect branches
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
+ // ARMV4T and above
def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
- [(brind GPR:$dst)]> {
+ [(brind GPR:$dst)]>,
+ Requires<[IsARM, HasV4T]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
let Inst{31-28} = 0b1110;
}
+
+ // ARMV4 only
+ def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
+ [(brind GPR:$dst)]>,
+ Requires<[IsARM, NoV4T]> {
+ let Inst{11-4} = 0b00000000;
+ let Inst{15-12} = 0b1111;
+ let Inst{19-16} = 0b0000;
+ let Inst{27-20} = 0b00011010;
+ let Inst{31-28} = 0b1110;
+ }
}
// FIXME: remove when we have a way to marking a MI with these properties.
@@ -732,14 +937,26 @@ let isCall = 1,
}
// ARMv4T
- def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
+ // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
+ def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
- [(ARMcall_nolink GPR:$func)]>,
- Requires<[IsARM, IsNotDarwin]> {
+ [(ARMcall_nolink tGPR:$func)]>,
+ Requires<[IsARM, HasV4T, IsNotDarwin]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
}
+
+ // ARMv4
+ def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
+ IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
+ [(ARMcall_nolink tGPR:$func)]>,
+ Requires<[IsARM, NoV4T, IsNotDarwin]> {
+ let Inst{11-4} = 0b00000000;
+ let Inst{15-12} = 0b1111;
+ let Inst{19-16} = 0b0000;
+ let Inst{27-20} = 0b00011010;
+ }
}
// On Darwin R9 is call-clobbered.
@@ -769,13 +986,26 @@ let isCall = 1,
}
// ARMv4T
- def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
+ // Note: Restrict $func to the tGPR regclass to prevent it being in LR.
+ def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
- [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
+ [(ARMcall_nolink tGPR:$func)]>,
+ Requires<[IsARM, HasV4T, IsDarwin]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
}
+
+ // ARMv4
+ def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
+ IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
+ [(ARMcall_nolink tGPR:$func)]>,
+ Requires<[IsARM, NoV4T, IsDarwin]> {
+ let Inst{11-4} = 0b00000000;
+ let Inst{15-12} = 0b1111;
+ let Inst{19-16} = 0b0000;
+ let Inst{27-20} = 0b00011010;
+ }
}
let isBranch = 1, isTerminator = 1 in {
@@ -821,25 +1051,75 @@ let isBranch = 1, isTerminator = 1 in {
} // isBarrier = 1
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
- // a two-value operand where a dag node expects two operands. :(
+ // a two-value operand where a dag node expects two operands. :(
def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
IIC_Br, "b", "\t$target",
[/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
}
+// Branch and Exchange Jazelle -- for disassembly only
+def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0010;
+ //let Inst{19-8} = 0xfff;
+ let Inst{7-4} = 0b0010;
+}
+
+// Secure Monitor Call is a system instruction -- for disassembly only
+def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0110;
+ let Inst{7-4} = 0b0111;
+}
+
+// Supervisor Call (Software Interrupt) -- for disassembly only
+let isCall = 1 in {
+def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
+ [/* For disassembly only; pattern left blank */]>;
+}
+
+// Store Return State is a system instruction -- for disassembly only
+def SRSW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
+ NoItinerary, "srs${addr:submode}\tsp!, $mode",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{22-20} = 0b110; // W = 1
+}
+
+def SRS : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, i32imm:$mode),
+ NoItinerary, "srs${addr:submode}\tsp, $mode",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{22-20} = 0b100; // W = 0
+}
+
+// Return From Exception is a system instruction -- for disassembly only
+def RFEW : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
+ NoItinerary, "rfe${addr:submode}\t$base!",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{22-20} = 0b011; // W = 1
+}
+
+def RFE : ABXI<{1,0,0,?}, (outs), (ins addrmode4:$addr, GPR:$base),
+ NoItinerary, "rfe${addr:submode}\t$base",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{22-20} = 0b001; // W = 0
+}
+
//===----------------------------------------------------------------------===//
// Load / store Instructions.
//
// Load
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
"ldr", "\t$dst, $addr",
[(set GPR:$dst, (load addrmode2:$addr))]>;
// Special LDR for loads from non-pc-relative constpools.
-let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
- mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
"ldr", "\t$dst, $addr", []>;
@@ -848,7 +1128,7 @@ def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
IIC_iLoadr, "ldrh", "\t$dst, $addr",
[(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
-def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
+def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
IIC_iLoadr, "ldrb", "\t$dst, $addr",
[(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
@@ -907,6 +1187,51 @@ def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
"ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
+
+// For disassembly only
+def LDRD_PRE : AI3lddpr<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
+ (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadr,
+ "ldrd", "\t$dst1, $dst2, $addr!", "$addr.base = $base_wb", []>,
+ Requires<[IsARM, HasV5TE]>;
+
+// For disassembly only
+def LDRD_POST : AI3lddpo<(outs GPR:$dst1, GPR:$dst2, GPR:$base_wb),
+ (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadr,
+ "ldrd", "\t$dst1, $dst2, [$base], $offset", "$base = $base_wb", []>,
+ Requires<[IsARM, HasV5TE]>;
+
+}
+
+// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
+
+def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
+ (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
+ "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+ let Inst{21} = 1; // overwrite
+}
+
+def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
+ (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
+ "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+ let Inst{21} = 1; // overwrite
+}
+
+def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
+ (ins GPR:$base,am2offset:$offset), LdMiscFrm, IIC_iLoadru,
+ "ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+ let Inst{21} = 1; // overwrite
+}
+
+def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
+ (ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
+ "ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+ let Inst{21} = 1; // overwrite
+}
+
+def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
+ (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
+ "ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+ let Inst{21} = 1; // overwrite
}
// Store
@@ -915,8 +1240,8 @@ def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
[(store GPR:$src, addrmode2:$addr)]>;
// Stores with truncate
-def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
- "strh", "\t$src, $addr",
+def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
+ IIC_iStorer, "strh", "\t$src, $addr",
[(truncstorei16 GPR:$src, addrmode3:$addr)]>;
def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
@@ -931,47 +1256,87 @@ def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
// Indexed stores
def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base, am2offset:$offset),
+ (ins GPR:$src, GPR:$base, am2offset:$offset),
StFrm, IIC_iStoreru,
"str", "\t$src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb,
(pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
def STR_POST : AI2stwpo<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am2offset:$offset),
+ (ins GPR:$src, GPR:$base,am2offset:$offset),
StFrm, IIC_iStoreru,
"str", "\t$src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb,
(post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am3offset:$offset),
+ (ins GPR:$src, GPR:$base,am3offset:$offset),
StMiscFrm, IIC_iStoreru,
"strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb,
(pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am3offset:$offset),
+ (ins GPR:$src, GPR:$base,am3offset:$offset),
StMiscFrm, IIC_iStoreru,
"strh", "\t$src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb, (post_truncsti16 GPR:$src,
GPR:$base, am3offset:$offset))]>;
def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am2offset:$offset),
+ (ins GPR:$src, GPR:$base,am2offset:$offset),
StFrm, IIC_iStoreru,
"strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
GPR:$base, am2offset:$offset))]>;
def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
- (ins GPR:$src, GPR:$base,am2offset:$offset),
+ (ins GPR:$src, GPR:$base,am2offset:$offset),
StFrm, IIC_iStoreru,
"strb", "\t$src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb, (post_truncsti8 GPR:$src,
GPR:$base, am2offset:$offset))]>;
+// For disassembly only
+def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
+ (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
+ StMiscFrm, IIC_iStoreru,
+ "strd", "\t$src1, $src2, [$base, $offset]!",
+ "$base = $base_wb", []>;
+
+// For disassembly only
+def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
+ (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
+ StMiscFrm, IIC_iStoreru,
+ "strd", "\t$src1, $src2, [$base], $offset",
+ "$base = $base_wb", []>;
+
+// STRT, STRBT, and STRHT are for disassembly only.
+
+def STRT : AI2stwpo<(outs GPR:$base_wb),
+ (ins GPR:$src, GPR:$base,am2offset:$offset),
+ StFrm, IIC_iStoreru,
+ "strt", "\t$src, [$base], $offset", "$base = $base_wb",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{21} = 1; // overwrite
+}
+
+def STRBT : AI2stbpo<(outs GPR:$base_wb),
+ (ins GPR:$src, GPR:$base,am2offset:$offset),
+ StFrm, IIC_iStoreru,
+ "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{21} = 1; // overwrite
+}
+
+def STRHT: AI3sthpo<(outs GPR:$base_wb),
+ (ins GPR:$src, GPR:$base,am3offset:$offset),
+ StMiscFrm, IIC_iStoreru,
+ "strht", "\t$src, [$base], $offset", "$base = $base_wb",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{21} = 1; // overwrite
+}
+
//===----------------------------------------------------------------------===//
// Load / store multiple Instructions.
//
@@ -999,7 +1364,7 @@ def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
let Inst{25} = 0;
}
-def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
+def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
DPSoRegFrm, IIC_iMOVsr,
"mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
let Inst{25} = 0;
@@ -1012,7 +1377,7 @@ def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
}
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
-def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
+def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
DPFrm, IIC_iMOVi,
"movw", "\t$dst, $src",
[(set GPR:$dst, imm0_65535:$src)]>,
@@ -1026,7 +1391,7 @@ def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
DPFrm, IIC_iMOVi,
"movt", "\t$dst, $imm",
[(set GPR:$dst,
- (or (and GPR:$src, 0xffff),
+ (or (and GPR:$src, 0xffff),
lo16AllZero:$imm))]>, UnaryDP,
Requires<[IsARM, HasV6T2]> {
let Inst{20} = 0;
@@ -1045,7 +1410,7 @@ def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
// due to flag operands.
let Defs = [CPSR] in {
-def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
+def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
[(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
@@ -1069,7 +1434,11 @@ defm SXTAB : AI_bin_rrot<0b01101010,
defm SXTAH : AI_bin_rrot<0b01101011,
"sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
-// TODO: SXT(A){B|H}16
+// For disassembly only
+defm SXTB16 : AI_unary_rrot_np<0b01101000, "sxtb16">;
+
+// For disassembly only
+defm SXTAB16 : AI_bin_rrot_np<0b01101000, "sxtab16">;
// Zero extenders
@@ -1093,9 +1462,9 @@ defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
}
// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
-//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
+// For disassembly only
+defm UXTAB16 : AI_bin_rrot_np<0b01101100, "uxtab16">;
-// TODO: UXT(A){B|H}16
def SBFX : I<(outs GPR:$dst),
(ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
@@ -1131,13 +1500,13 @@ defm SUBS : AI1_bin_s_irs<0b0010, "subs",
BinOpFrag<(subc node:$LHS, node:$RHS)>>;
defm ADC : AI1_adde_sube_irs<0b0101, "adc",
- BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
+ BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
- BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+ BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
- BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
+ BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
- BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+ BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
// These don't define reg/reg forms, because they are handled above.
def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
@@ -1171,14 +1540,14 @@ def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
let Uses = [CPSR] in {
def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
- [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
- Requires<[IsARM, CarryDefIsUnused]> {
+ [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
+ Requires<[IsARM]> {
let Inst{25} = 1;
}
def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
- [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
- Requires<[IsARM, CarryDefIsUnused]> {
+ [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
+ Requires<[IsARM]> {
let Inst{25} = 0;
}
}
@@ -1187,15 +1556,15 @@ def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
let Defs = [CPSR], Uses = [CPSR] in {
def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
- [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
- Requires<[IsARM, CarryDefIsUnused]> {
+ [(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
+ Requires<[IsARM]> {
let Inst{20} = 1;
let Inst{25} = 1;
}
def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
- [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
- Requires<[IsARM, CarryDefIsUnused]> {
+ [(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
+ Requires<[IsARM]> {
let Inst{20} = 1;
let Inst{25} = 0;
}
@@ -1216,6 +1585,126 @@ def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
// (mul X, 2^n+1) -> (add (X << n), X)
// (mul X, 2^n-1) -> (rsb X, (X << n))
+// ARM Arithmetic Instruction -- for disassembly only
+// GPR:$dst = GPR:$a op GPR:$b
+class AAI<bits<8> op27_20, bits<4> op7_4, string opc>
+ : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
+ opc, "\t$dst, $a, $b",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-20} = op27_20;
+ let Inst{7-4} = op7_4;
+}
+
+// Saturating add/subtract -- for disassembly only
+
+def QADD : AAI<0b00010000, 0b0101, "qadd">;
+def QADD16 : AAI<0b01100010, 0b0001, "qadd16">;
+def QADD8 : AAI<0b01100010, 0b1001, "qadd8">;
+def QASX : AAI<0b01100010, 0b0011, "qasx">;
+def QDADD : AAI<0b00010100, 0b0101, "qdadd">;
+def QDSUB : AAI<0b00010110, 0b0101, "qdsub">;
+def QSAX : AAI<0b01100010, 0b0101, "qsax">;
+def QSUB : AAI<0b00010010, 0b0101, "qsub">;
+def QSUB16 : AAI<0b01100010, 0b0111, "qsub16">;
+def QSUB8 : AAI<0b01100010, 0b1111, "qsub8">;
+def UQADD16 : AAI<0b01100110, 0b0001, "uqadd16">;
+def UQADD8 : AAI<0b01100110, 0b1001, "uqadd8">;
+def UQASX : AAI<0b01100110, 0b0011, "uqasx">;
+def UQSAX : AAI<0b01100110, 0b0101, "uqsax">;
+def UQSUB16 : AAI<0b01100110, 0b0111, "uqsub16">;
+def UQSUB8 : AAI<0b01100110, 0b1111, "uqsub8">;
+
+// Signed/Unsigned add/subtract -- for disassembly only
+
+def SASX : AAI<0b01100001, 0b0011, "sasx">;
+def SADD16 : AAI<0b01100001, 0b0001, "sadd16">;
+def SADD8 : AAI<0b01100001, 0b1001, "sadd8">;
+def SSAX : AAI<0b01100001, 0b0101, "ssax">;
+def SSUB16 : AAI<0b01100001, 0b0111, "ssub16">;
+def SSUB8 : AAI<0b01100001, 0b1111, "ssub8">;
+def UASX : AAI<0b01100101, 0b0011, "uasx">;
+def UADD16 : AAI<0b01100101, 0b0001, "uadd16">;
+def UADD8 : AAI<0b01100101, 0b1001, "uadd8">;
+def USAX : AAI<0b01100101, 0b0101, "usax">;
+def USUB16 : AAI<0b01100101, 0b0111, "usub16">;
+def USUB8 : AAI<0b01100101, 0b1111, "usub8">;
+
+// Signed/Unsigned halving add/subtract -- for disassembly only
+
+def SHASX : AAI<0b01100011, 0b0011, "shasx">;
+def SHADD16 : AAI<0b01100011, 0b0001, "shadd16">;
+def SHADD8 : AAI<0b01100011, 0b1001, "shadd8">;
+def SHSAX : AAI<0b01100011, 0b0101, "shsax">;
+def SHSUB16 : AAI<0b01100011, 0b0111, "shsub16">;
+def SHSUB8 : AAI<0b01100011, 0b1111, "shsub8">;
+def UHASX : AAI<0b01100111, 0b0011, "uhasx">;
+def UHADD16 : AAI<0b01100111, 0b0001, "uhadd16">;
+def UHADD8 : AAI<0b01100111, 0b1001, "uhadd8">;
+def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
+def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
+def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
+
+// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
+
+def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ MulFrm /* for convenience */, NoItinerary, "usad8",
+ "\t$dst, $a, $b", []>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{27-20} = 0b01111000;
+ let Inst{15-12} = 0b1111;
+ let Inst{7-4} = 0b0001;
+}
+def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
+ MulFrm /* for convenience */, NoItinerary, "usada8",
+ "\t$dst, $a, $b, $acc", []>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{27-20} = 0b01111000;
+ let Inst{7-4} = 0b0001;
+}
+
+// Signed/Unsigned saturate -- for disassembly only
+
+def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
+ DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-21} = 0b0110101;
+ let Inst{6-4} = 0b001;
+}
+
+def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
+ DPFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-21} = 0b0110101;
+ let Inst{6-4} = 0b101;
+}
+
+def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
+ NoItinerary, "ssat16", "\t$dst, $bit_pos, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-20} = 0b01101010;
+ let Inst{7-4} = 0b0011;
+}
+
+def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
+ DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-21} = 0b0110111;
+ let Inst{6-4} = 0b001;
+}
+
+def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
+ DPFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-21} = 0b0110111;
+ let Inst{6-4} = 0b101;
+}
+
+def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), DPFrm,
+ NoItinerary, "usat16", "\t$dst, $bit_pos, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-20} = 0b01101110;
+ let Inst{7-4} = 0b0011;
+}
//===----------------------------------------------------------------------===//
// Bitwise Instructions.
@@ -1239,6 +1728,17 @@ def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
let Inst{6-0} = 0b0011111;
}
+// A8.6.18 BFI - Bitfield insert (Encoding A1)
+// Added for disassembler with the pattern field purposely left blank.
+def BFI : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
+ AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
+ "bfi", "\t$dst, $src, $imm", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-21} = 0b0111110;
+ let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
+}
+
def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
"mvn", "\t$dst, $src",
[(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
@@ -1251,7 +1751,7 @@ def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
let Inst{25} = 0;
}
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
-def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
+def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
IIC_iMOVi, "mvn", "\t$dst, $imm",
[(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
let Inst{25} = 1;
@@ -1314,6 +1814,14 @@ def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
let Inst{15-12} = 0b1111;
}
+def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ IIC_iMUL32, "smmulr", "\t$dst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{7-4} = 0b0011; // R = 1
+ let Inst{15-12} = 0b1111;
+}
+
def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
[(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
@@ -1321,6 +1829,12 @@ def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
let Inst{7-4} = 0b0001;
}
+def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
+ IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{7-4} = 0b0011; // R = 1
+}
def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
@@ -1329,6 +1843,13 @@ def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
let Inst{7-4} = 0b1101;
}
+def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
+ IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6]> {
+ let Inst{7-4} = 0b1111; // R = 1
+}
+
multiclass AI_smul<string opc, PatFrag opnode> {
def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
@@ -1400,7 +1921,7 @@ multiclass AI_smla<string opc, PatFrag opnode> {
def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
- (sra GPR:$b, (i32 16)))))]>,
+ (sra GPR:$b, (i32 16)))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
@@ -1446,8 +1967,87 @@ multiclass AI_smla<string opc, PatFrag opnode> {
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
-// TODO: Halfword multiple accumulate long: SMLAL<x><y>
-// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
+// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
+def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 0;
+ let Inst{6} = 0;
+}
+
+def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 0;
+ let Inst{6} = 1;
+}
+
+def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 1;
+ let Inst{6} = 0;
+}
+
+def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 1;
+ let Inst{6} = 1;
+}
+
+// Helper class for AI_smld -- for disassembly only
+class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
+ InstrItinClass itin, string opc, string asm>
+ : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
+ let Inst{4} = 1;
+ let Inst{5} = swap;
+ let Inst{6} = sub;
+ let Inst{7} = 0;
+ let Inst{21-20} = 0b00;
+ let Inst{22} = long;
+ let Inst{27-23} = 0b01110;
+}
+
+multiclass AI_smld<bit sub, string opc> {
+
+ def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
+ NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
+
+ def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
+ NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
+
+ def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
+ NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
+
+ def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
+
+}
+
+defm SMLA : AI_smld<0, "smla">;
+defm SMLS : AI_smld<1, "smls">;
+
+multiclass AI_sdml<bit sub, string opc> {
+
+ def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
+ let Inst{15-12} = 0b1111;
+ }
+
+ def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
+ let Inst{15-12} = 0b1111;
+ }
+
+}
+
+defm SMUA : AI_sdml<0, "smua">;
+defm SMUS : AI_sdml<1, "smus">;
//===----------------------------------------------------------------------===//
// Misc. Arithmetic Instructions.
@@ -1505,7 +2105,7 @@ def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
- IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
+ IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
(and (shl GPR:$src2, (i32 imm:$shamt)),
0xFFFF0000)))]>,
@@ -1522,7 +2122,7 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
- IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
+ IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
(and (sra GPR:$src2, imm16_31:$shamt),
0xFFFF)))]>, Requires<[IsARM, HasV6]> {
@@ -1568,7 +2168,7 @@ def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
// Conditional moves
// FIXME: should be able to write a pattern for ARMcmov, but can't use
-// a two-value operand where a dag node expects two operands. :(
+// a two-value operand where a dag node expects two operands. :(
def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
IIC_iCMOVr, "mov", "\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
@@ -1606,6 +2206,7 @@ def Int_MemBarrierV7 : AInoP<(outs), (ins),
Requires<[IsARM, HasV7]> {
let Inst{31-4} = 0xf57ff05;
// FIXME: add support for options other than a full system DMB
+ // See DMB disassembly-only variants below.
let Inst{3-0} = 0b1111;
}
@@ -1616,6 +2217,7 @@ def Int_SyncBarrierV7 : AInoP<(outs), (ins),
Requires<[IsARM, HasV7]> {
let Inst{31-4} = 0xf57ff04;
// FIXME: add support for options other than a full system DSB
+ // See DSB disassembly-only variants below.
let Inst{3-0} = 0b1111;
}
@@ -1638,6 +2240,64 @@ def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
}
}
+// Helper class for multiclass MemB -- for disassembly only
+class AMBI<string opc, string asm>
+ : AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV7]> {
+ let Inst{31-20} = 0xf57;
+}
+
+multiclass MemB<bits<4> op7_4, string opc> {
+
+ def st : AMBI<opc, "\tst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b1110;
+ }
+
+ def ish : AMBI<opc, "\tish"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b1011;
+ }
+
+ def ishst : AMBI<opc, "\tishst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b1010;
+ }
+
+ def nsh : AMBI<opc, "\tnsh"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0111;
+ }
+
+ def nshst : AMBI<opc, "\tnshst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0110;
+ }
+
+ def osh : AMBI<opc, "\tosh"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0011;
+ }
+
+ def oshst : AMBI<opc, "\toshst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0010;
+ }
+}
+
+// These DMB variants are for disassembly only.
+defm DMB : MemB<0b0101, "dmb">;
+
+// These DSB variants are for disassembly only.
+defm DSB : MemB<0b0100, "dsb">;
+
+// ISB has only full system option -- for disassembly only
+def ISBsy : AMBI<"isb", ""> {
+ let Inst{7-4} = 0b0110;
+ let Inst{3-0} = 0b1111;
+}
+
let usesCustomInserter = 1 in {
let Uses = [CPSR] in {
def ATOMIC_LOAD_ADD_I8 : PseudoInst<
@@ -1777,6 +2437,35 @@ def STREXD : AIstrex<0b01, (outs GPR:$success),
[]>;
}
+// Clear-Exclusive is for disassembly only.
+def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV7]> {
+ let Inst{31-20} = 0xf57;
+ let Inst{7-4} = 0b0001;
+}
+
+// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
+let mayLoad = 1 in {
+def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
+ "swp", "\t$dst, $src, [$ptr]",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-23} = 0b00010;
+ let Inst{22} = 0; // B = 0
+ let Inst{21-20} = 0b00;
+ let Inst{7-4} = 0b1001;
+}
+
+def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
+ "swpb", "\t$dst, $src, [$ptr]",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-23} = 0b00010;
+ let Inst{22} = 1; // B = 1
+ let Inst{21-20} = 0b00;
+ let Inst{7-4} = 0b1001;
+}
+}
+
//===----------------------------------------------------------------------===//
// TLS Instructions
//
@@ -1827,7 +2516,7 @@ let Defs =
// Two piece so_imms.
let isReMaterializable = 1 in
-def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
+def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
Pseudo, IIC_iMOVi,
"mov", "\t$dst, $src",
[(set GPR:$dst, so_imm2part:$src)]>,
@@ -1852,7 +2541,7 @@ def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
// FIXME: Remove this when we can do generalized remat.
let isReMaterializable = 1 in
def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
- "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
+ "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
[(set GPR:$dst, (i32 imm:$src))]>,
Requires<[IsARM, HasV6T2]>;
@@ -1959,3 +2648,226 @@ include "ARMInstrVFP.td"
//
include "ARMInstrNEON.td"
+
+//===----------------------------------------------------------------------===//
+// Coprocessor Instructions. For disassembly only.
+//
+
+def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{4} = 0;
+}
+
+def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{4} = 0;
+}
+
+class ACI<dag oops, dag iops, string opc, string asm>
+ : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
+ opc, asm, "", [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-25} = 0b110;
+}
+
+multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
+
+ def _OFFSET : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+ opc, "\tp$cop, cr$CRd, $addr"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 1; // P = 1
+ let Inst{21} = 0; // W = 0
+ let Inst{22} = 0; // D = 0
+ let Inst{20} = load;
+ }
+
+ def _PRE : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+ opc, "\tp$cop, cr$CRd, $addr!"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 1; // P = 1
+ let Inst{21} = 1; // W = 1
+ let Inst{22} = 0; // D = 0
+ let Inst{20} = load;
+ }
+
+ def _POST : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
+ opc, "\tp$cop, cr$CRd, [$base], $offset"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 0; // P = 0
+ let Inst{21} = 1; // W = 1
+ let Inst{22} = 0; // D = 0
+ let Inst{20} = load;
+ }
+
+ def _OPTION : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
+ opc, "\tp$cop, cr$CRd, [$base], $option"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 0; // P = 0
+ let Inst{23} = 1; // U = 1
+ let Inst{21} = 0; // W = 0
+ let Inst{22} = 0; // D = 0
+ let Inst{20} = load;
+ }
+
+ def L_OFFSET : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+ opc, "l\tp$cop, cr$CRd, $addr"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 1; // P = 1
+ let Inst{21} = 0; // W = 0
+ let Inst{22} = 1; // D = 1
+ let Inst{20} = load;
+ }
+
+ def L_PRE : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+ opc, "l\tp$cop, cr$CRd, $addr!"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 1; // P = 1
+ let Inst{21} = 1; // W = 1
+ let Inst{22} = 1; // D = 1
+ let Inst{20} = load;
+ }
+
+ def L_POST : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
+ opc, "l\tp$cop, cr$CRd, [$base], $offset"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 0; // P = 0
+ let Inst{21} = 1; // W = 1
+ let Inst{22} = 1; // D = 1
+ let Inst{20} = load;
+ }
+
+ def L_OPTION : ACI<(outs),
+ (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
+ opc, "l\tp$cop, cr$CRd, [$base], $option"> {
+ let Inst{31-28} = op31_28;
+ let Inst{24} = 0; // P = 0
+ let Inst{23} = 1; // U = 1
+ let Inst{21} = 0; // W = 0
+ let Inst{22} = 1; // D = 1
+ let Inst{20} = load;
+ }
+}
+
+defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
+defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
+defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
+defm STC2 : LdStCop<0b1111, 0, "stc2">;
+
+def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{20} = 0;
+ let Inst{4} = 1;
+}
+
+def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{20} = 0;
+ let Inst{4} = 1;
+}
+
+def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{20} = 1;
+ let Inst{4} = 1;
+}
+
+def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{20} = 1;
+ let Inst{4} = 1;
+}
+
+def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0100;
+}
+
+def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{23-20} = 0b0100;
+}
+
+def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0101;
+}
+
+def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{23-20} = 0b0101;
+}
+
+//===----------------------------------------------------------------------===//
+// Move between special register and ARM core register -- for disassembly only
+//
+
+def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0000;
+ let Inst{7-4} = 0b0000;
+}
+
+def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0100;
+ let Inst{7-4} = 0b0000;
+}
+
+// FIXME: mask is ignored for the time being.
+def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0010;
+ let Inst{7-4} = 0b0000;
+}
+
+// FIXME: mask is ignored for the time being.
+def MSRi : ABI<0b0011,(outs),(ins so_imm:$a), NoItinerary, "msr", "\tcpsr, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0010;
+ let Inst{7-4} = 0b0000;
+}
+
+// FIXME: mask is ignored for the time being.
+def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"msr","\tspsr, $src",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0110;
+ let Inst{7-4} = 0b0000;
+}
+
+// FIXME: mask is ignored for the time being.
+def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a),NoItinerary,"msr","\tspsr, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0110;
+ let Inst{7-4} = 0b0000;
+}
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index e2be7ba..3aa0810 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -83,11 +83,17 @@ def NEONvrev32 : SDNode<"ARMISD::VREV32", SDTARMVSHUF>;
def NEONvrev16 : SDNode<"ARMISD::VREV16", SDTARMVSHUF>;
def SDTARMVSHUF2 : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
- SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>]>;
+ SDTCisSameAs<0, 2>,
+ SDTCisSameAs<0, 3>]>;
def NEONzip : SDNode<"ARMISD::VZIP", SDTARMVSHUF2>;
def NEONuzp : SDNode<"ARMISD::VUZP", SDTARMVSHUF2>;
def NEONtrn : SDNode<"ARMISD::VTRN", SDTARMVSHUF2>;
+def SDTARMFMAX : SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisSameAs<0, 1>,
+ SDTCisSameAs<0, 2>]>;
+def NEONfmax : SDNode<"ARMISD::FMAX", SDTARMFMAX>;
+def NEONfmin : SDNode<"ARMISD::FMIN", SDTARMFMAX>;
+
//===----------------------------------------------------------------------===//
// NEON operand definitions
//===----------------------------------------------------------------------===//
@@ -123,9 +129,7 @@ def h64imm : Operand<i64> {
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
def VLDMD : NI<(outs),
(ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
- IIC_fpLoadm,
- "vldm", "${addr:submode} ${addr:base}, $dst1",
- []> {
+ IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
let Inst{27-25} = 0b110;
let Inst{20} = 1;
let Inst{11-9} = 0b101;
@@ -133,9 +137,7 @@ def VLDMD : NI<(outs),
def VLDMS : NI<(outs),
(ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
- IIC_fpLoadm,
- "vldm", "${addr:submode} ${addr:base}, $dst1",
- []> {
+ IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
let Inst{27-25} = 0b110;
let Inst{20} = 1;
let Inst{11-9} = 0b101;
@@ -144,10 +146,9 @@ def VLDMS : NI<(outs),
*/
// Use vldmia to load a Q register as a D register pair.
-def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr),
- IIC_fpLoadm,
- "vldmia", "$addr, ${dst:dregpair}",
- [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> {
+def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm,
+ "vldmia", "$addr, ${dst:dregpair}",
+ [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> {
let Inst{27-25} = 0b110;
let Inst{24} = 0; // P bit
let Inst{23} = 1; // U bit
@@ -156,10 +157,9 @@ def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr),
}
// Use vstmia to store a Q register as a D register pair.
-def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr),
- IIC_fpStorem,
- "vstmia", "$addr, ${src:dregpair}",
- [(store (v2f64 QPR:$src), addrmode4:$addr)]> {
+def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), IIC_fpStorem,
+ "vstmia", "$addr, ${src:dregpair}",
+ [(store (v2f64 QPR:$src), addrmode4:$addr)]> {
let Inst{27-25} = 0b110;
let Inst{24} = 0; // P bit
let Inst{23} = 1; // U bit
@@ -191,6 +191,29 @@ def VLD1q32 : VLD1Q<0b1000, "vld1", "32", v4i32, int_arm_neon_vld1>;
def VLD1qf : VLD1Q<0b1000, "vld1", "32", v4f32, int_arm_neon_vld1>;
def VLD1q64 : VLD1Q<0b1100, "vld1", "64", v2i64, int_arm_neon_vld1>;
+// These (dreg triple/quadruple) are for disassembly only.
+class VLD1D3<bits<4> op7_4, string OpcodeStr, string Dt>
+ : NLdSt<0, 0b10, 0b0110, op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
+ (ins addrmode6:$addr), IIC_VLD1, OpcodeStr, Dt,
+ "\\{$dst1, $dst2, $dst3\\}, $addr", "",
+ [/* For disassembly only; pattern left blank */]>;
+class VLD1D4<bits<4> op7_4, string OpcodeStr, string Dt>
+ : NLdSt<0,0b10,0b0010,op7_4,(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
+ (ins addrmode6:$addr), IIC_VLD1, OpcodeStr, Dt,
+ "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr", "",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VLD1d8T : VLD1D3<0b0000, "vld1", "8">;
+def VLD1d16T : VLD1D3<0b0100, "vld1", "16">;
+def VLD1d32T : VLD1D3<0b1000, "vld1", "32">;
+//def VLD1d64T : VLD1D3<0b1100, "vld1", "64">;
+
+def VLD1d8Q : VLD1D4<0b0000, "vld1", "8">;
+def VLD1d16Q : VLD1D4<0b0100, "vld1", "16">;
+def VLD1d32Q : VLD1D4<0b1000, "vld1", "32">;
+//def VLD1d64Q : VLD1D4<0b1100, "vld1", "64">;
+
+
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
// VLD2 : Vector Load (multiple 2-element structures)
@@ -216,6 +239,16 @@ def VLD2q8 : VLD2Q<0b0000, "vld2", "8">;
def VLD2q16 : VLD2Q<0b0100, "vld2", "16">;
def VLD2q32 : VLD2Q<0b1000, "vld2", "32">;
+// These (double-spaced dreg pair) are for disassembly only.
+class VLD2Ddbl<bits<4> op7_4, string OpcodeStr, string Dt>
+ : NLdSt<0,0b10,0b1001,op7_4, (outs DPR:$dst1, DPR:$dst2),
+ (ins addrmode6:$addr), IIC_VLD2,
+ OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []>;
+
+def VLD2d8D : VLD2Ddbl<0b0000, "vld2", "8">;
+def VLD2d16D : VLD2Ddbl<0b0100, "vld2", "16">;
+def VLD2d32D : VLD2Ddbl<0b1000, "vld2", "32">;
+
// VLD3 : Vector Load (multiple 3-element structures)
class VLD3D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0100,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
@@ -285,105 +318,64 @@ def VLD4q32b : VLD4WB<0b1000, "vld4", "32">;
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",
+ IIC_VLD2, OpcodeStr, Dt, "\\{$dst1[$lane], $dst2[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2", []>;
// vld2 to single-spaced registers.
def VLD2LNd8 : VLD2LN<0b0001, "vld2", "8">;
-def VLD2LNd16 : VLD2LN<0b0101, "vld2", "16"> {
- let Inst{5} = 0;
-}
-def VLD2LNd32 : VLD2LN<0b1001, "vld2", "32"> {
- let Inst{6} = 0;
-}
+def VLD2LNd16 : VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 0; }
+def VLD2LNd32 : VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 0; }
// vld2 to double-spaced even registers.
-def VLD2LNq16a: VLD2LN<0b0101, "vld2", "16"> {
- let Inst{5} = 1;
-}
-def VLD2LNq32a: VLD2LN<0b1001, "vld2", "32"> {
- let Inst{6} = 1;
-}
+def VLD2LNq16a: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
+def VLD2LNq32a: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
// vld2 to double-spaced odd registers.
-def VLD2LNq16b: VLD2LN<0b0101, "vld2", "16"> {
- let Inst{5} = 1;
-}
-def VLD2LNq32b: VLD2LN<0b1001, "vld2", "32"> {
- let Inst{6} = 1;
-}
+def VLD2LNq16b: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
+def VLD2LNq32b: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
// VLD3LN : Vector Load (single 3-element structure to one lane)
class VLD3LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b10,op11_8,{?,?,?,?}, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
- nohash_imm:$lane), IIC_VLD3,
- OpcodeStr, Dt,
+ nohash_imm:$lane), IIC_VLD3, OpcodeStr, Dt,
"\\{$dst1[$lane], $dst2[$lane], $dst3[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2, $src3 = $dst3", []>;
// vld3 to single-spaced registers.
-def VLD3LNd8 : VLD3LN<0b0010, "vld3", "8"> {
- let Inst{4} = 0;
-}
-def VLD3LNd16 : VLD3LN<0b0110, "vld3", "16"> {
- let Inst{5-4} = 0b00;
-}
-def VLD3LNd32 : VLD3LN<0b1010, "vld3", "32"> {
- let Inst{6-4} = 0b000;
-}
+def VLD3LNd8 : VLD3LN<0b0010, "vld3", "8"> { let Inst{4} = 0; }
+def VLD3LNd16 : VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b00; }
+def VLD3LNd32 : VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b000; }
// vld3 to double-spaced even registers.
-def VLD3LNq16a: VLD3LN<0b0110, "vld3", "16"> {
- let Inst{5-4} = 0b10;
-}
-def VLD3LNq32a: VLD3LN<0b1010, "vld3", "32"> {
- let Inst{6-4} = 0b100;
-}
+def VLD3LNq16a: VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b10; }
+def VLD3LNq32a: VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b100; }
// vld3 to double-spaced odd registers.
-def VLD3LNq16b: VLD3LN<0b0110, "vld3", "16"> {
- let Inst{5-4} = 0b10;
-}
-def VLD3LNq32b: VLD3LN<0b1010, "vld3", "32"> {
- let Inst{6-4} = 0b100;
-}
+def VLD3LNq16b: VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b10; }
+def VLD3LNq32b: VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b100; }
// VLD4LN : Vector Load (single 4-element structure to one lane)
class VLD4LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b10,op11_8,{?,?,?,?},
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
- nohash_imm:$lane), IIC_VLD4,
- OpcodeStr, Dt,
+ nohash_imm:$lane), IIC_VLD4, OpcodeStr, Dt,
"\\{$dst1[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>;
// vld4 to single-spaced registers.
def VLD4LNd8 : VLD4LN<0b0011, "vld4", "8">;
-def VLD4LNd16 : VLD4LN<0b0111, "vld4", "16"> {
- let Inst{5} = 0;
-}
-def VLD4LNd32 : VLD4LN<0b1011, "vld4", "32"> {
- let Inst{6} = 0;
-}
+def VLD4LNd16 : VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 0; }
+def VLD4LNd32 : VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 0; }
// vld4 to double-spaced even registers.
-def VLD4LNq16a: VLD4LN<0b0111, "vld4", "16"> {
- let Inst{5} = 1;
-}
-def VLD4LNq32a: VLD4LN<0b1011, "vld4", "32"> {
- let Inst{6} = 1;
-}
+def VLD4LNq16a: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
+def VLD4LNq32a: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
// vld4 to double-spaced odd registers.
-def VLD4LNq16b: VLD4LN<0b0111, "vld4", "16"> {
- let Inst{5} = 1;
-}
-def VLD4LNq32b: VLD4LN<0b1011, "vld4", "32"> {
- let Inst{6} = 1;
-}
+def VLD4LNq16b: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
+def VLD4LNq32b: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
// VLD1DUP : Vector Load (single element to all lanes)
// VLD2DUP : Vector Load (single 2-element structure to all lanes)
@@ -418,6 +410,31 @@ def VST1qf : VST1Q<0b1000, "vst1", "32", v4f32, int_arm_neon_vst1>;
def VST1q64 : VST1Q<0b1100, "vst1", "64", v2i64, int_arm_neon_vst1>;
} // hasExtraSrcRegAllocReq
+// These (dreg triple/quadruple) are for disassembly only.
+class VST1D3<bits<4> op7_4, string OpcodeStr, string Dt>
+ : NLdSt<0, 0b00, 0b0110, op7_4, (outs),
+ (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
+ OpcodeStr, Dt,
+ "\\{$src1, $src2, $src3\\}, $addr", "",
+ [/* For disassembly only; pattern left blank */]>;
+class VST1D4<bits<4> op7_4, string OpcodeStr, string Dt>
+ : NLdSt<0, 0b00, 0b0010, op7_4, (outs),
+ (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
+ IIC_VST, OpcodeStr, Dt,
+ "\\{$src1, $src2, $src3, $src4\\}, $addr", "",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VST1d8T : VST1D3<0b0000, "vst1", "8">;
+def VST1d16T : VST1D3<0b0100, "vst1", "16">;
+def VST1d32T : VST1D3<0b1000, "vst1", "32">;
+//def VST1d64T : VST1D3<0b1100, "vst1", "64">;
+
+def VST1d8Q : VST1D4<0b0000, "vst1", "8">;
+def VST1d16Q : VST1D4<0b0100, "vst1", "16">;
+def VST1d32Q : VST1D4<0b1000, "vst1", "32">;
+//def VST1d64Q : VST1D4<0b1100, "vst1", "64">;
+
+
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
// VST2 : Vector Store (multiple 2-element structures)
@@ -428,8 +445,7 @@ class VST2D<bits<4> op7_4, string OpcodeStr, string Dt>
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",
+ IIC_VST, OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"", []>;
def VST2d8 : VST2D<0b0000, "vst2", "8">;
@@ -443,6 +459,16 @@ def VST2q8 : VST2Q<0b0000, "vst2", "8">;
def VST2q16 : VST2Q<0b0100, "vst2", "16">;
def VST2q32 : VST2Q<0b1000, "vst2", "32">;
+// These (double-spaced dreg pair) are for disassembly only.
+class VST2Ddbl<bits<4> op7_4, string OpcodeStr, string Dt>
+ : NLdSt<0, 0b00, 0b1001, op7_4, (outs),
+ (ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
+ OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []>;
+
+def VST2d8D : VST2Ddbl<0b0000, "vst2", "8">;
+def VST2d16D : VST2Ddbl<0b0100, "vst2", "16">;
+def VST2d32D : VST2Ddbl<0b1000, "vst2", "32">;
+
// VST3 : Vector Store (multiple 3-element structures)
class VST3D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0100,op7_4, (outs),
@@ -476,14 +502,12 @@ def VST3q32b : VST3WB<0b1000, "vst3", "32">;
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",
+ IIC_VST, 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",
+ IIC_VST, OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"$addr.addr = $wb", []>;
def VST4d8 : VST4D<0b0000, "vst4", "8">;
@@ -511,104 +535,63 @@ def VST4q32b : VST4WB<0b1000, "vst4", "32">;
// VST2LN : Vector Store (single 2-element structure from one lane)
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",
- "", []>;
+ (ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane),
+ IIC_VST, OpcodeStr, Dt, "\\{$src1[$lane], $src2[$lane]\\}, $addr",
+ "", []>;
// vst2 to single-spaced registers.
def VST2LNd8 : VST2LN<0b0001, "vst2", "8">;
-def VST2LNd16 : VST2LN<0b0101, "vst2", "16"> {
- let Inst{5} = 0;
-}
-def VST2LNd32 : VST2LN<0b1001, "vst2", "32"> {
- let Inst{6} = 0;
-}
+def VST2LNd16 : VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 0; }
+def VST2LNd32 : VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 0; }
// vst2 to double-spaced even registers.
-def VST2LNq16a: VST2LN<0b0101, "vst2", "16"> {
- let Inst{5} = 1;
-}
-def VST2LNq32a: VST2LN<0b1001, "vst2", "32"> {
- let Inst{6} = 1;
-}
+def VST2LNq16a: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
+def VST2LNq32a: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
// vst2 to double-spaced odd registers.
-def VST2LNq16b: VST2LN<0b0101, "vst2", "16"> {
- let Inst{5} = 1;
-}
-def VST2LNq32b: VST2LN<0b1001, "vst2", "32"> {
- let Inst{6} = 1;
-}
+def VST2LNq16b: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
+def VST2LNq32b: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
// VST3LN : Vector Store (single 3-element structure from one lane)
class VST3LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b00,op11_8,{?,?,?,?}, (outs),
- (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
- nohash_imm:$lane), IIC_VST,
- OpcodeStr, Dt,
- "\\{$src1[$lane], $src2[$lane], $src3[$lane]\\}, $addr", "", []>;
+ (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
+ nohash_imm:$lane), IIC_VST, OpcodeStr, Dt,
+ "\\{$src1[$lane], $src2[$lane], $src3[$lane]\\}, $addr", "", []>;
// vst3 to single-spaced registers.
-def VST3LNd8 : VST3LN<0b0010, "vst3", "8"> {
- let Inst{4} = 0;
-}
-def VST3LNd16 : VST3LN<0b0110, "vst3", "16"> {
- let Inst{5-4} = 0b00;
-}
-def VST3LNd32 : VST3LN<0b1010, "vst3", "32"> {
- let Inst{6-4} = 0b000;
-}
+def VST3LNd8 : VST3LN<0b0010, "vst3", "8"> { let Inst{4} = 0; }
+def VST3LNd16 : VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b00; }
+def VST3LNd32 : VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b000; }
// vst3 to double-spaced even registers.
-def VST3LNq16a: VST3LN<0b0110, "vst3", "16"> {
- let Inst{5-4} = 0b10;
-}
-def VST3LNq32a: VST3LN<0b1010, "vst3", "32"> {
- let Inst{6-4} = 0b100;
-}
+def VST3LNq16a: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
+def VST3LNq32a: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
// vst3 to double-spaced odd registers.
-def VST3LNq16b: VST3LN<0b0110, "vst3", "16"> {
- let Inst{5-4} = 0b10;
-}
-def VST3LNq32b: VST3LN<0b1010, "vst3", "32"> {
- let Inst{6-4} = 0b100;
-}
+def VST3LNq16b: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
+def VST3LNq32b: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
// VST4LN : Vector Store (single 4-element structure from one lane)
class VST4LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b00,op11_8,{?,?,?,?}, (outs),
- (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
- nohash_imm:$lane), IIC_VST,
- OpcodeStr, 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",
- "", []>;
+ "", []>;
// vst4 to single-spaced registers.
def VST4LNd8 : VST4LN<0b0011, "vst4", "8">;
-def VST4LNd16 : VST4LN<0b0111, "vst4", "16"> {
- let Inst{5} = 0;
-}
-def VST4LNd32 : VST4LN<0b1011, "vst4", "32"> {
- let Inst{6} = 0;
-}
+def VST4LNd16 : VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 0; }
+def VST4LNd32 : VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 0; }
// vst4 to double-spaced even registers.
-def VST4LNq16a: VST4LN<0b0111, "vst4", "16"> {
- let Inst{5} = 1;
-}
-def VST4LNq32a: VST4LN<0b1011, "vst4", "32"> {
- let Inst{6} = 1;
-}
+def VST4LNq16a: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
+def VST4LNq32a: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
// vst4 to double-spaced odd registers.
-def VST4LNq16b: VST4LN<0b0111, "vst4", "16"> {
- let Inst{5} = 1;
-}
-def VST4LNq32b: VST4LN<0b1011, "vst4", "32"> {
- let Inst{6} = 1;
-}
+def VST4LNq16b: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
+def VST4LNq32b: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
} // mayStore = 1, hasExtraSrcRegAllocReq = 1
@@ -656,34 +639,26 @@ def SubReg_i32_lane : SDNodeXForm<imm, [{
// Instruction Classes
//===----------------------------------------------------------------------===//
-// Basic 2-register operations, both double- and quad-register.
+// Basic 2-register operations: single-, double- and quad-register.
+class N2VS<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
+ bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
+ string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
+ : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
+ (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src),
+ IIC_VUNAD, OpcodeStr, Dt, "$dst, $src", "", []>;
class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
- bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,string Dt,
- ValueType ResTy, ValueType OpTy, SDNode OpNode>
+ bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
+ string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
: N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst),
(ins DPR:$src), IIC_VUNAD, OpcodeStr, Dt, "$dst, $src", "",
[(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src))))]>;
class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
- bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,string Dt,
- ValueType ResTy, ValueType OpTy, SDNode OpNode>
+ bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
+ string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
: N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst),
(ins QPR:$src), IIC_VUNAQ, OpcodeStr, Dt, "$dst, $src", "",
[(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src))))]>;
-// Basic 2-register operations, scalar single-precision.
-class N2VDs<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
- bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,string Dt,
- ValueType ResTy, ValueType OpTy, SDNode OpNode>
- : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
- (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src),
- IIC_VUNAD, OpcodeStr, Dt, "$dst, $src", "", []>;
-
-class N2VDsPat<SDNode OpNode, ValueType ResTy, ValueType OpTy, NeonI Inst>
- : NEONFPPat<(ResTy (OpNode SPR:$a)),
- (EXTRACT_SUBREG
- (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)), SPR:$a, arm_ssubreg_0)),
- arm_ssubreg_0)>;
-
// Basic 2-register intrinsics, both double- and quad-register.
class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
bits<2> op17_16, bits<5> op11_7, bit op4,
@@ -700,21 +675,6 @@ class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
(ins QPR:$src), itin, OpcodeStr, Dt, "$dst, $src", "",
[(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>;
-// Basic 2-register intrinsics, scalar single-precision
-class N2VDInts<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
- bits<2> op17_16, bits<5> op11_7, bit op4,
- InstrItinClass itin, string OpcodeStr, string Dt,
- ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
- : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
- (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), itin,
- OpcodeStr, Dt, "$dst, $src", "", []>;
-
-class N2VDIntsPat<SDNode OpNode, NeonI Inst>
- : NEONFPPat<(f32 (OpNode SPR:$a)),
- (EXTRACT_SUBREG
- (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$a, arm_ssubreg_0)),
- arm_ssubreg_0)>;
-
// Narrow 2-register intrinsics.
class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
@@ -742,15 +702,22 @@ class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt>
class N2VQShuffle<bits<2> op19_18, bits<5> op11_7,
InstrItinClass itin, string OpcodeStr, string Dt>
: N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$dst1, QPR:$dst2),
- (ins QPR:$src1, QPR:$src2), itin,
- OpcodeStr, Dt, "$dst1, $dst2",
+ (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$dst1, $dst2",
"$src1 = $dst1, $src2 = $dst2", []>;
-// Basic 3-register operations, both double- and quad-register.
+// Basic 3-register operations: single-, double- and quad-register.
+class N3VS<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
+ string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
+ SDNode OpNode, bit Commutable>
+ : N3V<op24, op23, op21_20, op11_8, 0, op4,
+ (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src1, DPR_VFP2:$src2), IIC_VBIND,
+ OpcodeStr, Dt, "$dst, $src1, $src2", "", []> {
+ let isCommutable = Commutable;
+}
+
class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt,
- ValueType ResTy, ValueType OpTy,
- SDNode OpNode, bit Commutable>
+ ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
: N3V<op24, op23, op21_20, op11_8, 0, op4,
(outs DPR:$dst), (ins DPR:$src1, DPR:$src2), itin,
OpcodeStr, Dt, "$dst, $src1, $src2", "",
@@ -763,9 +730,9 @@ class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
ValueType ResTy, ValueType OpTy,
SDNode OpNode, bit Commutable>
: N3VX<op24, op23, op21_20, op11_8, 0, op4,
- (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), itin,
- OpcodeStr, "$dst, $src1, $src2", "",
- [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src1), (OpTy DPR:$src2))))]> {
+ (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), itin,
+ OpcodeStr, "$dst, $src1, $src2", "",
+ [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src1), (OpTy DPR:$src2))))]>{
let isCommutable = Commutable;
}
class N3VDSL<bits<2> op21_20, bits<4> op11_8,
@@ -776,27 +743,23 @@ class N3VDSL<bits<2> op21_20, bits<4> op11_8,
itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
[(set (Ty DPR:$dst),
(Ty (ShOp (Ty DPR:$src1),
- (Ty (NEONvduplane (Ty DPR_VFP2:$src2),
- imm:$lane)))))]> {
+ (Ty (NEONvduplane (Ty DPR_VFP2:$src2), imm:$lane)))))]>{
let isCommutable = 0;
}
class N3VDSL16<bits<2> op21_20, bits<4> op11_8,
string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
: N3V<0, 1, op21_20, op11_8, 1, 0,
(outs DPR:$dst), (ins DPR:$src1, DPR_8:$src2, nohash_imm:$lane),
- IIC_VMULi16D,
- OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
+ IIC_VMULi16D, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
[(set (Ty DPR:$dst),
(Ty (ShOp (Ty DPR:$src1),
- (Ty (NEONvduplane (Ty DPR_8:$src2),
- imm:$lane)))))]> {
+ (Ty (NEONvduplane (Ty DPR_8:$src2), imm:$lane)))))]> {
let isCommutable = 0;
}
class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt,
- ValueType ResTy, ValueType OpTy,
- SDNode OpNode, bit Commutable>
+ ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
: N3V<op24, op23, op21_20, op11_8, 1, op4,
(outs QPR:$dst), (ins QPR:$src1, QPR:$src2), itin,
OpcodeStr, Dt, "$dst, $src1, $src2", "",
@@ -805,12 +768,11 @@ class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
}
class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr,
- ValueType ResTy, ValueType OpTy,
- SDNode OpNode, bit Commutable>
+ ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
: N3VX<op24, op23, op21_20, op11_8, 1, op4,
- (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), itin,
- OpcodeStr, "$dst, $src1, $src2", "",
- [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src1), (OpTy QPR:$src2))))]> {
+ (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), itin,
+ OpcodeStr, "$dst, $src1, $src2", "",
+ [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src1), (OpTy QPR:$src2))))]>{
let isCommutable = Commutable;
}
class N3VQSL<bits<2> op21_20, bits<4> op11_8,
@@ -825,13 +787,11 @@ class N3VQSL<bits<2> op21_20, bits<4> op11_8,
imm:$lane)))))]> {
let isCommutable = 0;
}
-class N3VQSL16<bits<2> op21_20, bits<4> op11_8,
- string OpcodeStr, string Dt,
+class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy, SDNode ShOp>
: N3V<1, 1, op21_20, op11_8, 1, 0,
(outs QPR:$dst), (ins QPR:$src1, DPR_8:$src2, nohash_imm:$lane),
- IIC_VMULi16Q,
- OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
+ IIC_VMULi16Q, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
[(set (ResTy QPR:$dst),
(ResTy (ShOp (ResTy QPR:$src1),
(ResTy (NEONvduplane (OpTy DPR_8:$src2),
@@ -839,27 +799,10 @@ class N3VQSL16<bits<2> op21_20, bits<4> op11_8,
let isCommutable = 0;
}
-// Basic 3-register operations, scalar single-precision
-class N3VDs<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
- string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
- SDNode OpNode, bit Commutable>
- : N3V<op24, op23, op21_20, op11_8, 0, op4,
- (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src1, DPR_VFP2:$src2), IIC_VBIND,
- OpcodeStr, Dt, "$dst, $src1, $src2", "", []> {
- let isCommutable = Commutable;
-}
-class N3VDsPat<SDNode OpNode, NeonI Inst>
- : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)),
- (EXTRACT_SUBREG
- (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$a, arm_ssubreg_0),
- (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$b, arm_ssubreg_0)),
- arm_ssubreg_0)>;
-
// Basic 3-register intrinsics, both double- and quad-register.
class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt,
- ValueType ResTy, ValueType OpTy,
- Intrinsic IntOp, bit Commutable>
+ ValueType ResTy, ValueType OpTy, Intrinsic IntOp, bit Commutable>
: N3V<op24, op23, op21_20, op11_8, 0, op4,
(outs DPR:$dst), (ins DPR:$src1, DPR:$src2), itin,
OpcodeStr, Dt, "$dst, $src1, $src2", "",
@@ -891,8 +834,7 @@ class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt,
- ValueType ResTy, ValueType OpTy,
- Intrinsic IntOp, bit Commutable>
+ ValueType ResTy, ValueType OpTy, Intrinsic IntOp, bit Commutable>
: N3V<op24, op23, op21_20, op11_8, 1, op4,
(outs QPR:$dst), (ins QPR:$src1, QPR:$src2), itin,
OpcodeStr, Dt, "$dst, $src1, $src2", "",
@@ -924,7 +866,15 @@ class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
let isCommutable = 0;
}
-// Multiply-Add/Sub operations, both double- and quad-register.
+// Multiply-Add/Sub operations: single-, double- and quad-register.
+class N3VSMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
+ InstrItinClass itin, string OpcodeStr, string Dt,
+ ValueType Ty, SDNode MulOp, SDNode OpNode>
+ : N3V<op24, op23, op21_20, op11_8, 0, op4,
+ (outs DPR_VFP2:$dst),
+ (ins DPR_VFP2:$src1, DPR_VFP2:$src2, DPR_VFP2:$src3), itin,
+ OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst", []>;
+
class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
InstrItinClass itin, string OpcodeStr, string Dt,
ValueType Ty, SDNode MulOp, SDNode OpNode>
@@ -976,8 +926,8 @@ class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
[(set (ResTy QPR:$dst),
(ResTy (ShOp (ResTy QPR:$src1),
(ResTy (MulOp QPR:$src2,
- (ResTy (NEONvduplane (OpTy DPR_VFP2:$src3),
- imm:$lane)))))))]>;
+ (ResTy (NEONvduplane (OpTy DPR_VFP2:$src3),
+ imm:$lane)))))))]>;
class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy,
@@ -989,25 +939,8 @@ class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
[(set (ResTy QPR:$dst),
(ResTy (ShOp (ResTy QPR:$src1),
(ResTy (MulOp QPR:$src2,
- (ResTy (NEONvduplane (OpTy DPR_8:$src3),
- imm:$lane)))))))]>;
-
-// Multiply-Add/Sub operations, scalar single-precision
-class N3VDMulOps<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
- InstrItinClass itin, string OpcodeStr, string Dt,
- ValueType Ty, SDNode MulOp, SDNode OpNode>
- : N3V<op24, op23, op21_20, op11_8, 0, op4,
- (outs DPR_VFP2:$dst),
- (ins DPR_VFP2:$src1, DPR_VFP2:$src2, DPR_VFP2:$src3), itin,
- OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst", []>;
-
-class N3VDMulOpsPat<SDNode MulNode, SDNode OpNode, NeonI Inst>
- : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))),
- (EXTRACT_SUBREG
- (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$acc, arm_ssubreg_0),
- (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$a, arm_ssubreg_0),
- (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$b, arm_ssubreg_0)),
- arm_ssubreg_0)>;
+ (ResTy (NEONvduplane (OpTy DPR_8:$src3),
+ imm:$lane)))))))]>;
// Neon 3-argument intrinsics, both double- and quad-register.
// The destination register is also used as the first source operand register.
@@ -1050,9 +983,9 @@ class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(OpTy DPR:$src2),
(OpTy (NEONvduplane (OpTy DPR_VFP2:$src3),
imm:$lane)))))]>;
-class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
- string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
- Intrinsic IntOp>
+class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8,
+ InstrItinClass itin, string OpcodeStr, string Dt,
+ ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
: N3V<op24, 1, op21_20, op11_8, 1, 0,
(outs QPR:$dst),
(ins QPR:$src1, DPR:$src2, DPR_8:$src3, nohash_imm:$lane), itin,
@@ -1063,7 +996,6 @@ class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass iti
(OpTy (NEONvduplane (OpTy DPR_8:$src3),
imm:$lane)))))]>;
-
// Narrowing 3-register intrinsics.
class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
string OpcodeStr, string Dt, ValueType TyD, ValueType TyQ,
@@ -1095,9 +1027,9 @@ class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
(ResTy (IntOp (OpTy DPR:$src1),
(OpTy (NEONvduplane (OpTy DPR_VFP2:$src2),
imm:$lane)))))]>;
-class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
- string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
- Intrinsic IntOp>
+class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
+ InstrItinClass itin, string OpcodeStr, string Dt,
+ ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
: N3V<op24, 1, op21_20, op11_8, 1, 0,
(outs QPR:$dst), (ins DPR:$src1, DPR_8:$src2, nohash_imm:$lane),
itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
@@ -1249,6 +1181,45 @@ class N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
// S = single int (32 bit) elements
// D = double int (64 bit) elements
+// Neon 2-register vector operations -- for disassembly only.
+
+// First with only element sizes of 8, 16 and 32 bits:
+multiclass N2V_QHS_cmp<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
+ bits<5> op11_7, bit op4, string opc, string Dt,
+ string asm> {
+ // 64-bit vector types.
+ def v8i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 0, op4,
+ (outs DPR:$dst), (ins DPR:$src), NoItinerary,
+ opc, !strconcat(Dt, "8"), asm, "", []>;
+ def v4i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4,
+ (outs DPR:$dst), (ins DPR:$src), NoItinerary,
+ opc, !strconcat(Dt, "16"), asm, "", []>;
+ def v2i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
+ (outs DPR:$dst), (ins DPR:$src), NoItinerary,
+ opc, !strconcat(Dt, "32"), asm, "", []>;
+ def v2f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
+ (outs DPR:$dst), (ins DPR:$src), NoItinerary,
+ opc, "f32", asm, "", []> {
+ let Inst{10} = 1; // overwrite F = 1
+ }
+
+ // 128-bit vector types.
+ def v16i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 1, op4,
+ (outs QPR:$dst), (ins QPR:$src), NoItinerary,
+ opc, !strconcat(Dt, "8"), asm, "", []>;
+ def v8i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4,
+ (outs QPR:$dst), (ins QPR:$src), NoItinerary,
+ opc, !strconcat(Dt, "16"), asm, "", []>;
+ def v4i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
+ (outs QPR:$dst), (ins QPR:$src), NoItinerary,
+ opc, !strconcat(Dt, "32"), asm, "", []>;
+ def v4f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
+ (outs QPR:$dst), (ins QPR:$src), NoItinerary,
+ opc, "f32", asm, "", []> {
+ let Inst{10} = 1; // overwrite F = 1
+ }
+}
+
// Neon 3-register vector operations.
// First with only element sizes of 8, 16 and 32 bits:
@@ -1262,22 +1233,22 @@ multiclass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
OpcodeStr, !strconcat(Dt, "8"),
v8i8, v8i8, OpNode, Commutable>;
def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, itinD16,
- OpcodeStr, !strconcat(Dt, "16"),
- v4i16, v4i16, OpNode, Commutable>;
+ OpcodeStr, !strconcat(Dt, "16"),
+ v4i16, v4i16, OpNode, Commutable>;
def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, itinD32,
- OpcodeStr, !strconcat(Dt, "32"),
- v2i32, v2i32, OpNode, Commutable>;
+ OpcodeStr, !strconcat(Dt, "32"),
+ v2i32, v2i32, OpNode, Commutable>;
// 128-bit vector types.
def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, itinQ16,
- OpcodeStr, !strconcat(Dt, "8"),
- v16i8, v16i8, OpNode, Commutable>;
+ OpcodeStr, !strconcat(Dt, "8"),
+ v16i8, v16i8, OpNode, Commutable>;
def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, itinQ16,
- OpcodeStr, !strconcat(Dt, "16"),
- v8i16, v8i16, OpNode, Commutable>;
+ OpcodeStr, !strconcat(Dt, "16"),
+ v8i16, v8i16, OpNode, Commutable>;
def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, itinQ32,
- OpcodeStr, !strconcat(Dt, "32"),
- v4i32, v4i32, OpNode, Commutable>;
+ OpcodeStr, !strconcat(Dt, "32"),
+ v4i32, v4i32, OpNode, Commutable>;
}
multiclass N3VSL_HS<bits<4> op11_8, string OpcodeStr, string Dt, SDNode ShOp> {
@@ -1372,7 +1343,7 @@ multiclass N3VIntSL_HS<bits<4> op11_8,
def v2i32 : N3VDIntSL<0b10, op11_8, itinD32,
OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp>;
def v8i16 : N3VQIntSL16<0b01, op11_8, itinQ16,
- OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>;
+ OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>;
def v4i32 : N3VQIntSL<0b10, op11_8, itinQ32,
OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, IntOp>;
}
@@ -1386,8 +1357,8 @@ multiclass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
: N3VInt_HS<op24, op23, op11_8, op4, itinD16, itinD32, itinQ16, itinQ32,
OpcodeStr, Dt, IntOp, Commutable> {
def v8i8 : N3VDInt<op24, op23, 0b00, op11_8, op4, itinD16,
- OpcodeStr, !strconcat(Dt, "8"),
- v8i8, v8i8, IntOp, Commutable>;
+ OpcodeStr, !strconcat(Dt, "8"),
+ v8i8, v8i8, IntOp, Commutable>;
def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, itinQ16,
OpcodeStr, !strconcat(Dt, "8"),
v16i8, v16i8, IntOp, Commutable>;
@@ -1402,11 +1373,11 @@ multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
: N3VInt_QHS<op24, op23, op11_8, op4, itinD16, itinD32, itinQ16, itinQ32,
OpcodeStr, Dt, IntOp, Commutable> {
def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, itinD32,
- OpcodeStr, !strconcat(Dt, "64"),
- v1i64, v1i64, IntOp, Commutable>;
+ OpcodeStr, !strconcat(Dt, "64"),
+ v1i64, v1i64, IntOp, Commutable>;
def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, itinQ32,
- OpcodeStr, !strconcat(Dt, "64"),
- v2i64, v2i64, IntOp, Commutable>;
+ OpcodeStr, !strconcat(Dt, "64"),
+ v2i64, v2i64, IntOp, Commutable>;
}
@@ -1511,9 +1482,11 @@ multiclass N3VMulOpSL_HS<bits<4> op11_8,
def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32,
OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, ShOp>;
def v8i16 : N3VQMulOpSL16<0b01, op11_8, itinQ16,
- OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, mul, ShOp>;
+ OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16,
+ mul, ShOp>;
def v4i32 : N3VQMulOpSL<0b10, op11_8, itinQ32,
- OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, mul, ShOp>;
+ OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32,
+ mul, ShOp>;
}
// Neon 3-argument intrinsics,
@@ -1522,19 +1495,19 @@ multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
string OpcodeStr, string Dt, Intrinsic IntOp> {
// 64-bit vector types.
def v8i8 : N3VDInt3<op24, op23, 0b00, op11_8, op4, IIC_VMACi16D,
- OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
+ OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, IIC_VMACi16D,
- OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;
+ OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;
def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, IIC_VMACi32D,
- OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;
+ OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;
// 128-bit vector types.
def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, IIC_VMACi16Q,
- OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
+ OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, IIC_VMACi16Q,
- OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;
+ OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;
def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, IIC_VMACi32Q,
- OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;
+ OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;
}
@@ -1576,17 +1549,17 @@ multiclass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
def v8i8 : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
itinD, OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
- itinD, OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;
+ itinD, OpcodeStr, !strconcat(Dt, "16"),v4i16,v4i16,IntOp>;
def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
- itinD, OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;
+ itinD, OpcodeStr, !strconcat(Dt, "32"),v2i32,v2i32,IntOp>;
// 128-bit vector types.
def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
- itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
+ itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8,v16i8,IntOp>;
def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
- itinQ, OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;
+ itinQ, OpcodeStr, !strconcat(Dt, "16"),v8i16,v8i16,IntOp>;
def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
- itinQ, OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;
+ itinQ, OpcodeStr, !strconcat(Dt, "32"),v4i32,v4i32,IntOp>;
}
@@ -1846,29 +1819,31 @@ def VMULpd : N3VDInt<1, 0, 0b00, 0b1001, 1, IIC_VMULi16D, "vmul", "p8",
def VMULpq : N3VQInt<1, 0, 0b00, 0b1001, 1, IIC_VMULi16Q, "vmul", "p8",
v16i8, v16i8, int_arm_neon_vmulp, 1>;
def VMULfd : N3VD<1, 0, 0b00, 0b1101, 1, IIC_VBIND, "vmul", "f32",
- v2f32, v2f32, fmul, 1>;
+ v2f32, v2f32, fmul, 1>;
def VMULfq : N3VQ<1, 0, 0b00, 0b1101, 1, IIC_VBINQ, "vmul", "f32",
- v4f32, v4f32, fmul, 1>;
-defm VMULsl : N3VSL_HS<0b1000, "vmul", "i", mul>;
-def VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>;
-def VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32, v2f32, fmul>;
+ v4f32, v4f32, fmul, 1>;
+defm VMULsl : N3VSL_HS<0b1000, "vmul", "i", mul>;
+def VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>;
+def VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32,
+ v2f32, fmul>;
+
def : Pat<(v8i16 (mul (v8i16 QPR:$src1),
(v8i16 (NEONvduplane (v8i16 QPR:$src2), imm:$lane)))),
(v8i16 (VMULslv8i16 (v8i16 QPR:$src1),
(v4i16 (EXTRACT_SUBREG QPR:$src2,
- (DSubReg_i16_reg imm:$lane))),
+ (DSubReg_i16_reg imm:$lane))),
(SubReg_i16_lane imm:$lane)))>;
def : Pat<(v4i32 (mul (v4i32 QPR:$src1),
(v4i32 (NEONvduplane (v4i32 QPR:$src2), imm:$lane)))),
(v4i32 (VMULslv4i32 (v4i32 QPR:$src1),
(v2i32 (EXTRACT_SUBREG QPR:$src2,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
def : Pat<(v4f32 (fmul (v4f32 QPR:$src1),
(v4f32 (NEONvduplane (v4f32 QPR:$src2), imm:$lane)))),
(v4f32 (VMULslfq (v4f32 QPR:$src1),
(v2f32 (EXTRACT_SUBREG QPR:$src2,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
// VQDMULH : Vector Saturating Doubling Multiply Returning High Half
@@ -1883,14 +1858,14 @@ def : Pat<(v8i16 (int_arm_neon_vqdmulh (v8i16 QPR:$src1),
imm:$lane)))),
(v8i16 (VQDMULHslv8i16 (v8i16 QPR:$src1),
(v4i16 (EXTRACT_SUBREG QPR:$src2,
- (DSubReg_i16_reg imm:$lane))),
+ (DSubReg_i16_reg imm:$lane))),
(SubReg_i16_lane imm:$lane)))>;
def : Pat<(v4i32 (int_arm_neon_vqdmulh (v4i32 QPR:$src1),
(v4i32 (NEONvduplane (v4i32 QPR:$src2),
imm:$lane)))),
(v4i32 (VQDMULHslv4i32 (v4i32 QPR:$src1),
(v2i32 (EXTRACT_SUBREG QPR:$src2,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
// VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half
@@ -1905,14 +1880,14 @@ def : Pat<(v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$src1),
imm:$lane)))),
(v8i16 (VQRDMULHslv8i16 (v8i16 QPR:$src1),
(v4i16 (EXTRACT_SUBREG QPR:$src2,
- (DSubReg_i16_reg imm:$lane))),
+ (DSubReg_i16_reg imm:$lane))),
(SubReg_i16_lane imm:$lane)))>;
def : Pat<(v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$src1),
(v4i32 (NEONvduplane (v4i32 QPR:$src2),
imm:$lane)))),
(v4i32 (VQRDMULHslv4i32 (v4i32 QPR:$src1),
(v2i32 (EXTRACT_SUBREG QPR:$src2,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
// VMULL : Vector Multiply Long (integer and polynomial) (Q = D * D)
@@ -1950,30 +1925,28 @@ def VMLAslfq : N3VQMulOpSL<0b10, 0b0001, IIC_VMACQ, "vmla", "f32",
v4f32, v2f32, fmul, fadd>;
def : Pat<(v8i16 (add (v8i16 QPR:$src1),
- (mul (v8i16 QPR:$src2),
- (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
- (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1),
- (v8i16 QPR:$src2),
+ (mul (v8i16 QPR:$src2),
+ (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
+ (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
(v4i16 (EXTRACT_SUBREG QPR:$src3,
- (DSubReg_i16_reg imm:$lane))),
+ (DSubReg_i16_reg imm:$lane))),
(SubReg_i16_lane imm:$lane)))>;
def : Pat<(v4i32 (add (v4i32 QPR:$src1),
- (mul (v4i32 QPR:$src2),
- (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
- (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1),
- (v4i32 QPR:$src2),
+ (mul (v4i32 QPR:$src2),
+ (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
+ (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
(v2i32 (EXTRACT_SUBREG QPR:$src3,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
def : Pat<(v4f32 (fadd (v4f32 QPR:$src1),
- (fmul (v4f32 QPR:$src2),
- (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
+ (fmul (v4f32 QPR:$src2),
+ (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
(v4f32 (VMLAslfq (v4f32 QPR:$src1),
(v4f32 QPR:$src2),
(v2f32 (EXTRACT_SUBREG QPR:$src3,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
// VMLAL : Vector Multiply Accumulate Long (Q += D * D)
@@ -2003,30 +1976,27 @@ def VMLSslfq : N3VQMulOpSL<0b10, 0b0101, IIC_VMACQ, "vmls", "f32",
v4f32, v2f32, fmul, fsub>;
def : Pat<(v8i16 (sub (v8i16 QPR:$src1),
- (mul (v8i16 QPR:$src2),
- (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
- (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1),
- (v8i16 QPR:$src2),
+ (mul (v8i16 QPR:$src2),
+ (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
+ (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
(v4i16 (EXTRACT_SUBREG QPR:$src3,
- (DSubReg_i16_reg imm:$lane))),
+ (DSubReg_i16_reg imm:$lane))),
(SubReg_i16_lane imm:$lane)))>;
def : Pat<(v4i32 (sub (v4i32 QPR:$src1),
- (mul (v4i32 QPR:$src2),
- (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
- (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1),
- (v4i32 QPR:$src2),
+ (mul (v4i32 QPR:$src2),
+ (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
+ (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
(v2i32 (EXTRACT_SUBREG QPR:$src3,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
def : Pat<(v4f32 (fsub (v4f32 QPR:$src1),
- (fmul (v4f32 QPR:$src2),
- (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
- (v4f32 (VMLSslfq (v4f32 QPR:$src1),
- (v4f32 QPR:$src2),
+ (fmul (v4f32 QPR:$src2),
+ (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
+ (v4f32 (VMLSslfq (v4f32 QPR:$src1), (v4f32 QPR:$src2),
(v2f32 (EXTRACT_SUBREG QPR:$src3,
- (DSubReg_i32_reg imm:$lane))),
+ (DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
// VMLSL : Vector Multiply Subtract Long (Q -= D * D)
@@ -2088,6 +2058,10 @@ def VCEQfd : N3VD<0,0,0b00,0b1110,0, IIC_VBIND, "vceq", "f32", v2i32, v2f32,
NEONvceq, 1>;
def VCEQfq : N3VQ<0,0,0b00,0b1110,0, IIC_VBINQ, "vceq", "f32", v4i32, v4f32,
NEONvceq, 1>;
+// For disassembly only.
+defm VCEQz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00010, 0, "vceq", "i",
+ "$dst, $src, #0">;
+
// VCGE : Vector Compare Greater Than or Equal
defm VCGEs : N3V_QHS<0, 0, 0b0011, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
IIC_VBINi4Q, "vcge", "s", NEONvcge, 0>;
@@ -2097,6 +2071,13 @@ def VCGEfd : N3VD<1,0,0b00,0b1110,0, IIC_VBIND, "vcge", "f32",
v2i32, v2f32, NEONvcge, 0>;
def VCGEfq : N3VQ<1,0,0b00,0b1110,0, IIC_VBINQ, "vcge", "f32", v4i32, v4f32,
NEONvcge, 0>;
+// For disassembly only.
+defm VCGEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00001, 0, "vcge", "s",
+ "$dst, $src, #0">;
+// For disassembly only.
+defm VCLEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00011, 0, "vcle", "s",
+ "$dst, $src, #0">;
+
// VCGT : Vector Compare Greater Than
defm VCGTs : N3V_QHS<0, 0, 0b0011, 0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
IIC_VBINi4Q, "vcgt", "s", NEONvcgt, 0>;
@@ -2106,6 +2087,13 @@ def VCGTfd : N3VD<1,0,0b10,0b1110,0, IIC_VBIND, "vcgt", "f32", v2i32, v2f32,
NEONvcgt, 0>;
def VCGTfq : N3VQ<1,0,0b10,0b1110,0, IIC_VBINQ, "vcgt", "f32", v4i32, v4f32,
NEONvcgt, 0>;
+// For disassembly only.
+defm VCGTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00000, 0, "vcgt", "s",
+ "$dst, $src, #0">;
+// For disassembly only.
+defm VCLTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00100, 0, "vclt", "s",
+ "$dst, $src, #0">;
+
// VACGE : Vector Absolute Compare Greater Than or Equal (aka VCAGE)
def VACGEd : N3VDInt<1, 0, 0b00, 0b1110, 1, IIC_VBIND, "vacge", "f32",
v2i32, v2f32, int_arm_neon_vacged, 0>;
@@ -2247,9 +2235,9 @@ defm VABALu : N3VLInt3_QHS<1,1,0b0101,0, "vabal", "u", int_arm_neon_vabalu>;
// Vector Maximum and Minimum.
// VMAX : Vector Maximum
-defm VMAXs : N3VInt_QHS<0, 0, 0b0110, 0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
+defm VMAXs : N3VInt_QHS<0,0,0b0110,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
IIC_VBINi4Q, "vmax", "s", int_arm_neon_vmaxs, 1>;
-defm VMAXu : N3VInt_QHS<1, 0, 0b0110, 0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
+defm VMAXu : N3VInt_QHS<1,0,0b0110,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
IIC_VBINi4Q, "vmax", "u", int_arm_neon_vmaxu, 1>;
def VMAXfd : N3VDInt<0, 0, 0b00, 0b1111, 0, IIC_VBIND, "vmax", "f32",
v2f32, v2f32, int_arm_neon_vmaxs, 1>;
@@ -2257,9 +2245,9 @@ def VMAXfq : N3VQInt<0, 0, 0b00, 0b1111, 0, IIC_VBINQ, "vmax", "f32",
v4f32, v4f32, int_arm_neon_vmaxs, 1>;
// VMIN : Vector Minimum
-defm VMINs : N3VInt_QHS<0, 0, 0b0110, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
+defm VMINs : N3VInt_QHS<0,0,0b0110,1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
IIC_VBINi4Q, "vmin", "s", int_arm_neon_vmins, 1>;
-defm VMINu : N3VInt_QHS<1, 0, 0b0110, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
+defm VMINu : N3VInt_QHS<1,0,0b0110,1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
IIC_VBINi4Q, "vmin", "u", int_arm_neon_vminu, 1>;
def VMINfd : N3VDInt<0, 0, 0b10, 0b1111, 0, IIC_VBIND, "vmin", "f32",
v2f32, v2f32, int_arm_neon_vmins, 1>;
@@ -2401,16 +2389,17 @@ def VSHLLi32 : N2VLShMax<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll", "i32",
v2i64, v2i32, NEONvshlli>;
// VSHRN : Vector Shift Right and Narrow
-defm VSHRN : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i", NEONvshrn>;
+defm VSHRN : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i",
+ NEONvshrn>;
// VRSHL : Vector Rounding Shift
defm VRSHLs : N3VInt_QHSD<0,0,0b0101,0, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vrshl", "s", int_arm_neon_vrshifts, 0>;
+ IIC_VSHLi4Q, "vrshl", "s", int_arm_neon_vrshifts,0>;
defm VRSHLu : N3VInt_QHSD<1,0,0b0101,0, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vrshl", "u", int_arm_neon_vrshiftu, 0>;
+ IIC_VSHLi4Q, "vrshl", "u", int_arm_neon_vrshiftu,0>;
// VRSHR : Vector Rounding Shift Right
-defm VRSHRs : N2VSh_QHSD<0, 1, 0b0010, 1, IIC_VSHLi4D, "vrshr", "s", NEONvrshrs>;
-defm VRSHRu : N2VSh_QHSD<1, 1, 0b0010, 1, IIC_VSHLi4D, "vrshr", "u", NEONvrshru>;
+defm VRSHRs : N2VSh_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s", NEONvrshrs>;
+defm VRSHRu : N2VSh_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u", NEONvrshru>;
// VRSHRN : Vector Rounding Shift Right and Narrow
defm VRSHRN : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i",
@@ -2418,14 +2407,14 @@ defm VRSHRN : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i",
// VQSHL : Vector Saturating Shift
defm VQSHLs : N3VInt_QHSD<0,0,0b0100,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vqshl", "s", int_arm_neon_vqshifts, 0>;
+ IIC_VSHLi4Q, "vqshl", "s", int_arm_neon_vqshifts,0>;
defm VQSHLu : N3VInt_QHSD<1,0,0b0100,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
- IIC_VSHLi4Q, "vqshl", "u", int_arm_neon_vqshiftu, 0>;
+ IIC_VSHLi4Q, "vqshl", "u", int_arm_neon_vqshiftu,0>;
// VQSHL : Vector Saturating Shift Left (Immediate)
-defm VQSHLsi : N2VSh_QHSD<0, 1, 0b0111, 1, IIC_VSHLi4D, "vqshl", "s", NEONvqshls>;
-defm VQSHLui : N2VSh_QHSD<1, 1, 0b0111, 1, IIC_VSHLi4D, "vqshl", "u", NEONvqshlu>;
+defm VQSHLsi : N2VSh_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s", NEONvqshls>;
+defm VQSHLui : N2VSh_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u", NEONvqshlu>;
// VQSHLU : Vector Saturating Shift Left (Immediate, Unsigned)
-defm VQSHLsu : N2VSh_QHSD<1, 1, 0b0110, 1, IIC_VSHLi4D, "vqshlu", "s", NEONvqshlsu>;
+defm VQSHLsu : N2VSh_QHSD<1,1,0b0110,1, IIC_VSHLi4D, "vqshlu","s",NEONvqshlsu>;
// VQSHRN : Vector Saturating Shift Right and Narrow
defm VQSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s",
@@ -2438,10 +2427,10 @@ defm VQSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 0, 1, IIC_VSHLi4D, "vqshrun", "s",
NEONvqshrnsu>;
// VQRSHL : Vector Saturating Rounding Shift
-defm VQRSHLs : N3VInt_QHSD<0, 0, 0b0101, 1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+defm VQRSHLs : N3VInt_QHSD<0,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
IIC_VSHLi4Q, "vqrshl", "s",
int_arm_neon_vqrshifts, 0>;
-defm VQRSHLu : N3VInt_QHSD<1, 0, 0b0101, 1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
+defm VQRSHLu : N3VInt_QHSD<1,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
IIC_VSHLi4Q, "vqrshl", "u",
int_arm_neon_vqrshiftu, 0>;
@@ -2508,7 +2497,7 @@ def VNEGs16q : VNEGQ<0b01, "vneg", "s16", v8i16>;
def VNEGs32q : VNEGQ<0b10, "vneg", "s32", v4i32>;
// VNEG : Vector Negate (floating-point)
-def VNEGf32d : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
+def VNEGfd : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
(outs DPR:$dst), (ins DPR:$src), IIC_VUNAD,
"vneg", "f32", "$dst, $src", "",
[(set DPR:$dst, (v2f32 (fneg DPR:$src)))]>;
@@ -2547,6 +2536,14 @@ def VCNTq : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,
IIC_VCNTiQ, "vcnt", "8",
v16i8, v16i8, int_arm_neon_vcnt>;
+// Vector Swap -- for disassembly only.
+def VSWPd : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0,
+ (outs DPR:$dst), (ins DPR:$src), NoItinerary,
+ "vswp", "$dst, $src", "", []>;
+def VSWPq : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0,
+ (outs QPR:$dst), (ins QPR:$src), NoItinerary,
+ "vswp", "$dst, $src", "", []>;
+
// Vector Move Operations.
// VMOV : Vector Move (Register)
@@ -2678,10 +2675,10 @@ def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),
(DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane))>;
def : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2),
- (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1), DPR_VFP2)),
+ (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1),DPR_VFP2)),
(SSubReg_f32_reg imm:$src2))>;
def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2),
- (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1), QPR_VFP2)),
+ (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1),QPR_VFP2)),
(SSubReg_f32_reg imm:$src2))>;
//def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2),
// (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;
@@ -2849,11 +2846,13 @@ def VDUPfqf : N2V<0b11, 0b11, {?,1}, {0,0}, 0b11000, 1, 0,
def : Pat<(v2i64 (NEONvduplane (v2i64 QPR:$src), imm:$lane)),
(INSERT_SUBREG QPR:$src,
- (i64 (EXTRACT_SUBREG QPR:$src, (DSubReg_f64_reg imm:$lane))),
+ (i64 (EXTRACT_SUBREG QPR:$src,
+ (DSubReg_f64_reg imm:$lane))),
(DSubReg_f64_other_reg imm:$lane))>;
def : Pat<(v2f64 (NEONvduplane (v2f64 QPR:$src), imm:$lane)),
(INSERT_SUBREG QPR:$src,
- (f64 (EXTRACT_SUBREG QPR:$src, (DSubReg_f64_reg imm:$lane))),
+ (f64 (EXTRACT_SUBREG QPR:$src,
+ (DSubReg_f64_reg imm:$lane))),
(DSubReg_f64_other_reg imm:$lane))>;
// VMOVN : Vector Narrowing Move
@@ -3092,70 +3091,110 @@ def VTBX4
// NEON instructions for single-precision FP math
//===----------------------------------------------------------------------===//
+class N2VSPat<SDNode OpNode, ValueType ResTy, ValueType OpTy, NeonI Inst>
+ : NEONFPPat<(ResTy (OpNode SPR:$a)),
+ (EXTRACT_SUBREG (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)),
+ SPR:$a, arm_ssubreg_0)),
+ arm_ssubreg_0)>;
+
+class N3VSPat<SDNode OpNode, NeonI Inst>
+ : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)),
+ (EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
+ SPR:$a, arm_ssubreg_0),
+ (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
+ SPR:$b, arm_ssubreg_0)),
+ arm_ssubreg_0)>;
+
+class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst>
+ : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))),
+ (EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
+ SPR:$acc, arm_ssubreg_0),
+ (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
+ SPR:$a, arm_ssubreg_0),
+ (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
+ SPR:$b, arm_ssubreg_0)),
+ arm_ssubreg_0)>;
+
// These need separate instructions because they must use DPR_VFP2 register
// class which have SPR sub-registers.
// Vector Add Operations used for single-precision FP
let neverHasSideEffects = 1 in
-def VADDfd_sfp : N3VDs<0, 0, 0b00, 0b1101, 0, "vadd", "f32", v2f32, v2f32, fadd,1>;
-def : N3VDsPat<fadd, VADDfd_sfp>;
+def VADDfd_sfp : N3VS<0,0,0b00,0b1101,0, "vadd", "f32", v2f32, v2f32, fadd, 1>;
+def : N3VSPat<fadd, VADDfd_sfp>;
// Vector Sub Operations used for single-precision FP
let neverHasSideEffects = 1 in
-def VSUBfd_sfp : N3VDs<0, 0, 0b10, 0b1101, 0, "vsub", "f32", v2f32, v2f32, fsub,0>;
-def : N3VDsPat<fsub, VSUBfd_sfp>;
+def VSUBfd_sfp : N3VS<0,0,0b10,0b1101,0, "vsub", "f32", v2f32, v2f32, fsub, 0>;
+def : N3VSPat<fsub, VSUBfd_sfp>;
// Vector Multiply Operations used for single-precision FP
let neverHasSideEffects = 1 in
-def VMULfd_sfp : N3VDs<1, 0, 0b00, 0b1101, 1, "vmul", "f32", v2f32, v2f32, fmul,1>;
-def : N3VDsPat<fmul, VMULfd_sfp>;
+def VMULfd_sfp : N3VS<1,0,0b00,0b1101,1, "vmul", "f32", v2f32, v2f32, fmul, 1>;
+def : N3VSPat<fmul, VMULfd_sfp>;
// Vector Multiply-Accumulate/Subtract used for single-precision FP
// vml[as].f32 can cause 4-8 cycle stalls in following ASIMD instructions, so
// we want to avoid them for now. e.g., alternating vmla/vadd instructions.
//let neverHasSideEffects = 1 in
-//def VMLAfd_sfp : N3VDMulOps<0, 0, 0b00, 0b1101, 1, IIC_VMACD, "vmla", "f32", v2f32,fmul,fadd>;
-//def : N3VDMulOpsPat<fmul, fadd, VMLAfd_sfp>;
+//def VMLAfd_sfp : N3VSMulOp<0,0,0b00,0b1101,1, IIC_VMACD, "vmla", "f32",
+// v2f32, fmul, fadd>;
+//def : N3VSMulOpPat<fmul, fadd, VMLAfd_sfp>;
//let neverHasSideEffects = 1 in
-//def VMLSfd_sfp : N3VDMulOps<0, 0, 0b10, 0b1101, 1, IIC_VMACD, "vmls", "f32", v2f32,fmul,fsub>;
-//def : N3VDMulOpsPat<fmul, fsub, VMLSfd_sfp>;
+//def VMLSfd_sfp : N3VSMulOp<0,0,0b10,0b1101,1, IIC_VMACD, "vmls", "f32",
+// v2f32, fmul, fsub>;
+//def : N3VSMulOpPat<fmul, fsub, VMLSfd_sfp>;
// Vector Absolute used for single-precision FP
let neverHasSideEffects = 1 in
-def VABSfd_sfp : N2VDInts<0b11, 0b11, 0b10, 0b01, 0b01110, 0,
- IIC_VUNAD, "vabs", "f32",
- v2f32, v2f32, int_arm_neon_vabs>;
-def : N2VDIntsPat<fabs, VABSfd_sfp>;
+def VABSfd_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01110, 0, 0,
+ (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), IIC_VUNAD,
+ "vabs", "f32", "$dst, $src", "", []>;
+def : N2VSPat<fabs, f32, v2f32, VABSfd_sfp>;
// Vector Negate used for single-precision FP
let neverHasSideEffects = 1 in
-def VNEGf32d_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
- (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), IIC_VUNAD,
- "vneg", "f32", "$dst, $src", "", []>;
-def : N2VDIntsPat<fneg, VNEGf32d_sfp>;
+def VNEGfd_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
+ (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), IIC_VUNAD,
+ "vneg", "f32", "$dst, $src", "", []>;
+def : N2VSPat<fneg, f32, v2f32, VNEGfd_sfp>;
+
+// Vector Maximum used for single-precision FP
+let neverHasSideEffects = 1 in
+def VMAXfd_sfp : N3V<0, 0, 0b00, 0b1111, 0, 0, (outs DPR_VFP2:$dst),
+ (ins DPR_VFP2:$src1, DPR_VFP2:$src2), IIC_VBIND,
+ "vmax", "f32", "$dst, $src1, $src2", "", []>;
+def : N3VSPat<NEONfmax, VMAXfd_sfp>;
+
+// Vector Minimum used for single-precision FP
+let neverHasSideEffects = 1 in
+def VMINfd_sfp : N3V<0, 0, 0b00, 0b1111, 0, 0, (outs DPR_VFP2:$dst),
+ (ins DPR_VFP2:$src1, DPR_VFP2:$src2), IIC_VBIND,
+ "vmin", "f32", "$dst, $src1, $src2", "", []>;
+def : N3VSPat<NEONfmin, VMINfd_sfp>;
// Vector Convert between single-precision FP and integer
let neverHasSideEffects = 1 in
-def VCVTf2sd_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
- v2i32, v2f32, fp_to_sint>;
-def : N2VDsPat<arm_ftosi, f32, v2f32, VCVTf2sd_sfp>;
+def VCVTf2sd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
+ v2i32, v2f32, fp_to_sint>;
+def : N2VSPat<arm_ftosi, f32, v2f32, VCVTf2sd_sfp>;
let neverHasSideEffects = 1 in
-def VCVTf2ud_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
- v2i32, v2f32, fp_to_uint>;
-def : N2VDsPat<arm_ftoui, f32, v2f32, VCVTf2ud_sfp>;
+def VCVTf2ud_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
+ v2i32, v2f32, fp_to_uint>;
+def : N2VSPat<arm_ftoui, f32, v2f32, VCVTf2ud_sfp>;
let neverHasSideEffects = 1 in
-def VCVTs2fd_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
- v2f32, v2i32, sint_to_fp>;
-def : N2VDsPat<arm_sitof, f32, v2i32, VCVTs2fd_sfp>;
+def VCVTs2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
+ v2f32, v2i32, sint_to_fp>;
+def : N2VSPat<arm_sitof, f32, v2i32, VCVTs2fd_sfp>;
let neverHasSideEffects = 1 in
-def VCVTu2fd_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
- v2f32, v2i32, uint_to_fp>;
-def : N2VDsPat<arm_uitof, f32, v2i32, VCVTu2fd_sfp>;
+def VCVTu2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
+ v2f32, v2i32, uint_to_fp>;
+def : N2VSPat<arm_uitof, f32, v2i32, VCVTu2fd_sfp>;
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 1dcea26..786dd65 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -120,7 +120,10 @@ def t_addrmode_sp : Operand<i32>,
// Miscellaneous Instructions.
//
-let Defs = [SP], Uses = [SP] in {
+// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
+// from removing one half of the matched pairs. That breaks PEI, which assumes
+// these will always be in pairs, and asserts if it finds otherwise. Better way?
+let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
def tADJCALLSTACKUP :
PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
"@ tADJCALLSTACKUP $amt1",
@@ -132,6 +135,76 @@ PseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
[(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>;
}
+def tNOP : T1pI<(outs), (ins), NoItinerary, "nop", "",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101111> {
+ let Inst{9-8} = 0b11;
+ let Inst{7-0} = 0b00000000;
+}
+
+def tYIELD : T1pI<(outs), (ins), NoItinerary, "yield", "",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101111> {
+ let Inst{9-8} = 0b11;
+ let Inst{7-0} = 0b00010000;
+}
+
+def tWFE : T1pI<(outs), (ins), NoItinerary, "wfe", "",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101111> {
+ let Inst{9-8} = 0b11;
+ let Inst{7-0} = 0b00100000;
+}
+
+def tWFI : T1pI<(outs), (ins), NoItinerary, "wfi", "",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101111> {
+ let Inst{9-8} = 0b11;
+ let Inst{7-0} = 0b00110000;
+}
+
+def tSEV : T1pI<(outs), (ins), NoItinerary, "sev", "",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101111> {
+ let Inst{9-8} = 0b11;
+ let Inst{7-0} = 0b01000000;
+}
+
+def tSETENDBE : T1I<(outs), (ins), NoItinerary, "setend\tbe",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101101> {
+ let Inst{9-5} = 0b10010;
+ let Inst{3} = 1;
+}
+
+def tSETENDLE : T1I<(outs), (ins), NoItinerary, "setend\tle",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101101> {
+ let Inst{9-5} = 0b10010;
+ let Inst{3} = 0;
+}
+
+// The i32imm operand $val can be used by a debugger to store more information
+// about the breakpoint.
+def tBKPT : T1I<(outs), (ins i32imm:$val), NoItinerary, "bkpt\t$val",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101111> {
+ let Inst{9-8} = 0b10;
+}
+
+// Change Processor State is a system instruction -- for disassembly only.
+// The singleton $opt operand contains the following information:
+// opt{4-0} = mode ==> don't care
+// opt{5} = changemode ==> 0 (false for 16-bit Thumb instr)
+// opt{8-6} = AIF from Inst{2-0}
+// opt{10-9} = 1:imod from Inst{4} with 0b10 as enable and 0b11 as disable
+//
+// The opt{4-0} and opt{5} sub-fields are to accommodate 32-bit Thumb and ARM
+// CPS which has more options.
+def tCPS : T1I<(outs), (ins i32imm:$opt), NoItinerary, "cps${opt:cps}",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Misc<0b0110011>;
+
// For both thumb1 and thumb2.
let isNotDuplicable = 1 in
def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr,
@@ -200,7 +273,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
let Inst{6-3} = 0b1110; // Rm = lr
}
// Alternative return instruction used by vararg functions.
- def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>,
+ def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target",[]>,
T1Special<{1,1,0,?}>; // A6.2.3 & A8.6.25
}
@@ -228,20 +301,20 @@ let isCall = 1,
D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
// Also used for Thumb2
def tBL : TIx2<0b11110, 0b11, 1,
- (outs), (ins i32imm:$func, variable_ops), IIC_Br,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
"bl\t${func:call}",
[(ARMtcall tglobaladdr:$func)]>,
Requires<[IsThumb, IsNotDarwin]>;
// ARMv5T and above, also used for Thumb2
def tBLXi : TIx2<0b11110, 0b11, 0,
- (outs), (ins i32imm:$func, variable_ops), IIC_Br,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
"blx\t${func:call}",
[(ARMcall tglobaladdr:$func)]>,
Requires<[IsThumb, HasV5T, IsNotDarwin]>;
// Also used for Thumb2
- def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br,
+ def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br,
"blx\t$func",
[(ARMtcall GPR:$func)]>,
Requires<[IsThumb, HasV5T, IsNotDarwin]>,
@@ -249,7 +322,7 @@ let isCall = 1,
// ARMv4T
def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?,
- (outs), (ins tGPR:$func, variable_ops), IIC_Br,
+ (outs), (ins tGPR:$func, variable_ops), IIC_Br,
"mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsThumb1Only, IsNotDarwin]>;
@@ -263,20 +336,20 @@ let isCall = 1,
D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
// Also used for Thumb2
def tBLr9 : TIx2<0b11110, 0b11, 1,
- (outs), (ins i32imm:$func, variable_ops), IIC_Br,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
"bl\t${func:call}",
[(ARMtcall tglobaladdr:$func)]>,
Requires<[IsThumb, IsDarwin]>;
// ARMv5T and above, also used for Thumb2
def tBLXi_r9 : TIx2<0b11110, 0b11, 0,
- (outs), (ins i32imm:$func, variable_ops), IIC_Br,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
"blx\t${func:call}",
[(ARMcall tglobaladdr:$func)]>,
Requires<[IsThumb, HasV5T, IsDarwin]>;
// Also used for Thumb2
- def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br,
+ def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br,
"blx\t$func",
[(ARMtcall GPR:$func)]>,
Requires<[IsThumb, HasV5T, IsDarwin]>,
@@ -284,7 +357,7 @@ let isCall = 1,
// ARMv4T
def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?,
- (outs), (ins tGPR:$func, variable_ops), IIC_Br,
+ (outs), (ins tGPR:$func, variable_ops), IIC_Br,
"mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsThumb1Only, IsDarwin]>;
@@ -299,7 +372,7 @@ let isBranch = 1, isTerminator = 1 in {
// Far jump
let Defs = [LR] in
- def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
+ def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
"bl\t$target\t@ far jump",[]>;
def tBR_JTr : T1JTI<(outs),
@@ -332,16 +405,34 @@ let isBranch = 1, isTerminator = 1 in {
T1Misc<{1,0,?,1,?,?,?}>;
}
+// A8.6.218 Supervisor Call (Software Interrupt) -- for disassembly only
+// A8.6.16 B: Encoding T1
+// If Inst{11-8} == 0b1111 then SEE SVC
+let isCall = 1 in {
+def tSVC : T1pI<(outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", []>,
+ Encoding16 {
+ let Inst{15-12} = 0b1101;
+ let Inst{11-8} = 0b1111;
+}
+}
+
+// A8.6.16 B: Encoding T1 -- for disassembly only
+// If Inst{11-8} == 0b1110 then UNDEFINED
+def tTRAP : T1I<(outs), (ins), IIC_Br, "trap", []>, Encoding16 {
+ let Inst{15-12} = 0b1101;
+ let Inst{11-8} = 0b1110;
+}
+
//===----------------------------------------------------------------------===//
// Load Store Instructions.
//
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
-def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
+let canFoldAsLoad = 1, isReMaterializable = 1 in
+def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
"ldr", "\t$dst, $addr",
[(set tGPR:$dst, (load t_addrmode_s4:$addr))]>,
T1LdSt<0b100>;
-def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
+def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
"ldr", "\t$dst, $addr",
[]>,
T1LdSt4Imm<{1,?,?}>;
@@ -391,15 +482,14 @@ def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
// Load tconstpool
// FIXME: Use ldr.n to work around a Darwin assembler bug.
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
"ldr", ".n\t$dst, $addr",
[(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>,
T1Encoding<{0,1,0,0,1,?}>; // A6.2 & A8.6.59
// Special LDR for loads from non-pc-relative constpools.
-let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
- mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
"ldr", "\t$dst, $addr", []>,
T1LdStSP<{1,?,?}>;
@@ -644,7 +734,7 @@ def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
// multiply register
let isCommutable = 1 in
def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32,
- "mul", "\t$dst, $rhs",
+ "mul", "\t$dst, $rhs, $dst", /* A8.6.105 MUL Encoding T1 */
[(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>,
T1DataProcessing<0b1101>;
@@ -761,7 +851,7 @@ def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
T1Misc<{0,0,1,0,1,0,?}>;
-// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
+// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC operation.
// Expanded after instruction selection into a branch sequence.
let usesCustomInserter = 1 in // Expanded after instruction selection.
def tMOVCCr_pseudo :
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 55c7aa2..6241766 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -13,7 +13,7 @@
// IT block predicate field
def it_pred : Operand<i32> {
- let PrintMethod = "printPredicateOperand";
+ let PrintMethod = "printMandatoryPredicateOperand";
}
// IT block condition mask
@@ -53,10 +53,10 @@ def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
// bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
def t2_so_imm : Operand<i32>,
PatLeaf<(imm), [{
- return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
+ return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
}]>;
-// t2_so_imm_not - Match an immediate that is a complement
+// t2_so_imm_not - Match an immediate that is a complement
// of a t2_so_imm.
def t2_so_imm_not : Operand<i32>,
PatLeaf<(imm), [{
@@ -114,13 +114,13 @@ def imm0_4095 : Operand<i32>,
return (uint32_t)N->getZExtValue() < 4096;
}]>;
-def imm0_4095_neg : PatLeaf<(i32 imm), [{
- return (uint32_t)(-N->getZExtValue()) < 4096;
-}], imm_neg_XFORM>;
+def imm0_4095_neg : PatLeaf<(i32 imm), [{
+ return (uint32_t)(-N->getZExtValue()) < 4096;
+}], imm_neg_XFORM>;
def imm0_255_neg : PatLeaf<(i32 imm), [{
return (uint32_t)(-N->getZExtValue()) < 255;
-}], imm_neg_XFORM>;
+}], imm_neg_XFORM>;
// Define Thumb2 specific addressing modes.
@@ -131,7 +131,7 @@ def t2addrmode_imm12 : Operand<i32>,
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
-// t2addrmode_imm8 := reg - imm8
+// t2addrmode_imm8 := reg +/- imm8
def t2addrmode_imm8 : Operand<i32>,
ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
let PrintMethod = "printT2AddrModeImm8Operand";
@@ -208,7 +208,7 @@ multiclass T2I_un_irs<bits<4> opcod, string opc, PatFrag opnode,
/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
// binary operation that produces a value. These are predicable and can be
/// changed to modify CPSR.
-multiclass T2I_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
+multiclass T2I_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
bit Commutable = 0, string wide =""> {
// shifted imm
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
@@ -368,15 +368,16 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
}
/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
-/// for a binary operation that produces a value and use and define the carry
+/// for a binary operation that produces a value and use the carry
/// bit. It's not predicable.
let Uses = [CPSR] in {
-multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, bit Commutable = 0> {
+multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
+ bit Commutable = 0> {
// shifted imm
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
opc, "\t$dst, $lhs, $rhs",
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
- Requires<[IsThumb2, CarryDefIsUnused]> {
+ Requires<[IsThumb2]> {
let Inst{31-27} = 0b11110;
let Inst{25} = 0;
let Inst{24-21} = opcod;
@@ -387,7 +388,7 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, bit Comm
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
opc, ".w\t$dst, $lhs, $rhs",
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
- Requires<[IsThumb2, CarryDefIsUnused]> {
+ Requires<[IsThumb2]> {
let isCommutable = Commutable;
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
@@ -401,19 +402,23 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, bit Comm
def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
opc, ".w\t$dst, $lhs, $rhs",
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
- Requires<[IsThumb2, CarryDefIsUnused]> {
+ Requires<[IsThumb2]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-21} = opcod;
let Inst{20} = 0; // The S bit.
}
- // Carry setting variants
+}
+
+// Carry setting variants
+let Defs = [CPSR] in {
+multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode,
+ bit Commutable = 0> {
// shifted imm
- def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
- !strconcat(opc, "s\t$dst, $lhs, $rhs"),
- [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
- Requires<[IsThumb2, CarryDefIsUsed]> {
- let Defs = [CPSR];
+ def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
+ opc, "\t$dst, $lhs, $rhs",
+ [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
+ Requires<[IsThumb2]> {
let Inst{31-27} = 0b11110;
let Inst{25} = 0;
let Inst{24-21} = opcod;
@@ -421,11 +426,10 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, bit Comm
let Inst{15} = 0;
}
// register
- def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
- !strconcat(opc, "s.w\t$dst, $lhs, $rhs"),
- [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
- Requires<[IsThumb2, CarryDefIsUsed]> {
- let Defs = [CPSR];
+ def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
+ opc, ".w\t$dst, $lhs, $rhs",
+ [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
+ Requires<[IsThumb2]> {
let isCommutable = Commutable;
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
@@ -436,11 +440,10 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, bit Comm
let Inst{5-4} = 0b00; // type
}
// shifted register
- def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
- !strconcat(opc, "s.w\t$dst, $lhs, $rhs"),
- [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
- Requires<[IsThumb2, CarryDefIsUsed]> {
- let Defs = [CPSR];
+ def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
+ opc, ".w\t$dst, $lhs, $rhs",
+ [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
+ Requires<[IsThumb2]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-21} = opcod;
@@ -448,6 +451,7 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, bit Comm
}
}
}
+}
/// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
let Defs = [CPSR] in {
@@ -626,19 +630,6 @@ multiclass T2I_st<bits<2> opcod, string opc, PatFrag opnode> {
}
}
-/// T2I_picld - Defines the PIC load pattern.
-class T2I_picld<string opc, PatFrag opnode> :
- T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi,
- !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr",
- [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
-
-/// T2I_picst - Defines the PIC store pattern.
-class T2I_picst<string opc, PatFrag opnode> :
- T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer,
- !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr",
- [(opnode GPR:$src, addrmodepc:$addr)]>;
-
-
/// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
/// register and one whose operand is a register rotated by 8/16/24.
multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
@@ -666,6 +657,57 @@ multiclass T2I_unary_rrot<bits<3> opcod, string opc, PatFrag opnode> {
}
}
+// SXTB16 and UXTB16 do not need the .w qualifier.
+multiclass T2I_unary_rrot_nw<bits<3> opcod, string opc, PatFrag opnode> {
+ def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
+ opc, "\t$dst, $src",
+ [(set GPR:$dst, (opnode GPR:$src))]> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0100;
+ let Inst{22-20} = opcod;
+ let Inst{19-16} = 0b1111; // Rn
+ let Inst{15-12} = 0b1111;
+ let Inst{7} = 1;
+ let Inst{5-4} = 0b00; // rotate
+ }
+ def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
+ opc, "\t$dst, $src, ror $rot",
+ [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0100;
+ let Inst{22-20} = opcod;
+ let Inst{19-16} = 0b1111; // Rn
+ let Inst{15-12} = 0b1111;
+ let Inst{7} = 1;
+ let Inst{5-4} = {?,?}; // rotate
+ }
+}
+
+// DO variant - disassembly only, no pattern
+
+multiclass T2I_unary_rrot_DO<bits<3> opcod, string opc> {
+ def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
+ opc, "\t$dst, $src", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0100;
+ let Inst{22-20} = opcod;
+ let Inst{19-16} = 0b1111; // Rn
+ let Inst{15-12} = 0b1111;
+ let Inst{7} = 1;
+ let Inst{5-4} = 0b00; // rotate
+ }
+ def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
+ opc, "\t$dst, $src, ror $rot", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0100;
+ let Inst{22-20} = opcod;
+ let Inst{19-16} = 0b1111; // Rn
+ let Inst{15-12} = 0b1111;
+ let Inst{7} = 1;
+ let Inst{5-4} = {?,?}; // rotate
+ }
+}
+
/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
/// register and one whose operand is a register rotated by 8/16/24.
multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
@@ -692,6 +734,29 @@ multiclass T2I_bin_rrot<bits<3> opcod, string opc, PatFrag opnode> {
}
}
+// DO variant - disassembly only, no pattern
+
+multiclass T2I_bin_rrot_DO<bits<3> opcod, string opc> {
+ def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
+ opc, "\t$dst, $LHS, $RHS", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0100;
+ let Inst{22-20} = opcod;
+ let Inst{15-12} = 0b1111;
+ let Inst{7} = 1;
+ let Inst{5-4} = 0b00; // rotate
+ }
+ def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
+ IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0100;
+ let Inst{22-20} = opcod;
+ let Inst{15-12} = 0b1111;
+ let Inst{7} = 1;
+ let Inst{5-4} = {?,?}; // rotate
+ }
+}
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -734,7 +799,7 @@ def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
let Inst{19-16} = 0b1101; // Rn = sp
let Inst{15} = 0;
}
-def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
+def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
IIC_iALUi, "addw", "\t$dst, $sp, $imm", []> {
let Inst{31-27} = 0b11110;
let Inst{25} = 1;
@@ -787,6 +852,25 @@ def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
let Inst{15} = 0;
}
+// Signed and unsigned division, for disassembly only
+def t2SDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
+ "sdiv", "\t$dst, $a, $b", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-21} = 0b011100;
+ let Inst{20} = 0b1;
+ let Inst{15-12} = 0b1111;
+ let Inst{7-4} = 0b1111;
+}
+
+def t2UDIV : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALUi,
+ "udiv", "\t$dst, $a, $b", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-21} = 0b011101;
+ let Inst{20} = 0b1;
+ let Inst{15-12} = 0b1111;
+ let Inst{7-4} = 0b1111;
+}
+
// Pseudo instruction that will expand into a t2SUBrSPi + a copy.
let usesCustomInserter = 1 in { // Expanded after instruction selection.
def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
@@ -803,7 +887,7 @@ def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
//
// Load
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
defm t2LDR : T2I_ld<0, 0b10, "ldr", UnOpFrag<(load node:$Src)>>;
// Loads with zero extension
@@ -925,10 +1009,32 @@ def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb),
[]>;
}
+// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
+// for disassembly only.
+// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
+class T2IldT<bit signed, bits<2> type, string opc>
+ : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi, opc,
+ "\t$dst, $addr", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-25} = 0b00;
+ let Inst{24} = signed;
+ let Inst{23} = 0;
+ let Inst{22-21} = type;
+ let Inst{20} = 1; // load
+ let Inst{11} = 1;
+ let Inst{10-8} = 0b110; // PUW.
+}
+
+def t2LDRT : T2IldT<0, 0b10, "ldrt">;
+def t2LDRBT : T2IldT<0, 0b00, "ldrbt">;
+def t2LDRHT : T2IldT<0, 0b01, "ldrht">;
+def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt">;
+def t2LDRSHT : T2IldT<1, 0b01, "ldrsht">;
+
// Store
-defm t2STR : T2I_st<0b10, "str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
-defm t2STRB : T2I_st<0b00, "strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
-defm t2STRH : T2I_st<0b01, "strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
+defm t2STR :T2I_st<0b10,"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
+defm t2STRB:T2I_st<0b00,"strb",BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
+defm t2STRH:T2I_st<0b01,"strh",BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
// Store doubleword
let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in
@@ -979,9 +1085,98 @@ def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
[(set GPR:$base_wb,
(post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
+// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
+// only.
+// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
+class T2IstT<bits<2> type, string opc>
+ : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), IIC_iStorei, opc,
+ "\t$src, $addr", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-25} = 0b00;
+ let Inst{24} = 0; // not signed
+ let Inst{23} = 0;
+ let Inst{22-21} = type;
+ let Inst{20} = 0; // store
+ let Inst{11} = 1;
+ let Inst{10-8} = 0b110; // PUW
+}
+
+def t2STRT : T2IstT<0b10, "strt">;
+def t2STRBT : T2IstT<0b00, "strbt">;
+def t2STRHT : T2IstT<0b01, "strht">;
// FIXME: ldrd / strd pre / post variants
+// T2Ipl (Preload Data/Instruction) signals the memory system of possible future
+// data/instruction access. These are for disassembly only.
+multiclass T2Ipl<bit instr, bit write, string opc> {
+
+ def i12 : T2I<(outs), (ins t2addrmode_imm12:$addr), IIC_iLoadi, opc,
+ "\t$addr", []> {
+ let Inst{31-25} = 0b1111100;
+ let Inst{24} = instr;
+ let Inst{23} = 1; // U = 1
+ let Inst{22} = 0;
+ let Inst{21} = write;
+ let Inst{20} = 1;
+ let Inst{15-12} = 0b1111;
+ }
+
+ def i8 : T2I<(outs), (ins t2addrmode_imm8:$addr), IIC_iLoadi, opc,
+ "\t$addr", []> {
+ let Inst{31-25} = 0b1111100;
+ let Inst{24} = instr;
+ let Inst{23} = 0; // U = 0
+ let Inst{22} = 0;
+ let Inst{21} = write;
+ let Inst{20} = 1;
+ let Inst{15-12} = 0b1111;
+ let Inst{11-8} = 0b1100;
+ }
+
+ // A8.6.118 #0 and #-0 differs. Translates -0 to -1, -1 to -2, ..., etc.
+ def pci : T2I<(outs), (ins GPR:$base, i32imm:$imm), IIC_iLoadi, opc,
+ "\t[pc, ${imm:negzero}]", []> {
+ let Inst{31-25} = 0b1111100;
+ let Inst{24} = instr;
+ let Inst{23} = ?; // add = (U == 1)
+ let Inst{22} = 0;
+ let Inst{21} = write;
+ let Inst{20} = 1;
+ let Inst{19-16} = 0b1111; // Rn = 0b1111
+ let Inst{15-12} = 0b1111;
+ }
+
+ def r : T2I<(outs), (ins GPR:$base, GPR:$a), IIC_iLoadi, opc,
+ "\t[$base, $a]", []> {
+ let Inst{31-25} = 0b1111100;
+ let Inst{24} = instr;
+ let Inst{23} = 0; // add = TRUE for T1
+ let Inst{22} = 0;
+ let Inst{21} = write;
+ let Inst{20} = 1;
+ let Inst{15-12} = 0b1111;
+ let Inst{11-6} = 0000000;
+ let Inst{5-4} = 0b00; // no shift is applied
+ }
+
+ def s : T2I<(outs), (ins GPR:$base, GPR:$a, i32imm:$shamt), IIC_iLoadi, opc,
+ "\t[$base, $a, lsl $shamt]", []> {
+ let Inst{31-25} = 0b1111100;
+ let Inst{24} = instr;
+ let Inst{23} = 0; // add = TRUE for T1
+ let Inst{22} = 0;
+ let Inst{21} = write;
+ let Inst{20} = 1;
+ let Inst{15-12} = 0b1111;
+ let Inst{11-6} = 0000000;
+ }
+}
+
+defm t2PLD : T2Ipl<0, 0, "pld">;
+defm t2PLDW : T2Ipl<0, 1, "pldw">;
+defm t2PLI : T2Ipl<1, 0, "pli">;
+
//===----------------------------------------------------------------------===//
// Load / store multiple Instructions.
//
@@ -989,7 +1184,7 @@ def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb),
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
def t2LDM : T2XI<(outs),
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
+ IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
@@ -1001,7 +1196,7 @@ def t2LDM : T2XI<(outs),
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
def t2STM : T2XI<(outs),
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
+ IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
@@ -1074,13 +1269,15 @@ defm t2SXTB : T2I_unary_rrot<0b100, "sxtb",
UnOpFrag<(sext_inreg node:$Src, i8)>>;
defm t2SXTH : T2I_unary_rrot<0b000, "sxth",
UnOpFrag<(sext_inreg node:$Src, i16)>>;
+defm t2SXTB16 : T2I_unary_rrot_DO<0b010, "sxtb16">;
defm t2SXTAB : T2I_bin_rrot<0b100, "sxtab",
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
defm t2SXTAH : T2I_bin_rrot<0b000, "sxtah",
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
+defm t2SXTAB16 : T2I_bin_rrot_DO<0b010, "sxtab16">;
-// TODO: SXT(A){B|H}16
+// TODO: SXT(A){B|H}16 - done for disassembly only
// Zero extenders
@@ -1089,7 +1286,7 @@ defm t2UXTB : T2I_unary_rrot<0b101, "uxtb",
UnOpFrag<(and node:$Src, 0x000000FF)>>;
defm t2UXTH : T2I_unary_rrot<0b001, "uxth",
UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
-defm t2UXTB16 : T2I_unary_rrot<0b011, "uxtb16",
+defm t2UXTB16 : T2I_unary_rrot_nw<0b011, "uxtb16",
UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
@@ -1101,6 +1298,7 @@ defm t2UXTAB : T2I_bin_rrot<0b101, "uxtab",
BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
defm t2UXTAH : T2I_bin_rrot<0b001, "uxtah",
BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
+defm t2UXTAB16 : T2I_bin_rrot_DO<0b011, "uxtab16">;
}
//===----------------------------------------------------------------------===//
@@ -1119,9 +1317,13 @@ defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
BinOpFrag<(subc node:$LHS, node:$RHS)>>;
defm t2ADC : T2I_adde_sube_irs<0b1010, "adc",
- BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
+ BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
- BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+ BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
+defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc",
+ BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
+defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc",
+ BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>;
// RSB
defm t2RSB : T2I_rbin_is <0b1110, "rsb",
@@ -1138,6 +1340,155 @@ def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
(t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
+// Select Bytes -- for disassembly only
+
+def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel",
+ "\t$dst, $a, $b", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-24} = 0b010;
+ let Inst{23} = 0b1;
+ let Inst{22-20} = 0b010;
+ let Inst{15-12} = 0b1111;
+ let Inst{7} = 0b1;
+ let Inst{6-4} = 0b000;
+}
+
+// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
+// And Miscellaneous operations -- for disassembly only
+class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc>
+ : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, opc,
+ "\t$dst, $a, $b", [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0101;
+ let Inst{22-20} = op22_20;
+ let Inst{15-12} = 0b1111;
+ let Inst{7-4} = op7_4;
+}
+
+// Saturating add/subtract -- for disassembly only
+
+def t2QADD : T2I_pam<0b000, 0b1000, "qadd">;
+def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
+def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
+def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
+def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
+def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
+def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
+def t2QSUB : T2I_pam<0b000, 0b1010, "qsub">;
+def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
+def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
+def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
+def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
+def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
+def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
+def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
+def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
+
+// Signed/Unsigned add/subtract -- for disassembly only
+
+def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
+def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
+def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
+def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
+def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
+def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
+def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
+def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
+def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
+def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
+def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
+def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
+
+// Signed/Unsigned halving add/subtract -- for disassembly only
+
+def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
+def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
+def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
+def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
+def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
+def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
+def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
+def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
+def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
+def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
+def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
+def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
+
+// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
+
+def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ NoItinerary, "usad8", "\t$dst, $a, $b", []> {
+ let Inst{15-12} = 0b1111;
+}
+def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst),
+ (ins GPR:$a, GPR:$b, GPR:$acc), NoItinerary, "usada8",
+ "\t$dst, $a, $b, $acc", []>;
+
+// Signed/Unsigned saturate -- for disassembly only
+
+def t2SSATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
+ NoItinerary, "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25-22} = 0b1100;
+ let Inst{20} = 0;
+ let Inst{15} = 0;
+ let Inst{21} = 0; // sh = '0'
+}
+
+def t2SSATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
+ NoItinerary, "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25-22} = 0b1100;
+ let Inst{20} = 0;
+ let Inst{15} = 0;
+ let Inst{21} = 1; // sh = '1'
+}
+
+def t2SSAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
+ "ssat16", "\t$dst, $bit_pos, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25-22} = 0b1100;
+ let Inst{20} = 0;
+ let Inst{15} = 0;
+ let Inst{21} = 1; // sh = '1'
+ let Inst{14-12} = 0b000; // imm3 = '000'
+ let Inst{7-6} = 0b00; // imm2 = '00'
+}
+
+def t2USATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
+ NoItinerary, "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25-22} = 0b1110;
+ let Inst{20} = 0;
+ let Inst{15} = 0;
+ let Inst{21} = 0; // sh = '0'
+}
+
+def t2USATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
+ NoItinerary, "usat", "\t$dst, $bit_pos, $a, asr $shamt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25-22} = 0b1110;
+ let Inst{20} = 0;
+ let Inst{15} = 0;
+ let Inst{21} = 1; // sh = '1'
+}
+
+def t2USAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
+ "usat16", "\t$dst, $bit_pos, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25-22} = 0b1110;
+ let Inst{20} = 0;
+ let Inst{15} = 0;
+ let Inst{21} = 1; // sh = '1'
+ let Inst{14-12} = 0b000; // imm3 = '000'
+ let Inst{7-6} = 0b00; // imm2 = '00'
+}
//===----------------------------------------------------------------------===//
// Shift and rotate Instructions.
@@ -1342,6 +1693,8 @@ def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
}
} // neverHasSideEffects
+// Rounding variants of the below included for disassembly only
+
// Most significant word multiply
def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
"smmul", "\t$dst, $a, $b",
@@ -1353,6 +1706,15 @@ def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
}
+def t2SMMULR : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
+ "smmulr", "\t$dst, $a, $b", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0110;
+ let Inst{22-20} = 0b101;
+ let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
+ let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
+}
+
def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
"smmla", "\t$dst, $a, $b, $c",
[(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]> {
@@ -1363,6 +1725,14 @@ def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
}
+def t2SMMLAR : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
+ "smmlar", "\t$dst, $a, $b, $c", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0110;
+ let Inst{22-20} = 0b101;
+ let Inst{15-12} = {?, ?, ?, ?}; // Ra
+ let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
+}
def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
"smmls", "\t$dst, $a, $b, $c",
@@ -1374,6 +1744,15 @@ def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
}
+def t2SMMLSR : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
+ "smmlsr", "\t$dst, $a, $b, $c", []> {
+ let Inst{31-27} = 0b11111;
+ let Inst{26-23} = 0b0110;
+ let Inst{22-20} = 0b110;
+ let Inst{15-12} = {?, ?, ?, ?}; // Ra
+ let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
+}
+
multiclass T2I_smul<string opc, PatFrag opnode> {
def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
!strconcat(opc, "bb"), "\t$dst, $a, $b",
@@ -1466,7 +1845,7 @@ multiclass T2I_smla<string opc, PatFrag opnode> {
def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
!strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
- (sra GPR:$b, (i32 16)))))]> {
+ (sra GPR:$b, (i32 16)))))]> {
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b001;
@@ -1490,7 +1869,7 @@ multiclass T2I_smla<string opc, PatFrag opnode> {
def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
!strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
- (sra GPR:$b, (i32 16)))))]> {
+ (sra GPR:$b, (i32 16)))))]> {
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b001;
@@ -1502,7 +1881,7 @@ multiclass T2I_smla<string opc, PatFrag opnode> {
def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
!strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
- (sext_inreg GPR:$b, i16)), (i32 16))))]> {
+ (sext_inreg GPR:$b, i16)), (i32 16))))]> {
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b011;
@@ -1514,7 +1893,7 @@ multiclass T2I_smla<string opc, PatFrag opnode> {
def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
!strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
- (sra GPR:$b, (i32 16))), (i32 16))))]> {
+ (sra GPR:$b, (i32 16))), (i32 16))))]> {
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b011;
@@ -1527,16 +1906,70 @@ multiclass T2I_smla<string opc, PatFrag opnode> {
defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
-// TODO: Halfword multiple accumulate long: SMLAL<x><y>
-// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
-
+// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
+def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>;
+def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>;
+def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>;
+def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>;
+
+// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
+// These are for disassembly only.
+
+def t2SMUAD : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
+ let Inst{15-12} = 0b1111;
+}
+def t2SMUADX : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
+ let Inst{15-12} = 0b1111;
+}
+def t2SMUSD : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
+ let Inst{15-12} = 0b1111;
+}
+def t2SMUSDX : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+ IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
+ let Inst{15-12} = 0b1111;
+}
+def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst),
+ (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlad",
+ "\t$dst, $a, $b, $acc", []>;
+def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst),
+ (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smladx",
+ "\t$dst, $a, $b, $acc", []>;
+def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst),
+ (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsd",
+ "\t$dst, $a, $b, $acc", []>;
+def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst),
+ (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsdx",
+ "\t$dst, $a, $b, $acc", []>;
+def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlald",
+ "\t$ldst, $hdst, $a, $b", []>;
+def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaldx",
+ "\t$ldst, $hdst, $a, $b", []>;
+def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsld",
+ "\t$ldst, $hdst, $a, $b", []>;
+def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs GPR:$ldst,GPR:$hdst),
+ (ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsldx",
+ "\t$ldst, $hdst, $a, $b", []>;
//===----------------------------------------------------------------------===//
// Misc. Arithmetic Instructions.
//
-class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, InstrItinClass itin,
- string opc, string asm, list<dag> pattern>
+class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
+ InstrItinClass itin, string opc, string asm, list<dag> pattern>
: T2I<oops, iops, itin, opc, asm, pattern> {
let Inst{31-27} = 0b11111;
let Inst{26-22} = 0b01010;
@@ -1572,7 +2005,7 @@ def t2REVSH : T2I_misc<0b01, 0b11, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
(shl GPR:$src, (i32 8))), i16))]>;
def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
- IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
+ IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
(and (shl GPR:$src2, (i32 imm:$shamt)),
0xFFFF0000)))]> {
@@ -1590,7 +2023,7 @@ def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
(t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
- IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
+ IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
(and (sra GPR:$src2, imm16_31:$shamt),
0xFFFF)))]> {
@@ -1643,7 +2076,7 @@ defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
// Conditional moves
// FIXME: should be able to write a pattern for ARMcmov, but can't use
-// a two-value operand where a dag node expects two operands. :(
+// a two-value operand where a dag node expects two operands. :(
def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr,
"mov", ".w\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
@@ -1723,6 +2156,66 @@ def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
}
}
+// Helper class for multiclass T2MemB -- for disassembly only
+class T2I_memb<string opc, string asm>
+ : T2I<(outs), (ins), NoItinerary, opc, asm,
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsThumb2, HasV7]> {
+ let Inst{31-20} = 0xf3b;
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+}
+
+multiclass T2MemB<bits<4> op7_4, string opc> {
+
+ def st : T2I_memb<opc, "\tst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b1110;
+ }
+
+ def ish : T2I_memb<opc, "\tish"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b1011;
+ }
+
+ def ishst : T2I_memb<opc, "\tishst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b1010;
+ }
+
+ def nsh : T2I_memb<opc, "\tnsh"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0111;
+ }
+
+ def nshst : T2I_memb<opc, "\tnshst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0110;
+ }
+
+ def osh : T2I_memb<opc, "\tosh"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0011;
+ }
+
+ def oshst : T2I_memb<opc, "\toshst"> {
+ let Inst{7-4} = op7_4;
+ let Inst{3-0} = 0b0010;
+ }
+}
+
+// These DMB variants are for disassembly only.
+defm t2DMB : T2MemB<0b0101, "dmb">;
+
+// These DSB variants are for disassembly only.
+defm t2DSB : T2MemB<0b0100, "dsb">;
+
+// ISB has only full system option -- for disassembly only
+def t2ISBsy : T2I_memb<"isb", ""> {
+ let Inst{7-4} = 0b0110;
+ let Inst{3-0} = 0b1111;
+}
+
class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
InstrItinClass itin, string opc, string asm, string cstr,
list<dag> pattern, bits<4> rt2 = 0b1111>
@@ -1789,6 +2282,16 @@ def t2STREXD : T2I_strex<0b11, (outs GPR:$success),
{?, ?, ?, ?}>;
}
+// Clear-Exclusive is for disassembly only.
+def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV7]> {
+ let Inst{31-20} = 0xf3b;
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+ let Inst{7-4} = 0b0010;
+}
+
//===----------------------------------------------------------------------===//
// TLS Instructions
//
@@ -1906,6 +2409,24 @@ def t2TBH :
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0001; // H form
}
+
+// Generic versions of the above two instructions, for disassembly only
+
+def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
+ "tbb", "\t[$a, $b]", []>{
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0001101;
+ let Inst{15-8} = 0b11110000;
+ let Inst{7-4} = 0b0000; // B form
+}
+
+def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
+ "tbh", "\t[$a, $b, lsl #1]", []> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0001101;
+ let Inst{15-8} = 0b11110000;
+ let Inst{7-4} = 0b0001; // H form
+}
} // isNotDuplicable, isIndirectBranch
} // isBranch, isTerminator, isBarrier
@@ -1931,6 +2452,119 @@ def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
let Inst{15-8} = 0b10111111;
}
+// Branch and Exchange Jazelle -- for disassembly only
+// Rm = Inst{19-16}
+def t2BXJ : T2I<(outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{26} = 0;
+ let Inst{25-20} = 0b111100;
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+}
+
+// Change Processor State is a system instruction -- for disassembly only.
+// The singleton $opt operand contains the following information:
+// opt{4-0} = mode from Inst{4-0}
+// opt{5} = changemode from Inst{17}
+// opt{8-6} = AIF from Inst{8-6}
+// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
+def t2CPS : T2XI<(outs),(ins i32imm:$opt), NoItinerary, "cps${opt:cps}",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{26} = 0;
+ let Inst{25-20} = 0b111010;
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+}
+
+// A6.3.4 Branches and miscellaneous control
+// Table A6-14 Change Processor State, and hint instructions
+// Helper class for disassembly only.
+class T2I_hint<bits<8> op7_0, string opc, string asm>
+ : T2I<(outs), (ins), NoItinerary, opc, asm,
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-20} = 0xf3a;
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+ let Inst{10-8} = 0b000;
+ let Inst{7-0} = op7_0;
+}
+
+def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
+def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
+def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
+def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
+def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
+
+def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-20} = 0xf3a;
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+ let Inst{10-8} = 0b000;
+ let Inst{7-4} = 0b1111;
+}
+
+// Secure Monitor Call is a system instruction -- for disassembly only
+// Option = Inst{19-16}
+def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{26-20} = 0b1111111;
+ let Inst{15-12} = 0b1000;
+}
+
+// Store Return State is a system instruction -- for disassembly only
+def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0000010; // W = 1
+}
+
+def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0000000; // W = 0
+}
+
+def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0011010; // W = 1
+}
+
+def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0011000; // W = 0
+}
+
+// Return From Exception is a system instruction -- for disassembly only
+def t2RFEDBW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfedb", "\t$base!",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0000011; // W = 1
+}
+
+def t2RFEDB : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeab", "\t$base",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0000001; // W = 0
+}
+
+def t2RFEIAW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base!",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0011011; // W = 1
+}
+
+def t2RFEIA : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-20} = 0b0011001; // W = 0
+}
+
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//
@@ -1970,9 +2604,59 @@ def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
// Pseudo instruction that combines ldr from constpool and add pc. This should
// be expanded into two instructions late to allow if-conversion and
// scheduling.
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
NoItinerary, "@ ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
[(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
imm:$cp))]>,
Requires<[IsThumb2]>;
+
+//===----------------------------------------------------------------------===//
+// Move between special register and ARM core register -- for disassembly only
+//
+
+// Rd = Instr{11-8}
+def t2MRS : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{26} = 0;
+ let Inst{25-21} = 0b11111;
+ let Inst{20} = 0; // The R bit.
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+}
+
+// Rd = Instr{11-8}
+def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{26} = 0;
+ let Inst{25-21} = 0b11111;
+ let Inst{20} = 1; // The R bit.
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+}
+
+// FIXME: mask is ignored for the time being.
+// Rn = Inst{19-16}
+def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{26} = 0;
+ let Inst{25-21} = 0b11100;
+ let Inst{20} = 0; // The R bit.
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+}
+
+// FIXME: mask is ignored for the time being.
+// Rn = Inst{19-16}
+def t2MSRsys : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tspsr, $src",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-27} = 0b11110;
+ let Inst{26} = 0;
+ let Inst{25-21} = 0b11100;
+ let Inst{20} = 1; // The R bit.
+ let Inst{15-14} = 0b10;
+ let Inst{12} = 0;
+}
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td
index 365e1e3..7c117ed 100644
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -54,7 +54,7 @@ def vfp_f64imm : Operand<f64>,
// Load / store Instructions.
//
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
+let canFoldAsLoad = 1, isReMaterializable = 1 in {
def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
IIC_fpLoad64, "vldr", ".64\t$dst, $addr",
[(set DPR:$dst, (load addrmode5:$addr))]>;
@@ -412,6 +412,101 @@ def VTOUIRS : AVConv1In<0b11101, 0b11, 0b1100, 0b1010,
let Inst{7} = 0; // Z bit
}
+// Convert between floating-point and fixed-point
+// Data type for fixed-point naming convention:
+// S16 (U=0, sx=0) -> SH
+// U16 (U=1, sx=0) -> UH
+// S32 (U=0, sx=1) -> SL
+// U32 (U=1, sx=1) -> UL
+
+let Constraints = "$a = $dst" in {
+
+// FP to Fixed-Point:
+
+def VTOSHS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOUHS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOSLS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOULS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOSHD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOUHD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOSLD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOULD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+// Fixed-Point to FP:
+
+def VSHTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VUHTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VSLTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VULTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VSHTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VUHTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VSLTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+} // End of 'let Constraints = "$src = $dst" in'
+
//===----------------------------------------------------------------------===//
// FP FMA Operations.
//
diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp
index bef5a06..6db6ba4 100644
--- a/lib/Target/ARM/ARMJITInfo.cpp
+++ b/lib/Target/ARM/ARMJITInfo.cpp
@@ -48,7 +48,13 @@ static TargetJITInfo::JITCompilerFn JITCompilerFunction;
// write our own wrapper, which does things our way, so we have complete
// control over register saving and restoring.
extern "C" {
-#if defined(__arm__)
+ // We don't need this on Android (generally on hand-held devices). This
+ // function is for the purpose of supporting "lazy symbol lookup" (lookup
+ // undefined symbol at runtime) (Actually, if you tried to remove the
+ // !defined(ANDROID) guard, you'll get compilation error since Android's
+ // toolchain choose armv5te as its CPU architecture which does not support
+ // instruction 'stmdb' and 'ldmia' within the function)
+#if defined(__arm__) && !defined(ANDROID)
void ARMCompilationCallback();
asm(
".text\n"
@@ -60,7 +66,7 @@ extern "C" {
// whole compilation callback doesn't exist as far as the caller is
// concerned, so we can't just preserve the callee saved regs.
"stmdb sp!, {r0, r1, r2, r3, lr}\n"
-#ifndef __SOFTFP__
+#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
"fstmfdd sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
#endif
// The LR contains the address of the stub function on entry.
@@ -83,7 +89,7 @@ extern "C" {
// 6-20 | D0..D7 | Saved VFP registers
// +--------+
//
-#ifndef __SOFTFP__
+#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
// Restore VFP caller-saved registers.
"fldmfdd sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
#endif
@@ -318,6 +324,18 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
*((intptr_t*)RelocPos) |= ResultPtr;
break;
}
+ case ARM::reloc_arm_movw: {
+ ResultPtr = ResultPtr & 0xFFFF;
+ *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF;
+ *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; // imm4:imm12, Insts[19-16] = imm4, Insts[11-0] = imm12
+ break;
+ }
+ case ARM::reloc_arm_movt: {
+ ResultPtr = (ResultPtr >> 16) & 0xFFFF;
+ *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF;
+ *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; // imm4:imm12, Insts[19-16] = imm4, Insts[11-0] = imm12
+ break;
+ }
}
}
}
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index b78b95b..19f1e3b 100644
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -350,7 +350,8 @@ ARMLoadStoreOpt::MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex,
: ARMRegisterInfo::getRegisterNumbering(Reg);
// AM4 - register numbers in ascending order.
// AM5 - consecutive register numbers in ascending order.
- if (NewOffset == Offset + (int)Size &&
+ if (Reg != ARM::SP &&
+ NewOffset == Offset + (int)Size &&
((isAM4 && RegNum > PRegNum) || RegNum == PRegNum+1)) {
Offset += Size;
PRegNum = RegNum;
@@ -747,11 +748,24 @@ static bool isMemoryOp(const MachineInstr *MI) {
if (MMO->isVolatile())
return false;
- // Unaligned ldr/str is emulated by some kernels, but unaligned ldm/stm is not.
+ // Unaligned ldr/str is emulated by some kernels, but unaligned ldm/stm is
+ // not.
if (MMO->getAlignment() < 4)
return false;
}
+ // str <undef> could probably be eliminated entirely, but for now we just want
+ // to avoid making a mess of it.
+ // FIXME: Use str <undef> as a wildcard to enable better stm folding.
+ if (MI->getNumOperands() > 0 && MI->getOperand(0).isReg() &&
+ MI->getOperand(0).isUndef())
+ return false;
+
+ // Likewise don't mess with references to undefined addresses.
+ if (MI->getNumOperands() > 1 && MI->getOperand(1).isReg() &&
+ MI->getOperand(1).isUndef())
+ return false;
+
int Opcode = MI->getOpcode();
switch (Opcode) {
default: break;
diff --git a/lib/Target/ARM/ARMRelocations.h b/lib/Target/ARM/ARMRelocations.h
index 2cc2950..86e7206 100644
--- a/lib/Target/ARM/ARMRelocations.h
+++ b/lib/Target/ARM/ARMRelocations.h
@@ -47,7 +47,13 @@ namespace llvm {
reloc_arm_pic_jt,
// reloc_arm_branch - Branch address relocation.
- reloc_arm_branch
+ reloc_arm_branch,
+
+ // reloc_arm_movt - MOVT immediate relocation.
+ reloc_arm_movt,
+
+ // reloc_arm_movw - MOVW immediate relocation.
+ reloc_arm_movw
};
}
}
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index 426862c..622034b 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -33,7 +33,7 @@ UseMOVT("arm-use-movt",
ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
bool isT)
- : ARMArchVersion(V4T)
+ : ARMArchVersion(V4)
, ARMFPUType(None)
, UseNEONForSinglePrecisionFP(UseNEONFP)
, IsThumb(isT)
@@ -54,6 +54,11 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
// Parse features string.
CPUString = ParseSubtargetFeatures(FS, CPUString);
+ // When no arch is specified either by CPU or by attributes, make the default
+ // ARMv4T.
+ if (CPUString == "generic" && (FS.empty() || FS == "generic"))
+ ARMArchVersion = V4T;
+
// Set the boolean corresponding to the current target triple, or the default
// if one cannot be determined, to true.
unsigned Len = TT.length();
@@ -68,25 +73,28 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
}
if (Idx) {
unsigned SubVer = TT[Idx];
- if (SubVer > '4' && SubVer <= '9') {
- if (SubVer >= '7') {
- ARMArchVersion = V7A;
- } else if (SubVer == '6') {
- ARMArchVersion = V6;
- if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
- ARMArchVersion = V6T2;
- } else if (SubVer == '5') {
- ARMArchVersion = V5T;
- if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
- ARMArchVersion = V5TE;
- }
- if (ARMArchVersion >= V6T2)
- ThumbMode = Thumb2;
+ if (SubVer >= '7' && SubVer <= '9') {
+ ARMArchVersion = V7A;
+ } else if (SubVer == '6') {
+ ARMArchVersion = V6;
+ if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
+ ARMArchVersion = V6T2;
+ } else if (SubVer == '5') {
+ ARMArchVersion = V5T;
+ if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
+ ARMArchVersion = V5TE;
+ } else if (SubVer == '4') {
+ if (Len >= Idx+2 && TT[Idx+1] == 't')
+ ARMArchVersion = V4T;
+ else
+ ARMArchVersion = V4;
}
}
// Thumb2 implies at least V6T2.
- if (ARMArchVersion < V6T2 && ThumbMode >= Thumb2)
+ if (ARMArchVersion >= V6T2)
+ ThumbMode = Thumb2;
+ else if (ThumbMode >= Thumb2)
ARMArchVersion = V6T2;
if (Len >= 10) {
diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h
index 3f06b7b..6980851 100644
--- a/lib/Target/ARM/ARMSubtarget.h
+++ b/lib/Target/ARM/ARMSubtarget.h
@@ -26,7 +26,7 @@ class GlobalValue;
class ARMSubtarget : public TargetSubtarget {
protected:
enum ARMArchEnum {
- V4T, V5T, V5TE, V6, V6T2, V7A
+ V4, V4T, V5T, V5TE, V6, V6T2, V7A
};
enum ARMFPEnum {
@@ -38,7 +38,7 @@ protected:
Thumb2
};
- /// ARMArchVersion - ARM architecture version: V4T (base), V5T, V5TE,
+ /// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE,
/// V6, V6T2, V7A.
ARMArchEnum ARMArchVersion;
diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h
index 9703403..a488c0a 100644
--- a/lib/Target/ARM/ARMTargetObjectFile.h
+++ b/lib/Target/ARM/ARMTargetObjectFile.h
@@ -10,7 +10,7 @@
#ifndef LLVM_TARGET_ARM_TARGETOBJECTFILE_H
#define LLVM_TARGET_ARM_TARGETOBJECTFILE_H
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCSectionELF.h"
namespace llvm {
@@ -24,7 +24,7 @@ namespace llvm {
if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) {
StaticCtorSection =
- getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
+ getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
StaticDtorSection =
diff --git a/lib/Target/ARM/Android.mk b/lib/Target/ARM/Android.mk
new file mode 100644
index 0000000..ea796af
--- /dev/null
+++ b/lib/Target/ARM/Android.mk
@@ -0,0 +1,49 @@
+LOCAL_PATH := $(call my-dir)
+
+# For the device only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES := \
+ ARMGenRegisterInfo.h.inc \
+ ARMGenRegisterNames.inc \
+ ARMGenRegisterInfo.inc \
+ ARMGenInstrNames.inc \
+ ARMGenInstrInfo.inc \
+ ARMGenDAGISel.inc \
+ ARMGenSubtarget.inc \
+ ARMGenCodeEmitter.inc \
+ ARMGenCallingConv.inc
+
+LOCAL_SRC_FILES := \
+ ARMBaseInstrInfo.cpp \
+ ARMBaseRegisterInfo.cpp \
+ ARMCodeEmitter.cpp \
+ ARMConstantIslandPass.cpp \
+ ARMConstantPoolValue.cpp \
+ ARMExpandPseudoInsts.cpp \
+ ARMISelDAGToDAG.cpp \
+ ARMISelLowering.cpp \
+ ARMInstrInfo.cpp \
+ ARMJITInfo.cpp \
+ ARMLoadStoreOptimizer.cpp \
+ ARMMCAsmInfo.cpp \
+ ARMRegisterInfo.cpp \
+ ARMSubtarget.cpp \
+ ARMTargetMachine.cpp \
+ NEONMoveFix.cpp \
+ NEONPreAllocPass.cpp \
+ Thumb1InstrInfo.cpp \
+ Thumb1RegisterInfo.cpp \
+ Thumb2ITBlockPass.cpp \
+ Thumb2InstrInfo.cpp \
+ Thumb2RegisterInfo.cpp \
+ Thumb2SizeReduction.cpp
+
+LOCAL_MODULE:= libLLVMARMCodeGen
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_TBLGEN_RULES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 0a75c09..d6d595c 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -30,6 +30,7 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
@@ -37,7 +38,6 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
@@ -122,6 +122,7 @@ namespace {
void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum);
void printPredicateOperand(const MachineInstr *MI, int OpNum);
+ void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum);
void printSBitModifierOperand(const MachineInstr *MI, int OpNum);
void printPCLabel(const MachineInstr *MI, int OpNum);
void printRegisterList(const MachineInstr *MI, int OpNum);
@@ -786,6 +787,12 @@ void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum) {
O << ARMCondCodeToString(CC);
}
+void ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
+ int OpNum) {
+ ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
+ O << ARMCondCodeToString(CC);
+}
+
void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum){
unsigned Reg = MI->getOperand(OpNum).getReg();
if (Reg) {
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
index d7d8e09..a2084b0 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
@@ -325,6 +325,12 @@ void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum) {
O << ARMCondCodeToString(CC);
}
+void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
+ unsigned OpNum) {
+ ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
+ O << ARMCondCodeToString(CC);
+}
+
void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum){
if (MI->getOperand(OpNum).getReg()) {
assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
index 23a7f05..b7964c9 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
@@ -71,6 +71,7 @@ public:
void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum) {}
void printPredicateOperand(const MCInst *MI, unsigned OpNum);
+ void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum);
void printSBitModifierOperand(const MCInst *MI, unsigned OpNum);
void printRegisterList(const MCInst *MI, unsigned OpNum);
void printCPInstOperand(const MCInst *MI, unsigned OpNum,
diff --git a/lib/Target/ARM/README.txt b/lib/Target/ARM/README.txt
index 9efb5a1..57b65cf 100644
--- a/lib/Target/ARM/README.txt
+++ b/lib/Target/ARM/README.txt
@@ -10,6 +10,8 @@ Reimplement 'select' in terms of 'SEL'.
* Implement pre/post increment support. (e.g. PR935)
* Implement smarter constant generation for binops with large immediates.
+A few ARMv6T2 ops should be pattern matched: BFI, SBFX, and UBFX
+
//===---------------------------------------------------------------------===//
Crazy idea: Consider code that uses lots of 8-bit or 16-bit values. By the
diff --git a/lib/Target/ARM/TargetInfo/Android.mk b/lib/Target/ARM/TargetInfo/Android.mk
new file mode 100644
index 0000000..c1998a1
--- /dev/null
+++ b/lib/Target/ARM/TargetInfo/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH := $(call my-dir)
+
+# For the device only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES := \
+ ARMGenRegisterNames.inc \
+ ARMGenInstrNames.inc
+
+TBLGEN_TD_DIR := $(LOCAL_PATH)/..
+
+LOCAL_SRC_FILES := \
+ ARMTargetInfo.cpp
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/..
+
+LOCAL_MODULE:= libLLVMARMInfo
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_TBLGEN_RULES_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp
index d6630ce..163d1e9 100644
--- a/lib/Target/ARM/Thumb1RegisterInfo.cpp
+++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp
@@ -450,9 +450,9 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Offset -= AFI->getGPRCalleeSavedArea1Offset();
else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
Offset -= AFI->getGPRCalleeSavedArea2Offset();
- else if (hasFP(MF)) {
- assert(SPAdj == 0 && "Unexpected");
- // There is alloca()'s in this function, must reference off the frame
+ else if (MF.getFrameInfo()->hasVarSizedObjects()) {
+ assert(SPAdj == 0 && hasFP(MF) && "Unexpected");
+ // There are alloca()'s in this function, must reference off the frame
// pointer instead.
FrameReg = getFrameRegister(MF);
Offset -= AFI->getFramePtrSpillOffset();
@@ -778,9 +778,19 @@ static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
}
static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
- return (MI->getOpcode() == ARM::tRestore &&
- MI->getOperand(1).isFI() &&
- isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
+ if (MI->getOpcode() == ARM::tRestore &&
+ MI->getOperand(1).isFI() &&
+ isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs))
+ return true;
+ else if (MI->getOpcode() == ARM::tPOP) {
+ // The first three operands are predicates and such. The last two are
+ // imp-def and imp-use of SP. Check everything in between.
+ for (int i = 3, e = MI->getNumOperands() - 2; i != e; ++i)
+ if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs))
+ return false;
+ return true;
+ }
+ return false;
}
void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
@@ -794,13 +804,13 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
int NumBytes = (int)MFI->getStackSize();
+ const unsigned *CSRegs = getCalleeSavedRegs();
if (!AFI->hasStackFrame()) {
if (NumBytes != 0)
emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
} else {
// Unwind MBBI to point to first LDR / VLDRD.
- const unsigned *CSRegs = getCalleeSavedRegs();
if (MBBI != MBB.begin()) {
do
--MBBI;
@@ -836,6 +846,9 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
}
if (VARegSaveSize) {
+ // Move back past the callee-saved register restoration
+ while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs))
+ ++MBBI;
// Epilogue for vararg functions: pop LR to R3 and branch off it.
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
.addReg(0) // No write back.
@@ -845,6 +858,7 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg))
.addReg(ARM::R3, RegState::Kill);
+ // erase the old tBX_RET instruction
MBB.erase(MBBI);
}
}
diff --git a/lib/Target/Alpha/AlphaCallingConv.td b/lib/Target/Alpha/AlphaCallingConv.td
index 38ada69..bde8819 100644
--- a/lib/Target/Alpha/AlphaCallingConv.td
+++ b/lib/Target/Alpha/AlphaCallingConv.td
@@ -14,7 +14,8 @@
//===----------------------------------------------------------------------===//
def RetCC_Alpha : CallingConv<[
// i64 is returned in register R0
- CCIfType<[i64], CCAssignToReg<[R0]>>,
+ // R1 is an llvm extension, I don't know what gcc does
+ CCIfType<[i64], CCAssignToReg<[R0,R1]>>,
// f32 / f64 are returned in F0/F1
CCIfType<[f32, f64], CCAssignToReg<[F0, F1]>>
diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
index eaefef9..5303d85 100644
--- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
+++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
@@ -64,7 +64,7 @@ namespace {
/// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are
/// in checking mode. If LHS is null, we assume that the mask has already
/// been validated before.
- uint64_t get_zapImm(SDValue LHS, uint64_t Constant) {
+ uint64_t get_zapImm(SDValue LHS, uint64_t Constant) const {
uint64_t BitsToCheck = 0;
unsigned Result = 0;
for (unsigned i = 0; i != 8; ++i) {
@@ -159,10 +159,6 @@ namespace {
// target-specific node if it hasn't already been changed.
SDNode *Select(SDNode *N);
- /// InstructionSelect - This callback is invoked by
- /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
- virtual void InstructionSelect();
-
virtual const char *getPassName() const {
return "Alpha DAG->DAG Pattern Instruction Selection";
}
@@ -222,20 +218,11 @@ SDNode *AlphaDAGToDAGISel::getGlobalRetAddr() {
return CurDAG->getRegister(GlobalRetAddr, TLI.getPointerTy()).getNode();
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void AlphaDAGToDAGISel::InstructionSelect() {
- // Select target instructions for the DAG.
- SelectRoot(*CurDAG);
- CurDAG->RemoveDeadNodes();
-}
-
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
SDNode *AlphaDAGToDAGISel::Select(SDNode *N) {
- if (N->isMachineOpcode()) {
+ if (N->isMachineOpcode())
return NULL; // Already selected.
- }
DebugLoc dl = N->getDebugLoc();
switch (N->getOpcode()) {
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 0bbe567..5d8310e 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -21,7 +21,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
@@ -282,7 +282,8 @@ AlphaTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
DAG.getIntPtrConstant(VA.getLocMemOffset()));
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), 0));
+ PseudoSourceValue::getStack(), 0,
+ false, false, 0));
}
}
@@ -426,7 +427,8 @@ AlphaTargetLowering::LowerFormalArguments(SDValue Chain,
// Create the SelectionDAG nodes corresponding to a load
//from this parameter
SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
- ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0);
+ ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0,
+ false, false, 0);
}
InVals.push_back(ArgVal);
}
@@ -442,14 +444,16 @@ AlphaTargetLowering::LowerFormalArguments(SDValue Chain,
int FI = MFI->CreateFixedObject(8, -8 * (6 - i), true, false);
if (i == 0) VarArgsBase = FI;
SDValue SDFI = DAG.getFrameIndex(FI, MVT::i64);
- LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0));
+ LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0,
+ false, false, 0));
if (TargetRegisterInfo::isPhysicalRegister(args_float[i]))
args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass);
argt = DAG.getCopyFromReg(Chain, dl, args_float[i], MVT::f64);
FI = MFI->CreateFixedObject(8, - 8 * (12 - i), true, false);
SDFI = DAG.getFrameIndex(FI, MVT::i64);
- LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0));
+ LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0,
+ false, false, 0));
}
//Set up a token factor with all the stack traffic
@@ -528,11 +532,12 @@ void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain,
const Value *VAListS = cast<SrcValueSDNode>(N->getOperand(2))->getValue();
DebugLoc dl = N->getDebugLoc();
- SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP, VAListS, 0);
+ SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP, VAListS, 0,
+ false, false, 0);
SDValue Tmp = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
DAG.getConstant(8, MVT::i64));
SDValue Offset = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Base.getValue(1),
- Tmp, NULL, 0, MVT::i32);
+ Tmp, NULL, 0, MVT::i32, false, false, 0);
DataPtr = DAG.getNode(ISD::ADD, dl, MVT::i64, Base, Offset);
if (N->getValueType(0).isFloatingPoint())
{
@@ -547,7 +552,7 @@ void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain,
SDValue NewOffset = DAG.getNode(ISD::ADD, dl, MVT::i64, Offset,
DAG.getConstant(8, MVT::i64));
Chain = DAG.getTruncStore(Offset.getValue(1), dl, NewOffset, Tmp, NULL, 0,
- MVT::i32);
+ MVT::i32, false, false, 0);
}
/// LowerOperation - Provide custom lowering hooks for some operations.
@@ -694,9 +699,10 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
SDValue Result;
if (Op.getValueType() == MVT::i32)
Result = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Chain, DataPtr,
- NULL, 0, MVT::i32);
+ NULL, 0, MVT::i32, false, false, 0);
else
- Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr, NULL, 0);
+ Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr, NULL, 0,
+ false, false, 0);
return Result;
}
case ISD::VACOPY: {
@@ -706,15 +712,18 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
- SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP, SrcS, 0);
- SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP, DestS, 0);
+ SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP, SrcS, 0,
+ false, false, 0);
+ SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP, DestS, 0,
+ false, false, 0);
SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP,
DAG.getConstant(8, MVT::i64));
Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result,
- NP, NULL,0, MVT::i32);
+ NP, NULL,0, MVT::i32, false, false, 0);
SDValue NPD = DAG.getNode(ISD::ADD, dl, MVT::i64, DestP,
DAG.getConstant(8, MVT::i64));
- return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD, NULL, 0, MVT::i32);
+ return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD, NULL, 0, MVT::i32,
+ false, false, 0);
}
case ISD::VASTART: {
SDValue Chain = Op.getOperand(0);
@@ -723,11 +732,12 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
// vastart stores the address of the VarArgsBase and VarArgsOffset
SDValue FR = DAG.getFrameIndex(VarArgsBase, MVT::i64);
- SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP, VAListS, 0);
+ SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP, VAListS, 0,
+ false, false, 0);
SDValue SA2 = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
DAG.getConstant(8, MVT::i64));
return DAG.getTruncStore(S1, dl, DAG.getConstant(VarArgsOffset, MVT::i64),
- SA2, NULL, 0, MVT::i32);
+ SA2, NULL, 0, MVT::i32, false, false, 0);
}
case ISD::RETURNADDR:
return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc::getUnknownLoc(),
@@ -749,7 +759,8 @@ void AlphaTargetLowering::ReplaceNodeResults(SDNode *N,
SDValue Chain, DataPtr;
LowerVAARG(N, Chain, DataPtr, DAG);
- SDValue Res = DAG.getLoad(N->getValueType(0), dl, Chain, DataPtr, NULL, 0);
+ SDValue Res = DAG.getLoad(N->getValueType(0), dl, Chain, DataPtr, NULL, 0,
+ false, false, 0);
Results.push_back(Res);
Results.push_back(SDValue(Res.getNode(), 1));
}
diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td
index 8917e86..341c4a7 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.td
+++ b/lib/Target/Alpha/AlphaInstrInfo.td
@@ -92,7 +92,7 @@ def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended
((int64_t)N->getZExtValue() << 32) >> 32;
}], SExt16>;
-def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm:$L), [{
+def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm), [{
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1));
if (!RHS) return 0;
uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getZExtValue());
@@ -602,9 +602,9 @@ def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle count
def MB : MfcPForm<0x18, 0x4000, "mb", s_imisc>; //memory barrier
def WMB : MfcPForm<0x18, 0x4400, "wmb", s_imisc>; //write memory barrier
-def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 1), (i64 imm:$dev)),
+def : Pat<(membarrier (i64 imm), (i64 imm), (i64 imm), (i64 1), (i64 imm)),
(WMB)>;
-def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 imm:$ss), (i64 imm:$dev)),
+def : Pat<(membarrier (i64 imm), (i64 imm), (i64 imm), (i64 imm), (i64 imm)),
(MB)>;
//Basic Floating point ops
diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp
index 64bdd62..ba662fb 100644
--- a/lib/Target/Alpha/AlphaRegisterInfo.cpp
+++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp
@@ -251,7 +251,7 @@ void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
} else {
std::string msg;
raw_string_ostream Msg(msg);
- Msg << "Too big a stack frame at " + NumBytes;
+ Msg << "Too big a stack frame at " << NumBytes;
llvm_report_error(Msg.str());
}
@@ -303,15 +303,14 @@ void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
} else {
std::string msg;
raw_string_ostream Msg(msg);
- Msg << "Too big a stack frame at " + NumBytes;
+ Msg << "Too big a stack frame at " << NumBytes;
llvm_report_error(Msg.str());
}
}
}
unsigned AlphaRegisterInfo::getRARegister() const {
- llvm_unreachable("What is the return address register");
- return 0;
+ return Alpha::R26;
}
unsigned AlphaRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
diff --git a/lib/Target/Android.mk b/lib/Target/Android.mk
new file mode 100644
index 0000000..8bf4340
--- /dev/null
+++ b/lib/Target/Android.mk
@@ -0,0 +1,38 @@
+LOCAL_PATH:= $(call my-dir)
+
+target_SRC_FILES := \
+ Mangler.cpp \
+ SubtargetFeature.cpp \
+ Target.cpp \
+ TargetAsmLexer.cpp \
+ TargetData.cpp \
+ TargetELFWriterInfo.cpp \
+ TargetFrameInfo.cpp \
+ TargetInstrInfo.cpp \
+ TargetIntrinsicInfo.cpp \
+ TargetLoweringObjectFile.cpp \
+ TargetMachine.cpp \
+ TargetRegisterInfo.cpp \
+ TargetSubtarget.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(target_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMTarget
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(target_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMTarget
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
index 2c9cc60..c8d71aa 100644
--- a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
+++ b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
@@ -41,7 +41,7 @@ namespace {
BlackfinDAGToDAGISel(BlackfinTargetMachine &TM, CodeGenOpt::Level OptLevel)
: SelectionDAGISel(TM, OptLevel) {}
- virtual void InstructionSelect();
+ virtual void PostprocessISelDAG();
virtual const char *getPassName() const {
return "Blackfin DAG->DAG Pattern Instruction Selection";
@@ -72,13 +72,7 @@ FunctionPass *llvm::createBlackfinISelDag(BlackfinTargetMachine &TM,
return new BlackfinDAGToDAGISel(TM, OptLevel);
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void BlackfinDAGToDAGISel::InstructionSelect() {
- // Select target instructions for the DAG.
- SelectRoot(*CurDAG);
- DEBUG(errs() << "Selected selection DAG before regclass fixup:\n");
- DEBUG(CurDAG->dump());
+void BlackfinDAGToDAGISel::PostprocessISelDAG() {
FixRegisterClasses(*CurDAG);
}
diff --git a/lib/Target/Blackfin/BlackfinISelLowering.cpp b/lib/Target/Blackfin/BlackfinISelLowering.cpp
index 269707a..5ce2013 100644
--- a/lib/Target/Blackfin/BlackfinISelLowering.cpp
+++ b/lib/Target/Blackfin/BlackfinISelLowering.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -206,7 +206,8 @@ BlackfinTargetLowering::LowerFormalArguments(SDValue Chain,
int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(),
true, false);
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
- InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -329,7 +330,7 @@ BlackfinTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
OffsetN = DAG.getNode(ISD::ADD, dl, MVT::i32, SPN, OffsetN);
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, OffsetN,
PseudoSourceValue::getStack(),
- Offset));
+ Offset, false, false, 0));
}
}
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index fd4c4e7..10f873f 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -49,7 +49,6 @@
#include "llvm/System/Host.h"
#include "llvm/Config/config.h"
#include <algorithm>
-#include <sstream>
using namespace llvm;
extern "C" void LLVMInitializeCBackendTarget() {
@@ -153,26 +152,16 @@ namespace {
return false;
}
- raw_ostream &printType(formatted_raw_ostream &Out,
- const Type *Ty,
+ raw_ostream &printType(raw_ostream &Out, const Type *Ty,
bool isSigned = false,
const std::string &VariableName = "",
bool IgnoreName = false,
const AttrListPtr &PAL = AttrListPtr());
- std::ostream &printType(std::ostream &Out, const Type *Ty,
- bool isSigned = false,
- const std::string &VariableName = "",
- bool IgnoreName = false,
- const AttrListPtr &PAL = AttrListPtr());
- raw_ostream &printSimpleType(formatted_raw_ostream &Out,
- const Type *Ty,
- bool isSigned,
- const std::string &NameSoFar = "");
- std::ostream &printSimpleType(std::ostream &Out, const Type *Ty,
- bool isSigned,
+ raw_ostream &printSimpleType(raw_ostream &Out, const Type *Ty,
+ bool isSigned,
const std::string &NameSoFar = "");
- void printStructReturnPointerFunctionType(formatted_raw_ostream &Out,
+ void printStructReturnPointerFunctionType(raw_ostream &Out,
const AttrListPtr &PAL,
const PointerType *Ty);
@@ -385,8 +374,8 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) {
// If this isn't a struct or array type, remove it from our set of types
// to name. This simplifies emission later.
- if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second) &&
- !isa<ArrayType>(I->second)) {
+ if (!I->second->isStructTy() && !I->second->isOpaqueTy() &&
+ !I->second->isArrayTy()) {
TST.remove(I);
} else {
// If this is not used, remove it from the symbol table.
@@ -405,7 +394,7 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) {
unsigned RenameCounter = 0;
for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end();
I != E; ++I)
- if (isa<StructType>(*I) || isa<ArrayType>(*I)) {
+ if ((*I)->isStructTy() || (*I)->isArrayTy()) {
while (M.addTypeName("unnamed"+utostr(RenameCounter), *I))
++RenameCounter;
Changed = true;
@@ -454,11 +443,12 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) {
/// printStructReturnPointerFunctionType - This is like printType for a struct
/// return type, except, instead of printing the type as void (*)(Struct*, ...)
/// print it as "Struct (*)(...)", for struct return functions.
-void CWriter::printStructReturnPointerFunctionType(formatted_raw_ostream &Out,
+void CWriter::printStructReturnPointerFunctionType(raw_ostream &Out,
const AttrListPtr &PAL,
const PointerType *TheTy) {
const FunctionType *FTy = cast<FunctionType>(TheTy->getElementType());
- std::stringstream FunctionInnards;
+ std::string tstr;
+ raw_string_ostream FunctionInnards(tstr);
FunctionInnards << " (*) (";
bool PrintedType = false;
@@ -470,7 +460,7 @@ void CWriter::printStructReturnPointerFunctionType(formatted_raw_ostream &Out,
FunctionInnards << ", ";
const Type *ArgTy = *I;
if (PAL.paramHasAttr(Idx, Attribute::ByVal)) {
- assert(isa<PointerType>(ArgTy));
+ assert(ArgTy->isPointerTy());
ArgTy = cast<PointerType>(ArgTy)->getElementType();
}
printType(FunctionInnards, ArgTy,
@@ -484,63 +474,14 @@ void CWriter::printStructReturnPointerFunctionType(formatted_raw_ostream &Out,
FunctionInnards << "void";
}
FunctionInnards << ')';
- std::string tstr = FunctionInnards.str();
printType(Out, RetTy,
- /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), tstr);
+ /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), FunctionInnards.str());
}
raw_ostream &
-CWriter::printSimpleType(formatted_raw_ostream &Out, const Type *Ty,
- bool isSigned,
+CWriter::printSimpleType(raw_ostream &Out, const Type *Ty, bool isSigned,
const std::string &NameSoFar) {
- assert((Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) &&
- "Invalid type for printSimpleType");
- switch (Ty->getTypeID()) {
- case Type::VoidTyID: return Out << "void " << NameSoFar;
- case Type::IntegerTyID: {
- unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth();
- if (NumBits == 1)
- return Out << "bool " << NameSoFar;
- else if (NumBits <= 8)
- return Out << (isSigned?"signed":"unsigned") << " char " << NameSoFar;
- else if (NumBits <= 16)
- return Out << (isSigned?"signed":"unsigned") << " short " << NameSoFar;
- else if (NumBits <= 32)
- return Out << (isSigned?"signed":"unsigned") << " int " << NameSoFar;
- else if (NumBits <= 64)
- return Out << (isSigned?"signed":"unsigned") << " long long "<< NameSoFar;
- else {
- assert(NumBits <= 128 && "Bit widths > 128 not implemented yet");
- return Out << (isSigned?"llvmInt128":"llvmUInt128") << " " << NameSoFar;
- }
- }
- case Type::FloatTyID: return Out << "float " << NameSoFar;
- case Type::DoubleTyID: return Out << "double " << NameSoFar;
- // Lacking emulation of FP80 on PPC, etc., we assume whichever of these is
- // present matches host 'long double'.
- case Type::X86_FP80TyID:
- case Type::PPC_FP128TyID:
- case Type::FP128TyID: return Out << "long double " << NameSoFar;
-
- case Type::VectorTyID: {
- const VectorType *VTy = cast<VectorType>(Ty);
- return printSimpleType(Out, VTy->getElementType(), isSigned,
- " __attribute__((vector_size(" +
- utostr(TD->getTypeAllocSize(VTy)) + " ))) " + NameSoFar);
- }
-
- default:
-#ifndef NDEBUG
- errs() << "Unknown primitive type: " << *Ty << "\n";
-#endif
- llvm_unreachable(0);
- }
-}
-
-std::ostream &
-CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
- const std::string &NameSoFar) {
- assert((Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) &&
+ assert((Ty->isPrimitiveType() || Ty->isIntegerTy() || Ty->isVectorTy()) &&
"Invalid type for printSimpleType");
switch (Ty->getTypeID()) {
case Type::VoidTyID: return Out << "void " << NameSoFar;
@@ -587,120 +528,16 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
// Pass the Type* and the variable name and this prints out the variable
// declaration.
//
-raw_ostream &CWriter::printType(formatted_raw_ostream &Out,
- const Type *Ty,
+raw_ostream &CWriter::printType(raw_ostream &Out, const Type *Ty,
bool isSigned, const std::string &NameSoFar,
bool IgnoreName, const AttrListPtr &PAL) {
- if (Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) {
- printSimpleType(Out, Ty, isSigned, NameSoFar);
- return Out;
- }
-
- // Check to see if the type is named.
- if (!IgnoreName || isa<OpaqueType>(Ty)) {
- std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);
- if (I != TypeNames.end()) return Out << I->second << ' ' << NameSoFar;
- }
-
- switch (Ty->getTypeID()) {
- case Type::FunctionTyID: {
- const FunctionType *FTy = cast<FunctionType>(Ty);
- std::stringstream FunctionInnards;
- FunctionInnards << " (" << NameSoFar << ") (";
- unsigned Idx = 1;
- for (FunctionType::param_iterator I = FTy->param_begin(),
- E = FTy->param_end(); I != E; ++I) {
- const Type *ArgTy = *I;
- if (PAL.paramHasAttr(Idx, Attribute::ByVal)) {
- assert(isa<PointerType>(ArgTy));
- ArgTy = cast<PointerType>(ArgTy)->getElementType();
- }
- if (I != FTy->param_begin())
- FunctionInnards << ", ";
- printType(FunctionInnards, ArgTy,
- /*isSigned=*/PAL.paramHasAttr(Idx, Attribute::SExt), "");
- ++Idx;
- }
- if (FTy->isVarArg()) {
- if (FTy->getNumParams())
- FunctionInnards << ", ...";
- } else if (!FTy->getNumParams()) {
- FunctionInnards << "void";
- }
- FunctionInnards << ')';
- std::string tstr = FunctionInnards.str();
- printType(Out, FTy->getReturnType(),
- /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), tstr);
- return Out;
- }
- case Type::StructTyID: {
- const StructType *STy = cast<StructType>(Ty);
- Out << NameSoFar + " {\n";
- unsigned Idx = 0;
- for (StructType::element_iterator I = STy->element_begin(),
- E = STy->element_end(); I != E; ++I) {
- Out << " ";
- printType(Out, *I, false, "field" + utostr(Idx++));
- Out << ";\n";
- }
- Out << '}';
- if (STy->isPacked())
- Out << " __attribute__ ((packed))";
- return Out;
- }
-
- case Type::PointerTyID: {
- const PointerType *PTy = cast<PointerType>(Ty);
- std::string ptrName = "*" + NameSoFar;
-
- if (isa<ArrayType>(PTy->getElementType()) ||
- isa<VectorType>(PTy->getElementType()))
- ptrName = "(" + ptrName + ")";
-
- if (!PAL.isEmpty())
- // Must be a function ptr cast!
- return printType(Out, PTy->getElementType(), false, ptrName, true, PAL);
- return printType(Out, PTy->getElementType(), false, ptrName);
- }
-
- case Type::ArrayTyID: {
- const ArrayType *ATy = cast<ArrayType>(Ty);
- unsigned NumElements = ATy->getNumElements();
- if (NumElements == 0) NumElements = 1;
- // Arrays are wrapped in structs to allow them to have normal
- // value semantics (avoiding the array "decay").
- Out << NameSoFar << " { ";
- printType(Out, ATy->getElementType(), false,
- "array[" + utostr(NumElements) + "]");
- return Out << "; }";
- }
-
- case Type::OpaqueTyID: {
- std::string TyName = "struct opaque_" + itostr(OpaqueCounter++);
- assert(TypeNames.find(Ty) == TypeNames.end());
- TypeNames[Ty] = TyName;
- return Out << TyName << ' ' << NameSoFar;
- }
- default:
- llvm_unreachable("Unhandled case in getTypeProps!");
- }
-
- return Out;
-}
-
-// Pass the Type* and the variable name and this prints out the variable
-// declaration.
-//
-std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
- bool isSigned, const std::string &NameSoFar,
- bool IgnoreName, const AttrListPtr &PAL) {
- if (Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) {
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy() || Ty->isVectorTy()) {
printSimpleType(Out, Ty, isSigned, NameSoFar);
return Out;
}
// Check to see if the type is named.
- if (!IgnoreName || isa<OpaqueType>(Ty)) {
+ if (!IgnoreName || Ty->isOpaqueTy()) {
std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);
if (I != TypeNames.end()) return Out << I->second << ' ' << NameSoFar;
}
@@ -708,14 +545,15 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
switch (Ty->getTypeID()) {
case Type::FunctionTyID: {
const FunctionType *FTy = cast<FunctionType>(Ty);
- std::stringstream FunctionInnards;
+ std::string tstr;
+ raw_string_ostream FunctionInnards(tstr);
FunctionInnards << " (" << NameSoFar << ") (";
unsigned Idx = 1;
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I) {
const Type *ArgTy = *I;
if (PAL.paramHasAttr(Idx, Attribute::ByVal)) {
- assert(isa<PointerType>(ArgTy));
+ assert(ArgTy->isPointerTy());
ArgTy = cast<PointerType>(ArgTy)->getElementType();
}
if (I != FTy->param_begin())
@@ -731,9 +569,8 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
FunctionInnards << "void";
}
FunctionInnards << ')';
- std::string tstr = FunctionInnards.str();
printType(Out, FTy->getReturnType(),
- /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), tstr);
+ /*isSigned=*/PAL.paramHasAttr(0, Attribute::SExt), FunctionInnards.str());
return Out;
}
case Type::StructTyID: {
@@ -756,8 +593,8 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
const PointerType *PTy = cast<PointerType>(Ty);
std::string ptrName = "*" + NameSoFar;
- if (isa<ArrayType>(PTy->getElementType()) ||
- isa<VectorType>(PTy->getElementType()))
+ if (PTy->getElementType()->isArrayTy() ||
+ PTy->getElementType()->isVectorTy())
ptrName = "(" + ptrName + ")";
if (!PAL.isEmpty())
@@ -1144,7 +981,7 @@ void CWriter::printConstant(Constant *CPV, bool Static) {
Out << "((";
printType(Out, CPV->getType()); // sign doesn't matter
Out << ")/*UNDEF*/";
- if (!isa<VectorType>(CPV->getType())) {
+ if (!CPV->getType()->isVectorTy()) {
Out << "0)";
} else {
Out << "{})";
@@ -1396,7 +1233,7 @@ bool CWriter::printConstExprCast(const ConstantExpr* CE, bool Static) {
}
if (NeedsExplicitCast) {
Out << "((";
- if (Ty->isInteger() && Ty != Type::getInt1Ty(Ty->getContext()))
+ if (Ty->isIntegerTy() && Ty != Type::getInt1Ty(Ty->getContext()))
printSimpleType(Out, Ty, TypeIsSigned);
else
printType(Out, Ty); // not integer, sign doesn't matter
@@ -1497,7 +1334,7 @@ void CWriter::writeInstComputationInline(Instruction &I) {
// We can't currently support integer types other than 1, 8, 16, 32, 64.
// Validate this.
const Type *Ty = I.getType();
- if (Ty->isInteger() && (Ty!=Type::getInt1Ty(I.getContext()) &&
+ if (Ty->isIntegerTy() && (Ty!=Type::getInt1Ty(I.getContext()) &&
Ty!=Type::getInt8Ty(I.getContext()) &&
Ty!=Type::getInt16Ty(I.getContext()) &&
Ty!=Type::getInt32Ty(I.getContext()) &&
@@ -1660,7 +1497,7 @@ void CWriter::writeOperandWithCast(Value* Operand, const ICmpInst &Cmp) {
// If the operand was a pointer, convert to a large integer type.
const Type* OpTy = Operand->getType();
- if (isa<PointerType>(OpTy))
+ if (OpTy->isPointerTy())
OpTy = TD->getIntPtrType(Operand->getContext());
Out << "((";
@@ -2102,10 +1939,10 @@ bool CWriter::doInitialization(Module &M) {
// complete. If the value is an aggregate, print out { 0 }, and let
// the compiler figure out the rest of the zeros.
Out << " = " ;
- if (isa<StructType>(I->getInitializer()->getType()) ||
- isa<VectorType>(I->getInitializer()->getType())) {
+ if (I->getInitializer()->getType()->isStructTy() ||
+ I->getInitializer()->getType()->isVectorTy()) {
Out << "{ 0 }";
- } else if (isa<ArrayType>(I->getInitializer()->getType())) {
+ } else if (I->getInitializer()->getType()->isArrayTy()) {
// As with structs and vectors, but with an extra set of braces
// because arrays are wrapped in structs.
Out << "{ { 0 } }";
@@ -2274,7 +2111,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
//
Out << "/* Structure contents */\n";
for (I = TST.begin(); I != End; ++I)
- if (isa<StructType>(I->second) || isa<ArrayType>(I->second))
+ if (I->second->isStructTy() || I->second->isArrayTy())
// Only print out used types!
printContainedStructs(I->second, StructPrinted);
}
@@ -2287,14 +2124,15 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
void CWriter::printContainedStructs(const Type *Ty,
std::set<const Type*> &StructPrinted) {
// Don't walk through pointers.
- if (isa<PointerType>(Ty) || Ty->isPrimitiveType() || Ty->isInteger()) return;
+ if (Ty->isPointerTy() || Ty->isPrimitiveType() || Ty->isIntegerTy())
+ return;
// Print all contained types first.
for (Type::subtype_iterator I = Ty->subtype_begin(),
E = Ty->subtype_end(); I != E; ++I)
printContainedStructs(*I, StructPrinted);
- if (isa<StructType>(Ty) || isa<ArrayType>(Ty)) {
+ if (Ty->isStructTy() || Ty->isArrayTy()) {
// Check to see if we have already printed this struct.
if (StructPrinted.insert(Ty).second) {
// Print structure type out.
@@ -2327,7 +2165,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
const AttrListPtr &PAL = F->getAttributes();
- std::stringstream FunctionInnards;
+ std::string tstr;
+ raw_string_ostream FunctionInnards(tstr);
// Print out the name...
FunctionInnards << GetValueName(F) << '(';
@@ -2382,7 +2221,7 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
if (PrintedArg) FunctionInnards << ", ";
const Type *ArgTy = *I;
if (PAL.paramHasAttr(Idx, Attribute::ByVal)) {
- assert(isa<PointerType>(ArgTy));
+ assert(ArgTy->isPointerTy());
ArgTy = cast<PointerType>(ArgTy)->getElementType();
}
printType(FunctionInnards, ArgTy,
@@ -2423,8 +2262,8 @@ static inline bool isFPIntBitCast(const Instruction &I) {
return false;
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DstTy = I.getType();
- return (SrcTy->isFloatingPoint() && DstTy->isInteger()) ||
- (DstTy->isFloatingPoint() && SrcTy->isInteger());
+ return (SrcTy->isFloatingPointTy() && DstTy->isIntegerTy()) ||
+ (DstTy->isFloatingPointTy() && SrcTy->isIntegerTy());
}
void CWriter::printFunction(Function &F) {
@@ -2713,7 +2552,7 @@ void CWriter::visitPHINode(PHINode &I) {
void CWriter::visitBinaryOperator(Instruction &I) {
// binary instructions, shift instructions, setCond instructions.
- assert(!isa<PointerType>(I.getType()));
+ assert(!I.getType()->isPointerTy());
// We must cast the results of binary operations which might be promoted.
bool needsCast = false;
@@ -3489,7 +3328,7 @@ void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I,
// exposed, like a global, avoid emitting (&foo)[0], just emit foo instead.
if (isAddressExposed(Ptr)) {
writeOperandInternal(Ptr, Static);
- } else if (I != E && isa<StructType>(*I)) {
+ } else if (I != E && (*I)->isStructTy()) {
// If we didn't already emit the first operand, see if we can print it as
// P->f instead of "P[0].f"
writeOperand(Ptr);
@@ -3504,13 +3343,13 @@ void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I,
}
for (; I != E; ++I) {
- if (isa<StructType>(*I)) {
+ if ((*I)->isStructTy()) {
Out << ".field" << cast<ConstantInt>(I.getOperand())->getZExtValue();
- } else if (isa<ArrayType>(*I)) {
+ } else if ((*I)->isArrayTy()) {
Out << ".array[";
writeOperandWithCast(I.getOperand(), Instruction::GetElementPtr);
Out << ']';
- } else if (!isa<VectorType>(*I)) {
+ } else if (!(*I)->isVectorTy()) {
Out << '[';
writeOperandWithCast(I.getOperand(), Instruction::GetElementPtr);
Out << ']';
@@ -3668,7 +3507,7 @@ void CWriter::visitInsertValueInst(InsertValueInst &IVI) {
i != e; ++i) {
const Type *IndexedTy =
ExtractValueInst::getIndexedType(IVI.getOperand(0)->getType(), b, i+1);
- if (isa<ArrayType>(IndexedTy))
+ if (IndexedTy->isArrayTy())
Out << ".array[" << *i << "]";
else
Out << ".field" << *i;
@@ -3689,7 +3528,7 @@ void CWriter::visitExtractValueInst(ExtractValueInst &EVI) {
i != e; ++i) {
const Type *IndexedTy =
ExtractValueInst::getIndexedType(EVI.getOperand(0)->getType(), b, i+1);
- if (isa<ArrayType>(IndexedTy))
+ if (IndexedTy->isArrayTy())
Out << ".array[" << *i << "]";
else
Out << ".field" << *i;
@@ -3705,7 +3544,8 @@ void CWriter::visitExtractValueInst(ExtractValueInst &EVI) {
bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &o,
CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel) {
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify) {
if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
PM.add(createGCLoweringPass());
diff --git a/lib/Target/CBackend/CTargetMachine.h b/lib/Target/CBackend/CTargetMachine.h
index 715bbda..d178e7f 100644
--- a/lib/Target/CBackend/CTargetMachine.h
+++ b/lib/Target/CBackend/CTargetMachine.h
@@ -27,7 +27,8 @@ struct CTargetMachine : public TargetMachine {
virtual bool addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel);
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify);
virtual const TargetData *getTargetData() const { return 0; }
};
diff --git a/lib/Target/CellSPU/SPU64InstrInfo.td b/lib/Target/CellSPU/SPU64InstrInfo.td
index 06eb149..47cb579 100644
--- a/lib/Target/CellSPU/SPU64InstrInfo.td
+++ b/lib/Target/CellSPU/SPU64InstrInfo.td
@@ -123,8 +123,8 @@ multiclass CompareLogicalGreaterThan64 {
defm I64LGT: CompareLogicalGreaterThan64;
def : Pat<(setugt R64C:$rA, R64C:$rB), I64LGTr64.Fragment>;
-def : Pat<(setugt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
- I64LGTv2i64.Fragment>;
+//def : Pat<(setugt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
+// I64LGTv2i64.Fragment>;
// i64 setult:
def : I64SETCCNegCond<setule, I64LGTr64>;
@@ -201,8 +201,8 @@ multiclass CompareGreaterThan64 {
defm I64GT: CompareLogicalGreaterThan64;
def : Pat<(setgt R64C:$rA, R64C:$rB), I64GTr64.Fragment>;
-def : Pat<(setgt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
- I64GTv2i64.Fragment>;
+//def : Pat<(setgt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
+// I64GTv2i64.Fragment>;
// i64 setult:
def : I64SETCCNegCond<setle, I64GTr64>;
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
index 80693e1..396a921 100644
--- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
+++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
@@ -294,15 +294,19 @@ namespace {
((vecVT == MVT::v2i64) &&
((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
(SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
- (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0))))
- return Select(bvNode);
+ (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) {
+ HandleSDNode Dummy(SDValue(bvNode, 0));
+ if (SDNode *N = Select(bvNode))
+ return N;
+ return Dummy.getValue().getNode();
+ }
// No, need to emit a constant pool spill:
std::vector<Constant*> CV;
for (size_t i = 0; i < bvNode->getNumOperands(); ++i) {
ConstantSDNode *V = dyn_cast<ConstantSDNode > (bvNode->getOperand(i));
- CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue()));
+ CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
}
Constant *CP = ConstantVector::get(CV);
@@ -311,10 +315,15 @@ namespace {
SDValue CGPoolOffset =
SPU::LowerConstantPool(CPIdx, *CurDAG,
SPUtli.getSPUTargetMachine());
- return SelectCode(CurDAG->getLoad(vecVT, dl,
- CurDAG->getEntryNode(), CGPoolOffset,
- PseudoSourceValue::getConstantPool(), 0,
- false, Alignment).getNode());
+
+ HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl,
+ CurDAG->getEntryNode(), CGPoolOffset,
+ PseudoSourceValue::getConstantPool(),0,
+ false, false, Alignment));
+ CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue());
+ if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
+ return N;
+ return Dummy.getValue().getNode();
}
/// Select - Convert the specified operand from a target-independent to a
@@ -390,10 +399,6 @@ namespace {
return false;
}
- /// InstructionSelect - This callback is invoked by
- /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
- virtual void InstructionSelect();
-
virtual const char *getPassName() const {
return "Cell SPU DAG->DAG Pattern Instruction Selection";
}
@@ -411,16 +416,6 @@ namespace {
};
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void
-SPUDAGToDAGISel::InstructionSelect()
-{
- // Select target instructions for the DAG.
- SelectRoot(*CurDAG);
- CurDAG->RemoveDeadNodes();
-}
-
/*!
\arg Op The ISD instruction operand
\arg N The address to be tested
@@ -692,9 +687,8 @@ SPUDAGToDAGISel::Select(SDNode *N) {
SDValue Ops[8];
DebugLoc dl = N->getDebugLoc();
- if (N->isMachineOpcode()) {
+ if (N->isMachineOpcode())
return NULL; // Already selected.
- }
if (Opc == ISD::FrameIndex) {
int FI = cast<FrameIndexSDNode>(N)->getIndex();
@@ -759,43 +753,67 @@ SPUDAGToDAGISel::Select(SDNode *N) {
}
SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode());
- SDNode *PromoteScalar =
- SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
- Op0VecVT, Op0).getNode());
-
+
+ HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
+ Op0VecVT, Op0));
+
+ SDValue PromScalar;
+ if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode()))
+ PromScalar = SDValue(N, 0);
+ else
+ PromScalar = PromoteScalar.getValue();
+
SDValue zextShuffle =
CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
- SDValue(PromoteScalar, 0),
- SDValue(PromoteScalar, 0),
+ PromScalar, PromScalar,
SDValue(shufMaskLoad, 0));
- // N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we
- // re-use it in the VEC2PREFSLOT selection without needing to explicitly
- // call SelectCode (it's already done for us.)
- SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle).getNode());
- return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
- zextShuffle).getNode());
+ HandleSDNode Dummy2(zextShuffle);
+ if (SDNode *N = SelectCode(Dummy2.getValue().getNode()))
+ zextShuffle = SDValue(N, 0);
+ else
+ zextShuffle = Dummy2.getValue();
+ HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
+ zextShuffle));
+
+ CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
+ SelectCode(Dummy.getValue().getNode());
+ return Dummy.getValue().getNode();
} else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
SDNode *CGLoad =
emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
- return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
- N->getOperand(0), N->getOperand(1),
- SDValue(CGLoad, 0)).getNode());
+ HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
+ N->getOperand(0), N->getOperand(1),
+ SDValue(CGLoad, 0)));
+
+ CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
+ if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
+ return N;
+ return Dummy.getValue().getNode();
} else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
SDNode *CGLoad =
emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode());
- return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
- N->getOperand(0), N->getOperand(1),
- SDValue(CGLoad, 0)).getNode());
+ HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
+ N->getOperand(0), N->getOperand(1),
+ SDValue(CGLoad, 0)));
+
+ CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
+ if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
+ return N;
+ return Dummy.getValue().getNode();
} else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
SDNode *CGLoad =
emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
- return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
- N->getOperand(0), N->getOperand(1),
- SDValue(CGLoad, 0)).getNode());
+ HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
+ N->getOperand(0), N->getOperand(1),
+ SDValue(CGLoad, 0)));
+ CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
+ if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
+ return N;
+ return Dummy.getValue().getNode();
} else if (Opc == ISD::TRUNCATE) {
SDValue Op0 = N->getOperand(0);
if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
@@ -832,17 +850,14 @@ SPUDAGToDAGISel::Select(SDNode *N) {
}
}
} else if (Opc == ISD::SHL) {
- if (OpVT == MVT::i64) {
+ if (OpVT == MVT::i64)
return SelectSHLi64(N, OpVT);
- }
} else if (Opc == ISD::SRL) {
- if (OpVT == MVT::i64) {
+ if (OpVT == MVT::i64)
return SelectSRLi64(N, OpVT);
- }
} else if (Opc == ISD::SRA) {
- if (OpVT == MVT::i64) {
+ if (OpVT == MVT::i64)
return SelectSRAi64(N, OpVT);
- }
} else if (Opc == ISD::FNEG
&& (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
DebugLoc dl = N->getDebugLoc();
@@ -1224,13 +1239,15 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
? shufmask.getNode()
: emitBuildVector(shufmask.getNode()));
- SDNode *shufNode =
- Select(CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
+ SDValue shufNode =
+ CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
SDValue(lhsNode, 0), SDValue(rhsNode, 0),
- SDValue(shufMaskNode, 0)).getNode());
-
- return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
- SDValue(shufNode, 0));
+ SDValue(shufMaskNode, 0));
+ HandleSDNode Dummy(shufNode);
+ SDNode *SN = SelectCode(Dummy.getValue().getNode());
+ if (SN == 0) SN = Dummy.getValue().getNode();
+
+ return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(SN, 0));
} else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
SDValue(emitBuildVector(i64vec.getNode()), 0));
diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp
index fe0f019..e863ee3 100644
--- a/lib/Target/CellSPU/SPUISelLowering.cpp
+++ b/lib/Target/CellSPU/SPUISelLowering.cpp
@@ -25,7 +25,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/Debug.h"
@@ -118,8 +118,7 @@ namespace {
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
0, TLI.getLibcallCallingConv(LC), false,
/*isReturnValueUsed=*/true,
- Callee, Args, DAG, Op.getDebugLoc(),
- DAG.GetOrdering(InChain.getNode()));
+ Callee, Args, DAG, Op.getDebugLoc());
return CallInfo.first;
}
@@ -669,7 +668,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
// Re-emit as a v16i8 vector load
result = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
LN->getSrcValue(), LN->getSrcValueOffset(),
- LN->isVolatile(), 16);
+ LN->isVolatile(), LN->isNonTemporal(), 16);
// Update the chain
the_chain = result.getValue(1);
@@ -820,7 +819,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
// Re-emit as a v16i8 vector load
alignLoadVec = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
SN->getSrcValue(), SN->getSrcValueOffset(),
- SN->isVolatile(), 16);
+ SN->isVolatile(), SN->isNonTemporal(), 16);
// Update the chain
the_chain = alignLoadVec.getValue(1);
@@ -861,7 +860,8 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
result = DAG.getStore(the_chain, dl, result, basePtr,
LN->getSrcValue(), LN->getSrcValueOffset(),
- LN->isVolatile(), LN->getAlignment());
+ LN->isVolatile(), LN->isNonTemporal(),
+ LN->getAlignment());
#if 0 && !defined(NDEBUG)
if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
@@ -1086,7 +1086,7 @@ SPUTargetLowering::LowerFormalArguments(SDValue Chain,
// or we're forced to do vararg
int FI = MFI->CreateFixedObject(ObjSize, ArgOffset, true, false);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
- ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0);
+ ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0, false, false, 0);
ArgOffset += StackSlotSize;
}
@@ -1108,7 +1108,8 @@ SPUTargetLowering::LowerFormalArguments(SDValue Chain,
true, false);
SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
- SDValue Store = DAG.getStore(Chain, dl, ArgVal, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, ArgVal, FIN, NULL, 0,
+ false, false, 0);
Chain = Store.getOperand(0);
MemOps.push_back(Store);
@@ -1190,7 +1191,8 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (ArgRegIdx != NumArgRegs) {
RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
} else {
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
ArgOffset += StackSlotSize;
}
break;
@@ -1199,7 +1201,8 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (ArgRegIdx != NumArgRegs) {
RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
} else {
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
ArgOffset += StackSlotSize;
}
break;
@@ -1212,7 +1215,8 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (ArgRegIdx != NumArgRegs) {
RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
} else {
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
ArgOffset += StackSlotSize;
}
break;
diff --git a/lib/Target/CellSPU/SPUMCAsmInfo.cpp b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
index 5ef3c6b..3e17a51 100644
--- a/lib/Target/CellSPU/SPUMCAsmInfo.cpp
+++ b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
@@ -34,5 +34,8 @@ SPULinuxMCAsmInfo::SPULinuxMCAsmInfo(const Target &T, const StringRef &TT) {
// Exception handling is not supported on CellSPU (think about it: you only
// have 256K for code+data. Would you support exception handling?)
ExceptionsType = ExceptionHandling::None;
+
+ // SPU assembly requires ".section" before ".bss"
+ UsesELFSectionDirectiveForBSS = true;
}
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 3dd8ca7..9c5893c 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -221,7 +221,7 @@ namespace {
APFloat APF = APFloat(CFP->getValueAPF()); // copy
if (CFP->getType() == Type::getFloatTy(CFP->getContext()))
APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
- Out << "ConstantFP::get(getGlobalContext(), ";
+ Out << "ConstantFP::get(mod->getContext(), ";
Out << "APFloat(";
#if HAVE_PRINTF_A
char Buffer[100];
@@ -344,23 +344,23 @@ namespace {
std::string CppWriter::getCppName(const Type* Ty) {
// First, handle the primitive types .. easy
- if (Ty->isPrimitiveType() || Ty->isInteger()) {
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy()) {
switch (Ty->getTypeID()) {
- case Type::VoidTyID: return "Type::getVoidTy(getGlobalContext())";
+ case Type::VoidTyID: return "Type::getVoidTy(mod->getContext())";
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
- return "IntegerType::get(getGlobalContext(), " + utostr(BitWidth) + ")";
+ return "IntegerType::get(mod->getContext(), " + utostr(BitWidth) + ")";
}
- case Type::X86_FP80TyID: return "Type::getX86_FP80Ty(getGlobalContext())";
- case Type::FloatTyID: return "Type::getFloatTy(getGlobalContext())";
- case Type::DoubleTyID: return "Type::getDoubleTy(getGlobalContext())";
- case Type::LabelTyID: return "Type::getLabelTy(getGlobalContext())";
+ case Type::X86_FP80TyID: return "Type::getX86_FP80Ty(mod->getContext())";
+ case Type::FloatTyID: return "Type::getFloatTy(mod->getContext())";
+ case Type::DoubleTyID: return "Type::getDoubleTy(mod->getContext())";
+ case Type::LabelTyID: return "Type::getLabelTy(mod->getContext())";
default:
error("Invalid primitive type");
break;
}
// shouldn't be returned, but make it sensible
- return "Type::getVoidTy(getGlobalContext())";
+ return "Type::getVoidTy(mod->getContext())";
}
// Now, see if we've seen the type before and return that
@@ -493,7 +493,7 @@ namespace {
bool CppWriter::printTypeInternal(const Type* Ty) {
// We don't print definitions for primitive types
- if (Ty->isPrimitiveType() || Ty->isInteger())
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy())
return false;
// If we already defined this type, we don't need to define it again.
@@ -514,7 +514,7 @@ namespace {
TypeMap::const_iterator I = UnresolvedTypes.find(Ty);
if (I == UnresolvedTypes.end()) {
Out << "PATypeHolder " << typeName;
- Out << "_fwd = OpaqueType::get(getGlobalContext());";
+ Out << "_fwd = OpaqueType::get(mod->getContext());";
nl(Out);
UnresolvedTypes[Ty] = typeName;
}
@@ -615,7 +615,7 @@ namespace {
}
case Type::OpaqueTyID: {
Out << "OpaqueType* " << typeName;
- Out << " = OpaqueType::get(getGlobalContext());";
+ Out << " = OpaqueType::get(mod->getContext());";
nl(Out);
break;
}
@@ -686,7 +686,7 @@ namespace {
// For primitive types and types already defined, just add a name
TypeMap::const_iterator TNI = TypeNames.find(TI->second);
- if (TI->second->isInteger() || TI->second->isPrimitiveType() ||
+ if (TI->second->isIntegerTy() || TI->second->isPrimitiveType() ||
TNI != TypeNames.end()) {
Out << "mod->addTypeName(\"";
printEscapedString(TI->first);
@@ -751,7 +751,7 @@ namespace {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
std::string constValue = CI->getValue().toString(10, true);
Out << "ConstantInt* " << constName
- << " = ConstantInt::get(getGlobalContext(), APInt("
+ << " = ConstantInt::get(mod->getContext(), APInt("
<< cast<IntegerType>(CI->getType())->getBitWidth()
<< ", StringRef(\"" << constValue << "\"), 10));";
} else if (isa<ConstantAggregateZero>(CV)) {
@@ -769,7 +769,7 @@ namespace {
CA->getType()->getElementType() ==
Type::getInt8Ty(CA->getContext())) {
Out << "Constant* " << constName <<
- " = ConstantArray::get(getGlobalContext(), \"";
+ " = ConstantArray::get(mod->getContext(), \"";
std::string tmp = CA->getAsString();
bool nullTerminate = false;
if (tmp[tmp.length()-1] == 0) {
@@ -995,7 +995,7 @@ namespace {
void CppWriter::printVariableHead(const GlobalVariable *GV) {
nl(Out) << "GlobalVariable* " << getCppName(GV);
if (is_inline) {
- Out << " = mod->getGlobalVariable(getGlobalContext(), ";
+ Out << " = mod->getGlobalVariable(mod->getContext(), ";
printEscapedString(GV->getName());
Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
nl(Out) << "if (!" << getCppName(GV) << ") {";
@@ -1094,7 +1094,7 @@ namespace {
case Instruction::Ret: {
const ReturnInst* ret = cast<ReturnInst>(I);
- Out << "ReturnInst::Create(getGlobalContext(), "
+ Out << "ReturnInst::Create(mod->getContext(), "
<< (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
break;
}
@@ -1171,7 +1171,7 @@ namespace {
}
case Instruction::Unreachable: {
Out << "new UnreachableInst("
- << "getGlobalContext(), "
+ << "mod->getContext(), "
<< bbname << ");";
break;
}
@@ -1673,7 +1673,7 @@ namespace {
BI != BE; ++BI) {
std::string bbname(getCppName(BI));
Out << "BasicBlock* " << bbname <<
- " = BasicBlock::Create(getGlobalContext(), \"";
+ " = BasicBlock::Create(mod->getContext(), \"";
if (BI->hasName())
printEscapedString(BI->getName());
Out << "\"," << getCppName(BI->getParent()) << ",0);";
@@ -2009,7 +2009,8 @@ char CppWriter::ID = 0;
bool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &o,
CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel) {
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify) {
if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
PM.add(new CppWriter(o));
return false;
diff --git a/lib/Target/CppBackend/CPPTargetMachine.h b/lib/Target/CppBackend/CPPTargetMachine.h
index 1f74f76..b7aae91 100644
--- a/lib/Target/CppBackend/CPPTargetMachine.h
+++ b/lib/Target/CppBackend/CPPTargetMachine.h
@@ -30,7 +30,8 @@ struct CPPTargetMachine : public TargetMachine {
virtual bool addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel);
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify);
virtual const TargetData *getTargetData() const { return 0; }
};
diff --git a/lib/Target/MBlaze/AsmPrinter/CMakeLists.txt b/lib/Target/MBlaze/AsmPrinter/CMakeLists.txt
new file mode 100644
index 0000000..cfb2fc8
--- /dev/null
+++ b/lib/Target/MBlaze/AsmPrinter/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ )
+
+add_llvm_library(LLVMMBlazeAsmPrinter
+ MBlazeAsmPrinter.cpp
+ )
+add_dependencies(LLVMMBlazeAsmPrinter MBlazeCodeGenTable_gen) \ No newline at end of file
diff --git a/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
new file mode 100644
index 0000000..6fe1026
--- /dev/null
+++ b/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
@@ -0,0 +1,302 @@
+//===-- MBlazeAsmPrinter.cpp - MBlaze LLVM assembly writer ----------------===//
+//
+// 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 printer that converts from our internal representation
+// of machine-dependent LLVM code to GAS-format MBlaze assembly language.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "mblaze-asm-printer"
+
+#include "MBlaze.h"
+#include "MBlazeSubtarget.h"
+#include "MBlazeInstrInfo.h"
+#include "MBlazeTargetMachine.h"
+#include "MBlazeMachineFunction.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/DwarfWriter.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/MathExtras.h"
+#include <cctype>
+
+using namespace llvm;
+
+namespace {
+ class MBlazeAsmPrinter : public AsmPrinter {
+ const MBlazeSubtarget *Subtarget;
+ public:
+ explicit MBlazeAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T )
+ : AsmPrinter(O, TM, Ctx, Streamer, T) {
+ Subtarget = &TM.getSubtarget<MBlazeSubtarget>();
+ }
+
+ virtual const char *getPassName() const {
+ return "MBlaze Assembly Printer";
+ }
+
+ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode);
+ void printOperand(const MachineInstr *MI, int opNum);
+ void printUnsignedImm(const MachineInstr *MI, int opNum);
+ void printFSLImm(const MachineInstr *MI, int opNum);
+ void printMemOperand(const MachineInstr *MI, int opNum,
+ const char *Modifier = 0);
+ void printFCCOperand(const MachineInstr *MI, int opNum,
+ const char *Modifier = 0);
+ void printSavedRegsBitmask();
+ void printHex32(unsigned int Value);
+
+ const char *emitCurrentABIString();
+ void emitFrameDirective();
+
+ void printInstruction(const MachineInstr *MI); // autogenerated.
+ void EmitInstruction(const MachineInstr *MI) {
+ printInstruction(MI);
+ O << '\n';
+ }
+ virtual void EmitFunctionBodyStart();
+ virtual void EmitFunctionBodyEnd();
+ static const char *getRegisterName(unsigned RegNo);
+
+ virtual void EmitFunctionEntryLabel();
+ void EmitStartOfAsmFile(Module &M);
+ };
+} // end of anonymous namespace
+
+#include "MBlazeGenAsmWriter.inc"
+
+//===----------------------------------------------------------------------===//
+//
+// MBlaze Asm Directives
+//
+// -- Frame directive "frame Stackpointer, Stacksize, RARegister"
+// Describe the stack frame.
+//
+// -- Mask directives "mask bitmask, offset"
+// Tells the assembler which registers are saved and where.
+// bitmask - contain a little endian bitset indicating which registers are
+// saved on function prologue (e.g. with a 0x80000000 mask, the
+// assembler knows the register 31 (RA) is saved at prologue.
+// offset - the position before stack pointer subtraction indicating where
+// the first saved register on prologue is located. (e.g. with a
+//
+// Consider the following function prologue:
+//
+// .frame R19,48,R15
+// .mask 0xc0000000,-8
+// addiu R1, R1, -48
+// sw R15, 40(R1)
+// sw R19, 36(R1)
+//
+// With a 0xc0000000 mask, the assembler knows the register 15 (R15) and
+// 19 (R19) are saved at prologue. As the save order on prologue is from
+// left to right, R15 is saved first. A -8 offset means that after the
+// stack pointer subtration, the first register in the mask (R15) will be
+// saved at address 48-8=40.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Mask directives
+//===----------------------------------------------------------------------===//
+
+// Create a bitmask with all callee saved registers for CPU or Floating Point
+// registers. For CPU registers consider RA, GP and FP for saving if necessary.
+void MBlazeAsmPrinter::printSavedRegsBitmask() {
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+ const MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
+
+ // CPU Saved Registers Bitmasks
+ unsigned int CPUBitmask = 0;
+
+ // Set the CPU Bitmasks
+ const MachineFrameInfo *MFI = MF->getFrameInfo();
+ const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
+ for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+ unsigned RegNum = MBlazeRegisterInfo::getRegisterNumbering(CSI[i].getReg());
+ if (CSI[i].getRegClass() == MBlaze::CPURegsRegisterClass)
+ CPUBitmask |= (1 << RegNum);
+ }
+
+ // Return Address and Frame registers must also be set in CPUBitmask.
+ if (RI.hasFP(*MF))
+ CPUBitmask |= (1 << MBlazeRegisterInfo::
+ getRegisterNumbering(RI.getFrameRegister(*MF)));
+
+ if (MFI->hasCalls())
+ CPUBitmask |= (1 << MBlazeRegisterInfo::
+ getRegisterNumbering(RI.getRARegister()));
+
+ // Print CPUBitmask
+ O << "\t.mask \t"; printHex32(CPUBitmask); O << ','
+ << MBlazeFI->getCPUTopSavedRegOff() << '\n';
+}
+
+// Print a 32 bit hex number with all numbers.
+void MBlazeAsmPrinter::printHex32(unsigned int Value) {
+ O << "0x";
+ for (int i = 7; i >= 0; i--)
+ O << utohexstr( (Value & (0xF << (i*4))) >> (i*4) );
+}
+
+//===----------------------------------------------------------------------===//
+// Frame and Set directives
+//===----------------------------------------------------------------------===//
+
+/// Frame Directive
+void MBlazeAsmPrinter::emitFrameDirective() {
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+
+ unsigned stackReg = RI.getFrameRegister(*MF);
+ unsigned returnReg = RI.getRARegister();
+ unsigned stackSize = MF->getFrameInfo()->getStackSize();
+
+
+ O << "\t.frame\t" << getRegisterName(stackReg)
+ << ',' << stackSize << ','
+ << getRegisterName(returnReg)
+ << '\n';
+}
+
+void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
+ O << "\t.ent\t" << *CurrentFnSym << '\n';
+ OutStreamer.EmitLabel(CurrentFnSym);
+}
+
+/// EmitFunctionBodyStart - Targets can override this to emit stuff before
+/// the first basic block in the function.
+void MBlazeAsmPrinter::EmitFunctionBodyStart() {
+ emitFrameDirective();
+ printSavedRegsBitmask();
+}
+
+/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
+/// the last basic block in the function.
+void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
+ O << "\t.end\t" << *CurrentFnSym << '\n';
+}
+
+// Print out an operand for an inline asm expression.
+bool MBlazeAsmPrinter::
+PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant,const char *ExtraCode){
+ // Does this asm operand have a single letter operand modifier?
+ if (ExtraCode && ExtraCode[0])
+ return true; // Unknown modifier.
+
+ printOperand(MI, OpNo);
+ return false;
+}
+
+void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
+ const MachineOperand &MO = MI->getOperand(opNum);
+
+ switch (MO.getType()) {
+ case MachineOperand::MO_Register:
+ O << getRegisterName(MO.getReg());
+ break;
+
+ case MachineOperand::MO_Immediate:
+ O << (int)MO.getImm();
+ break;
+
+ case MachineOperand::MO_FPImmediate: {
+ const ConstantFP* fp = MO.getFPImm();
+ printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue());
+ O << ";\t# immediate = " << *fp;
+ break;
+ }
+
+ case MachineOperand::MO_MachineBasicBlock:
+ O << *MO.getMBB()->getSymbol(OutContext);
+ return;
+
+ case MachineOperand::MO_GlobalAddress:
+ O << *GetGlobalValueSymbol(MO.getGlobal());
+ break;
+
+ case MachineOperand::MO_ExternalSymbol:
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
+ break;
+
+ case MachineOperand::MO_JumpTableIndex:
+ O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << '_' << MO.getIndex();
+ break;
+
+ case MachineOperand::MO_ConstantPoolIndex:
+ O << MAI->getPrivateGlobalPrefix() << "CPI"
+ << getFunctionNumber() << "_" << MO.getIndex();
+ if (MO.getOffset())
+ O << "+" << MO.getOffset();
+ break;
+
+ default:
+ llvm_unreachable("<unknown operand type>");
+ }
+}
+
+void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum) {
+ const MachineOperand &MO = MI->getOperand(opNum);
+ if (MO.getType() == MachineOperand::MO_Immediate)
+ O << (unsigned int)MO.getImm();
+ else
+ printOperand(MI, opNum);
+}
+
+void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum) {
+ const MachineOperand &MO = MI->getOperand(opNum);
+ if (MO.getType() == MachineOperand::MO_Immediate)
+ O << "rfsl" << (unsigned int)MO.getImm();
+ else
+ printOperand(MI, opNum);
+}
+
+void MBlazeAsmPrinter::
+printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
+ printOperand(MI, opNum+1);
+ O << ", ";
+ printOperand(MI, opNum);
+}
+
+void MBlazeAsmPrinter::
+printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
+ const MachineOperand& MO = MI->getOperand(opNum);
+ O << MBlaze::MBlazeFCCToString((MBlaze::CondCode)MO.getImm());
+}
+
+void MBlazeAsmPrinter::EmitStartOfAsmFile(Module &M) {
+}
+
+// Force static initialization.
+extern "C" void LLVMInitializeMBlazeAsmPrinter() {
+ RegisterAsmPrinter<MBlazeAsmPrinter> X(TheMBlazeTarget);
+}
diff --git a/lib/Target/MBlaze/AsmPrinter/Makefile b/lib/Target/MBlaze/AsmPrinter/Makefile
new file mode 100644
index 0000000..c8e4d8f
--- /dev/null
+++ b/lib/Target/MBlaze/AsmPrinter/Makefile
@@ -0,0 +1,17 @@
+##===- lib/Target/MBlaze/AsmPrinter/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 = LLVMMBlazeAsmPrinter
+
+# Hack: we need to include 'main' MBlaze target directory to grab
+# private headers
+CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Target/MBlaze/CMakeLists.txt b/lib/Target/MBlaze/CMakeLists.txt
new file mode 100644
index 0000000..c93e3df
--- /dev/null
+++ b/lib/Target/MBlaze/CMakeLists.txt
@@ -0,0 +1,27 @@
+set(LLVM_TARGET_DEFINITIONS MBlaze.td)
+
+tablegen(MBlazeGenRegisterInfo.h.inc -gen-register-desc-header)
+tablegen(MBlazeGenRegisterNames.inc -gen-register-enums)
+tablegen(MBlazeGenRegisterInfo.inc -gen-register-desc)
+tablegen(MBlazeGenInstrNames.inc -gen-instr-enums)
+tablegen(MBlazeGenInstrInfo.inc -gen-instr-desc)
+tablegen(MBlazeGenAsmWriter.inc -gen-asm-writer)
+tablegen(MBlazeGenDAGISel.inc -gen-dag-isel)
+tablegen(MBlazeGenCallingConv.inc -gen-callingconv)
+tablegen(MBlazeGenSubtarget.inc -gen-subtarget)
+tablegen(MBlazeGenIntrinsics.inc -gen-tgt-intrinsic)
+
+add_llvm_target(MBlazeCodeGen
+ MBlazeDelaySlotFiller.cpp
+ MBlazeInstrInfo.cpp
+ MBlazeISelDAGToDAG.cpp
+ MBlazeISelLowering.cpp
+ MBlazeMCAsmInfo.cpp
+ MBlazeRegisterInfo.cpp
+ MBlazeSubtarget.cpp
+ MBlazeTargetMachine.cpp
+ MBlazeTargetObjectFile.cpp
+ MBlazeIntrinsicInfo.cpp
+ )
+
+target_link_libraries (LLVMMBlazeCodeGen LLVMSelectionDAG)
diff --git a/lib/Target/MBlaze/MBlaze.h b/lib/Target/MBlaze/MBlaze.h
new file mode 100644
index 0000000..f9d828b
--- /dev/null
+++ b/lib/Target/MBlaze/MBlaze.h
@@ -0,0 +1,39 @@
+//===-- MBlaze.h - Top-level interface for MBlaze ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the entry points for global functions defined in
+// the LLVM MBlaze back-end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TARGET_MBLAZE_H
+#define TARGET_MBLAZE_H
+
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+ class MBlazeTargetMachine;
+ class FunctionPass;
+ class MachineCodeEmitter;
+ class formatted_raw_ostream;
+
+ FunctionPass *createMBlazeISelDag(MBlazeTargetMachine &TM);
+ FunctionPass *createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &TM);
+
+ extern Target TheMBlazeTarget;
+} // end namespace llvm;
+
+// Defines symbolic names for MBlaze registers. This defines a mapping from
+// register name to register number.
+#include "MBlazeGenRegisterNames.inc"
+
+// Defines symbolic names for the MBlaze instructions.
+#include "MBlazeGenInstrNames.inc"
+
+#endif
diff --git a/lib/Target/MBlaze/MBlaze.td b/lib/Target/MBlaze/MBlaze.td
new file mode 100644
index 0000000..1679752
--- /dev/null
+++ b/lib/Target/MBlaze/MBlaze.td
@@ -0,0 +1,85 @@
+//===- MBlaze.td - Describe the MBlaze Target Machine -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This is the top level entry point for the MBlaze target.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Target-independent interfaces
+//===----------------------------------------------------------------------===//
+
+include "llvm/Target/Target.td"
+
+//===----------------------------------------------------------------------===//
+// Register File, Calling Conv, Instruction Descriptions
+//===----------------------------------------------------------------------===//
+
+include "MBlazeRegisterInfo.td"
+include "MBlazeSchedule.td"
+include "MBlazeIntrinsics.td"
+include "MBlazeInstrInfo.td"
+include "MBlazeCallingConv.td"
+
+def MBlazeInstrInfo : InstrInfo {
+ let TSFlagsFields = [];
+ let TSFlagsShifts = [];
+}
+
+
+//===----------------------------------------------------------------------===//
+// Microblaze Subtarget features //
+//===----------------------------------------------------------------------===//
+
+def FeaturePipe3 : SubtargetFeature<"pipe3", "HasPipe3", "true",
+ "Implements 3-stage pipeline.">;
+def FeatureBarrel : SubtargetFeature<"barrel", "HasBarrel", "true",
+ "Implements barrel shifter.">;
+def FeatureDiv : SubtargetFeature<"div", "HasDiv", "true",
+ "Implements hardware divider.">;
+def FeatureMul : SubtargetFeature<"mul", "HasMul", "true",
+ "Implements hardware multiplier.">;
+def FeatureFSL : SubtargetFeature<"fsl", "HasFSL", "true",
+ "Implements FSL instructions.">;
+def FeatureEFSL : SubtargetFeature<"efsl", "HasEFSL", "true",
+ "Implements extended FSL instructions.">;
+def FeatureMSRSet : SubtargetFeature<"msrset", "HasMSRSet", "true",
+ "Implements MSR register set and clear.">;
+def FeatureException : SubtargetFeature<"exception", "HasException", "true",
+ "Implements hardware exception support.">;
+def FeaturePatCmp : SubtargetFeature<"patcmp", "HasPatCmp", "true",
+ "Implements pattern compare instruction.">;
+def FeatureFPU : SubtargetFeature<"fpu", "HasFPU", "true",
+ "Implements floating point unit.">;
+def FeatureESR : SubtargetFeature<"esr", "HasESR", "true",
+ "Implements ESR and EAR registers">;
+def FeaturePVR : SubtargetFeature<"pvr", "HasPVR", "true",
+ "Implements processor version register.">;
+def FeatureMul64 : SubtargetFeature<"mul64", "HasMul64", "true",
+ "Implements multiplier with 64-bit result">;
+def FeatureSqrt : SubtargetFeature<"sqrt", "HasSqrt", "true",
+ "Implements sqrt and floating point convert.">;
+def FeatureMMU : SubtargetFeature<"mmu", "HasMMU", "true",
+ "Implements memory management unit.">;
+
+//===----------------------------------------------------------------------===//
+// MBlaze processors supported.
+//===----------------------------------------------------------------------===//
+
+class Proc<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, MBlazeGenericItineraries, Features>;
+
+
+def : Proc<"v400", []>;
+def : Proc<"v500", []>;
+def : Proc<"v600", []>;
+def : Proc<"v700", []>;
+def : Proc<"v710", []>;
+
+def MBlaze : Target {
+ let InstructionSet = MBlazeInstrInfo;
+}
diff --git a/lib/Target/MBlaze/MBlazeCallingConv.td b/lib/Target/MBlaze/MBlazeCallingConv.td
new file mode 100644
index 0000000..ddd4998
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeCallingConv.td
@@ -0,0 +1,26 @@
+//===- MBlazeCallingConv.td - Calling Conventions for MBlaze ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This describes the calling conventions for MBlaze architecture.
+//===----------------------------------------------------------------------===//
+
+/// CCIfSubtarget - Match if the current subtarget has a feature F.
+class CCIfSubtarget<string F, CCAction A>:
+ CCIf<!strconcat("State.getTarget().getSubtarget<MBlazeSubtarget>().", F), A>;
+
+//===----------------------------------------------------------------------===//
+// MBlaze ABI Calling Convention
+//===----------------------------------------------------------------------===//
+
+def RetCC_MBlaze : CallingConv<[
+ // i32 are returned in registers R3, R4
+ CCIfType<[i32], CCAssignToReg<[R3, R4]>>,
+
+ // f32 are returned in registers F3, F4
+ CCIfType<[f32], CCAssignToReg<[F3, F4]>>
+]>;
diff --git a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp
new file mode 100644
index 0000000..42fea25
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp
@@ -0,0 +1,75 @@
+//===-- DelaySlotFiller.cpp - MBlaze delay slot filler --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Simple pass to fills delay slots with NOPs.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "delay-slot-filler"
+
+#include "MBlaze.h"
+#include "MBlazeTargetMachine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/ADT/Statistic.h"
+
+using namespace llvm;
+
+STATISTIC(FilledSlots, "Number of delay slots filled");
+
+namespace {
+ struct Filler : public MachineFunctionPass {
+
+ TargetMachine &TM;
+ const TargetInstrInfo *TII;
+
+ static char ID;
+ Filler(TargetMachine &tm)
+ : MachineFunctionPass(&ID), TM(tm), TII(tm.getInstrInfo()) { }
+
+ virtual const char *getPassName() const {
+ return "MBlaze Delay Slot Filler";
+ }
+
+ bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
+ bool runOnMachineFunction(MachineFunction &F) {
+ bool Changed = false;
+ for (MachineFunction::iterator FI = F.begin(), FE = F.end();
+ FI != FE; ++FI)
+ Changed |= runOnMachineBasicBlock(*FI);
+ return Changed;
+ }
+
+ };
+ char Filler::ID = 0;
+} // end of anonymous namespace
+
+/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
+/// Currently, we fill delay slots with NOPs. We assume there is only one
+/// delay slot per delayed instruction.
+bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
+ bool Changed = false;
+ for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
+ if (I->getDesc().hasDelaySlot()) {
+ MachineBasicBlock::iterator J = I;
+ ++J;
+ BuildMI(MBB, J, I->getDebugLoc(), TII->get(MBlaze::NOP));
+ ++FilledSlots;
+ Changed = true;
+ }
+ return Changed;
+}
+
+/// createMBlazeDelaySlotFillerPass - Returns a pass that fills in delay
+/// slots in MBlaze MachineFunctions
+FunctionPass *llvm::createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &tm) {
+ return new Filler(tm);
+}
+
diff --git a/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
new file mode 100644
index 0000000..7e59c4a
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp
@@ -0,0 +1,339 @@
+//===-- MBlazeISelDAGToDAG.cpp - A dag to dag inst selector for MBlaze ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an instruction selector for the MBlaze target.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "mblaze-isel"
+#include "MBlaze.h"
+#include "MBlazeISelLowering.h"
+#include "MBlazeMachineFunction.h"
+#include "MBlazeRegisterInfo.h"
+#include "MBlazeSubtarget.h"
+#include "MBlazeTargetMachine.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Type.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Instruction Selector Implementation
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// MBlazeDAGToDAGISel - MBlaze specific code to select MBlaze machine
+// instructions for SelectionDAG operations.
+//===----------------------------------------------------------------------===//
+namespace {
+
+class MBlazeDAGToDAGISel : public SelectionDAGISel {
+
+ /// TM - Keep a reference to MBlazeTargetMachine.
+ MBlazeTargetMachine &TM;
+
+ /// Subtarget - Keep a pointer to the MBlazeSubtarget around so that we can
+ /// make the right decision when generating code for different targets.
+ const MBlazeSubtarget &Subtarget;
+
+public:
+ explicit MBlazeDAGToDAGISel(MBlazeTargetMachine &tm) :
+ SelectionDAGISel(tm),
+ TM(tm), Subtarget(tm.getSubtarget<MBlazeSubtarget>()) {}
+
+ // Pass Name
+ virtual const char *getPassName() const {
+ return "MBlaze DAG->DAG Pattern Instruction Selection";
+ }
+private:
+ // Include the pieces autogenerated from the target description.
+ #include "MBlazeGenDAGISel.inc"
+
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const MBlazeTargetMachine &getTargetMachine() {
+ return static_cast<const MBlazeTargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const MBlazeInstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
+ SDNode *getGlobalBaseReg();
+ SDNode *Select(SDNode *N);
+
+ // Complex Pattern.
+ bool SelectAddr(SDNode *Op, SDValue N,
+ SDValue &Base, SDValue &Offset);
+
+ // Address Selection
+ bool SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index);
+ bool SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base);
+
+ // getI32Imm - Return a target constant with the specified value, of type i32.
+ inline SDValue getI32Imm(unsigned Imm) {
+ return CurDAG->getTargetConstant(Imm, MVT::i32);
+ }
+};
+
+}
+
+/// isIntS32Immediate - This method tests to see if the node is either a 32-bit
+/// or 64-bit immediate, and if the value can be accurately represented as a
+/// sign extension from a 32-bit value. If so, this returns true and the
+/// immediate.
+static bool isIntS32Immediate(SDNode *N, int32_t &Imm) {
+ unsigned Opc = N->getOpcode();
+ if (Opc != ISD::Constant)
+ return false;
+
+ Imm = (int32_t)cast<ConstantSDNode>(N)->getZExtValue();
+ if (N->getValueType(0) == MVT::i32)
+ return Imm == (int32_t)cast<ConstantSDNode>(N)->getZExtValue();
+ else
+ return Imm == (int64_t)cast<ConstantSDNode>(N)->getZExtValue();
+}
+
+static bool isIntS32Immediate(SDValue Op, int32_t &Imm) {
+ return isIntS32Immediate(Op.getNode(), Imm);
+}
+
+
+/// SelectAddressRegReg - Given the specified addressed, check to see if it
+/// can be represented as an indexed [r+r] operation. Returns false if it
+/// can be more efficiently represented with [r+imm].
+bool MBlazeDAGToDAGISel::
+SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) {
+ if (N.getOpcode() == ISD::FrameIndex) return false;
+ if (N.getOpcode() == ISD::TargetExternalSymbol ||
+ N.getOpcode() == ISD::TargetGlobalAddress)
+ return false; // direct calls.
+
+ int32_t imm = 0;
+ if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
+ if (isIntS32Immediate(N.getOperand(1), imm))
+ return false; // r+i
+
+ if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable ||
+ N.getOperand(1).getOpcode() == ISD::TargetJumpTable)
+ return false; // jump tables.
+
+ Base = N.getOperand(1);
+ Index = N.getOperand(0);
+ return true;
+ }
+
+ return false;
+}
+
+/// Returns true if the address N can be represented by a base register plus
+/// a signed 32-bit displacement [r+imm], and if it is not better
+/// represented as reg+reg.
+bool MBlazeDAGToDAGISel::
+SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base) {
+ // If this can be more profitably realized as r+r, fail.
+ if (SelectAddrRegReg(Op, N, Disp, Base))
+ return false;
+
+ if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
+ int32_t imm = 0;
+ if (isIntS32Immediate(N.getOperand(1), imm)) {
+ Disp = CurDAG->getTargetConstant(imm, MVT::i32);
+ if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
+ Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
+ } else {
+ Base = N.getOperand(0);
+ }
+ DEBUG( errs() << "WESLEY: Using Operand Immediate\n" );
+ return true; // [r+i]
+ }
+ } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
+ // Loading from a constant address.
+ uint32_t Imm = CN->getZExtValue();
+ Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0));
+ Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0));
+ DEBUG( errs() << "WESLEY: Using Constant Node\n" );
+ return true;
+ }
+
+ Disp = CurDAG->getTargetConstant(0, TM.getTargetLowering()->getPointerTy());
+ if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N))
+ Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
+ else
+ Base = N;
+ return true; // [r+0]
+}
+
+/// getGlobalBaseReg - Output the instructions required to put the
+/// GOT address into a register.
+SDNode *MBlazeDAGToDAGISel::getGlobalBaseReg() {
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
+ return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
+}
+
+/// ComplexPattern used on MBlazeInstrInfo
+/// Used on MBlaze Load/Store instructions
+bool MBlazeDAGToDAGISel::
+SelectAddr(SDNode *Op, SDValue Addr, SDValue &Offset, SDValue &Base) {
+ // if Address is FI, get the TargetFrameIndex.
+ if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
+ Offset = CurDAG->getTargetConstant(0, MVT::i32);
+ return true;
+ }
+
+ // on PIC code Load GA
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
+ (Addr.getOpcode() == ISD::TargetConstantPool) ||
+ (Addr.getOpcode() == ISD::TargetJumpTable)){
+ Base = CurDAG->getRegister(MBlaze::R15, MVT::i32);
+ Offset = Addr;
+ return true;
+ }
+ } else {
+ if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
+ Addr.getOpcode() == ISD::TargetGlobalAddress))
+ return false;
+ }
+
+ // Operand is a result from an ADD.
+ if (Addr.getOpcode() == ISD::ADD) {
+ if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
+ if (Predicate_immSExt16(CN)) {
+
+ // If the first operand is a FI, get the TargetFI Node
+ if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
+ (Addr.getOperand(0))) {
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
+ } else {
+ Base = Addr.getOperand(0);
+ }
+
+ Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
+ return true;
+ }
+ }
+ }
+
+ Base = Addr;
+ Offset = CurDAG->getTargetConstant(0, MVT::i32);
+ return true;
+}
+
+/// Select instructions not customized! Used for
+/// expanded, promoted and normal instructions
+SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) {
+ unsigned Opcode = Node->getOpcode();
+ DebugLoc dl = Node->getDebugLoc();
+
+ // Dump information about the Node being selected
+ DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
+
+ // If we have a custom node, we already have selected!
+ if (Node->isMachineOpcode()) {
+ DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
+ return NULL;
+ }
+
+ ///
+ // Instruction Selection not handled by the auto-generated
+ // tablegen selection should be handled here.
+ ///
+ switch(Opcode) {
+ default: break;
+
+ // Get target GOT address.
+ case ISD::GLOBAL_OFFSET_TABLE:
+ return getGlobalBaseReg();
+
+ case ISD::FrameIndex: {
+ SDValue imm = CurDAG->getTargetConstant(0, MVT::i32);
+ int FI = dyn_cast<FrameIndexSDNode>(Node)->getIndex();
+ EVT VT = Node->getValueType(0);
+ SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
+ unsigned Opc = MBlaze::ADDI;
+ if (Node->hasOneUse())
+ return CurDAG->SelectNodeTo(Node, Opc, VT, TFI, imm);
+ return CurDAG->getMachineNode(Opc, dl, VT, TFI, imm);
+ }
+
+
+ /// Handle direct and indirect calls when using PIC. On PIC, when
+ /// GOT is smaller than about 64k (small code) the GA target is
+ /// loaded with only one instruction. Otherwise GA's target must
+ /// be loaded with 3 instructions.
+ case MBlazeISD::JmpLink: {
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ SDValue Chain = Node->getOperand(0);
+ SDValue Callee = Node->getOperand(1);
+ SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32);
+ SDValue InFlag(0, 0);
+
+ if ( (isa<GlobalAddressSDNode>(Callee)) ||
+ (isa<ExternalSymbolSDNode>(Callee)) )
+ {
+ /// Direct call for global addresses and external symbols
+ SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32);
+
+ // Use load to get GOT target
+ SDValue Ops[] = { Callee, GPReg, Chain };
+ SDValue Load = SDValue(CurDAG->getMachineNode(MBlaze::LW, dl,
+ MVT::i32, MVT::Other, Ops, 3), 0);
+ Chain = Load.getValue(1);
+
+ // Call target must be on T9
+ Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Load, InFlag);
+ } else
+ /// Indirect call
+ Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Callee, InFlag);
+
+ // Emit Jump and Link Register
+ SDNode *ResNode = CurDAG->getMachineNode(MBlaze::BRLID, dl, MVT::Other,
+ MVT::Flag, R20Reg, Chain);
+ Chain = SDValue(ResNode, 0);
+ InFlag = SDValue(ResNode, 1);
+ ReplaceUses(SDValue(Node, 0), Chain);
+ ReplaceUses(SDValue(Node, 1), InFlag);
+ return ResNode;
+ }
+ }
+ }
+
+ // Select the default instruction
+ SDNode *ResNode = SelectCode(Node);
+
+ DEBUG(errs() << "=> ");
+ if (ResNode == NULL || ResNode == Node)
+ DEBUG(Node->dump(CurDAG));
+ else
+ DEBUG(ResNode->dump(CurDAG));
+ DEBUG(errs() << "\n");
+ return ResNode;
+}
+
+/// createMBlazeISelDag - This pass converts a legalized DAG into a
+/// MBlaze-specific DAG, ready for instruction scheduling.
+FunctionPass *llvm::createMBlazeISelDag(MBlazeTargetMachine &TM) {
+ return new MBlazeDAGToDAGISel(TM);
+}
diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp
new file mode 100644
index 0000000..f0864d0
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp
@@ -0,0 +1,975 @@
+//===-- MBlazeISelLowering.cpp - MBlaze DAG Lowering Implementation -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that MBlaze uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "mblaze-lower"
+#include "MBlazeISelLowering.h"
+#include "MBlazeMachineFunction.h"
+#include "MBlazeTargetMachine.h"
+#include "MBlazeTargetObjectFile.h"
+#include "MBlazeSubtarget.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/CallingConv.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+const char *MBlazeTargetLowering::getTargetNodeName(unsigned Opcode) const {
+ switch (Opcode) {
+ case MBlazeISD::JmpLink : return "MBlazeISD::JmpLink";
+ case MBlazeISD::GPRel : return "MBlazeISD::GPRel";
+ case MBlazeISD::Wrap : return "MBlazeISD::Wrap";
+ case MBlazeISD::ICmp : return "MBlazeISD::ICmp";
+ case MBlazeISD::Ret : return "MBlazeISD::Ret";
+ case MBlazeISD::Select_CC : return "MBlazeISD::Select_CC";
+ default : return NULL;
+ }
+}
+
+MBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM)
+ : TargetLowering(TM, new MBlazeTargetObjectFile()) {
+ Subtarget = &TM.getSubtarget<MBlazeSubtarget>();
+
+ // MBlaze does not have i1 type, so use i32 for
+ // setcc operations results (slt, sgt, ...).
+ setBooleanContents(ZeroOrOneBooleanContent);
+
+ // Set up the register classes
+ addRegisterClass(MVT::i32, MBlaze::CPURegsRegisterClass);
+ if (Subtarget->hasFPU()) {
+ addRegisterClass(MVT::f32, MBlaze::FGR32RegisterClass);
+ setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
+ }
+
+ // Floating point operations which are not supported
+ setOperationAction(ISD::FREM, MVT::f32, Expand);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i8, Expand);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i16, Expand);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
+ setOperationAction(ISD::FP_ROUND, MVT::f32, Expand);
+ setOperationAction(ISD::FP_ROUND, MVT::f64, Expand);
+ setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
+ setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
+ setOperationAction(ISD::FSIN, MVT::f32, Expand);
+ setOperationAction(ISD::FCOS, MVT::f32, Expand);
+ setOperationAction(ISD::FPOWI, MVT::f32, Expand);
+ setOperationAction(ISD::FPOW, MVT::f32, Expand);
+ setOperationAction(ISD::FLOG, MVT::f32, Expand);
+ setOperationAction(ISD::FLOG2, MVT::f32, Expand);
+ setOperationAction(ISD::FLOG10, MVT::f32, Expand);
+ setOperationAction(ISD::FEXP, MVT::f32, Expand);
+
+ // Load extented operations for i1 types must be promoted
+ setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
+ setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
+ setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
+
+ // MBlaze has no REM or DIVREM operations.
+ setOperationAction(ISD::UREM, MVT::i32, Expand);
+ setOperationAction(ISD::SREM, MVT::i32, Expand);
+ setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
+ setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
+
+ // If the processor doesn't support multiply then expand it
+ if (!Subtarget->hasMul()) {
+ setOperationAction(ISD::MUL, MVT::i32, Expand);
+ }
+
+ // If the processor doesn't support 64-bit multiply then expand
+ if (!Subtarget->hasMul() || !Subtarget->hasMul64()) {
+ setOperationAction(ISD::MULHS, MVT::i32, Expand);
+ setOperationAction(ISD::MULHS, MVT::i64, Expand);
+ setOperationAction(ISD::MULHU, MVT::i32, Expand);
+ setOperationAction(ISD::MULHU, MVT::i64, Expand);
+ }
+
+ // If the processor doesn't support division then expand
+ if (!Subtarget->hasDiv()) {
+ setOperationAction(ISD::UDIV, MVT::i32, Expand);
+ setOperationAction(ISD::SDIV, MVT::i32, Expand);
+ }
+
+ // Expand unsupported conversions
+ setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand);
+ setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand);
+
+ // Expand SELECT_CC
+ setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
+
+ // MBlaze doesn't have MUL_LOHI
+ setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
+ setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
+ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
+ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
+
+ // Used by legalize types to correctly generate the setcc result.
+ // Without this, every float setcc comes with a AND/OR with the result,
+ // we don't want this, since the fpcmp result goes to a flag register,
+ // which is used implicitly by brcond and select operations.
+ AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
+ AddPromotedToType(ISD::SELECT, MVT::i1, MVT::i32);
+ AddPromotedToType(ISD::SELECT_CC, MVT::i1, MVT::i32);
+
+ // MBlaze Custom Operations
+ setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
+ setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
+ setOperationAction(ISD::JumpTable, MVT::i32, Custom);
+ setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
+
+ // Variable Argument support
+ setOperationAction(ISD::VASTART, MVT::Other, Custom);
+ setOperationAction(ISD::VAEND, MVT::Other, Expand);
+ setOperationAction(ISD::VAARG, MVT::Other, Expand);
+ setOperationAction(ISD::VACOPY, MVT::Other, Expand);
+
+
+ // Operations not directly supported by MBlaze.
+ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
+ setOperationAction(ISD::BR_JT, MVT::Other, Expand);
+ setOperationAction(ISD::BR_CC, MVT::Other, Expand);
+ setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
+ setOperationAction(ISD::ROTL, MVT::i32, Expand);
+ setOperationAction(ISD::ROTR, MVT::i32, Expand);
+ setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
+ setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
+ setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
+ setOperationAction(ISD::CTLZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTPOP, MVT::i32, Expand);
+ setOperationAction(ISD::BSWAP, MVT::i32, Expand);
+
+ // We don't have line number support yet.
+ setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
+
+ // Use the default for now
+ setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
+ setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
+ setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
+
+ // MBlaze doesn't have extending float->double load/store
+ setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
+ setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+
+ setStackPointerRegisterToSaveRestore(MBlaze::R1);
+ computeRegisterProperties();
+}
+
+MVT::SimpleValueType MBlazeTargetLowering::getSetCCResultType(EVT VT) const {
+ return MVT::i32;
+}
+
+/// getFunctionAlignment - Return the Log2 alignment of this function.
+unsigned MBlazeTargetLowering::getFunctionAlignment(const Function *) const {
+ return 2;
+}
+
+SDValue MBlazeTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
+ switch (Op.getOpcode())
+ {
+ case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
+ case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
+ case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
+ case ISD::JumpTable: return LowerJumpTable(Op, DAG);
+ case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
+ case ISD::VASTART: return LowerVASTART(Op, DAG);
+ }
+ return SDValue();
+}
+
+//===----------------------------------------------------------------------===//
+// Lower helper functions
+//===----------------------------------------------------------------------===//
+MachineBasicBlock* MBlazeTargetLowering::
+EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB,
+ DenseMap<MachineBasicBlock*,
+ MachineBasicBlock*> *EM) const {
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+ DebugLoc dl = MI->getDebugLoc();
+
+ switch (MI->getOpcode()) {
+ default: assert(false && "Unexpected instr type to insert");
+ case MBlaze::ShiftRL:
+ case MBlaze::ShiftRA:
+ case MBlaze::ShiftL: {
+ // To "insert" a shift left instruction, we actually have to insert a
+ // simple loop. The incoming instruction knows the destination vreg to
+ // set, the source vreg to operate over and the shift amount.
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ MachineFunction::iterator It = BB;
+ ++It;
+
+ // start:
+ // andi samt, samt, 31
+ // beqid samt, finish
+ // add dst, src, r0
+ // loop:
+ // addik samt, samt, -1
+ // sra dst, dst
+ // bneid samt, loop
+ // nop
+ // finish:
+ MachineFunction *F = BB->getParent();
+ MachineRegisterInfo &R = F->getRegInfo();
+ MachineBasicBlock *loop = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *finish = F->CreateMachineBasicBlock(LLVM_BB);
+
+ unsigned IAMT = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
+ BuildMI(BB, dl, TII->get(MBlaze::ANDI), IAMT)
+ .addReg(MI->getOperand(2).getReg())
+ .addImm(31);
+
+ unsigned IVAL = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
+ BuildMI(BB, dl, TII->get(MBlaze::ADDI), IVAL)
+ .addReg(MI->getOperand(1).getReg())
+ .addImm(0);
+
+ BuildMI(BB, dl, TII->get(MBlaze::BEQID))
+ .addReg(IAMT)
+ .addMBB(finish);
+
+ F->insert(It, loop);
+ F->insert(It, finish);
+
+ // Update machine-CFG edges by first adding all successors of the current
+ // block to the new block which will contain the Phi node for the select.
+ // Also inform sdisel of the edge changes.
+ for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
+ e = BB->succ_end(); i != e; ++i) {
+ EM->insert(std::make_pair(*i, finish));
+ finish->addSuccessor(*i);
+ }
+
+ // Next, remove all successors of the current block, and add the true
+ // and fallthrough blocks as its successors.
+ while(!BB->succ_empty())
+ BB->removeSuccessor(BB->succ_begin());
+ BB->addSuccessor(loop);
+ BB->addSuccessor(finish);
+
+ // Next, add the finish block as a successor of the loop block
+ loop->addSuccessor(finish);
+ loop->addSuccessor(loop);
+
+ unsigned DST = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
+ unsigned NDST = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
+ BuildMI(loop, dl, TII->get(MBlaze::PHI), DST)
+ .addReg(IVAL).addMBB(BB)
+ .addReg(NDST).addMBB(loop);
+
+ unsigned SAMT = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
+ unsigned NAMT = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
+ BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT)
+ .addReg(IAMT).addMBB(BB)
+ .addReg(NAMT).addMBB(loop);
+
+ if (MI->getOpcode() == MBlaze::ShiftL)
+ BuildMI(loop, dl, TII->get(MBlaze::ADD), NDST).addReg(DST).addReg(DST);
+ else if (MI->getOpcode() == MBlaze::ShiftRA)
+ BuildMI(loop, dl, TII->get(MBlaze::SRA), NDST).addReg(DST);
+ else if (MI->getOpcode() == MBlaze::ShiftRL)
+ BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST);
+ else
+ llvm_unreachable( "Cannot lower unknown shift instruction" );
+
+ BuildMI(loop, dl, TII->get(MBlaze::ADDI), NAMT)
+ .addReg(SAMT)
+ .addImm(-1);
+
+ BuildMI(loop, dl, TII->get(MBlaze::BNEID))
+ .addReg(NAMT)
+ .addMBB(loop);
+
+ BuildMI(finish, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg())
+ .addReg(IVAL).addMBB(BB)
+ .addReg(NDST).addMBB(loop);
+
+ // The pseudo instruction is no longer needed so remove it
+ F->DeleteMachineInstr(MI);
+ return finish;
+ }
+
+ case MBlaze::Select_FCC:
+ case MBlaze::Select_CC: {
+ // To "insert" a SELECT_CC instruction, we actually have to insert the
+ // diamond control-flow pattern. The incoming instruction knows the
+ // destination vreg to set, the condition code register to branch on, the
+ // true/false values to select between, and a branch opcode to use.
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ MachineFunction::iterator It = BB;
+ ++It;
+
+ // thisMBB:
+ // ...
+ // TrueVal = ...
+ // setcc r1, r2, r3
+ // bNE r1, r0, copy1MBB
+ // fallthrough --> copy0MBB
+ MachineFunction *F = BB->getParent();
+ MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB);
+
+ unsigned Opc;
+ switch (MI->getOperand(4).getImm()) {
+ default: llvm_unreachable( "Unknown branch condition" );
+ case MBlazeCC::EQ: Opc = MBlaze::BNEID; break;
+ case MBlazeCC::NE: Opc = MBlaze::BEQID; break;
+ case MBlazeCC::GT: Opc = MBlaze::BLEID; break;
+ case MBlazeCC::LT: Opc = MBlaze::BGEID; break;
+ case MBlazeCC::GE: Opc = MBlaze::BLTID; break;
+ case MBlazeCC::LE: Opc = MBlaze::BGTID; break;
+ }
+
+ BuildMI(BB, dl, TII->get(Opc))
+ .addReg(MI->getOperand(3).getReg())
+ .addMBB(dneBB);
+
+ F->insert(It, flsBB);
+ F->insert(It, dneBB);
+
+ // Update machine-CFG edges by first adding all successors of the current
+ // block to the new block which will contain the Phi node for the select.
+ // Also inform sdisel of the edge changes.
+ for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
+ e = BB->succ_end(); i != e; ++i) {
+ EM->insert(std::make_pair(*i, dneBB));
+ dneBB->addSuccessor(*i);
+ }
+
+ // Next, remove all successors of the current block, and add the true
+ // and fallthrough blocks as its successors.
+ while(!BB->succ_empty())
+ BB->removeSuccessor(BB->succ_begin());
+ BB->addSuccessor(flsBB);
+ BB->addSuccessor(dneBB);
+ flsBB->addSuccessor(dneBB);
+
+ // sinkMBB:
+ // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
+ // ...
+ //BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg())
+ // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB)
+ // .addReg(MI->getOperand(2).getReg()).addMBB(BB);
+
+ BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg())
+ .addReg(MI->getOperand(2).getReg()).addMBB(flsBB)
+ .addReg(MI->getOperand(1).getReg()).addMBB(BB);
+
+ F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
+ return dneBB;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Misc Lower Operation implementation
+//===----------------------------------------------------------------------===//
+//
+
+SDValue MBlazeTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
+ SDValue LHS = Op.getOperand(0);
+ SDValue RHS = Op.getOperand(1);
+ SDValue TrueVal = Op.getOperand(2);
+ SDValue FalseVal = Op.getOperand(3);
+ DebugLoc dl = Op.getDebugLoc();
+ unsigned Opc;
+
+ SDValue CompareFlag;
+ if (LHS.getValueType() == MVT::i32) {
+ Opc = MBlazeISD::Select_CC;
+ CompareFlag = DAG.getNode(MBlazeISD::ICmp, dl, MVT::i32, LHS, RHS)
+ .getValue(1);
+ } else {
+ llvm_unreachable( "Cannot lower select_cc with unknown type" );
+ }
+
+ return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
+ CompareFlag);
+}
+
+SDValue MBlazeTargetLowering::
+LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
+ // FIXME there isn't actually debug info here
+ DebugLoc dl = Op.getDebugLoc();
+ GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+ SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
+
+ return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, GA);
+}
+
+SDValue MBlazeTargetLowering::
+LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) {
+ llvm_unreachable("TLS not implemented for MicroBlaze.");
+ return SDValue(); // Not reached
+}
+
+SDValue MBlazeTargetLowering::
+LowerJumpTable(SDValue Op, SelectionDAG &DAG) {
+ SDValue ResNode;
+ SDValue HiPart;
+ // FIXME there isn't actually debug info here
+ DebugLoc dl = Op.getDebugLoc();
+ bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
+ unsigned char OpFlag = IsPIC ? MBlazeII::MO_GOT : MBlazeII::MO_ABS_HILO;
+
+ EVT PtrVT = Op.getValueType();
+ JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
+
+ SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OpFlag);
+ return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, JTI);
+ //return JTI;
+}
+
+SDValue MBlazeTargetLowering::
+LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
+ SDValue ResNode;
+ EVT PtrVT = Op.getValueType();
+ ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
+ Constant *C = N->getConstVal();
+ SDValue Zero = DAG.getConstant(0, PtrVT);
+ DebugLoc dl = Op.getDebugLoc();
+
+ SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
+ N->getOffset(), MBlazeII::MO_ABS_HILO);
+ return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, CP);
+}
+
+SDValue MBlazeTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue FI = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
+
+ // vastart just stores the address of the VarArgsFrameIndex slot into the
+ // memory location argument.
+ const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
+ return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1), SV, 0,
+ false, false, 0);
+}
+
+//===----------------------------------------------------------------------===//
+// Calling Convention Implementation
+//===----------------------------------------------------------------------===//
+
+#include "MBlazeGenCallingConv.inc"
+
+static bool CC_MBlaze2(unsigned ValNo, EVT ValVT,
+ EVT LocVT, CCValAssign::LocInfo LocInfo,
+ ISD::ArgFlagsTy ArgFlags, CCState &State) {
+ static const unsigned RegsSize=6;
+ static const unsigned IntRegs[] = {
+ MBlaze::R5, MBlaze::R6, MBlaze::R7,
+ MBlaze::R8, MBlaze::R9, MBlaze::R10
+ };
+
+ static const unsigned FltRegs[] = {
+ MBlaze::F5, MBlaze::F6, MBlaze::F7,
+ MBlaze::F8, MBlaze::F9, MBlaze::F10
+ };
+
+ unsigned Reg=0;
+
+ // Promote i8 and i16
+ if (LocVT == MVT::i8 || LocVT == MVT::i16) {
+ LocVT = MVT::i32;
+ if (ArgFlags.isSExt())
+ LocInfo = CCValAssign::SExt;
+ else if (ArgFlags.isZExt())
+ LocInfo = CCValAssign::ZExt;
+ else
+ LocInfo = CCValAssign::AExt;
+ }
+
+ if (ValVT == MVT::i32) {
+ Reg = State.AllocateReg(IntRegs, RegsSize);
+ LocVT = MVT::i32;
+ } else if (ValVT == MVT::f32) {
+ Reg = State.AllocateReg(FltRegs, RegsSize);
+ LocVT = MVT::f32;
+ }
+
+ if (!Reg) {
+ unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
+ unsigned Offset = State.AllocateStack(SizeInBytes, SizeInBytes);
+ State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
+ } else {
+ unsigned SizeInBytes = ValVT.getSizeInBits() >> 3;
+ State.AllocateStack(SizeInBytes, SizeInBytes);
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+ }
+
+ return false; // CC must always match
+}
+
+//===----------------------------------------------------------------------===//
+// Call Calling Convention Implementation
+//===----------------------------------------------------------------------===//
+
+/// LowerCall - functions arguments are copied from virtual regs to
+/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
+/// TODO: isVarArg, isTailCall.
+SDValue MBlazeTargetLowering::
+LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
+ bool isVarArg, bool &isTailCall,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) {
+ // MBlaze does not yet support tail call optimization
+ isTailCall = false;
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+
+ // Analyze operands of the call, assigning locations to each operand.
+ SmallVector<CCValAssign, 16> ArgLocs;
+ CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs,
+ *DAG.getContext());
+ CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze2);
+
+ // Get a count of how many bytes are to be pushed on the stack.
+ unsigned NumBytes = CCInfo.getNextStackOffset();
+ Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
+
+ SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
+ SmallVector<SDValue, 8> MemOpChains;
+
+ // First/LastArgStackLoc contains the first/last
+ // "at stack" argument location.
+ int LastArgStackLoc = 0;
+ unsigned FirstStackArgLoc = 0;
+
+ // Walk the register/memloc assignments, inserting copies/loads.
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+ EVT RegVT = VA.getLocVT();
+ SDValue Arg = Outs[i].Val;
+
+ // Promote the value if needed.
+ switch (VA.getLocInfo()) {
+ default: llvm_unreachable("Unknown loc info!");
+ case CCValAssign::Full: break;
+ case CCValAssign::SExt:
+ Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, RegVT, Arg);
+ break;
+ case CCValAssign::ZExt:
+ Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, RegVT, Arg);
+ break;
+ case CCValAssign::AExt:
+ Arg = DAG.getNode(ISD::ANY_EXTEND, dl, RegVT, Arg);
+ break;
+ }
+
+ // Arguments that can be passed on register must be kept at
+ // RegsToPass vector
+ if (VA.isRegLoc()) {
+ RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
+ } else {
+ // Register can't get to this point...
+ assert(VA.isMemLoc());
+
+ // Create the frame index object for this incoming parameter
+ LastArgStackLoc = (FirstStackArgLoc + VA.getLocMemOffset());
+ int FI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8,
+ LastArgStackLoc, true, false);
+
+ SDValue PtrOff = DAG.getFrameIndex(FI,getPointerTy());
+
+ // emit ISD::STORE whichs stores the
+ // parameter value to a stack Location
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
+ }
+ }
+
+ // Transform all store nodes into one single node because all store
+ // nodes are independent of each other.
+ if (!MemOpChains.empty())
+ Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &MemOpChains[0], MemOpChains.size());
+
+ // Build a sequence of copy-to-reg nodes chained together with token
+ // chain and flag operands which copy the outgoing args into registers.
+ // The InFlag in necessary since all emited instructions must be
+ // stuck together.
+ SDValue InFlag;
+ for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+ Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
+ RegsToPass[i].second, InFlag);
+ InFlag = Chain.getValue(1);
+ }
+
+ // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
+ // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
+ // node so that legalize doesn't hack it.
+ unsigned char OpFlag = MBlazeII::MO_NO_FLAG;
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
+ Callee = DAG.getTargetGlobalAddress(G->getGlobal(),
+ getPointerTy(), 0, OpFlag);
+ else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
+ Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
+ getPointerTy(), OpFlag);
+
+ // MBlazeJmpLink = #chain, #target_address, #opt_in_flags...
+ // = Chain, Callee, Reg#1, Reg#2, ...
+ //
+ // Returns a chain & a flag for retval copy to use.
+ SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
+ SmallVector<SDValue, 8> Ops;
+ Ops.push_back(Chain);
+ Ops.push_back(Callee);
+
+ // Add argument registers to the end of the list so that they are
+ // known live into the call.
+ for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+ Ops.push_back(DAG.getRegister(RegsToPass[i].first,
+ RegsToPass[i].second.getValueType()));
+ }
+
+ if (InFlag.getNode())
+ Ops.push_back(InFlag);
+
+ Chain = DAG.getNode(MBlazeISD::JmpLink, dl, NodeTys, &Ops[0], Ops.size());
+ InFlag = Chain.getValue(1);
+
+ // Create the CALLSEQ_END node.
+ Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
+ DAG.getIntPtrConstant(0, true), InFlag);
+ if (!Ins.empty())
+ InFlag = Chain.getValue(1);
+
+ // Handle result values, copying them out of physregs into vregs that we
+ // return.
+ return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
+ Ins, dl, DAG, InVals);
+}
+
+/// LowerCallResult - Lower the result values of a call into the
+/// appropriate copies out of appropriate physical registers.
+SDValue MBlazeTargetLowering::
+LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv,
+ bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) {
+ // Assign locations to each value returned by this call.
+ SmallVector<CCValAssign, 16> RVLocs;
+ CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
+ RVLocs, *DAG.getContext());
+
+ CCInfo.AnalyzeCallResult(Ins, RetCC_MBlaze);
+
+ // Copy all of the result registers out of their specified physreg.
+ for (unsigned i = 0; i != RVLocs.size(); ++i) {
+ Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
+ RVLocs[i].getValVT(), InFlag).getValue(1);
+ InFlag = Chain.getValue(2);
+ InVals.push_back(Chain.getValue(0));
+ }
+
+ return Chain;
+}
+
+//===----------------------------------------------------------------------===//
+// Formal Arguments Calling Convention Implementation
+//===----------------------------------------------------------------------===//
+
+/// LowerFormalArguments - transform physical registers into
+/// virtual registers and generate load operations for
+/// arguments places on the stack.
+SDValue MBlazeTargetLowering::
+LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) {
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
+
+ unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
+ VarArgsFrameIndex = 0;
+
+ // Used with vargs to acumulate store chains.
+ std::vector<SDValue> OutChains;
+
+ // Keep track of the last register used for arguments
+ unsigned ArgRegEnd = 0;
+
+ // Assign locations to all of the incoming arguments.
+ SmallVector<CCValAssign, 16> ArgLocs;
+ CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
+ ArgLocs, *DAG.getContext());
+
+ CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze2);
+ SDValue StackPtr;
+
+ unsigned FirstStackArgLoc = 0;
+
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+
+ // Arguments stored on registers
+ if (VA.isRegLoc()) {
+ EVT RegVT = VA.getLocVT();
+ ArgRegEnd = VA.getLocReg();
+ TargetRegisterClass *RC = 0;
+
+ if (RegVT == MVT::i32)
+ RC = MBlaze::CPURegsRegisterClass;
+ else if (RegVT == MVT::f32)
+ RC = MBlaze::FGR32RegisterClass;
+ else
+ llvm_unreachable("RegVT not supported by LowerFormalArguments");
+
+ // Transform the arguments stored on
+ // physical registers into virtual ones
+ unsigned Reg = MF.addLiveIn(ArgRegEnd, RC);
+ SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
+
+ // If this is an 8 or 16-bit value, it has been passed promoted
+ // to 32 bits. Insert an assert[sz]ext to capture this, then
+ // truncate to the right size. If if is a floating point value
+ // then convert to the correct type.
+ if (VA.getLocInfo() != CCValAssign::Full) {
+ unsigned Opcode = 0;
+ if (VA.getLocInfo() == CCValAssign::SExt)
+ Opcode = ISD::AssertSext;
+ else if (VA.getLocInfo() == CCValAssign::ZExt)
+ Opcode = ISD::AssertZext;
+ if (Opcode)
+ ArgValue = DAG.getNode(Opcode, dl, RegVT, ArgValue,
+ DAG.getValueType(VA.getValVT()));
+ ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
+ }
+
+ InVals.push_back(ArgValue);
+
+ } else { // VA.isRegLoc()
+
+ // sanity check
+ assert(VA.isMemLoc());
+
+ // The last argument is not a register
+ ArgRegEnd = 0;
+
+ // The stack pointer offset is relative to the caller stack frame.
+ // Since the real stack size is unknown here, a negative SPOffset
+ // is used so there's a way to adjust these offsets when the stack
+ // size get known (on EliminateFrameIndex). A dummy SPOffset is
+ // used instead of a direct negative address (which is recorded to
+ // be used on emitPrologue) to avoid mis-calc of the first stack
+ // offset on PEI::calculateFrameObjectOffsets.
+ // Arguments are always 32-bit.
+ unsigned ArgSize = VA.getLocVT().getSizeInBits()/8;
+ int FI = MFI->CreateFixedObject(ArgSize, 0, true, false);
+ MBlazeFI->recordLoadArgsFI(FI, -(ArgSize+
+ (FirstStackArgLoc + VA.getLocMemOffset())));
+
+ // Create load nodes to retrieve arguments from the stack
+ SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
+ InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
+ }
+ }
+
+ // To meet ABI, when VARARGS are passed on registers, the registers
+ // must have their values written to the caller stack frame. If the last
+ // argument was placed in the stack, there's no need to save any register.
+ if ((isVarArg) && ArgRegEnd) {
+ if (StackPtr.getNode() == 0)
+ StackPtr = DAG.getRegister(StackReg, getPointerTy());
+
+ // The last register argument that must be saved is MBlaze::R10
+ TargetRegisterClass *RC = MBlaze::CPURegsRegisterClass;
+
+ unsigned Begin = MBlazeRegisterInfo::getRegisterNumbering(MBlaze::R5);
+ unsigned Start = MBlazeRegisterInfo::getRegisterNumbering(ArgRegEnd+1);
+ unsigned End = MBlazeRegisterInfo::getRegisterNumbering(MBlaze::R10);
+ unsigned StackLoc = ArgLocs.size()-1 + (Start - Begin);
+
+ for (; Start <= End; ++Start, ++StackLoc) {
+ unsigned Reg = MBlazeRegisterInfo::getRegisterFromNumbering(Start);
+ unsigned LiveReg = MF.addLiveIn(Reg, RC);
+ SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, LiveReg, MVT::i32);
+
+ int FI = MFI->CreateFixedObject(4, 0, true, false);
+ MBlazeFI->recordStoreVarArgsFI(FI, -(4+(StackLoc*4)));
+ SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
+ OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0,
+ false, false, 0));
+
+ // Record the frame index of the first variable argument
+ // which is a value necessary to VASTART.
+ if (!VarArgsFrameIndex)
+ VarArgsFrameIndex = FI;
+ }
+ }
+
+ // All stores are grouped in one node to allow the matching between
+ // the size of Ins and InVals. This only happens when on varg functions
+ if (!OutChains.empty()) {
+ OutChains.push_back(Chain);
+ Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &OutChains[0], OutChains.size());
+ }
+
+ return Chain;
+}
+
+//===----------------------------------------------------------------------===//
+// Return Value Calling Convention Implementation
+//===----------------------------------------------------------------------===//
+
+SDValue MBlazeTargetLowering::
+LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ DebugLoc dl, SelectionDAG &DAG) {
+ // CCValAssign - represent the assignment of
+ // the return value to a location
+ SmallVector<CCValAssign, 16> RVLocs;
+
+ // CCState - Info about the registers and stack slot.
+ CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
+ RVLocs, *DAG.getContext());
+
+ // Analize return values.
+ CCInfo.AnalyzeReturn(Outs, RetCC_MBlaze);
+
+ // If this is the first return lowered for this function, add
+ // the regs to the liveout set for the function.
+ if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
+ for (unsigned i = 0; i != RVLocs.size(); ++i)
+ if (RVLocs[i].isRegLoc())
+ DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
+ }
+
+ SDValue Flag;
+
+ // Copy the result values into the output registers.
+ for (unsigned i = 0; i != RVLocs.size(); ++i) {
+ CCValAssign &VA = RVLocs[i];
+ assert(VA.isRegLoc() && "Can only return in registers!");
+
+ Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
+ Outs[i].Val, Flag);
+
+ // guarantee that all emitted copies are
+ // stuck together, avoiding something bad
+ Flag = Chain.getValue(1);
+ }
+
+ // Return on MBlaze is always a "rtsd R15, 8"
+ if (Flag.getNode())
+ return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other,
+ Chain, DAG.getRegister(MBlaze::R15, MVT::i32), Flag);
+ else // Return Void
+ return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other,
+ Chain, DAG.getRegister(MBlaze::R15, MVT::i32));
+}
+
+//===----------------------------------------------------------------------===//
+// MBlaze Inline Assembly Support
+//===----------------------------------------------------------------------===//
+
+/// getConstraintType - Given a constraint letter, return the type of
+/// constraint it is for this target.
+MBlazeTargetLowering::ConstraintType MBlazeTargetLowering::
+getConstraintType(const std::string &Constraint) const
+{
+ // MBlaze specific constrainy
+ //
+ // 'd' : An address register. Equivalent to r.
+ // 'y' : Equivalent to r; retained for
+ // backwards compatibility.
+ // 'f' : Floating Point registers.
+ if (Constraint.size() == 1) {
+ switch (Constraint[0]) {
+ default : break;
+ case 'd':
+ case 'y':
+ case 'f':
+ return C_RegisterClass;
+ break;
+ }
+ }
+ return TargetLowering::getConstraintType(Constraint);
+}
+
+/// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
+/// return a list of registers that can be used to satisfy the constraint.
+/// This should only be used for C_RegisterClass constraints.
+std::pair<unsigned, const TargetRegisterClass*> MBlazeTargetLowering::
+getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const {
+ if (Constraint.size() == 1) {
+ switch (Constraint[0]) {
+ case 'r':
+ return std::make_pair(0U, MBlaze::CPURegsRegisterClass);
+ case 'f':
+ if (VT == MVT::f32)
+ return std::make_pair(0U, MBlaze::FGR32RegisterClass);
+ }
+ }
+ return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
+}
+
+/// Given a register class constraint, like 'r', if this corresponds directly
+/// to an LLVM register class, return a register of 0 and the register class
+/// pointer.
+std::vector<unsigned> MBlazeTargetLowering::
+getRegClassForInlineAsmConstraint(const std::string &Constraint, EVT VT) const {
+ if (Constraint.size() != 1)
+ return std::vector<unsigned>();
+
+ switch (Constraint[0]) {
+ default : break;
+ case 'r':
+ // GCC MBlaze Constraint Letters
+ case 'd':
+ case 'y':
+ return make_vector<unsigned>(
+ MBlaze::R3, MBlaze::R4, MBlaze::R5, MBlaze::R6,
+ MBlaze::R7, MBlaze::R9, MBlaze::R10, MBlaze::R11,
+ MBlaze::R12, MBlaze::R19, MBlaze::R20, MBlaze::R21,
+ MBlaze::R22, MBlaze::R23, MBlaze::R24, MBlaze::R25,
+ MBlaze::R26, MBlaze::R27, MBlaze::R28, MBlaze::R29,
+ MBlaze::R30, MBlaze::R31, 0);
+
+ case 'f':
+ return make_vector<unsigned>(
+ MBlaze::F3, MBlaze::F4, MBlaze::F5, MBlaze::F6,
+ MBlaze::F7, MBlaze::F9, MBlaze::F10, MBlaze::F11,
+ MBlaze::F12, MBlaze::F19, MBlaze::F20, MBlaze::F21,
+ MBlaze::F22, MBlaze::F23, MBlaze::F24, MBlaze::F25,
+ MBlaze::F26, MBlaze::F27, MBlaze::F28, MBlaze::F29,
+ MBlaze::F30, MBlaze::F31, 0);
+ }
+ return std::vector<unsigned>();
+}
+
+bool MBlazeTargetLowering::
+isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
+ // The MBlaze target isn't yet aware of offsets.
+ return false;
+}
+
+bool MBlazeTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
+ return VT != MVT::f32;
+}
diff --git a/lib/Target/MBlaze/MBlazeISelLowering.h b/lib/Target/MBlaze/MBlazeISelLowering.h
new file mode 100644
index 0000000..f8b1470
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeISelLowering.h
@@ -0,0 +1,149 @@
+//===-- MBlazeISelLowering.h - MBlaze DAG Lowering Interface ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that MBlaze uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBlazeISELLOWERING_H
+#define MBlazeISELLOWERING_H
+
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/Target/TargetLowering.h"
+#include "MBlaze.h"
+#include "MBlazeSubtarget.h"
+
+namespace llvm {
+ namespace MBlazeCC {
+ enum CC {
+ FIRST = 0,
+ EQ,
+ NE,
+ GT,
+ LT,
+ GE,
+ LE
+ };
+ }
+
+ namespace MBlazeISD {
+ enum NodeType {
+ // Start the numbering from where ISD NodeType finishes.
+ FIRST_NUMBER = ISD::BUILTIN_OP_END,
+
+ // Jump and link (call)
+ JmpLink,
+
+ // Handle gp_rel (small data/bss sections) relocation.
+ GPRel,
+
+ // Select CC Pseudo Instruction
+ Select_CC,
+
+ // Wrap up multiple types of instructions
+ Wrap,
+
+ // Integer Compare
+ ICmp,
+
+ // Return
+ Ret
+ };
+ }
+
+ //===--------------------------------------------------------------------===//
+ // TargetLowering Implementation
+ //===--------------------------------------------------------------------===//
+
+ class MBlazeTargetLowering : public TargetLowering {
+ int VarArgsFrameIndex; // FrameIndex for start of varargs area.
+
+ public:
+
+ explicit MBlazeTargetLowering(MBlazeTargetMachine &TM);
+
+ /// LowerOperation - Provide custom lowering hooks for some operations.
+ virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
+
+ /// getTargetNodeName - This method returns the name of a target specific
+ // DAG node.
+ virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+ /// getSetCCResultType - get the ISD::SETCC result ValueType
+ MVT::SimpleValueType getSetCCResultType(EVT VT) const;
+
+ virtual unsigned getFunctionAlignment(const Function *F) const;
+ private:
+ // Subtarget Info
+ const MBlazeSubtarget *Subtarget;
+
+
+ // Lower Operand helpers
+ SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
+ CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals);
+
+ // Lower Operand specifics
+ SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG);
+
+ virtual SDValue
+ LowerFormalArguments(SDValue Chain,
+ CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals);
+
+ virtual SDValue
+ LowerCall(SDValue Chain, SDValue Callee,
+ CallingConv::ID CallConv, bool isVarArg,
+ bool &isTailCall,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals);
+
+ virtual SDValue
+ LowerReturn(SDValue Chain,
+ CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ DebugLoc dl, SelectionDAG &DAG);
+
+ virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
+ MachineBasicBlock *MBB,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
+
+ // Inline asm support
+ ConstraintType getConstraintType(const std::string &Constraint) const;
+
+ std::pair<unsigned, const TargetRegisterClass*>
+ getRegForInlineAsmConstraint(const std::string &Constraint,
+ EVT VT) const;
+
+ std::vector<unsigned>
+ getRegClassForInlineAsmConstraint(const std::string &Constraint,
+ EVT VT) const;
+
+ virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+
+ /// isFPImmLegal - Returns true if the target can instruction select the
+ /// specified FP immediate natively. If false, the legalizer will
+ /// materialize the FP immediate as a load from a constant pool.
+ virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
+ };
+}
+
+#endif // MBlazeISELLOWERING_H
diff --git a/lib/Target/MBlaze/MBlazeInstrFPU.td b/lib/Target/MBlaze/MBlazeInstrFPU.td
new file mode 100644
index 0000000..a48a8c9
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeInstrFPU.td
@@ -0,0 +1,223 @@
+//===- MBlazeInstrFPU.td - MBlaze FPU Instruction defs ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// MBlaze profiles and nodes
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// MBlaze Operand, Complex Patterns and Transformations Definitions.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Memory Access Instructions
+//===----------------------------------------------------------------------===//
+class LoadFM<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TA<op, 0x000, (outs FGR32:$dst), (ins memrr:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(set FGR32:$dst, (OpNode xaddr:$addr))], IILoad>;
+
+class LoadFMI<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TAI<op, (outs FGR32:$dst), (ins memri:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(set FGR32:$dst, (OpNode iaddr:$addr))], IILoad>;
+
+class StoreFM<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TA<op, 0x000, (outs), (ins FGR32:$dst, memrr:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(OpNode FGR32:$dst, xaddr:$addr)], IIStore>;
+
+class StoreFMI<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TAI<op, (outs), (ins FGR32:$dst, memrr:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(OpNode FGR32:$dst, iaddr:$addr)], IIStore>;
+
+class ArithF<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
+ InstrItinClass itin> :
+ TA<op, flags, (outs FGR32:$dst), (ins FGR32:$b, FGR32:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [(set FGR32:$dst, (OpNode FGR32:$b, FGR32:$c))], itin>;
+
+class CmpFN<bits<6> op, bits<11> flags, string instr_asm,
+ InstrItinClass itin> :
+ TA<op, flags, (outs CPURegs:$dst), (ins FGR32:$b, FGR32:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], itin>;
+
+class ArithFR<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
+ InstrItinClass itin> :
+ TA<op, flags, (outs FGR32:$dst), (ins FGR32:$b, FGR32:$c),
+ !strconcat(instr_asm, " $dst, $c, $b"),
+ [(set FGR32:$dst, (OpNode FGR32:$b, FGR32:$c))], itin>;
+
+class ArithF2<bits<6> op, bits<11> flags, string instr_asm,
+ InstrItinClass itin> :
+ TF<op, flags, (outs FGR32:$dst), (ins FGR32:$b),
+ !strconcat(instr_asm, " $dst, $b"),
+ [], itin>;
+
+class ArithIF<bits<6> op, bits<11> flags, string instr_asm,
+ InstrItinClass itin> :
+ TF<op, flags, (outs FGR32:$dst), (ins CPURegs:$b),
+ !strconcat(instr_asm, " $dst, $b"),
+ [], itin>;
+
+class ArithFI<bits<6> op, bits<11> flags, string instr_asm,
+ InstrItinClass itin> :
+ TF<op, flags, (outs CPURegs:$dst), (ins FGR32:$b),
+ !strconcat(instr_asm, " $dst, $b"),
+ [], itin>;
+
+class LogicF<bits<6> op, string instr_asm> :
+ TAI<op, (outs FGR32:$dst), (ins FGR32:$b, FGR32:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [],
+ IIAlu>;
+
+class LogicFI<bits<6> op, string instr_asm> :
+ TAI<op, (outs FGR32:$dst), (ins FGR32:$b, fimm:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [],
+ IIAlu>;
+
+//===----------------------------------------------------------------------===//
+// Pseudo instructions
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// FPU Arithmetic Instructions
+//===----------------------------------------------------------------------===//
+let Predicates=[HasFPU] in {
+ def FOR : LogicF<0x28, "or ">;
+ def FORI : LogicFI<0x28, "ori ">;
+ def FADD : ArithF<0x16, 0x000, "fadd ", fadd, IIAlu>;
+ def FRSUB : ArithFR<0x16, 0x080, "frsub ", fsub, IIAlu>;
+ def FMUL : ArithF<0x16, 0x100, "fmul ", fmul, IIAlu>;
+ def FDIV : ArithF<0x16, 0x180, "fdiv ", fdiv, IIAlu>;
+
+ def LWF : LoadFM<0x32, "lw ", load>;
+ def LWFI : LoadFMI<0x32, "lwi ", load>;
+
+ def SWF : StoreFM<0x32, "sw ", store>;
+ def SWFI : StoreFMI<0x32, "swi ", store>;
+}
+
+let Predicates=[HasFPU,HasSqrt] in {
+ def FLT : ArithIF<0x16, 0x280, "flt ", IIAlu>;
+ def FINT : ArithFI<0x16, 0x300, "fint ", IIAlu>;
+ def FSQRT : ArithF2<0x16, 0x300, "fsqrt ", IIAlu>;
+}
+
+let isAsCheapAsAMove = 1 in {
+ def FCMP_UN : CmpFN<0x16, 0x200, "fcmp.un", IIAlu>;
+ def FCMP_LT : CmpFN<0x16, 0x210, "fcmp.lt", IIAlu>;
+ def FCMP_EQ : CmpFN<0x16, 0x220, "fcmp.eq", IIAlu>;
+ def FCMP_LE : CmpFN<0x16, 0x230, "fcmp.le", IIAlu>;
+ def FCMP_GT : CmpFN<0x16, 0x240, "fcmp.gt", IIAlu>;
+ def FCMP_NE : CmpFN<0x16, 0x250, "fcmp.ne", IIAlu>;
+ def FCMP_GE : CmpFN<0x16, 0x260, "fcmp.ge", IIAlu>;
+}
+
+
+let usesCustomInserter = 1 in {
+ def Select_FCC : MBlazePseudo<(outs FGR32:$dst),
+ (ins FGR32:$T, FGR32:$F, CPURegs:$CMP, i32imm:$CC),
+ "; SELECT_FCC PSEUDO!",
+ []>;
+}
+
+// Floating point conversions
+let Predicates=[HasFPU] in {
+ def : Pat<(sint_to_fp CPURegs:$V), (FLT CPURegs:$V)>;
+ def : Pat<(fp_to_sint FGR32:$V), (FINT FGR32:$V)>;
+ def : Pat<(fsqrt FGR32:$V), (FSQRT FGR32:$V)>;
+}
+
+// SET_CC operations
+let Predicates=[HasFPU] in {
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETEQ),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_EQ FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETNE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_EQ FGR32:$L, FGR32:$R), 1)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETOEQ),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_EQ FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETONE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (XOR (FCMP_UN FGR32:$L, FGR32:$R),
+ (FCMP_EQ FGR32:$L, FGR32:$R)), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETONE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (OR (FCMP_UN FGR32:$L, FGR32:$R),
+ (FCMP_EQ FGR32:$L, FGR32:$R)), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETGT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_GT FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETLT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_LT FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETGE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_GE FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETLE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_LE FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETOGT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_GT FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETOLT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_LT FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETOGE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_GE FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETOLE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_LE FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETUEQ),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (OR (FCMP_UN FGR32:$L, FGR32:$R),
+ (FCMP_EQ FGR32:$L, FGR32:$R)), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETUNE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_NE FGR32:$L, FGR32:$R), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETUGT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (OR (FCMP_UN FGR32:$L, FGR32:$R),
+ (FCMP_GT FGR32:$L, FGR32:$R)), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETULT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (OR (FCMP_UN FGR32:$L, FGR32:$R),
+ (FCMP_LT FGR32:$L, FGR32:$R)), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETUGE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (OR (FCMP_UN FGR32:$L, FGR32:$R),
+ (FCMP_GE FGR32:$L, FGR32:$R)), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETULE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (OR (FCMP_UN FGR32:$L, FGR32:$R),
+ (FCMP_LE FGR32:$L, FGR32:$R)), 2)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETO),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_UN FGR32:$L, FGR32:$R), 1)>;
+ def : Pat<(setcc FGR32:$L, FGR32:$R, SETUO),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (FCMP_UN FGR32:$L, FGR32:$R), 2)>;
+}
+
+// SELECT operations
+def : Pat<(select CPURegs:$C, FGR32:$T, FGR32:$F),
+ (Select_FCC FGR32:$T, FGR32:$F, CPURegs:$C, 2)>;
+
+//===----------------------------------------------------------------------===//
+// Patterns for Floating Point Instructions
+//===----------------------------------------------------------------------===//
+def : Pat<(f32 fpimm:$imm), (FORI F0, fpimm:$imm)>;
diff --git a/lib/Target/MBlaze/MBlazeInstrFSL.td b/lib/Target/MBlaze/MBlazeInstrFSL.td
new file mode 100644
index 0000000..b59999e
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeInstrFSL.td
@@ -0,0 +1,153 @@
+//===- MBlazeInstrFSL.td - MBlaze FSL Instruction defs ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// FSL Instruction Formats
+//===----------------------------------------------------------------------===//
+class FSLGetD<bits<6> op, bits<11> flags, string instr_asm, Intrinsic OpNode> :
+ TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$b),
+ !strconcat(instr_asm, " $dst, $b"),
+ [(set CPURegs:$dst, (OpNode CPURegs:$b))], IIAlu>;
+
+class FSLGet<bits<6> op, string instr_asm, Intrinsic OpNode> :
+ TAI<op, (outs CPURegs:$dst), (ins fslimm:$b),
+ !strconcat(instr_asm, " $dst, $b"),
+ [(set CPURegs:$dst, (OpNode immZExt4:$b))], IIAlu>;
+
+class FSLPutD<bits<6> op, bits<11> flags, string instr_asm, Intrinsic OpNode> :
+ TA<op, flags, (outs), (ins CPURegs:$v, CPURegs:$b),
+ !strconcat(instr_asm, " $v, $b"),
+ [(OpNode CPURegs:$v, CPURegs:$b)], IIAlu>;
+
+class FSLPut<bits<6> op, string instr_asm, Intrinsic OpNode> :
+ TAI<op, (outs), (ins CPURegs:$v, fslimm:$b),
+ !strconcat(instr_asm, " $v, $b"),
+ [(OpNode CPURegs:$v, immZExt4:$b)], IIAlu>;
+
+class FSLPutTD<bits<6> op, bits<11> flags, string instr_asm, Intrinsic OpNode> :
+ TA<op, flags, (outs), (ins CPURegs:$b),
+ !strconcat(instr_asm, " $b"),
+ [(OpNode CPURegs:$b)], IIAlu>;
+
+class FSLPutT<bits<6> op, string instr_asm, Intrinsic OpNode> :
+ TAI<op, (outs), (ins fslimm:$b),
+ !strconcat(instr_asm, " $b"),
+ [(OpNode immZExt4:$b)], IIAlu>;
+
+//===----------------------------------------------------------------------===//
+// FSL Get Instructions
+//===----------------------------------------------------------------------===//
+def GET : FSLGet<0x1B, "get ", int_mblaze_fsl_get>;
+def AGET : FSLGet<0x1B, "aget ", int_mblaze_fsl_aget>;
+def CGET : FSLGet<0x1B, "cget ", int_mblaze_fsl_cget>;
+def CAGET : FSLGet<0x1B, "caget ", int_mblaze_fsl_caget>;
+def EGET : FSLGet<0x1B, "eget ", int_mblaze_fsl_eget>;
+def EAGET : FSLGet<0x1B, "eaget ", int_mblaze_fsl_eaget>;
+def ECGET : FSLGet<0x1B, "ecget ", int_mblaze_fsl_ecget>;
+def ECAGET : FSLGet<0x1B, "ecaget ", int_mblaze_fsl_ecaget>;
+def NGET : FSLGet<0x1B, "nget ", int_mblaze_fsl_nget>;
+def NAGET : FSLGet<0x1B, "naget ", int_mblaze_fsl_naget>;
+def NCGET : FSLGet<0x1B, "ncget ", int_mblaze_fsl_ncget>;
+def NCAGET : FSLGet<0x1B, "ncaget ", int_mblaze_fsl_ncaget>;
+def NEGET : FSLGet<0x1B, "neget ", int_mblaze_fsl_neget>;
+def NEAGET : FSLGet<0x1B, "neaget ", int_mblaze_fsl_neaget>;
+def NECGET : FSLGet<0x1B, "necget ", int_mblaze_fsl_necget>;
+def NECAGET : FSLGet<0x1B, "necaget ", int_mblaze_fsl_necaget>;
+def TGET : FSLGet<0x1B, "tget ", int_mblaze_fsl_tget>;
+def TAGET : FSLGet<0x1B, "taget ", int_mblaze_fsl_taget>;
+def TCGET : FSLGet<0x1B, "tcget ", int_mblaze_fsl_tcget>;
+def TCAGET : FSLGet<0x1B, "tcaget ", int_mblaze_fsl_tcaget>;
+def TEGET : FSLGet<0x1B, "teget ", int_mblaze_fsl_teget>;
+def TEAGET : FSLGet<0x1B, "teaget ", int_mblaze_fsl_teaget>;
+def TECGET : FSLGet<0x1B, "tecget ", int_mblaze_fsl_tecget>;
+def TECAGET : FSLGet<0x1B, "tecaget ", int_mblaze_fsl_tecaget>;
+def TNGET : FSLGet<0x1B, "tnget ", int_mblaze_fsl_tnget>;
+def TNAGET : FSLGet<0x1B, "tnaget ", int_mblaze_fsl_tnaget>;
+def TNCGET : FSLGet<0x1B, "tncget ", int_mblaze_fsl_tncget>;
+def TNCAGET : FSLGet<0x1B, "tncaget ", int_mblaze_fsl_tncaget>;
+def TNEGET : FSLGet<0x1B, "tneget ", int_mblaze_fsl_tneget>;
+def TNEAGET : FSLGet<0x1B, "tneaget ", int_mblaze_fsl_tneaget>;
+def TNECGET : FSLGet<0x1B, "tnecget ", int_mblaze_fsl_tnecget>;
+def TNECAGET : FSLGet<0x1B, "tnecaget ", int_mblaze_fsl_tnecaget>;
+
+//===----------------------------------------------------------------------===//
+// FSL Dynamic Get Instructions
+//===----------------------------------------------------------------------===//
+def GETD : FSLGetD<0x1B, 0x00, "getd ", int_mblaze_fsl_get>;
+def AGETD : FSLGetD<0x1B, 0x00, "agetd ", int_mblaze_fsl_aget>;
+def CGETD : FSLGetD<0x1B, 0x00, "cgetd ", int_mblaze_fsl_cget>;
+def CAGETD : FSLGetD<0x1B, 0x00, "cagetd ", int_mblaze_fsl_caget>;
+def EGETD : FSLGetD<0x1B, 0x00, "egetd ", int_mblaze_fsl_eget>;
+def EAGETD : FSLGetD<0x1B, 0x00, "eagetd ", int_mblaze_fsl_eaget>;
+def ECGETD : FSLGetD<0x1B, 0x00, "ecgetd ", int_mblaze_fsl_ecget>;
+def ECAGETD : FSLGetD<0x1B, 0x00, "ecagetd ", int_mblaze_fsl_ecaget>;
+def NGETD : FSLGetD<0x1B, 0x00, "ngetd ", int_mblaze_fsl_nget>;
+def NAGETD : FSLGetD<0x1B, 0x00, "nagetd ", int_mblaze_fsl_naget>;
+def NCGETD : FSLGetD<0x1B, 0x00, "ncgetd ", int_mblaze_fsl_ncget>;
+def NCAGETD : FSLGetD<0x1B, 0x00, "ncagetd ", int_mblaze_fsl_ncaget>;
+def NEGETD : FSLGetD<0x1B, 0x00, "negetd ", int_mblaze_fsl_neget>;
+def NEAGETD : FSLGetD<0x1B, 0x00, "neagetd ", int_mblaze_fsl_neaget>;
+def NECGETD : FSLGetD<0x1B, 0x00, "necgetd ", int_mblaze_fsl_necget>;
+def NECAGETD : FSLGetD<0x1B, 0x00, "necagetd ", int_mblaze_fsl_necaget>;
+def TGETD : FSLGetD<0x1B, 0x00, "tgetd ", int_mblaze_fsl_tget>;
+def TAGETD : FSLGetD<0x1B, 0x00, "tagetd ", int_mblaze_fsl_taget>;
+def TCGETD : FSLGetD<0x1B, 0x00, "tcgetd ", int_mblaze_fsl_tcget>;
+def TCAGETD : FSLGetD<0x1B, 0x00, "tcagetd ", int_mblaze_fsl_tcaget>;
+def TEGETD : FSLGetD<0x1B, 0x00, "tegetd ", int_mblaze_fsl_teget>;
+def TEAGETD : FSLGetD<0x1B, 0x00, "teagetd ", int_mblaze_fsl_teaget>;
+def TECGETD : FSLGetD<0x1B, 0x00, "tecgetd ", int_mblaze_fsl_tecget>;
+def TECAGETD : FSLGetD<0x1B, 0x00, "tecagetd ", int_mblaze_fsl_tecaget>;
+def TNGETD : FSLGetD<0x1B, 0x00, "tngetd ", int_mblaze_fsl_tnget>;
+def TNAGETD : FSLGetD<0x1B, 0x00, "tnagetd ", int_mblaze_fsl_tnaget>;
+def TNCGETD : FSLGetD<0x1B, 0x00, "tncgetd ", int_mblaze_fsl_tncget>;
+def TNCAGETD : FSLGetD<0x1B, 0x00, "tncagetd ", int_mblaze_fsl_tncaget>;
+def TNEGETD : FSLGetD<0x1B, 0x00, "tnegetd ", int_mblaze_fsl_tneget>;
+def TNEAGETD : FSLGetD<0x1B, 0x00, "tneagetd ", int_mblaze_fsl_tneaget>;
+def TNECGETD : FSLGetD<0x1B, 0x00, "tnecgetd ", int_mblaze_fsl_tnecget>;
+def TNECAGETD : FSLGetD<0x1B, 0x00, "tnecagetd", int_mblaze_fsl_tnecaget>;
+
+//===----------------------------------------------------------------------===//
+// FSL Put Instructions
+//===----------------------------------------------------------------------===//
+def PUT : FSLPut<0x1B, "put ", int_mblaze_fsl_put>;
+def APUT : FSLPut<0x1B, "aput ", int_mblaze_fsl_aput>;
+def CPUT : FSLPut<0x1B, "cput ", int_mblaze_fsl_cput>;
+def CAPUT : FSLPut<0x1B, "caput ", int_mblaze_fsl_caput>;
+def NPUT : FSLPut<0x1B, "nput ", int_mblaze_fsl_nput>;
+def NAPUT : FSLPut<0x1B, "naput ", int_mblaze_fsl_naput>;
+def NCPUT : FSLPut<0x1B, "ncput ", int_mblaze_fsl_ncput>;
+def NCAPUT : FSLPut<0x1B, "ncaput ", int_mblaze_fsl_ncaput>;
+def TPUT : FSLPutT<0x1B, "tput ", int_mblaze_fsl_tput>;
+def TAPUT : FSLPutT<0x1B, "taput ", int_mblaze_fsl_taput>;
+def TCPUT : FSLPutT<0x1B, "tcput ", int_mblaze_fsl_tcput>;
+def TCAPUT : FSLPutT<0x1B, "tcaput ", int_mblaze_fsl_tcaput>;
+def TNPUT : FSLPutT<0x1B, "tnput ", int_mblaze_fsl_tnput>;
+def TNAPUT : FSLPutT<0x1B, "tnaput ", int_mblaze_fsl_tnaput>;
+def TNCPUT : FSLPutT<0x1B, "tncput ", int_mblaze_fsl_tncput>;
+def TNCAPUT : FSLPutT<0x1B, "tncaput ", int_mblaze_fsl_tncaput>;
+
+//===----------------------------------------------------------------------===//
+// FSL Dynamic Put Instructions
+//===----------------------------------------------------------------------===//
+def PUTD : FSLPutD<0x1B, 0x00, "putd ", int_mblaze_fsl_put>;
+def APUTD : FSLPutD<0x1B, 0x00, "aputd ", int_mblaze_fsl_aput>;
+def CPUTD : FSLPutD<0x1B, 0x00, "cputd ", int_mblaze_fsl_cput>;
+def CAPUTD : FSLPutD<0x1B, 0x00, "caputd ", int_mblaze_fsl_caput>;
+def NPUTD : FSLPutD<0x1B, 0x00, "nputd ", int_mblaze_fsl_nput>;
+def NAPUTD : FSLPutD<0x1B, 0x00, "naputd ", int_mblaze_fsl_naput>;
+def NCPUTD : FSLPutD<0x1B, 0x00, "ncputd ", int_mblaze_fsl_ncput>;
+def NCAPUTD : FSLPutD<0x1B, 0x00, "ncaputd ", int_mblaze_fsl_ncaput>;
+def TPUTD : FSLPutTD<0x1B, 0x00, "tputd ", int_mblaze_fsl_tput>;
+def TAPUTD : FSLPutTD<0x1B, 0x00, "taputd ", int_mblaze_fsl_taput>;
+def TCPUTD : FSLPutTD<0x1B, 0x00, "tcputd ", int_mblaze_fsl_tcput>;
+def TCAPUTD : FSLPutTD<0x1B, 0x00, "tcaputd ", int_mblaze_fsl_tcaput>;
+def TNPUTD : FSLPutTD<0x1B, 0x00, "tnputd ", int_mblaze_fsl_tnput>;
+def TNAPUTD : FSLPutTD<0x1B, 0x00, "tnaputd ", int_mblaze_fsl_tnaput>;
+def TNCPUTD : FSLPutTD<0x1B, 0x00, "tncputd ", int_mblaze_fsl_tncput>;
+def TNCAPUTD : FSLPutTD<0x1B, 0x00, "tncaputd ", int_mblaze_fsl_tncaput>;
diff --git a/lib/Target/MBlaze/MBlazeInstrFormats.td b/lib/Target/MBlaze/MBlazeInstrFormats.td
new file mode 100644
index 0000000..7d65543
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeInstrFormats.td
@@ -0,0 +1,246 @@
+//===- MBlazeInstrFormats.td - MB Instruction defs --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Describe MBlaze instructions format
+//
+// CPU INSTRUCTION FORMATS
+//
+// opcode - operation code.
+// rd - dst reg.
+// ra - first src. reg.
+// rb - second src. reg.
+// imm16 - 16-bit immediate value.
+//
+//===----------------------------------------------------------------------===//
+
+// Generic MBlaze Format
+class MBlazeInst<dag outs, dag ins, string asmstr, list<dag> pattern,
+ InstrItinClass itin> : Instruction
+{
+ field bits<32> Inst;
+
+ let Namespace = "MBlaze";
+
+ bits<6> opcode;
+
+ // Top 6 bits are the 'opcode' field
+ let Inst{0-5} = opcode;
+
+ dag OutOperandList = outs;
+ dag InOperandList = ins;
+
+ let AsmString = asmstr;
+ let Pattern = pattern;
+ let Itinerary = itin;
+}
+
+//===----------------------------------------------------------------------===//
+// Pseudo instruction class
+//===----------------------------------------------------------------------===//
+class MBlazePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
+ MBlazeInst<outs, ins, asmstr, pattern, IIPseudo>;
+
+//===----------------------------------------------------------------------===//
+// Type A instruction class in MBlaze : <|opcode|rd|ra|rb|flags|>
+//===----------------------------------------------------------------------===//
+
+class TA<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> rd;
+ bits<5> ra;
+ bits<5> rb;
+
+ let opcode = op;
+
+ let Inst{6-10} = rd;
+ let Inst{11-15} = ra;
+ let Inst{16-20} = rb;
+ let Inst{21-31} = flags;
+}
+
+class TAI<bits<6> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> rd;
+ bits<5> ra;
+ bits<16> imm16;
+
+ let opcode = op;
+
+ let Inst{6-10} = rd;
+ let Inst{11-15} = ra;
+ let Inst{16-31} = imm16;
+}
+
+class TIMM<bits<6> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> ra;
+ bits<16> imm16;
+
+ let opcode = op;
+
+ let Inst{6-15} = 0;
+ let Inst{16-31} = imm16;
+}
+
+class TADDR<bits<6> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<26> addr;
+
+ let opcode = op;
+
+ let Inst{6-31} = addr;
+}
+
+//===----------------------------------------------------------------------===//
+// Type B instruction class in MBlaze : <|opcode|rd|ra|immediate|>
+//===----------------------------------------------------------------------===//
+
+class TB<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
+ InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> rd;
+ bits<5> ra;
+ bits<16> imm16;
+
+ let opcode = op;
+
+ let Inst{6-10} = rd;
+ let Inst{11-15} = ra;
+ let Inst{16-31} = imm16;
+}
+
+//===----------------------------------------------------------------------===//
+// Float instruction class in MBlaze : <|opcode|rd|ra|flags|>
+//===----------------------------------------------------------------------===//
+
+class TF<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> rd;
+ bits<5> ra;
+
+ let opcode = op;
+
+ let Inst{6-10} = rd;
+ let Inst{11-15} = ra;
+ let Inst{16-20} = 0;
+ let Inst{21-31} = flags;
+}
+
+//===----------------------------------------------------------------------===//
+// Branch instruction class in MBlaze : <|opcode|rd|br|ra|flags|>
+//===----------------------------------------------------------------------===//
+
+class TBR<bits<6> op, bits<5> br, bits<11> flags, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> ra;
+
+ let opcode = op;
+
+ let Inst{6-10} = 0;
+ let Inst{11-15} = br;
+ let Inst{16-20} = ra;
+ let Inst{21-31} = flags;
+}
+
+class TBRC<bits<6> op, bits<5> br, bits<11> flags, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> ra;
+ bits<5> rb;
+
+ let opcode = op;
+
+ let Inst{6-10} = br;
+ let Inst{11-15} = ra;
+ let Inst{16-20} = rb;
+ let Inst{21-31} = flags;
+}
+
+class TBRL<bits<6> op, bits<5> br, bits<11> flags, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> ra;
+
+ let opcode = op;
+
+ let Inst{6-10} = 0xF;
+ let Inst{11-15} = br;
+ let Inst{16-20} = ra;
+ let Inst{21-31} = flags;
+}
+
+class TBRI<bits<6> op, bits<5> br, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<16> imm16;
+
+ let opcode = op;
+
+ let Inst{6-10} = 0;
+ let Inst{11-15} = br;
+ let Inst{16-31} = imm16;
+}
+
+class TBRLI<bits<6> op, bits<5> br, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<16> imm16;
+
+ let opcode = op;
+
+ let Inst{6-10} = 0xF;
+ let Inst{11-15} = br;
+ let Inst{16-31} = imm16;
+}
+
+class TBRCI<bits<6> op, bits<5> br, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> ra;
+ bits<16> imm16;
+
+ let opcode = op;
+
+ let Inst{6-10} = br;
+ let Inst{11-15} = ra;
+ let Inst{16-31} = imm16;
+}
+
+class TRET<bits<6> op, dag outs, dag ins,
+ string asmstr, list<dag> pattern, InstrItinClass itin> :
+ MBlazeInst<outs, ins, asmstr, pattern, itin>
+{
+ bits<5> ra;
+ bits<16> imm16;
+
+ let opcode = op;
+
+ let Inst{6-10} = 0x10;
+ let Inst{11-15} = ra;
+ let Inst{16-31} = imm16;
+}
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.cpp b/lib/Target/MBlaze/MBlazeInstrInfo.cpp
new file mode 100644
index 0000000..a7e8eb7
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.cpp
@@ -0,0 +1,222 @@
+//===- MBlazeInstrInfo.cpp - MBlaze Instruction Information -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MBlaze implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlazeInstrInfo.h"
+#include "MBlazeTargetMachine.h"
+#include "MBlazeMachineFunction.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "MBlazeGenInstrInfo.inc"
+
+using namespace llvm;
+
+MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
+ : TargetInstrInfoImpl(MBlazeInsts, array_lengthof(MBlazeInsts)),
+ TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
+
+static bool isZeroImm(const MachineOperand &op) {
+ return op.isImm() && op.getImm() == 0;
+}
+
+/// Return true if the instruction is a register to register move and
+/// leave the source and dest operands in the passed parameters.
+bool MBlazeInstrInfo::
+isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
+ SrcSubIdx = DstSubIdx = 0; // No sub-registers.
+
+ // add $dst, $src, $zero || addu $dst, $zero, $src
+ // or $dst, $src, $zero || or $dst, $zero, $src
+ if ((MI.getOpcode() == MBlaze::ADD) || (MI.getOpcode() == MBlaze::OR)) {
+ if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == MBlaze::R0) {
+ DstReg = MI.getOperand(0).getReg();
+ SrcReg = MI.getOperand(2).getReg();
+ return true;
+ } else if (MI.getOperand(2).isReg() &&
+ MI.getOperand(2).getReg() == MBlaze::R0) {
+ DstReg = MI.getOperand(0).getReg();
+ SrcReg = MI.getOperand(1).getReg();
+ return true;
+ }
+ }
+
+ // addi $dst, $src, 0
+ // ori $dst, $src, 0
+ if ((MI.getOpcode() == MBlaze::ADDI) || (MI.getOpcode() == MBlaze::ORI)) {
+ if ((MI.getOperand(1).isReg()) && (isZeroImm(MI.getOperand(2)))) {
+ DstReg = MI.getOperand(0).getReg();
+ SrcReg = MI.getOperand(1).getReg();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/// isLoadFromStackSlot - If the specified machine instruction is a direct
+/// load from a stack slot, return the virtual or physical register number of
+/// the destination along with the FrameIndex of the loaded stack slot. If
+/// not, return 0. This predicate must return 0 if the instruction has
+/// any side effects other than loading from the stack slot.
+unsigned MBlazeInstrInfo::
+isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
+ if (MI->getOpcode() == MBlaze::LWI) {
+ if ((MI->getOperand(2).isFI()) && // is a stack slot
+ (MI->getOperand(1).isImm()) && // the imm is zero
+ (isZeroImm(MI->getOperand(1)))) {
+ FrameIndex = MI->getOperand(2).getIndex();
+ return MI->getOperand(0).getReg();
+ }
+ }
+
+ return 0;
+}
+
+/// isStoreToStackSlot - If the specified machine instruction is a direct
+/// store to a stack slot, return the virtual or physical register number of
+/// the source reg along with the FrameIndex of the loaded stack slot. If
+/// not, return 0. This predicate must return 0 if the instruction has
+/// any side effects other than storing to the stack slot.
+unsigned MBlazeInstrInfo::
+isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
+ if (MI->getOpcode() == MBlaze::SWI) {
+ if ((MI->getOperand(2).isFI()) && // is a stack slot
+ (MI->getOperand(1).isImm()) && // the imm is zero
+ (isZeroImm(MI->getOperand(1)))) {
+ FrameIndex = MI->getOperand(2).getIndex();
+ return MI->getOperand(0).getReg();
+ }
+ }
+ return 0;
+}
+
+/// insertNoop - If data hazard condition is found insert the target nop
+/// instruction.
+void MBlazeInstrInfo::
+insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
+ DebugLoc DL = DebugLoc::getUnknownLoc();
+ if (MI != MBB.end()) DL = MI->getDebugLoc();
+ BuildMI(MBB, MI, DL, get(MBlaze::NOP));
+}
+
+bool MBlazeInstrInfo::
+copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+ unsigned DestReg, unsigned SrcReg,
+ const TargetRegisterClass *DestRC,
+ const TargetRegisterClass *SrcRC) const {
+ DebugLoc dl = DebugLoc::getUnknownLoc();
+ llvm::BuildMI(MBB, I, dl, get(MBlaze::ADD), DestReg)
+ .addReg(SrcReg).addReg(MBlaze::R0);
+ return true;
+}
+
+void MBlazeInstrInfo::
+storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+ unsigned SrcReg, bool isKill, int FI,
+ const TargetRegisterClass *RC) const {
+ DebugLoc dl = DebugLoc::getUnknownLoc();
+ BuildMI(MBB, I, dl, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
+ .addImm(0).addFrameIndex(FI);
+}
+
+void MBlazeInstrInfo::
+loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+ unsigned DestReg, int FI,
+ const TargetRegisterClass *RC) const {
+ DebugLoc dl = DebugLoc::getUnknownLoc();
+ BuildMI(MBB, I, dl, get(MBlaze::LWI), DestReg)
+ .addImm(0).addFrameIndex(FI);
+}
+
+MachineInstr *MBlazeInstrInfo::
+foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops, int FI) const {
+ if (Ops.size() != 1) return NULL;
+
+ MachineInstr *NewMI = NULL;
+
+ switch (MI->getOpcode()) {
+ case MBlaze::OR:
+ case MBlaze::ADD:
+ if ((MI->getOperand(0).isReg()) &&
+ (MI->getOperand(2).isReg()) &&
+ (MI->getOperand(2).getReg() == MBlaze::R0) &&
+ (MI->getOperand(1).isReg())) {
+ if (Ops[0] == 0) { // COPY -> STORE
+ unsigned SrcReg = MI->getOperand(1).getReg();
+ bool isKill = MI->getOperand(1).isKill();
+ bool isUndef = MI->getOperand(1).isUndef();
+ NewMI = BuildMI(MF, MI->getDebugLoc(), get(MBlaze::SW))
+ .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
+ .addImm(0).addFrameIndex(FI);
+ } else { // COPY -> LOAD
+ unsigned DstReg = MI->getOperand(0).getReg();
+ bool isDead = MI->getOperand(0).isDead();
+ bool isUndef = MI->getOperand(0).isUndef();
+ NewMI = BuildMI(MF, MI->getDebugLoc(), get(MBlaze::LW))
+ .addReg(DstReg, RegState::Define | getDeadRegState(isDead) |
+ getUndefRegState(isUndef))
+ .addImm(0).addFrameIndex(FI);
+ }
+ }
+ break;
+ }
+
+ return NewMI;
+}
+
+//===----------------------------------------------------------------------===//
+// Branch Analysis
+//===----------------------------------------------------------------------===//
+unsigned MBlazeInstrInfo::
+InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ const SmallVectorImpl<MachineOperand> &Cond) const {
+ DebugLoc dl = DebugLoc::getUnknownLoc();
+
+ // Can only insert uncond branches so far.
+ assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
+ BuildMI(&MBB, dl, get(MBlaze::BRI)).addMBB(TBB);
+ return 1;
+}
+
+/// getGlobalBaseReg - Return a virtual register initialized with the
+/// the global base register value. Output instructions required to
+/// initialize the register in the function entry block, if necessary.
+///
+unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
+ MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
+ unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg();
+ if (GlobalBaseReg != 0)
+ return GlobalBaseReg;
+
+ // Insert the set of GlobalBaseReg into the first MBB of the function
+ MachineBasicBlock &FirstMBB = MF->front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ MachineRegisterInfo &RegInfo = MF->getRegInfo();
+ const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+
+ GlobalBaseReg = RegInfo.createVirtualRegister(MBlaze::CPURegsRegisterClass);
+ bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, MBlaze::R20,
+ MBlaze::CPURegsRegisterClass,
+ MBlaze::CPURegsRegisterClass);
+ assert(Ok && "Couldn't assign to global base register!");
+ Ok = Ok; // Silence warning when assertions are turned off.
+ RegInfo.addLiveIn(MBlaze::R20);
+
+ MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
+ return GlobalBaseReg;
+}
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.h b/lib/Target/MBlaze/MBlazeInstrInfo.h
new file mode 100644
index 0000000..4f79f1c
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.h
@@ -0,0 +1,242 @@
+//===- MBlazeInstrInfo.h - MBlaze Instruction Information -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MBlaze implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBLAZEINSTRUCTIONINFO_H
+#define MBLAZEINSTRUCTIONINFO_H
+
+#include "MBlaze.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "MBlazeRegisterInfo.h"
+
+namespace llvm {
+
+namespace MBlaze {
+
+ // MBlaze Branch Codes
+ enum FPBranchCode {
+ BRANCH_F,
+ BRANCH_T,
+ BRANCH_FL,
+ BRANCH_TL,
+ BRANCH_INVALID
+ };
+
+ // MBlaze Condition Codes
+ enum CondCode {
+ // To be used with float branch True
+ FCOND_F,
+ FCOND_UN,
+ FCOND_EQ,
+ FCOND_UEQ,
+ FCOND_OLT,
+ FCOND_ULT,
+ FCOND_OLE,
+ FCOND_ULE,
+ FCOND_SF,
+ FCOND_NGLE,
+ FCOND_SEQ,
+ FCOND_NGL,
+ FCOND_LT,
+ FCOND_NGE,
+ FCOND_LE,
+ FCOND_NGT,
+
+ // To be used with float branch False
+ // This conditions have the same mnemonic as the
+ // above ones, but are used with a branch False;
+ FCOND_T,
+ FCOND_OR,
+ FCOND_NEQ,
+ FCOND_OGL,
+ FCOND_UGE,
+ FCOND_OGE,
+ FCOND_UGT,
+ FCOND_OGT,
+ FCOND_ST,
+ FCOND_GLE,
+ FCOND_SNE,
+ FCOND_GL,
+ FCOND_NLT,
+ FCOND_GE,
+ FCOND_NLE,
+ FCOND_GT,
+
+ // Only integer conditions
+ COND_E,
+ COND_GZ,
+ COND_GEZ,
+ COND_LZ,
+ COND_LEZ,
+ COND_NE,
+ COND_INVALID
+ };
+
+ // Turn condition code into conditional branch opcode.
+ unsigned GetCondBranchFromCond(CondCode CC);
+
+ /// GetOppositeBranchCondition - Return the inverse of the specified cond,
+ /// e.g. turning COND_E to COND_NE.
+ CondCode GetOppositeBranchCondition(MBlaze::CondCode CC);
+
+ /// MBlazeCCToString - Map each FP condition code to its string
+ inline static const char *MBlazeFCCToString(MBlaze::CondCode CC)
+ {
+ switch (CC) {
+ default: llvm_unreachable("Unknown condition code");
+ case FCOND_F:
+ case FCOND_T: return "f";
+ case FCOND_UN:
+ case FCOND_OR: return "un";
+ case FCOND_EQ:
+ case FCOND_NEQ: return "eq";
+ case FCOND_UEQ:
+ case FCOND_OGL: return "ueq";
+ case FCOND_OLT:
+ case FCOND_UGE: return "olt";
+ case FCOND_ULT:
+ case FCOND_OGE: return "ult";
+ case FCOND_OLE:
+ case FCOND_UGT: return "ole";
+ case FCOND_ULE:
+ case FCOND_OGT: return "ule";
+ case FCOND_SF:
+ case FCOND_ST: return "sf";
+ case FCOND_NGLE:
+ case FCOND_GLE: return "ngle";
+ case FCOND_SEQ:
+ case FCOND_SNE: return "seq";
+ case FCOND_NGL:
+ case FCOND_GL: return "ngl";
+ case FCOND_LT:
+ case FCOND_NLT: return "lt";
+ case FCOND_NGE:
+ case FCOND_GE: return "ge";
+ case FCOND_LE:
+ case FCOND_NLE: return "nle";
+ case FCOND_NGT:
+ case FCOND_GT: return "gt";
+ }
+ }
+}
+
+/// MBlazeII - This namespace holds all of the target specific flags that
+/// instruction info tracks.
+///
+namespace MBlazeII {
+ /// Target Operand Flag enum.
+ enum TOF {
+ //===------------------------------------------------------------------===//
+ // MBlaze Specific MachineOperand flags.
+ MO_NO_FLAG,
+
+ /// MO_GOT - Represents the offset into the global offset table at which
+ /// the address the relocation entry symbol resides during execution.
+ MO_GOT,
+
+ /// MO_GOT_CALL - Represents the offset into the global offset table at
+ /// which the address of a call site relocation entry symbol resides
+ /// during execution. This is different from the above since this flag
+ /// can only be present in call instructions.
+ MO_GOT_CALL,
+
+ /// MO_GPREL - Represents the offset from the current gp value to be used
+ /// for the relocatable object file being produced.
+ MO_GPREL,
+
+ /// MO_ABS_HILO - Represents the hi or low part of an absolute symbol
+ /// address.
+ MO_ABS_HILO
+
+ };
+}
+
+class MBlazeInstrInfo : public TargetInstrInfoImpl {
+ MBlazeTargetMachine &TM;
+ const MBlazeRegisterInfo RI;
+public:
+ explicit MBlazeInstrInfo(MBlazeTargetMachine &TM);
+
+ /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
+ /// such, whenever a client has an instance of instruction info, it should
+ /// always be able to get register info as well (through this method).
+ ///
+ virtual const MBlazeRegisterInfo &getRegisterInfo() const { return RI; }
+
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
+ virtual bool isMoveInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+
+ /// isLoadFromStackSlot - If the specified machine instruction is a direct
+ /// load from a stack slot, return the virtual or physical register number of
+ /// the destination along with the FrameIndex of the loaded stack slot. If
+ /// not, return 0. This predicate must return 0 if the instruction has
+ /// any side effects other than loading from the stack slot.
+ virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
+ int &FrameIndex) const;
+
+ /// isStoreToStackSlot - If the specified machine instruction is a direct
+ /// store to a stack slot, return the virtual or physical register number of
+ /// the source reg along with the FrameIndex of the loaded stack slot. If
+ /// not, return 0. This predicate must return 0 if the instruction has
+ /// any side effects other than storing to the stack slot.
+ virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
+ int &FrameIndex) const;
+
+ /// Branch Analysis
+ virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ const SmallVectorImpl<MachineOperand> &Cond) const;
+ virtual bool copyRegToReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ unsigned DestReg, unsigned SrcReg,
+ const TargetRegisterClass *DestRC,
+ const TargetRegisterClass *SrcRC) const;
+ virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ unsigned SrcReg, bool isKill, int FrameIndex,
+ const TargetRegisterClass *RC) const;
+
+ virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ unsigned DestReg, int FrameIndex,
+ const TargetRegisterClass *RC) const;
+
+ virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ int FrameIndex) const;
+
+ virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ MachineInstr* LoadMI) const {
+ return 0;
+ }
+
+ /// Insert nop instruction when hazard condition is found
+ virtual void insertNoop(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const;
+
+ /// getGlobalBaseReg - Return a virtual register initialized with the
+ /// the global base register value. Output instructions required to
+ /// initialize the register in the function entry block, if necessary.
+ ///
+ unsigned getGlobalBaseReg(MachineFunction *MF) const;
+};
+
+}
+
+#endif
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td
new file mode 100644
index 0000000..3c406dd
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.td
@@ -0,0 +1,672 @@
+//===- MBlazeInstrInfo.td - MBlaze Instruction defs -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction format superclass
+//===----------------------------------------------------------------------===//
+include "MBlazeInstrFormats.td"
+
+//===----------------------------------------------------------------------===//
+// MBlaze profiles and nodes
+//===----------------------------------------------------------------------===//
+def SDT_MBlazeRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
+def SDT_MBlazeJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+
+// Call
+def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink,
+ [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag]>;
+
+// Return
+def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet,
+ [SDNPHasChain, SDNPOptInFlag]>;
+
+// Hi and Lo nodes are used to handle global addresses. Used on
+// MBlazeISelLowering to lower stuff like GlobalAddress, ExternalSymbol
+// static model.
+def MBWrapper : SDNode<"MBlazeISD::Wrap", SDTIntUnaryOp>;
+def MBlazeGPRel : SDNode<"MBlazeISD::GPRel", SDTIntUnaryOp>;
+
+def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
+def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
+
+// These are target-independent nodes, but have target-specific formats.
+def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MBCallSeqStart,
+ [SDNPHasChain, SDNPOutFlag]>;
+def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MBCallSeqEnd,
+ [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+
+def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>;
+
+//===----------------------------------------------------------------------===//
+// MBlaze Instruction Predicate Definitions.
+//===----------------------------------------------------------------------===//
+def HasPipe3 : Predicate<"Subtarget.hasPipe3()">;
+def HasBarrel : Predicate<"Subtarget.hasBarrel()">;
+def NoBarrel : Predicate<"!Subtarget.hasBarrel()">;
+def HasDiv : Predicate<"Subtarget.hasDiv()">;
+def HasMul : Predicate<"Subtarget.hasMul()">;
+def HasFSL : Predicate<"Subtarget.hasFSL()">;
+def HasEFSL : Predicate<"Subtarget.hasEFSL()">;
+def HasMSRSet : Predicate<"Subtarget.hasMSRSet()">;
+def HasException : Predicate<"Subtarget.hasException()">;
+def HasPatCmp : Predicate<"Subtarget.hasPatCmp()">;
+def HasFPU : Predicate<"Subtarget.hasFPU()">;
+def HasESR : Predicate<"Subtarget.hasESR()">;
+def HasPVR : Predicate<"Subtarget.hasPVR()">;
+def HasMul64 : Predicate<"Subtarget.hasMul64()">;
+def HasSqrt : Predicate<"Subtarget.hasSqrt()">;
+def HasMMU : Predicate<"Subtarget.hasMMU()">;
+
+//===----------------------------------------------------------------------===//
+// MBlaze Operand, Complex Patterns and Transformations Definitions.
+//===----------------------------------------------------------------------===//
+
+// Instruction operand types
+def brtarget : Operand<OtherVT>;
+def calltarget : Operand<i32>;
+def simm16 : Operand<i32>;
+def uimm5 : Operand<i32>;
+def fimm : Operand<f32>;
+
+// Unsigned Operand
+def uimm16 : Operand<i32> {
+ let PrintMethod = "printUnsignedImm";
+}
+
+// FSL Operand
+def fslimm : Operand<i32> {
+ let PrintMethod = "printFSLImm";
+}
+
+// Address operand
+def memri : Operand<i32> {
+ let PrintMethod = "printMemOperand";
+ let MIOperandInfo = (ops simm16, CPURegs);
+}
+
+def memrr : Operand<i32> {
+ let PrintMethod = "printMemOperand";
+ let MIOperandInfo = (ops CPURegs, CPURegs);
+}
+
+// Transformation Function - get the lower 16 bits.
+def LO16 : SDNodeXForm<imm, [{
+ return getI32Imm((unsigned)N->getZExtValue() & 0xFFFF);
+}]>;
+
+// Transformation Function - get the higher 16 bits.
+def HI16 : SDNodeXForm<imm, [{
+ return getI32Imm((unsigned)N->getZExtValue() >> 16);
+}]>;
+
+// Node immediate fits as 16-bit sign extended on target immediate.
+// e.g. addi, andi
+def immSExt16 : PatLeaf<(imm), [{
+ return (N->getZExtValue() >> 16) == 0;
+}]>;
+
+// Node immediate fits as 16-bit zero extended on target immediate.
+// The LO16 param means that only the lower 16 bits of the node
+// immediate are caught.
+// e.g. addiu, sltiu
+def immZExt16 : PatLeaf<(imm), [{
+ return (N->getZExtValue() >> 16) == 0;
+}], LO16>;
+
+// FSL immediate field must fit in 4 bits.
+def immZExt4 : PatLeaf<(imm), [{
+ return N->getZExtValue() == ((N->getZExtValue()) & 0xf) ;
+}]>;
+
+// shamt field must fit in 5 bits.
+def immZExt5 : PatLeaf<(imm), [{
+ return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ;
+}]>;
+
+// MBlaze Address Mode! SDNode frameindex could possibily be a match
+// since load and store instructions from stack used it.
+def iaddr : ComplexPattern<i32, 2, "SelectAddrRegImm", [frameindex], []>;
+def xaddr : ComplexPattern<i32, 2, "SelectAddrRegReg", [], []>;
+
+//===----------------------------------------------------------------------===//
+// Pseudo instructions
+//===----------------------------------------------------------------------===//
+
+// As stack alignment is always done with addiu, we need a 16-bit immediate
+let Defs = [R1], Uses = [R1] in {
+def ADJCALLSTACKDOWN : MBlazePseudo<(outs), (ins simm16:$amt),
+ "${:comment} ADJCALLSTACKDOWN $amt",
+ [(callseq_start timm:$amt)]>;
+def ADJCALLSTACKUP : MBlazePseudo<(outs),
+ (ins uimm16:$amt1, simm16:$amt2),
+ "${:comment} ADJCALLSTACKUP $amt1",
+ [(callseq_end timm:$amt1, timm:$amt2)]>;
+}
+
+// Some assembly macros need to avoid pseudoinstructions and assembler
+// automatic reodering, we should reorder ourselves.
+def MACRO : MBlazePseudo<(outs), (ins), ".set macro", []>;
+def REORDER : MBlazePseudo<(outs), (ins), ".set reorder", []>;
+def NOMACRO : MBlazePseudo<(outs), (ins), ".set nomacro", []>;
+def NOREORDER : MBlazePseudo<(outs), (ins), ".set noreorder", []>;
+
+// When handling PIC code the assembler needs .cpload and .cprestore
+// directives. If the real instructions corresponding these directives
+// are used, we have the same behavior, but get also a bunch of warnings
+// from the assembler.
+def CPLOAD : MBlazePseudo<(outs), (ins CPURegs:$reg), ".cpload $reg", []>;
+def CPRESTORE : MBlazePseudo<(outs), (ins uimm16:$l), ".cprestore $l\n", []>;
+
+//===----------------------------------------------------------------------===//
+// Instructions specific format
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Arithmetic Instructions
+//===----------------------------------------------------------------------===//
+class Arith<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
+ InstrItinClass itin> :
+ TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>;
+
+class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
+ Operand Od, PatLeaf imm_type> :
+ TAI<op, (outs CPURegs:$dst), (ins CPURegs:$b, Od:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>;
+
+class ArithR<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
+ InstrItinClass itin> :
+ TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$c, CPURegs:$b),
+ !strconcat(instr_asm, " $dst, $c, $b"),
+ [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>;
+
+class ArithRI<bits<6> op, string instr_asm, SDNode OpNode,
+ Operand Od, PatLeaf imm_type> :
+ TAI<op, (outs CPURegs:$dst), (ins Od:$b, CPURegs:$c),
+ !strconcat(instr_asm, " $dst, $c, $b"),
+ [(set CPURegs:$dst, (OpNode imm_type:$b, CPURegs:$c))], IIAlu>;
+
+class ArithN<bits<6> op, bits<11> flags, string instr_asm,
+ InstrItinClass itin> :
+ TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], itin>;
+
+class ArithNI<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> :
+ TAI<op, (outs CPURegs:$dst), (ins CPURegs:$b, Od:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], IIAlu>;
+
+class ArithRN<bits<6> op, bits<11> flags, string instr_asm,
+ InstrItinClass itin> :
+ TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$c, CPURegs:$b),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], itin>;
+
+class ArithRNI<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> :
+ TAI<op, (outs CPURegs:$dst), (ins Od:$c, CPURegs:$b),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], IIAlu>;
+
+//===----------------------------------------------------------------------===//
+// Misc Arithmetic Instructions
+//===----------------------------------------------------------------------===//
+
+class Logic<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode> :
+ TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
+
+class LogicI<bits<6> op, string instr_asm, SDNode OpNode> :
+ TAI<op, (outs CPURegs:$dst), (ins CPURegs:$b, uimm16:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt16:$c))],
+ IIAlu>;
+
+class EffectiveAddress<string instr_asm> :
+ TAI<0x08, (outs CPURegs:$dst), (ins memri:$addr),
+ instr_asm, [(set CPURegs:$dst, iaddr:$addr)], IIAlu>;
+
+//===----------------------------------------------------------------------===//
+// Memory Access Instructions
+//===----------------------------------------------------------------------===//
+class LoadM<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TA<op, 0x000, (outs CPURegs:$dst), (ins memrr:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(set CPURegs:$dst, (OpNode xaddr:$addr))], IILoad>;
+
+class LoadMI<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TAI<op, (outs CPURegs:$dst), (ins memri:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(set CPURegs:$dst, (OpNode iaddr:$addr))], IILoad>;
+
+class StoreM<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TA<op, 0x000, (outs), (ins CPURegs:$dst, memrr:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(OpNode CPURegs:$dst, xaddr:$addr)], IIStore>;
+
+class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> :
+ TAI<op, (outs), (ins CPURegs:$dst, memri:$addr),
+ !strconcat(instr_asm, " $dst, $addr"),
+ [(OpNode CPURegs:$dst, iaddr:$addr)], IIStore>;
+
+//===----------------------------------------------------------------------===//
+// Branch Instructions
+//===----------------------------------------------------------------------===//
+class Branch<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> :
+ TBR<op, br, flags, (outs), (ins CPURegs:$target),
+ !strconcat(instr_asm, " $target"),
+ [(brind CPURegs:$target)], IIBranch>;
+
+class BranchI<bits<6> op, bits<5> brf, string instr_asm> :
+ TBRI<op, brf, (outs), (ins brtarget:$target),
+ !strconcat(instr_asm, " $target"),
+ [(br bb:$target)], IIBranch>;
+
+//===----------------------------------------------------------------------===//
+// Branch and Link Instructions
+//===----------------------------------------------------------------------===//
+class BranchL<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> :
+ TBRL<op, br, flags, (outs), (ins CPURegs:$target),
+ !strconcat(instr_asm, " r15, $target"),
+ [], IIBranch>;
+
+class BranchLI<bits<6> op, bits<5> br, string instr_asm> :
+ TBRLI<op, br, (outs), (ins calltarget:$target),
+ !strconcat(instr_asm, " r15, $target"),
+ [], IIBranch>;
+
+//===----------------------------------------------------------------------===//
+// Conditional Branch Instructions
+//===----------------------------------------------------------------------===//
+class BranchC<bits<6> op, bits<5> br, bits<11> flags, string instr_asm,
+ PatFrag cond_op> :
+ TBRC<op, br, flags, (outs),
+ (ins CPURegs:$a, CPURegs:$b, brtarget:$offset),
+ !strconcat(instr_asm, " $a, $b, $offset"),
+ [], IIBranch>;
+ //(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)],
+ //IIBranch>;
+
+class BranchCI<bits<6> op, bits<5> br, string instr_asm, PatFrag cond_op> :
+ TBRCI<op, br, (outs), (ins CPURegs:$a, brtarget:$offset),
+ !strconcat(instr_asm, " $a, $offset"),
+ [], IIBranch>;
+
+//===----------------------------------------------------------------------===//
+// MBlaze arithmetic instructions
+//===----------------------------------------------------------------------===//
+
+let isCommutable = 1, isAsCheapAsAMove = 1 in {
+ def ADD : Arith<0x00, 0x000, "add ", add, IIAlu>;
+ def ADDC : Arith<0x02, 0x000, "addc ", adde, IIAlu>;
+ def ADDK : Arith<0x04, 0x000, "addk ", addc, IIAlu>;
+ def ADDKC : ArithN<0x06, 0x000, "addkc ", IIAlu>;
+ def AND : Logic<0x21, 0x000, "and ", and>;
+ def OR : Logic<0x20, 0x000, "or ", or>;
+ def XOR : Logic<0x22, 0x000, "xor ", xor>;
+}
+
+let isAsCheapAsAMove = 1 in {
+ def ANDN : ArithN<0x23, 0x000, "andn ", IIAlu>;
+ def CMP : ArithN<0x05, 0x001, "cmp ", IIAlu>;
+ def CMPU : ArithN<0x05, 0x003, "cmpu ", IIAlu>;
+ def RSUB : ArithR<0x01, 0x000, "rsub ", sub, IIAlu>;
+ def RSUBC : ArithR<0x03, 0x000, "rsubc ", sube, IIAlu>;
+ def RSUBK : ArithR<0x05, 0x000, "rsubk ", subc, IIAlu>;
+ def RSUBKC : ArithRN<0x07, 0x000, "rsubkc ", IIAlu>;
+}
+
+let isCommutable = 1, Predicates=[HasMul] in {
+ def MUL : Arith<0x10, 0x000, "mul ", mul, IIAlu>;
+}
+
+let isCommutable = 1, Predicates=[HasMul,HasMul64] in {
+ def MULH : Arith<0x10, 0x001, "mulh ", mulhs, IIAlu>;
+ def MULHU : Arith<0x10, 0x003, "mulhu ", mulhu, IIAlu>;
+}
+
+let Predicates=[HasMul,HasMul64] in {
+ def MULHSU : ArithN<0x10, 0x002, "mulhsu ", IIAlu>;
+}
+
+let Predicates=[HasBarrel] in {
+ def BSRL : Arith<0x11, 0x000, "bsrl ", srl, IIAlu>;
+ def BSRA : Arith<0x11, 0x200, "bsra ", sra, IIAlu>;
+ def BSLL : Arith<0x11, 0x400, "bsll ", shl, IIAlu>;
+ def BSRLI : ArithI<0x11, "bsrli ", srl, uimm5, immZExt5>;
+ def BSRAI : ArithI<0x11, "bsrai ", sra, uimm5, immZExt5>;
+ def BSLLI : ArithI<0x11, "bslli ", shl, uimm5, immZExt5>;
+}
+
+let Predicates=[HasDiv] in {
+ def IDIV : Arith<0x12, 0x000, "idiv ", sdiv, IIAlu>;
+ def IDIVU : Arith<0x12, 0x002, "idivu ", udiv, IIAlu>;
+}
+
+//===----------------------------------------------------------------------===//
+// MBlaze immediate mode arithmetic instructions
+//===----------------------------------------------------------------------===//
+
+let isAsCheapAsAMove = 1 in {
+ def ADDI : ArithI<0x08, "addi ", add, simm16, immSExt16>;
+ def ADDIC : ArithNI<0x0A, "addic ", simm16, immSExt16>;
+ def ADDIK : ArithNI<0x0C, "addik ", simm16, immSExt16>;
+ def ADDIKC : ArithI<0x0E, "addikc ", addc, simm16, immSExt16>;
+ def RSUBI : ArithRI<0x09, "rsubi ", sub, simm16, immSExt16>;
+ def RSUBIC : ArithRNI<0x0B, "rsubi ", simm16, immSExt16>;
+ def RSUBIK : ArithRNI<0x0E, "rsubic ", simm16, immSExt16>;
+ def RSUBIKC : ArithRI<0x0F, "rsubikc", subc, simm16, immSExt16>;
+ def ANDNI : ArithNI<0x2B, "andni ", uimm16, immZExt16>;
+ def ANDI : LogicI<0x29, "andi ", and>;
+ def ORI : LogicI<0x28, "ori ", or>;
+ def XORI : LogicI<0x2A, "xori ", xor>;
+}
+
+let Predicates=[HasMul] in {
+ def MULI : ArithI<0x18, "muli ", mul, simm16, immSExt16>;
+}
+
+//===----------------------------------------------------------------------===//
+// MBlaze memory access instructions
+//===----------------------------------------------------------------------===//
+
+let canFoldAsLoad = 1, isReMaterializable = 1 in {
+ def LBU : LoadM<0x30, "lbu ", zextloadi8>;
+ def LHU : LoadM<0x31, "lhu ", zextloadi16>;
+ def LW : LoadM<0x32, "lw ", load>;
+
+ def LBUI : LoadMI<0x30, "lbui ", zextloadi8>;
+ def LHUI : LoadMI<0x31, "lhui ", zextloadi16>;
+ def LWI : LoadMI<0x32, "lwi ", load>;
+}
+
+ def SB : StoreM<0x34, "sb ", truncstorei8>;
+ def SH : StoreM<0x35, "sh ", truncstorei16>;
+ def SW : StoreM<0x36, "sw ", store>;
+
+ def SBI : StoreMI<0x34, "sbi ", truncstorei8>;
+ def SHI : StoreMI<0x35, "shi ", truncstorei16>;
+ def SWI : StoreMI<0x36, "swi ", store>;
+
+//===----------------------------------------------------------------------===//
+// MBlaze branch instructions
+//===----------------------------------------------------------------------===//
+
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
+ def BRI : BranchI<0x2E, 0x00, "bri ">;
+ def BRAI : BranchI<0x2E, 0x08, "brai ">;
+ def BEQI : BranchCI<0x2F, 0x00, "beqi ", seteq>;
+ def BNEI : BranchCI<0x2F, 0x01, "bnei ", setne>;
+ def BLTI : BranchCI<0x2F, 0x02, "blti ", setlt>;
+ def BLEI : BranchCI<0x2F, 0x03, "blei ", setle>;
+ def BGTI : BranchCI<0x2F, 0x04, "bgti ", setgt>;
+ def BGEI : BranchCI<0x2F, 0x05, "bgei ", setge>;
+}
+
+let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
+ def BR : Branch<0x26, 0x00, 0x000, "br ">;
+ def BRA : Branch<0x26, 0x08, 0x000, "bra ">;
+ def BEQ : BranchC<0x27, 0x00, 0x000, "beq ", seteq>;
+ def BNE : BranchC<0x27, 0x01, 0x000, "bne ", setne>;
+ def BLT : BranchC<0x27, 0x02, 0x000, "blt ", setlt>;
+ def BLE : BranchC<0x27, 0x03, 0x000, "ble ", setle>;
+ def BGT : BranchC<0x27, 0x04, 0x000, "bgt ", setgt>;
+ def BGE : BranchC<0x27, 0x05, 0x000, "bge ", setge>;
+}
+
+let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1 in {
+ def BRID : BranchI<0x2E, 0x10, "brid ">;
+ def BRAID : BranchI<0x2E, 0x18, "braid ">;
+ def BEQID : BranchCI<0x2F, 0x10, "beqid ", seteq>;
+ def BNEID : BranchCI<0x2F, 0x11, "bneid ", setne>;
+ def BLTID : BranchCI<0x2F, 0x12, "bltid ", setlt>;
+ def BLEID : BranchCI<0x2F, 0x13, "bleid ", setle>;
+ def BGTID : BranchCI<0x2F, 0x14, "bgtid ", setgt>;
+ def BGEID : BranchCI<0x2F, 0x15, "bgeid ", setge>;
+}
+
+let isBranch = 1, isIndirectBranch = 1, isTerminator = 1,
+ hasDelaySlot = 1, hasCtrlDep = 1 in {
+ def BRD : Branch<0x26, 0x10, 0x000, "brd ">;
+ def BRAD : Branch<0x26, 0x18, 0x000, "brad ">;
+ def BEQD : BranchC<0x27, 0x10, 0x000, "beqd ", seteq>;
+ def BNED : BranchC<0x27, 0x11, 0x000, "bned ", setne>;
+ def BLTD : BranchC<0x27, 0x12, 0x000, "bltd ", setlt>;
+ def BLED : BranchC<0x27, 0x13, 0x000, "bled ", setle>;
+ def BGTD : BranchC<0x27, 0x14, 0x000, "bgtd ", setgt>;
+ def BGED : BranchC<0x27, 0x15, 0x000, "bged ", setge>;
+}
+
+let isCall = 1, hasCtrlDep = 1, isIndirectBranch = 1,
+ Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
+ Uses = [R1,R5,R6,R7,R8,R9,R10] in {
+ def BRL : BranchL<0x26, 0x04, 0x000, "brl ">;
+ def BRAL : BranchL<0x26, 0x0C, 0x000, "bral ">;
+}
+
+let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1,
+ Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
+ Uses = [R1,R5,R6,R7,R8,R9,R10] in {
+ def BRLID : BranchLI<0x2E, 0x14, "brlid ">;
+ def BRALID : BranchLI<0x2E, 0x1C, "bralid ">;
+}
+
+let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1,
+ Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
+ Uses = [R1,R5,R6,R7,R8,R9,R10] in {
+ def BRLD : BranchL<0x26, 0x14, 0x000, "brld ">;
+ def BRALD : BranchL<0x26, 0x1C, 0x000, "brald ">;
+}
+
+let isReturn=1, isTerminator=1, hasDelaySlot=1,
+ isBarrier=1, hasCtrlDep=1, imm16=0x8 in {
+ def RTSD : TRET<0x2D, (outs), (ins CPURegs:$target),
+ "rtsd $target, 8",
+ [(MBlazeRet CPURegs:$target)],
+ IIBranch>;
+}
+
+//===----------------------------------------------------------------------===//
+// MBlaze misc instructions
+//===----------------------------------------------------------------------===//
+
+let addr = 0 in {
+ def NOP : TADDR<0x00, (outs), (ins), "nop ", [], IIAlu>;
+}
+
+let usesCustomInserter = 1 in {
+ //class PseudoSelCC<RegisterClass RC, string asmstr>:
+ // MBlazePseudo<(outs RC:$D), (ins RC:$T, RC:$F, CPURegs:$CMP), asmstr,
+ // [(set RC:$D, (MBlazeSelectCC RC:$T, RC:$F, CPURegs:$CMP))]>;
+ //def Select_CC : PseudoSelCC<CPURegs, "# MBlazeSelect_CC">;
+
+ def Select_CC : MBlazePseudo<(outs CPURegs:$dst),
+ (ins CPURegs:$T, CPURegs:$F, CPURegs:$CMP, i32imm:$CC),
+ "; SELECT_CC PSEUDO!",
+ []>;
+
+ def ShiftL : MBlazePseudo<(outs CPURegs:$dst),
+ (ins CPURegs:$L, CPURegs:$R),
+ "; ShiftL PSEUDO!",
+ []>;
+
+ def ShiftRA : MBlazePseudo<(outs CPURegs:$dst),
+ (ins CPURegs:$L, CPURegs:$R),
+ "; ShiftRA PSEUDO!",
+ []>;
+
+ def ShiftRL : MBlazePseudo<(outs CPURegs:$dst),
+ (ins CPURegs:$L, CPURegs:$R),
+ "; ShiftRL PSEUDO!",
+ []>;
+}
+
+
+let rb = 0 in {
+ def SEXT16 : TA<0x24, 0x061, (outs CPURegs:$dst), (ins CPURegs:$src),
+ "sext16 $dst, $src", [], IIAlu>;
+ def SEXT8 : TA<0x24, 0x060, (outs CPURegs:$dst), (ins CPURegs:$src),
+ "sext8 $dst, $src", [], IIAlu>;
+ def SRL : TA<0x24, 0x041, (outs CPURegs:$dst), (ins CPURegs:$src),
+ "srl $dst, $src", [], IIAlu>;
+ def SRA : TA<0x24, 0x001, (outs CPURegs:$dst), (ins CPURegs:$src),
+ "sra $dst, $src", [], IIAlu>;
+ def SRC : TA<0x24, 0x021, (outs CPURegs:$dst), (ins CPURegs:$src),
+ "src $dst, $src", [], IIAlu>;
+}
+
+def LEA_ADDI : EffectiveAddress<"addi $dst, ${addr:stackloc}">;
+
+//===----------------------------------------------------------------------===//
+// Arbitrary patterns that map to one or more instructions
+//===----------------------------------------------------------------------===//
+
+// Small immediates
+def : Pat<(i32 0), (ADD R0, R0)>;
+def : Pat<(i32 immSExt16:$imm), (ADDI R0, imm:$imm)>;
+def : Pat<(i32 immZExt16:$imm), (ORI R0, imm:$imm)>;
+
+// Arbitrary immediates
+def : Pat<(i32 imm:$imm), (ADDI R0, imm:$imm)>;
+
+// In register sign extension
+def : Pat<(sext_inreg CPURegs:$src, i16), (SEXT16 CPURegs:$src)>;
+def : Pat<(sext_inreg CPURegs:$src, i8), (SEXT8 CPURegs:$src)>;
+
+// Call
+def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)), (BRLID tglobaladdr:$dst)>;
+def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),(BRLID texternalsym:$dst)>;
+def : Pat<(MBlazeJmpLink CPURegs:$dst), (BRLD CPURegs:$dst)>;
+
+// Shift Instructions
+def : Pat<(shl CPURegs:$L, CPURegs:$R), (ShiftL CPURegs:$L, CPURegs:$R)>;
+def : Pat<(sra CPURegs:$L, CPURegs:$R), (ShiftRA CPURegs:$L, CPURegs:$R)>;
+def : Pat<(srl CPURegs:$L, CPURegs:$R), (ShiftRL CPURegs:$L, CPURegs:$R)>;
+
+// SET_CC operations
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETEQ),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMP CPURegs:$L, CPURegs:$R), 1)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETNE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMP CPURegs:$L, CPURegs:$R), 2)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETGT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMP CPURegs:$L, CPURegs:$R), 3)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETLT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMP CPURegs:$L, CPURegs:$R), 4)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETGE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMP CPURegs:$L, CPURegs:$R), 5)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETLE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMP CPURegs:$L, CPURegs:$R), 6)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETUGT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMPU CPURegs:$L, CPURegs:$R), 3)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETULT),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMPU CPURegs:$L, CPURegs:$R), 4)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETUGE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMPU CPURegs:$L, CPURegs:$R), 5)>;
+def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETULE),
+ (Select_CC (ADDI R0, 1), (ADDI R0, 0),
+ (CMPU CPURegs:$L, CPURegs:$R), 6)>;
+
+// SELECT operations
+def : Pat<(select CPURegs:$C, CPURegs:$T, CPURegs:$F),
+ (Select_CC CPURegs:$T, CPURegs:$F, CPURegs:$C, 2)>;
+
+// SELECT_CC
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETEQ),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 1)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETNE),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 2)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETGT),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 3)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETLT),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 4)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETGE),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 5)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETLE),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 6)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETUGT),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 3)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETULT),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 4)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETUGE),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 5)>;
+def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETULE),
+ (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 6)>;
+
+// BRCOND instructions
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETEQ), bb:$T),
+ (BEQID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETNE), bb:$T),
+ (BNEID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETGT), bb:$T),
+ (BGTID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETLT), bb:$T),
+ (BLTID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETGE), bb:$T),
+ (BGEID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETLE), bb:$T),
+ (BLEID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETUGT), bb:$T),
+ (BGTID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETULT), bb:$T),
+ (BLTID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETUGE), bb:$T),
+ (BGEID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETULE), bb:$T),
+ (BLEID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>;
+def : Pat<(brcond CPURegs:$C, bb:$T),
+ (BNEID CPURegs:$C, bb:$T)>;
+
+// Jump tables, global addresses, and constant pools
+def : Pat<(MBWrapper tglobaladdr:$in), (ORI R0, tglobaladdr:$in)>;
+def : Pat<(MBWrapper tjumptable:$in), (ORI R0, tjumptable:$in)>;
+def : Pat<(MBWrapper tconstpool:$in), (ORI R0, tconstpool:$in)>;
+
+// Misc instructions
+def : Pat<(and CPURegs:$lh, (not CPURegs:$rh)),(ANDN CPURegs:$lh, CPURegs:$rh)>;
+
+// Arithmetic with immediates
+def : Pat<(add CPURegs:$in, imm:$imm),(ADDI CPURegs:$in, imm:$imm)>;
+def : Pat<(or CPURegs:$in, imm:$imm),(ORI CPURegs:$in, imm:$imm)>;
+def : Pat<(xor CPURegs:$in, imm:$imm),(XORI CPURegs:$in, imm:$imm)>;
+
+// extended load and stores
+def : Pat<(extloadi1 iaddr:$src), (LBUI iaddr:$src)>;
+def : Pat<(extloadi8 iaddr:$src), (LBUI iaddr:$src)>;
+def : Pat<(extloadi16 iaddr:$src), (LHUI iaddr:$src)>;
+def : Pat<(extloadi1 xaddr:$src), (LBU xaddr:$src)>;
+def : Pat<(extloadi8 xaddr:$src), (LBU xaddr:$src)>;
+def : Pat<(extloadi16 xaddr:$src), (LHU xaddr:$src)>;
+
+def : Pat<(sextloadi1 iaddr:$src), (SEXT8 (LBUI iaddr:$src))>;
+def : Pat<(sextloadi8 iaddr:$src), (SEXT8 (LBUI iaddr:$src))>;
+def : Pat<(sextloadi16 iaddr:$src), (SEXT16 (LHUI iaddr:$src))>;
+def : Pat<(sextloadi1 xaddr:$src), (SEXT8 (LBU xaddr:$src))>;
+def : Pat<(sextloadi8 xaddr:$src), (SEXT8 (LBU xaddr:$src))>;
+def : Pat<(sextloadi16 xaddr:$src), (SEXT16 (LHU xaddr:$src))>;
+
+// peepholes
+def : Pat<(store (i32 0), iaddr:$dst), (SWI R0, iaddr:$dst)>;
+
+//===----------------------------------------------------------------------===//
+// Floating Point Support
+//===----------------------------------------------------------------------===//
+include "MBlazeInstrFSL.td"
+include "MBlazeInstrFPU.td"
diff --git a/lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp b/lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp
new file mode 100644
index 0000000..c8faffc
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp
@@ -0,0 +1,109 @@
+//===- MBlazeIntrinsicInfo.cpp - Intrinsic Information -00-------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MBlaze implementation of TargetIntrinsicInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlazeIntrinsicInfo.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+#include "llvm/Type.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+
+using namespace llvm;
+
+namespace mblazeIntrinsic {
+
+ enum ID {
+ last_non_mblaze_intrinsic = Intrinsic::num_intrinsics-1,
+#define GET_INTRINSIC_ENUM_VALUES
+#include "MBlazeGenIntrinsics.inc"
+#undef GET_INTRINSIC_ENUM_VALUES
+ , num_mblaze_intrinsics
+ };
+
+#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
+#include "MBlazeGenIntrinsics.inc"
+#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
+}
+
+std::string MBlazeIntrinsicInfo::getName(unsigned IntrID, const Type **Tys,
+ unsigned numTys) const {
+ static const char *const names[] = {
+#define GET_INTRINSIC_NAME_TABLE
+#include "MBlazeGenIntrinsics.inc"
+#undef GET_INTRINSIC_NAME_TABLE
+ };
+
+ assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded");
+ if (IntrID < Intrinsic::num_intrinsics)
+ return 0;
+ assert(IntrID < mblazeIntrinsic::num_mblaze_intrinsics &&
+ "Invalid intrinsic ID");
+
+ std::string Result(names[IntrID - Intrinsic::num_intrinsics]);
+ return Result;
+}
+
+unsigned MBlazeIntrinsicInfo::
+lookupName(const char *Name, unsigned Len) const {
+#define GET_FUNCTION_RECOGNIZER
+#include "MBlazeGenIntrinsics.inc"
+#undef GET_FUNCTION_RECOGNIZER
+ return 0;
+}
+
+unsigned MBlazeIntrinsicInfo::
+lookupGCCName(const char *Name) const {
+ return mblazeIntrinsic::getIntrinsicForGCCBuiltin("mblaze",Name);
+}
+
+bool MBlazeIntrinsicInfo::isOverloaded(unsigned IntrID) const {
+ // Overload Table
+ const bool OTable[] = {
+#define GET_INTRINSIC_OVERLOAD_TABLE
+#include "MBlazeGenIntrinsics.inc"
+#undef GET_INTRINSIC_OVERLOAD_TABLE
+ };
+ if (IntrID == 0)
+ return false;
+ else
+ return OTable[IntrID - Intrinsic::num_intrinsics];
+}
+
+/// This defines the "getAttributes(ID id)" method.
+#define GET_INTRINSIC_ATTRIBUTES
+#include "MBlazeGenIntrinsics.inc"
+#undef GET_INTRINSIC_ATTRIBUTES
+
+static const FunctionType *getType(LLVMContext &Context, unsigned id) {
+ const Type *ResultTy = NULL;
+ std::vector<const Type*> ArgTys;
+ bool IsVarArg = false;
+
+#define GET_INTRINSIC_GENERATOR
+#include "MBlazeGenIntrinsics.inc"
+#undef GET_INTRINSIC_GENERATOR
+
+ return FunctionType::get(ResultTy, ArgTys, IsVarArg);
+}
+
+Function *MBlazeIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
+ const Type **Tys,
+ unsigned numTy) const {
+ assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded");
+ AttrListPtr AList = getAttributes((mblazeIntrinsic::ID) IntrID);
+ return cast<Function>(M->getOrInsertFunction(getName(IntrID),
+ getType(M->getContext(), IntrID),
+ AList));
+}
diff --git a/lib/Target/MBlaze/MBlazeIntrinsicInfo.h b/lib/Target/MBlaze/MBlazeIntrinsicInfo.h
new file mode 100644
index 0000000..9804c77
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeIntrinsicInfo.h
@@ -0,0 +1,33 @@
+//===- MBlazeIntrinsicInfo.h - MBlaze Intrinsic Information -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MBlaze implementation of TargetIntrinsicInfo.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MBLAZEINTRINSICS_H
+#define MBLAZEINTRINSICS_H
+
+#include "llvm/Target/TargetIntrinsicInfo.h"
+
+namespace llvm {
+
+ class MBlazeIntrinsicInfo : public TargetIntrinsicInfo {
+ public:
+ std::string getName(unsigned IntrID, const Type **Tys = 0,
+ unsigned numTys = 0) const;
+ unsigned lookupName(const char *Name, unsigned Len) const;
+ unsigned lookupGCCName(const char *Name) const;
+ bool isOverloaded(unsigned IID) const;
+ Function *getDeclaration(Module *M, unsigned ID, const Type **Tys = 0,
+ unsigned numTys = 0) const;
+ };
+
+}
+
+#endif
diff --git a/lib/Target/MBlaze/MBlazeIntrinsics.td b/lib/Target/MBlaze/MBlazeIntrinsics.td
new file mode 100644
index 0000000..76eb563
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeIntrinsics.td
@@ -0,0 +1,137 @@
+//===- IntrinsicsMBlaze.td - Defines MBlaze intrinsics -----*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the MicroBlaze-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Definitions for all MBlaze intrinsics.
+//
+
+// MBlaze intrinsic classes.
+let TargetPrefix = "mblaze", isTarget = 1 in {
+ class MBFSL_Get_Intrinsic : Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty],
+ [IntrWriteMem]>;
+
+ class MBFSL_Put_Intrinsic : Intrinsic<[llvm_void_ty],
+ [llvm_i32_ty, llvm_i32_ty],
+ [IntrWriteMem]>;
+
+ class MBFSL_PutT_Intrinsic : Intrinsic<[llvm_void_ty],
+ [llvm_i32_ty],
+ [IntrWriteMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// MicroBlaze FSL Get Intrinsic Definitions.
+//
+
+def int_mblaze_fsl_get : GCCBuiltin<"__builtin_mblaze_fsl_get">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_aget : GCCBuiltin<"__builtin_mblaze_fsl_aget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_cget : GCCBuiltin<"__builtin_mblaze_fsl_cget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_caget : GCCBuiltin<"__builtin_mblaze_fsl_caget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_eget : GCCBuiltin<"__builtin_mblaze_fsl_eget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_eaget : GCCBuiltin<"__builtin_mblaze_fsl_eaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_ecget : GCCBuiltin<"__builtin_mblaze_fsl_ecget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_ecaget : GCCBuiltin<"__builtin_mblaze_fsl_ecaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_nget : GCCBuiltin<"__builtin_mblaze_fsl_nget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_naget : GCCBuiltin<"__builtin_mblaze_fsl_naget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_ncget : GCCBuiltin<"__builtin_mblaze_fsl_ncget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_ncaget : GCCBuiltin<"__builtin_mblaze_fsl_ncaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_neget : GCCBuiltin<"__builtin_mblaze_fsl_neget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_neaget : GCCBuiltin<"__builtin_mblaze_fsl_neaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_necget : GCCBuiltin<"__builtin_mblaze_fsl_necget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_necaget : GCCBuiltin<"__builtin_mblaze_fsl_necaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tget : GCCBuiltin<"__builtin_mblaze_fsl_tget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_taget : GCCBuiltin<"__builtin_mblaze_fsl_taget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tcget : GCCBuiltin<"__builtin_mblaze_fsl_tcget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tcaget : GCCBuiltin<"__builtin_mblaze_fsl_tcaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_teget : GCCBuiltin<"__builtin_mblaze_fsl_teget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_teaget : GCCBuiltin<"__builtin_mblaze_fsl_teaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tecget : GCCBuiltin<"__builtin_mblaze_fsl_tecget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tecaget : GCCBuiltin<"__builtin_mblaze_fsl_tecaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tnget : GCCBuiltin<"__builtin_mblaze_fsl_tnget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tnaget : GCCBuiltin<"__builtin_mblaze_fsl_tnaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tncget : GCCBuiltin<"__builtin_mblaze_fsl_tncget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tncaget : GCCBuiltin<"__builtin_mblaze_fsl_tncaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tneget : GCCBuiltin<"__builtin_mblaze_fsl_tneget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tneaget : GCCBuiltin<"__builtin_mblaze_fsl_tneaget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tnecget : GCCBuiltin<"__builtin_mblaze_fsl_tnecget">,
+ MBFSL_Get_Intrinsic;
+def int_mblaze_fsl_tnecaget : GCCBuiltin<"__builtin_mblaze_fsl_tnecaget">,
+ MBFSL_Get_Intrinsic;
+
+//===----------------------------------------------------------------------===//
+// MicroBlaze FSL Put Intrinsic Definitions.
+//
+
+def int_mblaze_fsl_put : GCCBuiltin<"__builtin_mblaze_fsl_put">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_aput : GCCBuiltin<"__builtin_mblaze_fsl_aput">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_cput : GCCBuiltin<"__builtin_mblaze_fsl_cput">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_caput : GCCBuiltin<"__builtin_mblaze_fsl_caput">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_nput : GCCBuiltin<"__builtin_mblaze_fsl_nput">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_naput : GCCBuiltin<"__builtin_mblaze_fsl_naput">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_ncput : GCCBuiltin<"__builtin_mblaze_fsl_ncput">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_ncaput : GCCBuiltin<"__builtin_mblaze_fsl_ncaput">,
+ MBFSL_Put_Intrinsic;
+def int_mblaze_fsl_tput : GCCBuiltin<"__builtin_mblaze_fsl_tput">,
+ MBFSL_PutT_Intrinsic;
+def int_mblaze_fsl_taput : GCCBuiltin<"__builtin_mblaze_fsl_taput">,
+ MBFSL_PutT_Intrinsic;
+def int_mblaze_fsl_tcput : GCCBuiltin<"__builtin_mblaze_fsl_tcput">,
+ MBFSL_PutT_Intrinsic;
+def int_mblaze_fsl_tcaput : GCCBuiltin<"__builtin_mblaze_fsl_tcaput">,
+ MBFSL_PutT_Intrinsic;
+def int_mblaze_fsl_tnput : GCCBuiltin<"__builtin_mblaze_fsl_tnput">,
+ MBFSL_PutT_Intrinsic;
+def int_mblaze_fsl_tnaput : GCCBuiltin<"__builtin_mblaze_fsl_tnaput">,
+ MBFSL_PutT_Intrinsic;
+def int_mblaze_fsl_tncput : GCCBuiltin<"__builtin_mblaze_fsl_tncput">,
+ MBFSL_PutT_Intrinsic;
+def int_mblaze_fsl_tncaput : GCCBuiltin<"__builtin_mblaze_fsl_tncaput">,
+ MBFSL_PutT_Intrinsic;
diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
new file mode 100644
index 0000000..7ae465d
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
@@ -0,0 +1,27 @@
+//===-- MBlazeMCAsmInfo.cpp - MBlaze asm properties -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations of the MBlazeMCAsmInfo properties.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlazeMCAsmInfo.h"
+using namespace llvm;
+
+MBlazeMCAsmInfo::MBlazeMCAsmInfo(const Target &T, const StringRef &TT) {
+ AlignmentIsInBytes = false;
+ Data16bitsDirective = "\t.half\t";
+ Data32bitsDirective = "\t.word\t";
+ Data64bitsDirective = 0;
+ PrivateGlobalPrefix = "$";
+ CommentString = "#";
+ ZeroDirective = "\t.space\t";
+ GPRel32Directive = "\t.gpword\t";
+ HasSetDirective = false;
+}
diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.h b/lib/Target/MBlaze/MBlazeMCAsmInfo.h
new file mode 100644
index 0000000..bccb418
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.h
@@ -0,0 +1,30 @@
+//=====-- MBlazeMCAsmInfo.h - MBlaze asm properties -----------*- C++ -*--====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MBlazeMCAsmInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBLAZETARGETASMINFO_H
+#define MBLAZETARGETASMINFO_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+ class Target;
+ class StringRef;
+
+ class MBlazeMCAsmInfo : public MCAsmInfo {
+ public:
+ explicit MBlazeMCAsmInfo(const Target &T, const StringRef &TT);
+ };
+
+} // namespace llvm
+
+#endif
diff --git a/lib/Target/MBlaze/MBlazeMachineFunction.h b/lib/Target/MBlaze/MBlazeMachineFunction.h
new file mode 100644
index 0000000..08d4dca
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeMachineFunction.h
@@ -0,0 +1,136 @@
+//===-- MBlazeMachineFunctionInfo.h - Private data ----------------*- 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 MBlaze specific subclass of MachineFunctionInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBLAZE_MACHINE_FUNCTION_INFO_H
+#define MBLAZE_MACHINE_FUNCTION_INFO_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/VectorExtras.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+
+namespace llvm {
+
+/// MBlazeFunctionInfo - This class is derived from MachineFunction private
+/// MBlaze target-specific information for each MachineFunction.
+class MBlazeFunctionInfo : public MachineFunctionInfo {
+
+private:
+ /// Holds for each function where on the stack the Frame Pointer must be
+ /// saved. This is used on Prologue and Epilogue to emit FP save/restore
+ int FPStackOffset;
+
+ /// Holds for each function where on the stack the Return Address must be
+ /// saved. This is used on Prologue and Epilogue to emit RA save/restore
+ int RAStackOffset;
+
+ /// At each function entry a special bitmask directive must be emitted
+ /// to help in debugging CPU callee saved registers. It needs a negative
+ /// offset from the final stack size and its higher register location on
+ /// the stack.
+ int CPUTopSavedRegOff;
+
+ /// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
+ struct MBlazeFIHolder {
+
+ int FI;
+ int SPOffset;
+
+ MBlazeFIHolder(int FrameIndex, int StackPointerOffset)
+ : FI(FrameIndex), SPOffset(StackPointerOffset) {}
+ };
+
+ /// When PIC is used the GP must be saved on the stack on the function
+ /// prologue and must be reloaded from this stack location after every
+ /// call. A reference to its stack location and frame index must be kept
+ /// to be used on emitPrologue and processFunctionBeforeFrameFinalized.
+ MBlazeFIHolder GPHolder;
+
+ /// On LowerFormalArguments the stack size is unknown, so the Stack
+ /// Pointer Offset calculation of "not in register arguments" must be
+ /// postponed to emitPrologue.
+ SmallVector<MBlazeFIHolder, 16> FnLoadArgs;
+ bool HasLoadArgs;
+
+ // When VarArgs, we must write registers back to caller stack, preserving
+ // on register arguments. Since the stack size is unknown on
+ // LowerFormalArguments, the Stack Pointer Offset calculation must be
+ // postponed to emitPrologue.
+ SmallVector<MBlazeFIHolder, 4> FnStoreVarArgs;
+ bool HasStoreVarArgs;
+
+ /// SRetReturnReg - Some subtargets require that sret lowering includes
+ /// returning the value of the returned struct in a register. This field
+ /// holds the virtual register into which the sret argument is passed.
+ unsigned SRetReturnReg;
+
+ /// GlobalBaseReg - keeps track of the virtual register initialized for
+ /// use as the global base register. This is used for PIC in some PIC
+ /// relocation models.
+ unsigned GlobalBaseReg;
+
+public:
+ MBlazeFunctionInfo(MachineFunction& MF)
+ : FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
+ GPHolder(-1,-1), HasLoadArgs(false), HasStoreVarArgs(false),
+ SRetReturnReg(0), GlobalBaseReg(0)
+ {}
+
+ int getFPStackOffset() const { return FPStackOffset; }
+ void setFPStackOffset(int Off) { FPStackOffset = Off; }
+
+ int getRAStackOffset() const { return RAStackOffset; }
+ void setRAStackOffset(int Off) { RAStackOffset = Off; }
+
+ int getCPUTopSavedRegOff() const { return CPUTopSavedRegOff; }
+ void setCPUTopSavedRegOff(int Off) { CPUTopSavedRegOff = Off; }
+
+ int getGPStackOffset() const { return GPHolder.SPOffset; }
+ int getGPFI() const { return GPHolder.FI; }
+ void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
+ void setGPFI(int FI) { GPHolder.FI = FI; }
+ bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; }
+
+ bool hasLoadArgs() const { return HasLoadArgs; }
+ bool hasStoreVarArgs() const { return HasStoreVarArgs; }
+
+ void recordLoadArgsFI(int FI, int SPOffset) {
+ if (!HasLoadArgs) HasLoadArgs=true;
+ FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));
+ }
+ void recordStoreVarArgsFI(int FI, int SPOffset) {
+ if (!HasStoreVarArgs) HasStoreVarArgs=true;
+ FnStoreVarArgs.push_back(MBlazeFIHolder(FI, SPOffset));
+ }
+
+ void adjustLoadArgsFI(MachineFrameInfo *MFI) const {
+ if (!hasLoadArgs()) return;
+ for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i)
+ MFI->setObjectOffset( FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset );
+ }
+ void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const {
+ if (!hasStoreVarArgs()) return;
+ for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i)
+ MFI->setObjectOffset( FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset );
+ }
+
+ unsigned getSRetReturnReg() const { return SRetReturnReg; }
+ void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
+
+ unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
+ void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
+};
+
+} // end of namespace llvm
+
+#endif // MBLAZE_MACHINE_FUNCTION_INFO_H
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
new file mode 100644
index 0000000..8dfca81
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
@@ -0,0 +1,421 @@
+//===- MBlazeRegisterInfo.cpp - MBlaze Register Information -== -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MBlaze implementation of the TargetRegisterInfo
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "mblaze-reg-info"
+
+#include "MBlaze.h"
+#include "MBlazeSubtarget.h"
+#include "MBlazeRegisterInfo.h"
+#include "MBlazeMachineFunction.h"
+#include "llvm/Constants.h"
+#include "llvm/Type.h"
+#include "llvm/Function.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace llvm;
+
+MBlazeRegisterInfo::
+MBlazeRegisterInfo(const MBlazeSubtarget &ST, const TargetInstrInfo &tii)
+ : MBlazeGenRegisterInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
+ Subtarget(ST), TII(tii) {}
+
+/// getRegisterNumbering - Given the enum value for some register, e.g.
+/// MBlaze::R0, return the number that it corresponds to (e.g. 0).
+unsigned MBlazeRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
+ switch (RegEnum) {
+ case MBlaze::R0 : case MBlaze::F0 : return 0;
+ case MBlaze::R1 : case MBlaze::F1 : return 1;
+ case MBlaze::R2 : case MBlaze::F2 : return 2;
+ case MBlaze::R3 : case MBlaze::F3 : return 3;
+ case MBlaze::R4 : case MBlaze::F4 : return 4;
+ case MBlaze::R5 : case MBlaze::F5 : return 5;
+ case MBlaze::R6 : case MBlaze::F6 : return 6;
+ case MBlaze::R7 : case MBlaze::F7 : return 7;
+ case MBlaze::R8 : case MBlaze::F8 : return 8;
+ case MBlaze::R9 : case MBlaze::F9 : return 9;
+ case MBlaze::R10 : case MBlaze::F10 : return 10;
+ case MBlaze::R11 : case MBlaze::F11 : return 11;
+ case MBlaze::R12 : case MBlaze::F12 : return 12;
+ case MBlaze::R13 : case MBlaze::F13 : return 13;
+ case MBlaze::R14 : case MBlaze::F14 : return 14;
+ case MBlaze::R15 : case MBlaze::F15 : return 15;
+ case MBlaze::R16 : case MBlaze::F16 : return 16;
+ case MBlaze::R17 : case MBlaze::F17 : return 17;
+ case MBlaze::R18 : case MBlaze::F18 : return 18;
+ case MBlaze::R19 : case MBlaze::F19 : return 19;
+ case MBlaze::R20 : case MBlaze::F20 : return 20;
+ case MBlaze::R21 : case MBlaze::F21 : return 21;
+ case MBlaze::R22 : case MBlaze::F22 : return 22;
+ case MBlaze::R23 : case MBlaze::F23 : return 23;
+ case MBlaze::R24 : case MBlaze::F24 : return 24;
+ case MBlaze::R25 : case MBlaze::F25 : return 25;
+ case MBlaze::R26 : case MBlaze::F26 : return 26;
+ case MBlaze::R27 : case MBlaze::F27 : return 27;
+ case MBlaze::R28 : case MBlaze::F28 : return 28;
+ case MBlaze::R29 : case MBlaze::F29 : return 29;
+ case MBlaze::R30 : case MBlaze::F30 : return 30;
+ case MBlaze::R31 : case MBlaze::F31 : return 31;
+ default: llvm_unreachable("Unknown register number!");
+ }
+ return 0; // Not reached
+}
+
+/// getRegisterFromNumbering - Given the enum value for some register, e.g.
+/// MBlaze::R0, return the number that it corresponds to (e.g. 0).
+unsigned MBlazeRegisterInfo::getRegisterFromNumbering(unsigned Reg) {
+ switch (Reg) {
+ case 0 : return MBlaze::R0;
+ case 1 : return MBlaze::R1;
+ case 2 : return MBlaze::R2;
+ case 3 : return MBlaze::R3;
+ case 4 : return MBlaze::R4;
+ case 5 : return MBlaze::R5;
+ case 6 : return MBlaze::R6;
+ case 7 : return MBlaze::R7;
+ case 8 : return MBlaze::R8;
+ case 9 : return MBlaze::R9;
+ case 10 : return MBlaze::R10;
+ case 11 : return MBlaze::R11;
+ case 12 : return MBlaze::R12;
+ case 13 : return MBlaze::R13;
+ case 14 : return MBlaze::R14;
+ case 15 : return MBlaze::R15;
+ case 16 : return MBlaze::R16;
+ case 17 : return MBlaze::R17;
+ case 18 : return MBlaze::R18;
+ case 19 : return MBlaze::R19;
+ case 20 : return MBlaze::R20;
+ case 21 : return MBlaze::R21;
+ case 22 : return MBlaze::R22;
+ case 23 : return MBlaze::R23;
+ case 24 : return MBlaze::R24;
+ case 25 : return MBlaze::R25;
+ case 26 : return MBlaze::R26;
+ case 27 : return MBlaze::R27;
+ case 28 : return MBlaze::R28;
+ case 29 : return MBlaze::R29;
+ case 30 : return MBlaze::R30;
+ case 31 : return MBlaze::R31;
+ default: llvm_unreachable("Unknown register number!");
+ }
+ return 0; // Not reached
+}
+
+unsigned MBlazeRegisterInfo::getPICCallReg() {
+ return MBlaze::R20;
+}
+
+//===----------------------------------------------------------------------===//
+// Callee Saved Registers methods
+//===----------------------------------------------------------------------===//
+
+/// MBlaze Callee Saved Registers
+const unsigned* MBlazeRegisterInfo::
+getCalleeSavedRegs(const MachineFunction *MF) const {
+ // MBlaze callee-save register range is R20 - R31
+ static const unsigned CalleeSavedRegs[] = {
+ MBlaze::R20, MBlaze::R21, MBlaze::R22, MBlaze::R23,
+ MBlaze::R24, MBlaze::R25, MBlaze::R26, MBlaze::R27,
+ MBlaze::R28, MBlaze::R29, MBlaze::R30, MBlaze::R31,
+ 0
+ };
+
+ return CalleeSavedRegs;
+}
+
+/// MBlaze Callee Saved Register Classes
+const TargetRegisterClass* const* MBlazeRegisterInfo::
+getCalleeSavedRegClasses(const MachineFunction *MF) const {
+ static const TargetRegisterClass * const CalleeSavedRC[] = {
+ &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
+ &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
+ &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
+ &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
+ &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
+ &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
+ 0
+ };
+
+ return CalleeSavedRC;
+}
+
+BitVector MBlazeRegisterInfo::
+getReservedRegs(const MachineFunction &MF) const {
+ BitVector Reserved(getNumRegs());
+ Reserved.set(MBlaze::R0);
+ Reserved.set(MBlaze::R1);
+ Reserved.set(MBlaze::R2);
+ Reserved.set(MBlaze::R13);
+ Reserved.set(MBlaze::R14);
+ Reserved.set(MBlaze::R15);
+ Reserved.set(MBlaze::R16);
+ Reserved.set(MBlaze::R17);
+ Reserved.set(MBlaze::R18);
+ Reserved.set(MBlaze::R19);
+ return Reserved;
+}
+
+//===----------------------------------------------------------------------===//
+//
+// Stack Frame Processing methods
+// +----------------------------+
+//
+// The stack is allocated decrementing the stack pointer on
+// the first instruction of a function prologue. Once decremented,
+// all stack references are are done through a positive offset
+// from the stack/frame pointer, so the stack is considered
+// to grow up.
+//
+//===----------------------------------------------------------------------===//
+
+void MBlazeRegisterInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
+
+ // See the description at MicroBlazeMachineFunction.h
+ int TopCPUSavedRegOff = -1;
+
+ // Adjust CPU Callee Saved Registers Area. Registers RA and FP must
+ // be saved in this CPU Area there is the need. This whole Area must
+ // be aligned to the default Stack Alignment requirements.
+ unsigned StackOffset = MFI->getStackSize();
+ unsigned RegSize = 4;
+
+ // Replace the dummy '0' SPOffset by the negative offsets, as explained on
+ // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
+ // the approach done by calculateFrameObjectOffsets to the stack frame.
+ MBlazeFI->adjustLoadArgsFI(MFI);
+ MBlazeFI->adjustStoreVarArgsFI(MFI);
+
+ if (hasFP(MF)) {
+ MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
+ StackOffset);
+ MBlazeFI->setFPStackOffset(StackOffset);
+ TopCPUSavedRegOff = StackOffset;
+ StackOffset += RegSize;
+ }
+
+ if (MFI->hasCalls()) {
+ MBlazeFI->setRAStackOffset(0);
+ MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
+ StackOffset);
+ TopCPUSavedRegOff = StackOffset;
+ StackOffset += RegSize;
+ }
+
+ // Update frame info
+ MFI->setStackSize(StackOffset);
+
+ // Recalculate the final tops offset. The final values must be '0'
+ // if there isn't a callee saved register for CPU or FPU, otherwise
+ // a negative offset is needed.
+ if (TopCPUSavedRegOff >= 0)
+ MBlazeFI->setCPUTopSavedRegOff(TopCPUSavedRegOff-StackOffset);
+}
+
+// hasFP - Return true if the specified function should have a dedicated frame
+// pointer register. This is true if the function has variable sized allocas or
+// if frame pointer elimination is disabled.
+bool MBlazeRegisterInfo::hasFP(const MachineFunction &MF) const {
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ return NoFramePointerElim || MFI->hasVarSizedObjects();
+}
+
+// This function eliminate ADJCALLSTACKDOWN,
+// ADJCALLSTACKUP pseudo instructions
+void MBlazeRegisterInfo::
+eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I) const {
+ // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
+ MBB.erase(I);
+}
+
+// FrameIndex represent objects inside a abstract stack.
+// We must replace FrameIndex with an stack/frame pointer
+// direct reference.
+unsigned MBlazeRegisterInfo::
+eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
+ int *Value, RegScavenger *RS) const {
+ MachineInstr &MI = *II;
+ MachineFunction &MF = *MI.getParent()->getParent();
+
+ unsigned i = 0;
+ while (!MI.getOperand(i).isFI()) {
+ ++i;
+ assert(i < MI.getNumOperands() &&
+ "Instr doesn't have FrameIndex operand!");
+ }
+
+ unsigned oi = i == 2 ? 1 : 2;
+
+ DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
+ errs() << "<--------->\n" << MI);
+
+ int FrameIndex = MI.getOperand(i).getIndex();
+ int stackSize = MF.getFrameInfo()->getStackSize();
+ int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
+
+ DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
+ << "spOffset : " << spOffset << "\n"
+ << "stackSize : " << stackSize << "\n");
+
+ // as explained on LowerFormalArguments, detect negative offsets
+ // and adjust SPOffsets considering the final stack size.
+ int Offset = (spOffset < 0) ? (stackSize - spOffset) : (spOffset + 4);
+ Offset += MI.getOperand(oi).getImm();
+
+ DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
+
+ MI.getOperand(oi).ChangeToImmediate(Offset);
+ MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
+ return 0;
+}
+
+void MBlazeRegisterInfo::
+emitPrologue(MachineFunction &MF) const {
+ MachineBasicBlock &MBB = MF.front();
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
+ MachineBasicBlock::iterator MBBI = MBB.begin();
+ DebugLoc dl = (MBBI != MBB.end() ?
+ MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
+
+ // Get the right frame order for MBlaze.
+ adjustMBlazeStackFrame(MF);
+
+ // Get the number of bytes to allocate from the FrameInfo.
+ unsigned StackSize = MFI->getStackSize();
+
+ // No need to allocate space on the stack.
+ if (StackSize == 0 && !MFI->hasCalls()) return;
+ if (StackSize < 28 && MFI->hasCalls()) StackSize = 28;
+
+ int FPOffset = MBlazeFI->getFPStackOffset();
+ int RAOffset = MBlazeFI->getRAStackOffset();
+
+ // Adjust stack : addi R1, R1, -imm
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
+ .addReg(MBlaze::R1).addImm(-StackSize);
+
+ // Save the return address only if the function isnt a leaf one.
+ // swi R15, R1, stack_loc
+ if (MFI->hasCalls()) {
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::SWI))
+ .addReg(MBlaze::R15).addImm(RAOffset).addReg(MBlaze::R1);
+ }
+
+ // if framepointer enabled, save it and set it
+ // to point to the stack pointer
+ if (hasFP(MF)) {
+ // swi R19, R1, stack_loc
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::SWI))
+ .addReg(MBlaze::R19).addImm(FPOffset).addReg(MBlaze::R1);
+
+ // add R19, R1, R0
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R19)
+ .addReg(MBlaze::R1).addReg(MBlaze::R0);
+ }
+}
+
+void MBlazeRegisterInfo::
+emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
+ MachineBasicBlock::iterator MBBI = prior(MBB.end());
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
+ DebugLoc dl = MBBI->getDebugLoc();
+
+ // Get the FI's where RA and FP are saved.
+ int FPOffset = MBlazeFI->getFPStackOffset();
+ int RAOffset = MBlazeFI->getRAStackOffset();
+
+ // if framepointer enabled, restore it and restore the
+ // stack pointer
+ if (hasFP(MF)) {
+ // add R1, R19, R0
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
+ .addReg(MBlaze::R19).addReg(MBlaze::R0);
+
+ // lwi R19, R1, stack_loc
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
+ .addImm(FPOffset).addReg(MBlaze::R1);
+ }
+
+ // Restore the return address only if the function isnt a leaf one.
+ // lwi R15, R1, stack_loc
+ if (MFI->hasCalls()) {
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
+ .addImm(RAOffset).addReg(MBlaze::R1);
+ }
+
+ // Get the number of bytes from FrameInfo
+ int StackSize = (int) MFI->getStackSize();
+ if (StackSize < 28 && MFI->hasCalls()) StackSize = 28;
+
+ // adjust stack.
+ // addi R1, R1, imm
+ if (StackSize) {
+ BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
+ .addReg(MBlaze::R1).addImm(StackSize);
+ }
+}
+
+
+void MBlazeRegisterInfo::
+processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
+ // Set the stack offset where GP must be saved/loaded from.
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
+ if (MBlazeFI->needGPSaveRestore())
+ MFI->setObjectOffset(MBlazeFI->getGPFI(), MBlazeFI->getGPStackOffset());
+}
+
+unsigned MBlazeRegisterInfo::getRARegister() const {
+ return MBlaze::R15;
+}
+
+unsigned MBlazeRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
+ return hasFP(MF) ? MBlaze::R19 : MBlaze::R1;
+}
+
+unsigned MBlazeRegisterInfo::getEHExceptionRegister() const {
+ llvm_unreachable("What is the exception register");
+ return 0;
+}
+
+unsigned MBlazeRegisterInfo::getEHHandlerRegister() const {
+ llvm_unreachable("What is the exception handler register");
+ return 0;
+}
+
+int MBlazeRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
+ llvm_unreachable("What is the dwarf register number");
+ return -1;
+}
+
+#include "MBlazeGenRegisterInfo.inc"
+
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.h b/lib/Target/MBlaze/MBlazeRegisterInfo.h
new file mode 100644
index 0000000..cde7d39
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.h
@@ -0,0 +1,96 @@
+//===- MBlazeRegisterInfo.h - MBlaze Register Information Impl --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MBlaze implementation of the TargetRegisterInfo
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBLAZEREGISTERINFO_H
+#define MBLAZEREGISTERINFO_H
+
+#include "MBlaze.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "MBlazeGenRegisterInfo.h.inc"
+
+namespace llvm {
+class MBlazeSubtarget;
+class TargetInstrInfo;
+class Type;
+
+namespace MBlaze {
+ /// SubregIndex - The index of various sized subregister classes. Note that
+ /// these indices must be kept in sync with the class indices in the
+ /// MBlazeRegisterInfo.td file.
+ enum SubregIndex {
+ SUBREG_FPEVEN = 1, SUBREG_FPODD = 2
+ };
+}
+
+struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
+ const MBlazeSubtarget &Subtarget;
+ const TargetInstrInfo &TII;
+
+ MBlazeRegisterInfo(const MBlazeSubtarget &Subtarget,
+ const TargetInstrInfo &tii);
+
+ /// getRegisterNumbering - Given the enum value for some register, e.g.
+ /// MBlaze::RA, return the number that it corresponds to (e.g. 31).
+ static unsigned getRegisterNumbering(unsigned RegEnum);
+ static unsigned getRegisterFromNumbering(unsigned RegEnum);
+
+ /// Get PIC indirect call register
+ static unsigned getPICCallReg();
+
+ /// Adjust the MBlaze stack frame.
+ void adjustMBlazeStackFrame(MachineFunction &MF) const;
+
+ /// Code Generation virtual methods...
+ const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const;
+
+ const TargetRegisterClass* const*
+ getCalleeSavedRegClasses(const MachineFunction* MF = 0) const;
+
+ BitVector getReservedRegs(const MachineFunction &MF) const;
+
+ bool hasFP(const MachineFunction &MF) const;
+
+ void eliminateCallFramePseudoInstr(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I) const;
+
+ /// Stack Frame Processing Methods
+ unsigned eliminateFrameIndex(MachineBasicBlock::iterator II,
+ int SPAdj, int *Value = NULL,
+ RegScavenger *RS = NULL) const;
+
+ void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
+
+ void emitPrologue(MachineFunction &MF) const;
+ void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
+
+ /// Debug information queries.
+ unsigned getRARegister() const;
+ unsigned getFrameRegister(const MachineFunction &MF) const;
+
+ /// Exception handling queries.
+ unsigned getEHExceptionRegister() const;
+ unsigned getEHHandlerRegister() const;
+
+ /// targetHandlesStackFrameRounding - Returns true if the target is
+ /// responsible for rounding up the stack frame (probably at emitPrologue
+ /// time).
+ bool targetHandlesStackFrameRounding() const { return true; }
+
+ int getDwarfRegNum(unsigned RegNum, bool isEH) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.td b/lib/Target/MBlaze/MBlazeRegisterInfo.td
new file mode 100644
index 0000000..96a5c98
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.td
@@ -0,0 +1,186 @@
+//===- MBlazeRegisterInfo.td - MBlaze Register defs -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Declarations that describe the MicroBlaze register file
+//===----------------------------------------------------------------------===//
+
+// We have banks of 32 registers each.
+class MBlazeReg<string n> : Register<n> {
+ field bits<5> Num;
+ let Namespace = "MBlaze";
+}
+
+class MBlazeRegWithSubRegs<string n, list<Register> subregs>
+ : RegisterWithSubRegs<n, subregs> {
+ field bits<5> Num;
+ let Namespace = "MBlaze";
+}
+
+// MBlaze CPU Registers
+class MBlazeGPRReg<bits<5> num, string n> : MBlazeReg<n> {
+ let Num = num;
+}
+
+// MBlaze 32-bit (aliased) FPU Registers
+class FPR<bits<5> num, string n, list<Register> subregs>
+ : MBlazeRegWithSubRegs<n, subregs> {
+ let Num = num;
+}
+
+//===----------------------------------------------------------------------===//
+// Registers
+//===----------------------------------------------------------------------===//
+
+let Namespace = "MBlaze" in {
+
+ // General Purpose Registers
+ def R0 : MBlazeGPRReg< 0, "r0">, DwarfRegNum<[0]>;
+ def R1 : MBlazeGPRReg< 1, "r1">, DwarfRegNum<[1]>;
+ def R2 : MBlazeGPRReg< 2, "r2">, DwarfRegNum<[2]>;
+ def R3 : MBlazeGPRReg< 3, "r3">, DwarfRegNum<[3]>;
+ def R4 : MBlazeGPRReg< 4, "r4">, DwarfRegNum<[5]>;
+ def R5 : MBlazeGPRReg< 5, "r5">, DwarfRegNum<[5]>;
+ def R6 : MBlazeGPRReg< 6, "r6">, DwarfRegNum<[6]>;
+ def R7 : MBlazeGPRReg< 7, "r7">, DwarfRegNum<[7]>;
+ def R8 : MBlazeGPRReg< 8, "r8">, DwarfRegNum<[8]>;
+ def R9 : MBlazeGPRReg< 9, "r9">, DwarfRegNum<[9]>;
+ def R10 : MBlazeGPRReg< 10, "r10">, DwarfRegNum<[10]>;
+ def R11 : MBlazeGPRReg< 11, "r11">, DwarfRegNum<[11]>;
+ def R12 : MBlazeGPRReg< 12, "r12">, DwarfRegNum<[12]>;
+ def R13 : MBlazeGPRReg< 13, "r13">, DwarfRegNum<[13]>;
+ def R14 : MBlazeGPRReg< 14, "r14">, DwarfRegNum<[14]>;
+ def R15 : MBlazeGPRReg< 15, "r15">, DwarfRegNum<[15]>;
+ def R16 : MBlazeGPRReg< 16, "r16">, DwarfRegNum<[16]>;
+ def R17 : MBlazeGPRReg< 17, "r17">, DwarfRegNum<[17]>;
+ def R18 : MBlazeGPRReg< 18, "r18">, DwarfRegNum<[18]>;
+ def R19 : MBlazeGPRReg< 19, "r19">, DwarfRegNum<[19]>;
+ def R20 : MBlazeGPRReg< 20, "r20">, DwarfRegNum<[20]>;
+ def R21 : MBlazeGPRReg< 21, "r21">, DwarfRegNum<[21]>;
+ def R22 : MBlazeGPRReg< 22, "r22">, DwarfRegNum<[22]>;
+ def R23 : MBlazeGPRReg< 23, "r23">, DwarfRegNum<[23]>;
+ def R24 : MBlazeGPRReg< 24, "r24">, DwarfRegNum<[24]>;
+ def R25 : MBlazeGPRReg< 25, "r25">, DwarfRegNum<[25]>;
+ def R26 : MBlazeGPRReg< 26, "r26">, DwarfRegNum<[26]>;
+ def R27 : MBlazeGPRReg< 27, "r27">, DwarfRegNum<[27]>;
+ def R28 : MBlazeGPRReg< 28, "r28">, DwarfRegNum<[28]>;
+ def R29 : MBlazeGPRReg< 29, "r29">, DwarfRegNum<[29]>;
+ def R30 : MBlazeGPRReg< 30, "r30">, DwarfRegNum<[30]>;
+ def R31 : MBlazeGPRReg< 31, "r31">, DwarfRegNum<[31]>;
+
+ /// MBlaze Single point precision FPU Registers
+ def F0 : FPR< 0, "r0", [R0]>, DwarfRegNum<[32]>;
+ def F1 : FPR< 1, "r1", [R1]>, DwarfRegNum<[33]>;
+ def F2 : FPR< 2, "r2", [R2]>, DwarfRegNum<[34]>;
+ def F3 : FPR< 3, "r3", [R3]>, DwarfRegNum<[35]>;
+ def F4 : FPR< 4, "r4", [R4]>, DwarfRegNum<[36]>;
+ def F5 : FPR< 5, "r5", [R5]>, DwarfRegNum<[37]>;
+ def F6 : FPR< 6, "r6", [R6]>, DwarfRegNum<[38]>;
+ def F7 : FPR< 7, "r7", [R7]>, DwarfRegNum<[39]>;
+ def F8 : FPR< 8, "r8", [R8]>, DwarfRegNum<[40]>;
+ def F9 : FPR< 9, "r9", [R9]>, DwarfRegNum<[41]>;
+ def F10 : FPR<10, "r10", [R10]>, DwarfRegNum<[42]>;
+ def F11 : FPR<11, "r11", [R11]>, DwarfRegNum<[43]>;
+ def F12 : FPR<12, "r12", [R12]>, DwarfRegNum<[44]>;
+ def F13 : FPR<13, "r13", [R13]>, DwarfRegNum<[45]>;
+ def F14 : FPR<14, "r14", [R14]>, DwarfRegNum<[46]>;
+ def F15 : FPR<15, "r15", [R15]>, DwarfRegNum<[47]>;
+ def F16 : FPR<16, "r16", [R16]>, DwarfRegNum<[48]>;
+ def F17 : FPR<17, "r17", [R17]>, DwarfRegNum<[49]>;
+ def F18 : FPR<18, "r18", [R18]>, DwarfRegNum<[50]>;
+ def F19 : FPR<19, "r19", [R19]>, DwarfRegNum<[51]>;
+ def F20 : FPR<20, "r20", [R20]>, DwarfRegNum<[52]>;
+ def F21 : FPR<21, "r21", [R21]>, DwarfRegNum<[53]>;
+ def F22 : FPR<22, "r22", [R22]>, DwarfRegNum<[54]>;
+ def F23 : FPR<23, "r23", [R23]>, DwarfRegNum<[55]>;
+ def F24 : FPR<24, "r24", [R24]>, DwarfRegNum<[56]>;
+ def F25 : FPR<25, "r25", [R25]>, DwarfRegNum<[57]>;
+ def F26 : FPR<26, "r26", [R26]>, DwarfRegNum<[58]>;
+ def F27 : FPR<27, "r27", [R27]>, DwarfRegNum<[59]>;
+ def F28 : FPR<28, "r28", [R28]>, DwarfRegNum<[60]>;
+ def F29 : FPR<29, "r29", [R29]>, DwarfRegNum<[61]>;
+ def F30 : FPR<30, "r30", [R30]>, DwarfRegNum<[62]>;
+ def F31 : FPR<31, "r31", [R31]>, DwarfRegNum<[63]>;
+}
+
+//===----------------------------------------------------------------------===//
+// Register Classes
+//===----------------------------------------------------------------------===//
+
+def CPURegs : RegisterClass<"MBlaze", [i32], 32,
+ [
+ // Return Values and Arguments
+ R3, R4, R5, R6, R7, R8, R9, R10,
+
+ // Not preserved across procedure calls
+ R11, R12,
+
+ // Callee save
+ R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
+
+ // Reserved
+ R0, // Always zero
+ R1, // The stack pointer
+ R2, // Read-only small data area anchor
+ R13, // Read-write small data area anchor
+ R14, // Return address for interrupts
+ R15, // Return address for sub-routines
+ R16, // Return address for trap
+ R17, // Return address for exceptions
+ R18, // Reserved for assembler
+ R19 // The frame-pointer
+ ]>
+{
+ let MethodProtos = [{
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ CPURegsClass::iterator
+ CPURegsClass::allocation_order_end(const MachineFunction &MF) const {
+ // The last 10 registers on the list above are reserved
+ return end()-10;
+ }
+ }];
+}
+
+def FGR32 : RegisterClass<"MBlaze", [f32], 32,
+ [
+ // Return Values and Arguments
+ F3, F4, F5, F6, F7, F8, F9, F10,
+
+ // Not preserved across procedure calls
+ F11, F12,
+
+ // Callee save
+ F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31,
+
+ // Reserved
+ F0, // Always zero
+ F1, // The stack pointer
+ F2, // Read-only small data area anchor
+ F13, // Read-write small data area anchor
+ F14, // Return address for interrupts
+ F15, // Return address for sub-routines
+ F16, // Return address for trap
+ F17, // Return address for exceptions
+ F18, // Reserved for assembler
+ F19 // The frame pointer
+ ]>
+{
+ let MethodProtos = [{
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ FGR32Class::iterator
+ FGR32Class::allocation_order_end(const MachineFunction &MF) const {
+ // The last 10 registers on the list above are reserved
+ return end()-10;
+ }
+ }];
+}
diff --git a/lib/Target/MBlaze/MBlazeSchedule.td b/lib/Target/MBlaze/MBlazeSchedule.td
new file mode 100644
index 0000000..6a94491
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeSchedule.td
@@ -0,0 +1,63 @@
+//===- MBlazeSchedule.td - MBlaze Scheduling Definitions --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Functional units across MBlaze chips sets. Based on GCC/MBlaze backend files.
+//===----------------------------------------------------------------------===//
+def ALU : FuncUnit;
+def IMULDIV : FuncUnit;
+
+//===----------------------------------------------------------------------===//
+// Instruction Itinerary classes used for MBlaze
+//===----------------------------------------------------------------------===//
+def IIAlu : InstrItinClass;
+def IILoad : InstrItinClass;
+def IIStore : InstrItinClass;
+def IIXfer : InstrItinClass;
+def IIBranch : InstrItinClass;
+def IIHiLo : InstrItinClass;
+def IIImul : InstrItinClass;
+def IIIdiv : InstrItinClass;
+def IIFcvt : InstrItinClass;
+def IIFmove : InstrItinClass;
+def IIFcmp : InstrItinClass;
+def IIFadd : InstrItinClass;
+def IIFmulSingle : InstrItinClass;
+def IIFmulDouble : InstrItinClass;
+def IIFdivSingle : InstrItinClass;
+def IIFdivDouble : InstrItinClass;
+def IIFsqrtSingle : InstrItinClass;
+def IIFsqrtDouble : InstrItinClass;
+def IIFrecipFsqrtStep : InstrItinClass;
+def IIPseudo : InstrItinClass;
+
+//===----------------------------------------------------------------------===//
+// MBlaze Generic instruction itineraries.
+//===----------------------------------------------------------------------===//
+def MBlazeGenericItineraries : ProcessorItineraries<[
+ InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
+ InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
+ InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
+ InstrItinData<IIXfer , [InstrStage<2, [ALU]>]>,
+ InstrItinData<IIBranch , [InstrStage<1, [ALU]>]>,
+ InstrItinData<IIHiLo , [InstrStage<1, [IMULDIV]>]>,
+ InstrItinData<IIImul , [InstrStage<17, [IMULDIV]>]>,
+ InstrItinData<IIIdiv , [InstrStage<38, [IMULDIV]>]>,
+ InstrItinData<IIFcvt , [InstrStage<1, [ALU]>]>,
+ InstrItinData<IIFmove , [InstrStage<2, [ALU]>]>,
+ InstrItinData<IIFcmp , [InstrStage<3, [ALU]>]>,
+ InstrItinData<IIFadd , [InstrStage<4, [ALU]>]>,
+ InstrItinData<IIFmulSingle , [InstrStage<7, [ALU]>]>,
+ InstrItinData<IIFmulDouble , [InstrStage<8, [ALU]>]>,
+ InstrItinData<IIFdivSingle , [InstrStage<23, [ALU]>]>,
+ InstrItinData<IIFdivDouble , [InstrStage<36, [ALU]>]>,
+ InstrItinData<IIFsqrtSingle , [InstrStage<54, [ALU]>]>,
+ InstrItinData<IIFsqrtDouble , [InstrStage<12, [ALU]>]>,
+ InstrItinData<IIFrecipFsqrtStep , [InstrStage<5, [ALU]>]>
+]>;
diff --git a/lib/Target/MBlaze/MBlazeSubtarget.cpp b/lib/Target/MBlaze/MBlazeSubtarget.cpp
new file mode 100644
index 0000000..3440521
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeSubtarget.cpp
@@ -0,0 +1,31 @@
+//===- MBlazeSubtarget.cpp - MBlaze Subtarget Information -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MBlaze specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlazeSubtarget.h"
+#include "MBlaze.h"
+#include "MBlazeGenSubtarget.inc"
+#include "llvm/Support/CommandLine.h"
+using namespace llvm;
+
+MBlazeSubtarget::MBlazeSubtarget(const std::string &TT, const std::string &FS):
+ HasPipe3(false), HasBarrel(false), HasDiv(false), HasMul(false),
+ HasFSL(false), HasEFSL(false), HasMSRSet(false), HasException(false),
+ HasPatCmp(false), HasFPU(false), HasESR(false), HasPVR(false),
+ HasMul64(false), HasSqrt(false), HasMMU(false)
+{
+ std::string CPU = "v400";
+ MBlazeArchVersion = V400;
+
+ // Parse features string.
+ ParseSubtargetFeatures(FS, CPU);
+}
diff --git a/lib/Target/MBlaze/MBlazeSubtarget.h b/lib/Target/MBlaze/MBlazeSubtarget.h
new file mode 100644
index 0000000..bebb3f7
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeSubtarget.h
@@ -0,0 +1,79 @@
+//=====-- MBlazeSubtarget.h - Define Subtarget for the MBlaze -*- 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 MBlaze specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBLAZESUBTARGET_H
+#define MBLAZESUBTARGET_H
+
+#include "llvm/Target/TargetSubtarget.h"
+#include "llvm/Target/TargetMachine.h"
+
+#include <string>
+
+namespace llvm {
+
+class MBlazeSubtarget : public TargetSubtarget {
+
+protected:
+
+ enum MBlazeArchEnum {
+ V400, V500, V600, V700, V710
+ };
+
+ // MBlaze architecture version
+ MBlazeArchEnum MBlazeArchVersion;
+
+ bool HasPipe3;
+ bool HasBarrel;
+ bool HasDiv;
+ bool HasMul;
+ bool HasFSL;
+ bool HasEFSL;
+ bool HasMSRSet;
+ bool HasException;
+ bool HasPatCmp;
+ bool HasFPU;
+ bool HasESR;
+ bool HasPVR;
+ bool HasMul64;
+ bool HasSqrt;
+ bool HasMMU;
+
+ InstrItineraryData InstrItins;
+
+public:
+
+ /// This constructor initializes the data members to match that
+ /// of the specified triple.
+ MBlazeSubtarget(const std::string &TT, const std::string &FS);
+
+ /// ParseSubtargetFeatures - Parses features string setting specified
+ /// subtarget options. Definition of function is auto generated by tblgen.
+ std::string ParseSubtargetFeatures(const std::string &FS,
+ const std::string &CPU);
+
+ bool hasFPU() const { return HasFPU; }
+ bool hasSqrt() const { return HasSqrt; }
+ bool hasMul() const { return HasMul; }
+ bool hasMul64() const { return HasMul64; }
+ bool hasDiv() const { return HasDiv; }
+ bool hasBarrel() const { return HasBarrel; }
+
+ bool isV400() const { return MBlazeArchVersion == V400; }
+ bool isV500() const { return MBlazeArchVersion == V500; }
+ bool isV600() const { return MBlazeArchVersion == V600; }
+ bool isV700() const { return MBlazeArchVersion == V700; }
+ bool isV710() const { return MBlazeArchVersion == V710; }
+};
+} // End llvm namespace
+
+#endif
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
new file mode 100644
index 0000000..9eba2b3
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
@@ -0,0 +1,66 @@
+//===-- MBlazeTargetMachine.cpp - Define TargetMachine for MBlaze ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the info about MBlaze target spec.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlaze.h"
+#include "MBlazeMCAsmInfo.h"
+#include "MBlazeTargetMachine.h"
+#include "llvm/PassManager.h"
+#include "llvm/Target/TargetRegistry.h"
+using namespace llvm;
+
+extern "C" void LLVMInitializeMBlazeTarget() {
+ // Register the target.
+ RegisterTargetMachine<MBlazeTargetMachine> X(TheMBlazeTarget);
+ RegisterAsmInfo<MBlazeMCAsmInfo> A(TheMBlazeTarget);
+}
+
+// DataLayout --> Big-endian, 32-bit pointer/ABI/alignment
+// The stack is always 8 byte aligned
+// On function prologue, the stack is created by decrementing
+// its pointer. Once decremented, all references are done with positive
+// offset from the stack/frame pointer, using StackGrowsUp enables
+// an easier handling.
+MBlazeTargetMachine::
+MBlazeTargetMachine(const Target &T, const std::string &TT,
+ const std::string &FS):
+ LLVMTargetMachine(T, TT),
+ Subtarget(TT, FS),
+ DataLayout("E-p:32:32-i8:8:8-i16:16:16-i64:32:32-"
+ "f64:32:32-v64:32:32-v128:32:32-n32"),
+ InstrInfo(*this),
+ FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0),
+ TLInfo(*this) {
+ if (getRelocationModel() == Reloc::Default) {
+ setRelocationModel(Reloc::Static);
+ }
+
+ if (getCodeModel() == CodeModel::Default)
+ setCodeModel(CodeModel::Small);
+}
+
+// Install an instruction selector pass using
+// the ISelDag to gen MBlaze code.
+bool MBlazeTargetMachine::
+addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
+ PM.add(createMBlazeISelDag(*this));
+ return false;
+}
+
+// Implemented by targets that want to run passes immediately before
+// machine code is emitted. return true if -print-machineinstrs should
+// print out the code after the passes.
+bool MBlazeTargetMachine::
+addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
+ PM.add(createMBlazeDelaySlotFillerPass(*this));
+ return true;
+}
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.h b/lib/Target/MBlaze/MBlazeTargetMachine.h
new file mode 100644
index 0000000..85c975c
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.h
@@ -0,0 +1,69 @@
+//===-- MBlazeTargetMachine.h - Define TargetMachine for MBlaze --- 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 MBlaze specific subclass of TargetMachine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBLAZE_TARGETMACHINE_H
+#define MBLAZE_TARGETMACHINE_H
+
+#include "MBlazeSubtarget.h"
+#include "MBlazeInstrInfo.h"
+#include "MBlazeISelLowering.h"
+#include "MBlazeIntrinsicInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetFrameInfo.h"
+
+namespace llvm {
+ class formatted_raw_ostream;
+
+ class MBlazeTargetMachine : public LLVMTargetMachine {
+ MBlazeSubtarget Subtarget;
+ const TargetData DataLayout; // Calculates type size & alignment
+ MBlazeInstrInfo InstrInfo;
+ TargetFrameInfo FrameInfo;
+ MBlazeTargetLowering TLInfo;
+ MBlazeIntrinsicInfo IntrinsicInfo;
+ public:
+ MBlazeTargetMachine(const Target &T, const std::string &TT,
+ const std::string &FS);
+
+ virtual const MBlazeInstrInfo *getInstrInfo() const
+ { return &InstrInfo; }
+
+ virtual const TargetFrameInfo *getFrameInfo() const
+ { return &FrameInfo; }
+
+ virtual const MBlazeSubtarget *getSubtargetImpl() const
+ { return &Subtarget; }
+
+ virtual const TargetData *getTargetData() const
+ { return &DataLayout;}
+
+ virtual const MBlazeRegisterInfo *getRegisterInfo() const
+ { return &InstrInfo.getRegisterInfo(); }
+
+ virtual MBlazeTargetLowering *getTargetLowering() const
+ { return const_cast<MBlazeTargetLowering*>(&TLInfo); }
+
+ const TargetIntrinsicInfo *getIntrinsicInfo() const
+ { return &IntrinsicInfo; }
+
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(PassManagerBase &PM,
+ CodeGenOpt::Level OptLevel);
+
+ virtual bool addPreEmitPass(PassManagerBase &PM,
+ CodeGenOpt::Level OptLevel);
+ };
+} // End llvm namespace
+
+#endif
diff --git a/lib/Target/MBlaze/MBlazeTargetObjectFile.cpp b/lib/Target/MBlaze/MBlazeTargetObjectFile.cpp
new file mode 100644
index 0000000..79c9494
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeTargetObjectFile.cpp
@@ -0,0 +1,88 @@
+//===-- MBlazeTargetObjectFile.cpp - MBlaze object files ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlazeTargetObjectFile.h"
+#include "MBlazeSubtarget.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/CommandLine.h"
+using namespace llvm;
+
+void MBlazeTargetObjectFile::
+Initialize(MCContext &Ctx, const TargetMachine &TM) {
+ TargetLoweringObjectFileELF::Initialize(Ctx, TM);
+
+ SmallDataSection =
+ getELFSection(".sdata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getDataRel());
+
+ SmallBSSSection =
+ getELFSection(".sbss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getBSS());
+
+}
+
+// A address must be loaded from a small section if its size is less than the
+// small section size threshold. Data in this section must be addressed using
+// gp_rel operator.
+static bool IsInSmallSection(uint64_t Size) {
+ return Size > 0 && Size <= 8;
+}
+
+bool MBlazeTargetObjectFile::
+IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const {
+ if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
+ return false;
+
+ return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
+}
+
+/// IsGlobalInSmallSection - Return true if this global address should be
+/// placed into small data/bss section.
+bool MBlazeTargetObjectFile::
+IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
+ SectionKind Kind) const {
+ // Only global variables, not functions.
+ const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
+ if (!GVA)
+ return false;
+
+ // We can only do this for datarel or BSS objects for now.
+ if (!Kind.isBSS() && !Kind.isDataRel())
+ return false;
+
+ // If this is a internal constant string, there is a special
+ // section for it, but not in small data/bss.
+ if (Kind.isMergeable1ByteCString())
+ return false;
+
+ const Type *Ty = GV->getType()->getElementType();
+ return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
+}
+
+const MCSection *MBlazeTargetObjectFile::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
+ // sections?
+
+ // Handle Small Section classification here.
+ if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
+ return SmallBSSSection;
+ if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
+ return SmallDataSection;
+
+ // Otherwise, we work the same as ELF.
+ return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
+}
diff --git a/lib/Target/MBlaze/MBlazeTargetObjectFile.h b/lib/Target/MBlaze/MBlazeTargetObjectFile.h
new file mode 100644
index 0000000..20e7702
--- /dev/null
+++ b/lib/Target/MBlaze/MBlazeTargetObjectFile.h
@@ -0,0 +1,41 @@
+//===-- llvm/Target/MBlazeTargetObjectFile.h - MBlaze Obj. Info -*- 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_MBLAZE_TARGETOBJECTFILE_H
+#define LLVM_TARGET_MBLAZE_TARGETOBJECTFILE_H
+
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+
+namespace llvm {
+
+ class MBlazeTargetObjectFile : public TargetLoweringObjectFileELF {
+ const MCSection *SmallDataSection;
+ const MCSection *SmallBSSSection;
+ public:
+
+ void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+
+ /// IsGlobalInSmallSection - Return true if this global address should be
+ /// placed into small data/bss section.
+ bool IsGlobalInSmallSection(const GlobalValue *GV,
+ const TargetMachine &TM,
+ SectionKind Kind) const;
+
+ bool IsGlobalInSmallSection(const GlobalValue *GV,
+ const TargetMachine &TM) const;
+
+ const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
+ SectionKind Kind,
+ Mangler *Mang,
+ const TargetMachine &TM) const;
+ };
+} // end namespace llvm
+
+#endif
diff --git a/lib/Target/MBlaze/Makefile b/lib/Target/MBlaze/Makefile
new file mode 100644
index 0000000..19e508c
--- /dev/null
+++ b/lib/Target/MBlaze/Makefile
@@ -0,0 +1,23 @@
+##===- lib/Target/MBlaze/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 = LLVMMBlazeCodeGen
+TARGET = MBlaze
+
+# Make sure that tblgen is run, first thing.
+BUILT_SOURCES = MBlazeGenRegisterInfo.h.inc MBlazeGenRegisterNames.inc \
+ MBlazeGenRegisterInfo.inc MBlazeGenInstrNames.inc \
+ MBlazeGenInstrInfo.inc MBlazeGenAsmWriter.inc \
+ MBlazeGenDAGISel.inc MBlazeGenCallingConv.inc \
+ MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc
+
+DIRS = AsmPrinter TargetInfo
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Target/MBlaze/TargetInfo/CMakeLists.txt b/lib/Target/MBlaze/TargetInfo/CMakeLists.txt
new file mode 100644
index 0000000..5afb14d
--- /dev/null
+++ b/lib/Target/MBlaze/TargetInfo/CMakeLists.txt
@@ -0,0 +1,7 @@
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+add_llvm_library(LLVMMBlazeInfo
+ MBlazeTargetInfo.cpp
+ )
+
+add_dependencies(LLVMMBlazeInfo MBlazeCodeGenTable_gen)
diff --git a/lib/Target/MBlaze/TargetInfo/MBlazeTargetInfo.cpp b/lib/Target/MBlaze/TargetInfo/MBlazeTargetInfo.cpp
new file mode 100644
index 0000000..16e01db
--- /dev/null
+++ b/lib/Target/MBlaze/TargetInfo/MBlazeTargetInfo.cpp
@@ -0,0 +1,19 @@
+//===-- MBlazeTargetInfo.cpp - MBlaze Target Implementation ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlaze.h"
+#include "llvm/Module.h"
+#include "llvm/Target/TargetRegistry.h"
+using namespace llvm;
+
+Target llvm::TheMBlazeTarget;
+
+extern "C" void LLVMInitializeMBlazeTargetInfo() {
+ RegisterTarget<Triple::mblaze> X(TheMBlazeTarget, "mblaze", "MBlaze");
+}
diff --git a/lib/Target/MBlaze/TargetInfo/Makefile b/lib/Target/MBlaze/TargetInfo/Makefile
new file mode 100644
index 0000000..fb7ea11
--- /dev/null
+++ b/lib/Target/MBlaze/TargetInfo/Makefile
@@ -0,0 +1,15 @@
+##===- lib/Target/MBlaze/TargetInfo/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 = LLVMMBlazeInfo
+
+# Hack: we need to include 'main' target directory to grab private headers
+CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index a96ee49..ac41cc8 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -38,7 +38,8 @@ namespace llvm {
virtual bool addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel);
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify);
virtual const TargetData *getTargetData() const { return 0; }
};
@@ -57,7 +58,7 @@ bool MSILModule::runOnModule(Module &M) {
TypeSymbolTable& Table = M.getTypeSymbolTable();
std::set<const Type *> Types = getAnalysis<FindUsedTypes>().getTypes();
for (TypeSymbolTable::iterator I = Table.begin(), E = Table.end(); I!=E; ) {
- if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second))
+ if (!I->second->isStructTy() && !I->second->isOpaqueTy())
Table.remove(I++);
else {
std::set<const Type *>::iterator T = Types.find(I->second);
@@ -187,7 +188,7 @@ void MSILWriter::printModuleStartup() {
break;
case 1:
Arg1 = F->arg_begin();
- if (Arg1->getType()->isInteger()) {
+ if (Arg1->getType()->isIntegerTy()) {
Out << "\tldloc\targc\n";
Args = getTypeName(Arg1->getType());
BadSig = false;
@@ -195,7 +196,7 @@ void MSILWriter::printModuleStartup() {
break;
case 2:
Arg1 = Arg2 = F->arg_begin(); ++Arg2;
- if (Arg1->getType()->isInteger() &&
+ if (Arg1->getType()->isIntegerTy() &&
Arg2->getType()->getTypeID() == Type::PointerTyID) {
Out << "\tldloc\targc\n\tldloc\targv\n";
Args = getTypeName(Arg1->getType())+","+getTypeName(Arg2->getType());
@@ -207,7 +208,7 @@ void MSILWriter::printModuleStartup() {
}
bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID);
- if (BadSig || (!F->getReturnType()->isInteger() && !RetVoid)) {
+ if (BadSig || (!F->getReturnType()->isIntegerTy() && !RetVoid)) {
Out << "\tldc.i4.0\n";
} else {
Out << "\tcall\t" << getTypeName(F->getReturnType()) <<
@@ -334,7 +335,7 @@ std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
bool isNested) {
- if (Ty->isPrimitiveType() || Ty->isInteger())
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy())
return getPrimitiveTypeName(Ty,isSigned);
// FIXME: "OpaqueType" support
switch (Ty->getTypeID()) {
@@ -1459,7 +1460,7 @@ void MSILWriter::printDeclarations(const TypeSymbolTable& ST) {
for (std::set<const Type*>::const_iterator
UI = UsedTypes->begin(), UE = UsedTypes->end(); UI!=UE; ++UI) {
const Type* Ty = *UI;
- if (isa<ArrayType>(Ty) || isa<VectorType>(Ty) || isa<StructType>(Ty))
+ if (Ty->isArrayTy() || Ty->isVectorTy() || Ty->isStructTy())
Name = getTypeName(Ty, false, true);
// Type with no need to declare.
else continue;
@@ -1688,7 +1689,8 @@ void MSILWriter::printExternals() {
bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &o,
CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel)
+ CodeGenOpt::Level OptLevel,
+ bool DisableVerify)
{
if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
MSILWriter* Writer = new MSILWriter(o);
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index def5fc6..7a35eb0 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -98,12 +98,19 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
uint64_t Offset = MO.getOffset();
- O << (isMemOp ? '&' : '#');
+ // If the global address expression is a part of displacement field with a
+ // register base, we should not emit any prefix symbol here, e.g.
+ // mov.w &foo, r1
+ // vs
+ // mov.w glb(r1), r2
+ // Otherwise (!) msp430-as will silently miscompile the output :(
+ if (!Modifier || strcmp(Modifier, "nohash"))
+ O << (isMemOp ? '&' : '#');
if (Offset)
O << '(' << Offset << '+';
O << *GetGlobalValueSymbol(MO.getGlobal());
-
+
if (Offset)
O << ')';
@@ -124,15 +131,11 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
const MachineOperand &Disp = MI->getOperand(OpNum+1);
// Print displacement first
- if (!Disp.isImm()) {
- printOperand(MI, OpNum+1, "mem");
- } else {
- if (!Base.getReg())
- O << '&';
-
- printOperand(MI, OpNum+1, "nohash");
- }
+ // Imm here is in fact global address - print extra modifier.
+ if (Disp.isImm() && !Base.getReg())
+ O << '&';
+ printOperand(MI, OpNum+1, "nohash");
// Print register base field
if (Base.getReg()) {
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
index f6565bd..d7636e6 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
@@ -62,21 +62,26 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
const MCOperand &Disp = MI->getOperand(OpNo+1);
// Print displacement first
- if (Disp.isExpr()) {
- O << '&' << *Disp.getExpr();
- } else {
- assert(Disp.isImm() && "Expected immediate in displacement field");
- if (!Base.getReg())
- O << '&';
+ // If the global address expression is a part of displacement field with a
+ // register base, we should not emit any prefix symbol here, e.g.
+ // mov.w &foo, r1
+ // vs
+ // mov.w glb(r1), r2
+ // Otherwise (!) msp430-as will silently miscompile the output :(
+ if (!Base.getReg())
+ O << '&';
+
+ if (Disp.isExpr())
+ O << *Disp.getExpr();
+ else {
+ assert(Disp.isImm() && "Expected immediate in displacement field");
O << Disp.getImm();
}
-
// Print register base field
- if (Base.getReg()) {
+ if (Base.getReg())
O << '(' << getRegisterName(Base.getReg()) << ')';
- }
}
void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo) {
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index 4eec757..911cfcb 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -26,26 +26,12 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetLowering.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/Statistic.h"
-
using namespace llvm;
-#ifndef NDEBUG
-static cl::opt<bool>
-ViewRMWDAGs("view-msp430-rmw-dags", cl::Hidden,
- cl::desc("Pop up a window to show isel dags after RMW preprocess"));
-#else
-static const bool ViewRMWDAGs = false;
-#endif
-
-STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
-
-
namespace {
struct MSP430ISelAddressMode {
enum {
@@ -123,8 +109,6 @@ namespace {
Lowering(*TM.getTargetLowering()),
Subtarget(*TM.getSubtargetImpl()) { }
- virtual void InstructionSelect();
-
virtual const char *getPassName() const {
return "MSP430 DAG->DAG Pattern Instruction Selection";
}
@@ -133,9 +117,6 @@ namespace {
bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const;
-
virtual bool
SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
std::vector<SDValue> &OutOps);
@@ -144,18 +125,12 @@ namespace {
#include "MSP430GenDAGISel.inc"
private:
- DenseMap<SDNode*, SDNode*> RMWStores;
- void PreprocessForRMW();
SDNode *Select(SDNode *N);
SDNode *SelectIndexedLoad(SDNode *Op);
SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
unsigned Opc8, unsigned Opc16);
bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp);
-
- #ifndef NDEBUG
- unsigned Indent;
- #endif
};
} // end anonymous namespace
@@ -217,10 +192,7 @@ bool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM)
}
bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
- DEBUG({
- errs() << "MatchAddress: ";
- AM.dump();
- });
+ DEBUG(errs() << "MatchAddress: "; AM.dump());
switch (N.getOpcode()) {
default: break;
@@ -336,270 +308,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
return false;
}
-bool MSP430DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
- if (OptLevel == CodeGenOpt::None) return false;
-
- /// RMW preprocessing creates the following code:
- /// [Load1]
- /// ^ ^
- /// / |
- /// / |
- /// [Load2] |
- /// ^ ^ |
- /// | | |
- /// | \-|
- /// | |
- /// | [Op]
- /// | ^
- /// | |
- /// \ /
- /// \ /
- /// [Store]
- ///
- /// The path Store => Load2 => Load1 is via chain. Note that in general it is
- /// not allowed to fold Load1 into Op (and Store) since it will creates a
- /// cycle. However, this is perfectly legal for the loads moved below the
- /// TokenFactor by PreprocessForRMW. Query the map Store => Load1 (created
- /// during preprocessing) to determine whether it's legal to introduce such
- /// "cycle" for a moment.
- DenseMap<SDNode*, SDNode*>::const_iterator I = RMWStores.find(Root);
- if (I != RMWStores.end() && I->second == N)
- return true;
-
- // Proceed to 'generic' cycle finder code
- return SelectionDAGISel::IsLegalAndProfitableToFold(N, U, Root);
-}
-
-
-/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
-/// and move load below the TokenFactor. Replace store's chain operand with
-/// load's chain result.
-static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load,
- SDValue Store, SDValue TF) {
- SmallVector<SDValue, 4> Ops;
- for (unsigned i = 0, e = TF.getNode()->getNumOperands(); i != e; ++i)
- if (Load.getNode() == TF.getOperand(i).getNode())
- Ops.push_back(Load.getOperand(0));
- else
- Ops.push_back(TF.getOperand(i));
- SDValue NewTF = CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size());
- SDValue NewLoad = CurDAG->UpdateNodeOperands(Load, NewTF,
- Load.getOperand(1),
- Load.getOperand(2));
- CurDAG->UpdateNodeOperands(Store, NewLoad.getValue(1), Store.getOperand(1),
- Store.getOperand(2), Store.getOperand(3));
-}
-
-/// MoveBelowTokenFactor2 - Replace TokenFactor operand with load's chain operand
-/// and move load below the TokenFactor. Replace store's chain operand with
-/// load's chain result. This a version which sinks two loads below token factor.
-/// Look into PreprocessForRMW comments for explanation of transform.
-static void MoveBelowTokenFactor2(SelectionDAG *CurDAG,
- SDValue Load1, SDValue Load2,
- SDValue Store, SDValue TF) {
- SmallVector<SDValue, 4> Ops;
- for (unsigned i = 0, e = TF.getNode()->getNumOperands(); i != e; ++i) {
- SDNode* N = TF.getOperand(i).getNode();
- if (Load2.getNode() == N)
- Ops.push_back(Load2.getOperand(0));
- else if (Load1.getNode() != N)
- Ops.push_back(TF.getOperand(i));
- }
-
- SDValue NewTF = SDValue(CurDAG->MorphNodeTo(TF.getNode(),
- TF.getOpcode(),
- TF.getNode()->getVTList(),
- &Ops[0], Ops.size()), TF.getResNo());
- SDValue NewLoad2 = CurDAG->UpdateNodeOperands(Load2, NewTF,
- Load2.getOperand(1),
- Load2.getOperand(2));
-
- SDValue NewLoad1 = CurDAG->UpdateNodeOperands(Load1, NewLoad2.getValue(1),
- Load1.getOperand(1),
- Load1.getOperand(2));
-
- CurDAG->UpdateNodeOperands(Store,
- NewLoad1.getValue(1),
- Store.getOperand(1),
- Store.getOperand(2), Store.getOperand(3));
-}
-
-/// isAllowedToSink - return true if N a load which can be moved below token
-/// factor. Basically, the load should be non-volatile and has single use.
-static bool isLoadAllowedToSink(SDValue N, SDValue Chain) {
- if (N.getOpcode() == ISD::BIT_CONVERT)
- N = N.getOperand(0);
-
- LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
- if (!LD || LD->isVolatile())
- return false;
- if (LD->getAddressingMode() != ISD::UNINDEXED)
- return false;
-
- ISD::LoadExtType ExtType = LD->getExtensionType();
- if (ExtType != ISD::NON_EXTLOAD && ExtType != ISD::EXTLOAD)
- return false;
-
- return (N.hasOneUse() &&
- LD->hasNUsesOfValue(1, 1) &&
- LD->isOperandOf(Chain.getNode()));
-}
-
-
-/// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG.
-/// The chain produced by the load must only be used by the store's chain
-/// operand, otherwise this may produce a cycle in the DAG.
-static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
- SDValue &Load) {
- if (isLoadAllowedToSink(N, Chain) &&
- N.getOperand(1) == Address) {
- Load = N;
- return true;
- }
- return false;
-}
-
-/// PreprocessForRMW - Preprocess the DAG to make instruction selection better.
-/// This is only run if not in -O0 mode.
-/// This allows the instruction selector to pick more read-modify-write
-/// instructions. This is a common case:
-///
-/// [Load chain]
-/// ^
-/// |
-/// [Load]
-/// ^ ^
-/// | |
-/// / \-
-/// / |
-/// [TokenFactor] [Op]
-/// ^ ^
-/// | |
-/// \ /
-/// \ /
-/// [Store]
-///
-/// The fact the store's chain operand != load's chain will prevent the
-/// (store (op (load))) instruction from being selected. We can transform it to:
-///
-/// [Load chain]
-/// ^
-/// |
-/// [TokenFactor]
-/// ^
-/// |
-/// [Load]
-/// ^ ^
-/// | |
-/// | \-
-/// | |
-/// | [Op]
-/// | ^
-/// | |
-/// \ /
-/// \ /
-/// [Store]
-///
-/// We also recognize the case where second operand of Op is load as well and
-/// move it below token factor as well creating DAG as follows:
-///
-/// [Load chain]
-/// ^
-/// |
-/// [TokenFactor]
-/// ^
-/// |
-/// [Load1]
-/// ^ ^
-/// / |
-/// / |
-/// [Load2] |
-/// ^ ^ |
-/// | | |
-/// | \-|
-/// | |
-/// | [Op]
-/// | ^
-/// | |
-/// \ /
-/// \ /
-/// [Store]
-///
-/// This allows selection of mem-mem instructions. Yay!
-
-void MSP430DAGToDAGISel::PreprocessForRMW() {
- for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
- E = CurDAG->allnodes_end(); I != E; ++I) {
- if (!ISD::isNON_TRUNCStore(I))
- continue;
- SDValue Chain = I->getOperand(0);
-
- if (Chain.getNode()->getOpcode() != ISD::TokenFactor)
- continue;
-
- SDValue N1 = I->getOperand(1);
- SDValue N2 = I->getOperand(2);
- if ((N1.getValueType().isFloatingPoint() &&
- !N1.getValueType().isVector()) ||
- !N1.hasOneUse())
- continue;
-
- unsigned RModW = 0;
- SDValue Load1, Load2;
- unsigned Opcode = N1.getNode()->getOpcode();
- switch (Opcode) {
- case ISD::ADD:
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR:
- case ISD::ADDC:
- case ISD::ADDE: {
- SDValue N10 = N1.getOperand(0);
- SDValue N11 = N1.getOperand(1);
- if (isRMWLoad(N10, Chain, N2, Load1)) {
- if (isLoadAllowedToSink(N11, Chain)) {
- Load2 = N11;
- RModW = 2;
- } else
- RModW = 1;
- } else if (isRMWLoad(N11, Chain, N2, Load1)) {
- if (isLoadAllowedToSink(N10, Chain)) {
- Load2 = N10;
- RModW = 2;
- } else
- RModW = 1;
- }
- break;
- }
- case ISD::SUB:
- case ISD::SUBC:
- case ISD::SUBE: {
- SDValue N10 = N1.getOperand(0);
- SDValue N11 = N1.getOperand(1);
- if (isRMWLoad(N10, Chain, N2, Load1)) {
- if (isLoadAllowedToSink(N11, Chain)) {
- Load2 = N11;
- RModW = 2;
- } else
- RModW = 1;
- }
- break;
- }
- }
-
- NumLoadMoved += RModW;
- if (RModW == 1)
- MoveBelowTokenFactor(CurDAG, Load1, SDValue(I, 0), Chain);
- else if (RModW == 2) {
- MoveBelowTokenFactor2(CurDAG, Load1, Load2, SDValue(I, 0), Chain);
- SDNode* Store = I;
- RMWStores[Store] = Load2.getNode();
- }
- }
-}
-
-
static bool isValidIndexedLoad(const LoadSDNode *LD) {
ISD::MemIndexedMode AM = LD->getAddressingMode();
if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
@@ -656,7 +364,7 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
unsigned Opc8, unsigned Opc16) {
if (N1.getOpcode() == ISD::LOAD &&
N1.hasOneUse() &&
- IsLegalAndProfitableToFold(N1.getNode(), Op, Op)) {
+ IsLegalToFold(N1, Op, Op)) {
LoadSDNode *LD = cast<LoadSDNode>(N1);
if (!isValidIndexedLoad(LD))
return NULL;
@@ -682,46 +390,19 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void MSP430DAGToDAGISel::InstructionSelect() {
- std::string BlockName;
- if (ViewRMWDAGs)
- BlockName = MF->getFunction()->getNameStr() + ":" +
- BB->getBasicBlock()->getNameStr();
-
- PreprocessForRMW();
-
- if (ViewRMWDAGs) CurDAG->viewGraph("RMW preprocessed:" + BlockName);
-
- DEBUG(errs() << "Selection DAG after RMW preprocessing:\n");
- DEBUG(CurDAG->dump());
-
- // Codegen the basic block.
- DEBUG(errs() << "===== Instruction selection begins:\n");
- DEBUG(Indent = 0);
- SelectRoot(*CurDAG);
- DEBUG(errs() << "===== Instruction selection ends:\n");
-
- CurDAG->RemoveDeadNodes();
- RMWStores.clear();
-}
-
SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
DebugLoc dl = Node->getDebugLoc();
// Dump information about the Node being selected
- DEBUG(errs().indent(Indent) << "Selecting: ");
+ DEBUG(errs() << "Selecting: ");
DEBUG(Node->dump(CurDAG));
DEBUG(errs() << "\n");
- DEBUG(Indent += 2);
// If we have a custom node, we already have selected!
if (Node->isMachineOpcode()) {
- DEBUG(errs().indent(Indent-2) << "== ";
+ DEBUG(errs() << "== ";
Node->dump(CurDAG);
errs() << "\n");
- DEBUG(Indent -= 2);
return NULL;
}
@@ -809,13 +490,12 @@ SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
// Select the default instruction
SDNode *ResNode = SelectCode(Node);
- DEBUG(errs() << std::string(Indent-2, ' ') << "=> ");
+ DEBUG(errs() << "=> ");
if (ResNode == NULL || ResNode == Node)
DEBUG(Node->dump(CurDAG));
else
DEBUG(ResNode->dump(CurDAG));
DEBUG(errs() << "\n");
- DEBUG(Indent -= 2);
return ResNode;
}
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index ef81f51..e6c7e1e 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -31,8 +31,8 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -371,7 +371,8 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
//from this parameter
SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0));
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0));
}
}
@@ -500,7 +501,7 @@ MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
PseudoSourceValue::getStack(),
- VA.getLocMemOffset()));
+ VA.getLocMemOffset(), false, false, 0));
}
}
@@ -794,18 +795,15 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
if (andCC) {
// C = ~Z, thus Res = SRW & 1, no processing is required
} else {
- // Res = (SRW >> 1) & 1
+ // Res = ~((SRW >> 1) & 1)
Shift = true;
+ Invert = true;
}
break;
case MSP430CC::COND_E:
- if (andCC) {
- // C = ~Z, thus Res = ~(SRW & 1)
- } else {
- // Res = ~((SRW >> 1) & 1)
- Shift = true;
- }
- Invert = true;
+ Shift = true;
+ // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
+ // Res = (SRW >> 1) & 1 is 1 word shorter.
break;
}
EVT VT = Op.getValueType();
@@ -893,13 +891,13 @@ SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
DAG.getNode(ISD::ADD, dl, getPointerTy(),
FrameAddr, Offset),
- NULL, 0);
+ NULL, 0, false, false, 0);
}
// Just load the return address.
SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- RetAddrFI, NULL, 0);
+ RetAddrFI, NULL, 0, false, false, 0);
}
SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
@@ -911,7 +909,8 @@ SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
MSP430::FPW, VT);
while (Depth--)
- FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
+ FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0,
+ false, false, 0);
return FrameAddr;
}
@@ -971,7 +970,7 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
bool MSP430TargetLowering::isTruncateFree(const Type *Ty1,
const Type *Ty2) const {
- if (!Ty1->isInteger() || !Ty2->isInteger())
+ if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
return false;
return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
@@ -986,7 +985,7 @@ bool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
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);
+ return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
}
bool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index bb06f7b..144ba26 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -250,7 +250,7 @@ def MOV16ri : I16ri<0x0,
[(set GR16:$dst, imm:$src)]>;
}
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
+let canFoldAsLoad = 1, isReMaterializable = 1 in {
def MOV8rm : I8rm<0x0,
(outs GR8:$dst), (ins memsrc:$src),
"mov.b\t{$src, $dst}",
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index f1d4a67..c4746db 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -59,8 +59,6 @@ public:
SelectionDAGISel(tm),
TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
- virtual void InstructionSelect();
-
// Pass Name
virtual const char *getPassName() const {
return "MIPS DAG->DAG Pattern Instruction Selection";
@@ -98,29 +96,10 @@ private:
inline SDValue getI32Imm(unsigned Imm) {
return CurDAG->getTargetConstant(Imm, MVT::i32);
}
-
-
- #ifndef NDEBUG
- unsigned Indent;
- #endif
};
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void MipsDAGToDAGISel::InstructionSelect() {
- // Codegen the basic block.
- DEBUG(errs() << "===== Instruction selection begins:\n");
- DEBUG(Indent = 0);
-
- // Select target instructions for the DAG.
- SelectRoot(*CurDAG);
-
- DEBUG(errs() << "===== Instruction selection ends:\n");
-
- CurDAG->RemoveDeadNodes();
-}
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
@@ -329,17 +308,11 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
DebugLoc dl = Node->getDebugLoc();
// Dump information about the Node being selected
- DEBUG(errs().indent(Indent) << "Selecting: ";
- Node->dump(CurDAG);
- errs() << "\n");
- DEBUG(Indent += 2);
+ DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
// If we have a custom node, we already have selected!
if (Node->isMachineOpcode()) {
- DEBUG(errs().indent(Indent-2) << "== ";
- Node->dump(CurDAG);
- errs() << "\n");
- DEBUG(Indent -= 2);
+ DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
return NULL;
}
@@ -547,14 +520,12 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
// Select the default instruction
SDNode *ResNode = SelectCode(Node);
- DEBUG(errs().indent(Indent-2) << "=> ");
+ DEBUG(errs() << "=> ");
if (ResNode == NULL || ResNode == Node)
DEBUG(Node->dump(CurDAG));
else
DEBUG(ResNode->dump(CurDAG));
DEBUG(errs() << "\n");
- DEBUG(Indent -= 2);
-
return ResNode;
}
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index d94944f..584b887 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -510,7 +510,8 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32, 0,
MipsII::MO_GOT);
SDValue ResNode = DAG.getLoad(MVT::i32, dl,
- DAG.getEntryNode(), GA, NULL, 0);
+ DAG.getEntryNode(), GA, NULL, 0,
+ false, false, 0);
// On functions and global targets not internal linked only
// a load from got/GP is necessary for PIC to work.
if (!GV->hasLocalLinkage() || isa<Function>(GV))
@@ -549,7 +550,8 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG)
SDValue Ops[] = { JTI };
HiPart = DAG.getNode(MipsISD::Hi, dl, DAG.getVTList(MVT::i32), Ops, 1);
} else // Emit Load from Global Pointer
- HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI, NULL, 0);
+ HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI, NULL, 0,
+ false, false, 0);
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTI);
ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo);
@@ -586,7 +588,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG)
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
N->getOffset(), MipsII::MO_GOT);
SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(),
- CP, NULL, 0);
+ CP, NULL, 0, false, false, 0);
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP);
ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo);
}
@@ -601,7 +603,8 @@ SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
// vastart just stores the address of the VarArgsFrameIndex slot into the
// memory location argument.
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
//===----------------------------------------------------------------------===//
@@ -859,7 +862,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// emit ISD::STORE whichs stores the
// parameter value to a stack Location
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
}
// Transform all store nodes into one single node because all store
@@ -933,7 +937,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// Reload GP value.
FI = MipsFI->getGPFI();
SDValue FIN = DAG.getFrameIndex(FI,getPointerTy());
- SDValue GPLoad = DAG.getLoad(MVT::i32, dl, Chain, FIN, NULL, 0);
+ SDValue GPLoad = DAG.getLoad(MVT::i32, dl, Chain, FIN, NULL, 0,
+ false, false, 0);
Chain = GPLoad.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, DAG.getRegister(Mips::GP, MVT::i32),
GPLoad, SDValue(0,0));
@@ -1097,7 +1102,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
// Create load nodes to retrieve arguments from the stack
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
- InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -1132,7 +1138,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
int FI = MFI->CreateFixedObject(4, 0, true, false);
MipsFI->recordStoreVarArgsFI(FI, -(4+(StackLoc*4)));
SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
- OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0));
+ OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0,
+ false, false, 0));
// Record the frame index of the first variable argument
// which is a value necessary to VASTART.
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index e67bcbf..cef3697 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -120,7 +120,7 @@ def immZExt5 : PatLeaf<(imm), [{
// Mips Address Mode! SDNode frameindex could possibily be a match
// since load and store instructions from stack used it.
-def addr : ComplexPattern<i32, 2, "SelectAddr", [frameindex], []>;
+def addr : ComplexPattern<iPTR, 2, "SelectAddr", [frameindex], []>;
//===----------------------------------------------------------------------===//
// Instructions specific format
@@ -300,9 +300,8 @@ class JumpFR<bits<6> op, bits<6> func, string instr_asm>:
// Jump and Link (Call)
let isCall=1, hasDelaySlot=1,
// All calls clobber the non-callee saved registers...
- Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9,
- K0, K1, F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13,
- F14, F15, F16, F17, F18, F19], Uses = [GP] in {
+ Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9,
+ K0, K1, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9], Uses = [GP] in {
class JumpLink<bits<6> op, string instr_asm>:
FJ< op,
(outs),
@@ -593,8 +592,8 @@ def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
(JAL tglobaladdr:$dst)>;
def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
(JAL texternalsym:$dst)>;
-def : Pat<(MipsJmpLink CPURegs:$dst),
- (JALR CPURegs:$dst)>;
+//def : Pat<(MipsJmpLink CPURegs:$dst),
+// (JALR CPURegs:$dst)>;
// hi/lo relocs
def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
diff --git a/lib/Target/Mips/MipsTargetObjectFile.h b/lib/Target/Mips/MipsTargetObjectFile.h
index 32e0436..237b160 100644
--- a/lib/Target/Mips/MipsTargetObjectFile.h
+++ b/lib/Target/Mips/MipsTargetObjectFile.h
@@ -10,7 +10,7 @@
#ifndef LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
#define LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
namespace llvm {
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
index 72f7c16..44a6cc0 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
@@ -106,8 +106,9 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
DbgInfo.BeginFunction(MF);
// Now emit the instructions of function in its code section.
- const MCSection *fCodeSection
- = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
+ const MCSection *fCodeSection =
+ getObjFileLowering().SectionForCode(CurrentFnSym->getName(),
+ PAN::isISR(F->getSection()));
// Start the Code Section.
O << "\n";
@@ -157,6 +158,7 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// printOperand - print operand of insn.
void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand(opNum);
+ const Function *F = MI->getParent()->getParent()->getFunction();
switch (MO.getType()) {
case MachineOperand::MO_Register:
@@ -189,19 +191,18 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
}
case MachineOperand::MO_ExternalSymbol: {
const char *Sname = MO.getSymbolName();
+ std::string Printname = Sname;
- // If its a libcall name, record it to decls section.
- 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;
- if (PAN::isMemIntrinsic(Sym)) {
- Sym = PAN::addPrefix(Sym);
- LibcallDecls.push_back(createESName(Sym));
+ // Intrinsic stuff needs to be renamed if we are printing IL fn.
+ if (PAN::isIntrinsicStuff(Printname)) {
+ if (PAN::isISR(F->getSection())) {
+ Printname = PAN::Rename(Sname);
+ }
+ // Record these decls, we need to print them in asm as extern.
+ LibcallDecls.push_back(createESName(Printname));
}
- O << Sym;
+ O << Printname;
break;
}
case MachineOperand::MO_MachineBasicBlock:
@@ -247,8 +248,6 @@ void PIC16AsmPrinter::printLibcallDecls() {
for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
I != LibcallDecls.end(); I++) {
O << MAI->getExternDirective() << *I << "\n";
- O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
- O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
}
O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
}
diff --git a/lib/Target/PIC16/PIC16ABINames.h b/lib/Target/PIC16/PIC16ABINames.h
index e18ddf1..4c1a8da 100644
--- a/lib/Target/PIC16/PIC16ABINames.h
+++ b/lib/Target/PIC16/PIC16ABINames.h
@@ -178,18 +178,21 @@ namespace llvm {
return Func1 + tag;
}
+ // Get the retval label for the given function.
static std::string getRetvalLabel(const std::string &Func) {
std::string Func1 = addPrefix(Func);
std::string tag = getTagName(RET_LABEL);
return Func1 + tag;
}
+ // Get the argument label for the given function.
static std::string getArgsLabel(const std::string &Func) {
std::string Func1 = addPrefix(Func);
std::string tag = getTagName(ARGS_LABEL);
return Func1 + tag;
}
+ // Get the tempdata label for the given function.
static std::string getTempdataLabel(const std::string &Func) {
std::string Func1 = addPrefix(Func);
std::string tag = getTagName(TEMPS_LABEL);
@@ -263,6 +266,7 @@ namespace llvm {
return false;
}
+
inline static bool isMemIntrinsic (const std::string &Name) {
if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 ||
Name.compare("@memmove") == 0) {
@@ -272,6 +276,41 @@ namespace llvm {
return false;
}
+ // Currently names of libcalls are assigned during TargetLowering
+ // object construction. There is no provision to change the when the
+ // code for a function IL function being generated.
+ // So we have to change these names while printing assembly.
+ // We need to do that mainly for names related to intrinsics. This
+ // function returns true if a name needs to be cloned.
+ inline static bool isIntrinsicStuff(const std::string &Name) {
+ // Return true if the name contains LIBCALL marker, or a MemIntrinisc.
+ // these are mainly ARGS_LABEL, RET_LABEL, and the LIBCALL name itself.
+ if ((Name.find(getTagName(LIBCALL)) != std::string::npos)
+ || isMemIntrinsic(Name))
+ return true;
+
+ return false;
+ }
+
+ // Rename the name for IL.
+ inline static std::string Rename(const std::string &Name) {
+ std::string Newname;
+ // If its a label (LIBCALL+Func+LABEL), change it to
+ // (LIBCALL+Func+IL+LABEL).
+ TAGS id = getSymbolTag(Name);
+ if (id == ARGS_LABEL || id == RET_LABEL) {
+ std::size_t pos = Name.find(getTagName(id));
+ Newname = Name.substr(0, pos) + ".IL" + getTagName(id);
+ return Newname;
+ }
+
+ // Else, just append IL to name.
+ return Name + ".IL";
+ }
+
+
+
+
inline static bool isLocalToFunc (std::string &Func, std::string &Var) {
if (! isLocalName(Var)) return false;
@@ -325,6 +364,35 @@ namespace llvm {
return o.str();
}
+
+ // Return true if the current function is an ISR
+ inline static bool isISR(const std::string SectName) {
+ if (SectName.find("interrupt") != std::string::npos)
+ return true;
+
+ return false;
+ }
+
+ // Return the address for ISR starts in rom.
+ inline static std::string getISRAddr(void) {
+ return "0x4";
+ }
+
+ // Returns the name of clone of a function.
+ static std::string getCloneFnName(const std::string &Func) {
+ return (Func + ".IL");
+ }
+
+ // Returns the name of clone of a variable.
+ static std::string getCloneVarName(const std::string &Fn,
+ const std::string &Var) {
+ std::string cloneVarName = Var;
+ // These vars are named like fun.auto.var.
+ // Just replace the function name, with clone function name.
+ std::string cloneFnName = getCloneFnName(Fn);
+ cloneVarName.replace(cloneVarName.find(Fn), Fn.length(), cloneFnName);
+ return cloneVarName;
+ }
}; // class PAN.
} // end namespace llvm;
diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp
index c517b1b..877e4ff 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.cpp
+++ b/lib/Target/PIC16/PIC16DebugInfo.cpp
@@ -419,7 +419,7 @@ void PIC16DbgInfo::EmitAuxEntry(const std::string VarName, int Aux[], int Num,
if (TagName != "")
O << ", " << TagName;
for (int i = 0; i<Num; i++)
- O << "," << Aux[i];
+ O << "," << (Aux[i] && 0xff);
}
/// EmitSymbol - Emit .def for a symbol. Value is offset for the member.
diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
index 82197ae..6cbd002 100644
--- a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
+++ b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
@@ -14,10 +14,7 @@
#define DEBUG_TYPE "pic16-isel"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
#include "PIC16ISelDAGToDAG.h"
-#include "llvm/Support/Debug.h"
-
using namespace llvm;
/// createPIC16ISelDag - This pass converts a legalized DAG into a
@@ -27,13 +24,6 @@ FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) {
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void PIC16DAGToDAGISel::InstructionSelect() {
- SelectRoot(*CurDAG);
- CurDAG->RemoveDeadNodes();
-}
-
/// Select - Select instructions not customized! Used for
/// expanded, promoted and normal instructions.
SDNode* PIC16DAGToDAGISel::Select(SDNode *N) {
diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.h b/lib/Target/PIC16/PIC16ISelDAGToDAG.h
index 813a540..8ed5bf7 100644
--- a/lib/Target/PIC16/PIC16ISelDAGToDAG.h
+++ b/lib/Target/PIC16/PIC16ISelDAGToDAG.h
@@ -19,6 +19,8 @@
#include "PIC16TargetMachine.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Intrinsics.h"
using namespace llvm;
@@ -46,8 +48,6 @@ public:
return "PIC16 DAG->DAG Pattern Instruction Selection";
}
- virtual void InstructionSelect();
-
private:
// Include the pieces autogenerated from the target description.
#include "PIC16GenDAGISel.inc"
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index 7754a4f..d17abb9 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -419,8 +419,7 @@ PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call,
LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
false, 0, CallingConv::C, false,
/*isReturnValueUsed=*/true,
- Callee, Args, DAG, dl,
- DAG.GetOrdering(DAG.getEntryNode().getNode()));
+ Callee, Args, DAG, dl);
return CallInfo.first;
}
@@ -622,12 +621,12 @@ SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) {
ChainHi = Chain.getOperand(1);
}
SDValue Store1 = DAG.getStore(ChainLo, dl, SrcLo, Ptr, NULL,
- 0 + StoreOffset);
+ 0 + StoreOffset, false, false, 0);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(4, Ptr.getValueType()));
SDValue Store2 = DAG.getStore(ChainHi, dl, SrcHi, Ptr, NULL,
- 1 + StoreOffset);
+ 1 + StoreOffset, false, false, 0);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1,
Store2);
@@ -1513,8 +1512,7 @@ bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp,
// Direct load operands are folded in binary operations. But before folding
// verify if this folding is legal. Fold only if it is legal otherwise
// convert this direct load to a separate memory operation.
- if(ISel->IsLegalAndProfitableToFold(Op.getOperand(0).getNode(),
- Op.getNode(), Op.getNode()))
+ if(ISel->IsLegalToFold(Op.getOperand(0), Op.getNode(), Op.getNode()))
return false;
else
MemOp = 0;
@@ -1528,10 +1526,24 @@ bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp,
return true;
if (isDirectLoad(Op.getOperand(1))) {
- if (Op.getOperand(1).hasOneUse())
- return false;
- else
- MemOp = 1;
+ if (Op.getOperand(1).hasOneUse()) {
+ // Legal and profitable folding check uses the NodeId of DAG nodes.
+ // This NodeId is assigned by topological order. Therefore first
+ // assign topological order then perform legal and profitable check.
+ // Note:- Though this ordering is done before begining with legalization,
+ // newly added node during legalization process have NodeId=-1 (NewNode)
+ // therefore before performing any check proper ordering of the node is
+ // required.
+ DAG.AssignTopologicalOrder();
+
+ // Direct load operands are folded in binary operations. But before folding
+ // verify if this folding is legal. Fold only if it is legal otherwise
+ // convert this direct load to a separate memory operation.
+ if(ISel->IsLegalToFold(Op.getOperand(1), Op.getNode(), Op.getNode()))
+ return false;
+ else
+ MemOp = 1;
+ }
}
return true;
}
diff --git a/lib/Target/PIC16/PIC16MemSelOpt.cpp b/lib/Target/PIC16/PIC16MemSelOpt.cpp
index cc71b04..ab81ed1 100644
--- a/lib/Target/PIC16/PIC16MemSelOpt.cpp
+++ b/lib/Target/PIC16/PIC16MemSelOpt.cpp
@@ -59,6 +59,7 @@ namespace {
const TargetInstrInfo *TII; // Machine instruction info.
MachineBasicBlock *MBB; // Current basic block
std::string CurBank;
+ int PageChanged;
};
char MemSelOpt::ID = 0;
@@ -93,10 +94,56 @@ bool MemSelOpt::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
// Let us assume that when entering a basic block now bank is selected.
// Ideally we should look at the predecessors for this information.
CurBank="";
+ PageChanged=0;
- for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) {
+ MachineBasicBlock::iterator I;
+ for (I = BB.begin(); I != BB.end(); ++I) {
Changed |= processInstruction(I);
+
+ // if the page has changed insert a page sel before
+ // any instruction that needs one
+ if (PageChanged == 1)
+ {
+ // Restore the page if it was changed, before leaving the basic block,
+ // because it may be required by the goto terminator or the fall thru
+ // basic blcok.
+ // If the terminator is return, we don't need to restore since there
+ // is no goto or fall thru basic block.
+ if ((I->getOpcode() == PIC16::sublw_3) || //macro has goto
+ (I->getOpcode() == PIC16::sublw_6) || //macro has goto
+ (I->getOpcode() == PIC16::addlwc) || //macro has goto
+ (TII->get(I->getOpcode()).isBranch()))
+ {
+ DebugLoc dl = I->getDebugLoc();
+ BuildMI(*MBB, I, dl, TII->get(PIC16::pagesel)).addExternalSymbol("$");
+ Changed = true;
+ PageChanged = 0;
+ }
+ }
}
+
+ // The basic block is over, but if we did not find any goto yet,
+ // we haven't restored the page.
+ // Restore the page if it was changed, before leaving the basic block,
+ // because it may be required by fall thru basic blcok.
+ // If the terminator is return, we don't need to restore since there
+ // is fall thru basic block.
+ if (PageChanged == 1) {
+ // save the end pointer before we move back to last insn.
+ MachineBasicBlock::iterator J = I;
+ I--;
+ const TargetInstrDesc &TID = TII->get(I->getOpcode());
+ if (! TID.isReturn())
+ {
+ DebugLoc dl = I->getDebugLoc();
+ BuildMI(*MBB, J, dl,
+ TII->get(PIC16::pagesel)).addExternalSymbol("$");
+ Changed = true;
+ PageChanged = 0;
+ }
+ }
+
+
return Changed;
}
@@ -112,42 +159,74 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
if (!(TID.isBranch() || TID.isCall() || TID.mayLoad() || TID.mayStore()))
return false;
+ // The first thing we should do is that record if banksel/pagesel are
+ // changed in an unknown way. This can happend via any type of call.
+ // We do it here first before scanning of MemOp / BBOp as the indirect
+ // call insns do not have any operands, but they still may change bank/page.
+ if (TID.isCall()) {
+ // Record that we have changed the page, so that we can restore it
+ // before basic block ends.
+ // We require to signal that a page anc bank change happened even for
+ // indirect calls.
+ PageChanged = 1;
+
+ // When a call is made, there may be banksel for variables in callee.
+ // Hence the banksel in caller needs to be reset.
+ CurBank = "";
+ }
+
// Scan for the memory address operand.
// FIXME: Should we use standard interfaces like memoperands_iterator,
// hasMemOperand() etc ?
int MemOpPos = -1;
+ int BBOpPos = -1;
for (unsigned i = 0; i < NumOperands; i++) {
MachineOperand Op = MI->getOperand(i);
if (Op.getType() == MachineOperand::MO_GlobalAddress ||
- Op.getType() == MachineOperand::MO_ExternalSymbol ||
- Op.getType() == MachineOperand::MO_MachineBasicBlock) {
+ Op.getType() == MachineOperand::MO_ExternalSymbol) {
// We found one mem operand. Next one may be BS.
MemOpPos = i;
- break;
+ }
+ if (Op.getType() == MachineOperand::MO_MachineBasicBlock) {
+ // We found one BB operand. Next one may be pagesel.
+ BBOpPos = i;
}
}
// If we did not find an insn accessing memory. Continue.
- if (MemOpPos == -1) return Changed;
+ if ((MemOpPos == -1) &&
+ (BBOpPos == -1))
+ return false;
+ assert ((BBOpPos != MemOpPos) && "operand can only be of one type");
- // Get the MemOp.
- MachineOperand &Op = MI->getOperand(MemOpPos);
// If this is a pagesel material, handle it first.
- if (MI->getOpcode() == PIC16::CALL ||
- MI->getOpcode() == PIC16::br_uncond) {
+ // CALL and br_ucond insns use MemOp (GA or ES) and not BBOp.
+ // Pagesel is required only for a direct call.
+ if ((MI->getOpcode() == PIC16::CALL)) {
+ // Get the BBOp.
+ MachineOperand &MemOp = MI->getOperand(MemOpPos);
DebugLoc dl = MI->getDebugLoc();
- BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).
- addOperand(Op);
- return true;
+ BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).addOperand(MemOp);
+
+ // CALL and br_ucond needs only pagesel. so we are done.
+ return true;
}
+ // Pagesel is handled. Now, add a Banksel if needed.
+ if (MemOpPos == -1) return Changed;
+ // Get the MemOp.
+ MachineOperand &Op = MI->getOperand(MemOpPos);
+
// Get the section name(NewBank) for MemOp.
// This assumes that the section names for globals are already set by
// AsmPrinter->doInitialization.
std::string NewBank = CurBank;
+ bool hasExternalLinkage = false;
if (Op.getType() == MachineOperand::MO_GlobalAddress &&
Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) {
+ if (Op.getGlobal()->hasExternalLinkage())
+ hasExternalLinkage= true;
NewBank = Op.getGlobal()->getSection();
} else if (Op.getType() == MachineOperand::MO_ExternalSymbol) {
// External Symbol is generated for temp data and arguments. They are
@@ -162,7 +241,7 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
// If the previous and new section names are same, we don't need to
// emit banksel.
- if (NewBank.compare(CurBank) != 0 ) {
+ if (NewBank.compare(CurBank) != 0 || hasExternalLinkage) {
DebugLoc dl = MI->getDebugLoc();
BuildMI(*MBB, MI, dl, TII->get(PIC16::banksel)).
addOperand(Op);
diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp
new file mode 100644
index 0000000..865da35
--- /dev/null
+++ b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp
@@ -0,0 +1,299 @@
+//===-- PIC16Cloner.cpp - PIC16 LLVM Cloner for shared functions -*- 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 code to clone all functions that are shared between
+// the main line code (ML) and interrupt line code (IL). It clones all such
+// shared functions and their automatic global vars by adding the .IL suffix.
+//
+// This pass is supposed to be run on the linked .bc module.
+// It traveses the module call graph twice. Once starting from the main function
+// and marking each reached function as "ML". Again, starting from the ISR
+// and cloning any reachable function that was marked as "ML". After cloning
+// the function, it remaps all the call sites in IL functions to call the
+// cloned functions.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "PIC16Cloner.h"
+#include "../PIC16ABINames.h"
+#include <vector>
+
+using namespace llvm;
+using std::vector;
+using std::string;
+using std::map;
+
+namespace llvm {
+ char PIC16Cloner::ID = 0;
+
+ ModulePass *createPIC16ClonerPass() { return new PIC16Cloner(); }
+}
+
+// We currently intend to run these passes in opt, which does not have any
+// diagnostic support. So use these functions for now. In future
+// we will probably write our own driver tool.
+//
+void PIC16Cloner::reportError(string ErrorString) {
+ errs() << "ERROR : " << ErrorString << "\n";
+ exit(1);
+}
+
+void PIC16Cloner::
+reportError (string ErrorString, vector<string> &Values) {
+ unsigned ValCount = Values.size();
+ string TargetString;
+ for (unsigned i=0; i<ValCount; ++i) {
+ TargetString = "%";
+ TargetString += ((char)i + '0');
+ ErrorString.replace(ErrorString.find(TargetString), TargetString.length(),
+ Values[i]);
+ }
+ errs() << "ERROR : " << ErrorString << "\n";
+ exit(1);
+}
+
+
+// Entry point
+//
+bool PIC16Cloner::runOnModule(Module &M) {
+ CallGraph &CG = getAnalysis<CallGraph>();
+
+ // Search for the "main" and "ISR" functions.
+ CallGraphNode *mainCGN = NULL, *isrCGN = NULL;
+ for (CallGraph::iterator it = CG.begin() ; it != CG.end(); it++)
+ {
+ // External calling node doesn't have any function associated with it.
+ if (! it->first)
+ continue;
+
+ if (it->first->getName().str() == "main") {
+ mainCGN = it->second;
+ }
+
+ if (PAN::isISR(it->first->getSection())) {
+ isrCGN = it->second;
+ }
+
+ // Don't search further if we've found both.
+ if (mainCGN && isrCGN)
+ break;
+ }
+
+ // We have nothing to do if any of the main or ISR is missing.
+ if (! mainCGN || ! isrCGN) return false;
+
+ // Time for some diagnostics.
+ // See if the main itself is interrupt function then report an error.
+ if (PAN::isISR(mainCGN->getFunction()->getSection())) {
+ reportError("Function 'main' can't be interrupt function");
+ }
+
+
+ // Mark all reachable functions from main as ML.
+ markCallGraph(mainCGN, "ML");
+
+ // And then all the functions reachable from ISR will be cloned.
+ cloneSharedFunctions(isrCGN);
+
+ return true;
+}
+
+// Mark all reachable functions from the given node, with the given mark.
+//
+void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) {
+ // Mark the top node first.
+ Function *thisF = CGN->getFunction();
+
+ thisF->setSection(StringMark);
+
+ // Mark all the called functions
+ for(CallGraphNode::iterator cgn_it = CGN->begin();
+ cgn_it != CGN->end(); ++cgn_it) {
+ Function *CalledF = cgn_it->second->getFunction();
+
+ // If calling an external function then CallGraphNode
+ // will not be associated with any function.
+ if (! CalledF)
+ continue;
+
+ // Issue diagnostic if interrupt function is being called.
+ if (PAN::isISR(CalledF->getSection())) {
+ vector<string> Values;
+ Values.push_back(CalledF->getName().str());
+ reportError("Interrupt function (%0) can't be called", Values);
+ }
+
+ // Has already been mark
+ if (CalledF->getSection().find(StringMark) != string::npos) {
+ // Should we do anything here?
+ } else {
+ // Mark now
+ CalledF->setSection(StringMark);
+ }
+
+ // Before going any further mark all the called function by current
+ // function.
+ markCallGraph(cgn_it->second ,StringMark);
+ } // end of loop of all called functions.
+}
+
+
+// For PIC16, automatic variables of a function are emitted as globals.
+// Clone the auto variables of a function and put them in ValueMap,
+// this ValueMap will be used while
+// Cloning the code of function itself.
+//
+void PIC16Cloner::CloneAutos(Function *F) {
+ // We'll need to update module's globals list as well. So keep a reference
+ // handy.
+ Module *M = F->getParent();
+ Module::GlobalListType &Globals = M->getGlobalList();
+
+ // Clear the leftovers in ValueMap by any previous cloning.
+ ValueMap.clear();
+
+ // Find the auto globls for this function and clone them, and put them
+ // in ValueMap.
+ std::string FnName = F->getName().str();
+ std::string VarName, ClonedVarName;
+ for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I) {
+ VarName = I->getName().str();
+ if (PAN::isLocalToFunc(FnName, VarName)) {
+ // Auto variable for current function found. Clone it.
+ GlobalVariable *GV = I;
+
+ const Type *InitTy = GV->getInitializer()->getType();
+ GlobalVariable *ClonedGV =
+ new GlobalVariable(InitTy, false, GV->getLinkage(),
+ GV->getInitializer());
+ ClonedGV->setName(PAN::getCloneVarName(FnName, VarName));
+ // Add these new globals to module's globals list.
+ Globals.push_back(ClonedGV);
+
+ // Update ValueMap.
+ ValueMap[GV] = ClonedGV;
+ }
+ }
+}
+
+
+// Clone all functions that are reachable from ISR and are already
+// marked as ML.
+//
+void PIC16Cloner::cloneSharedFunctions(CallGraphNode *CGN) {
+
+ // Check all the called functions from ISR.
+ for(CallGraphNode::iterator cgn_it = CGN->begin();
+ cgn_it != CGN->end(); ++cgn_it) {
+ Function *CalledF = cgn_it->second->getFunction();
+
+ // If calling an external function then CallGraphNode
+ // will not be associated with any function.
+ if (!CalledF)
+ continue;
+
+ // Issue diagnostic if interrupt function is being called.
+ if (PAN::isISR(CalledF->getSection())) {
+ vector<string> Values;
+ Values.push_back(CalledF->getName().str());
+ reportError("Interrupt function (%0) can't be called", Values);
+ }
+
+ if (CalledF->getSection().find("ML") != string::npos) {
+ // Function is alternatively marked. It should be a shared one.
+ // Create IL copy. Passing called function as first argument
+ // and the caller as the second argument.
+
+ // Before making IL copy, first ensure that this function has a
+ // body. If the function does have a body. It can't be cloned.
+ // Such a case may occur when the function has been declarated
+ // in the C source code but its body exists in assembly file.
+ if (!CalledF->isDeclaration()) {
+ Function *cf = cloneFunction(CalledF);
+ remapAllSites(CGN->getFunction(), CalledF, cf);
+ } else {
+ // It is called only from ISR. Still mark it as we need this info
+ // in code gen while calling intrinsics.Function is not marked.
+ CalledF->setSection("IL");
+ }
+ }
+ // Before going any further clone all the shared function reachaable
+ // by current function.
+ cloneSharedFunctions(cgn_it->second);
+ } // end of loop of all called functions.
+}
+
+// Clone the given function and return it.
+// Note: it uses the ValueMap member of the class, which is already populated
+// by cloneAutos by the time we reach here.
+// FIXME: Should we just pass ValueMap's ref as a parameter here? rather
+// than keeping the ValueMap as a member.
+Function *
+PIC16Cloner::cloneFunction(Function *OrgF) {
+ Function *ClonedF;
+
+ // See if we already cloned it. Return that.
+ cloned_map_iterator cm_it = ClonedFunctionMap.find(OrgF);
+ if(cm_it != ClonedFunctionMap.end()) {
+ ClonedF = cm_it->second;
+ return ClonedF;
+ }
+
+ // Clone does not exist.
+ // First clone the autos, and populate ValueMap.
+ CloneAutos(OrgF);
+
+ // Now create the clone.
+ ClonedF = CloneFunction(OrgF, ValueMap);
+
+ // The new function should be for interrupt line. Therefore should have
+ // the name suffixed with IL and section attribute marked with IL.
+ ClonedF->setName(PAN::getCloneFnName(OrgF->getName()));
+ ClonedF->setSection("IL");
+
+ // Add the newly created function to the module.
+ OrgF->getParent()->getFunctionList().push_back(ClonedF);
+
+ // Update the ClonedFunctionMap to record this cloning activity.
+ ClonedFunctionMap[OrgF] = ClonedF;
+
+ return ClonedF;
+}
+
+
+// Remap the call sites of shared functions, that are in IL.
+// Change the IL call site of a shared function to its clone.
+//
+void PIC16Cloner::
+remapAllSites(Function *Caller, Function *OrgF, Function *Clone) {
+ // First find the caller to update. If the caller itself is cloned
+ // then use the cloned caller. Otherwise use it.
+ cloned_map_iterator cm_it = ClonedFunctionMap.find(Caller);
+ if (cm_it != ClonedFunctionMap.end())
+ Caller = cm_it->second;
+
+ // For the lack of a better call site finding mechanism, iterate over
+ // all insns to find the uses of original fn.
+ for (Function::iterator BI = Caller->begin(); BI != Caller->end(); ++BI) {
+ BasicBlock &BB = *BI;
+ for (BasicBlock::iterator II = BB.begin(); II != BB.end(); ++II) {
+ if (II->getNumOperands() > 0 && II->getOperand(0) == OrgF)
+ II->setOperand(0, Clone);
+ }
+ }
+}
+
+
+
diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h
new file mode 100644
index 0000000..24c1152
--- /dev/null
+++ b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h
@@ -0,0 +1,83 @@
+//===-- PIC16Cloner.h - PIC16 LLVM Cloner for shared functions --*- 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 declaration of a cloner class clone all functions that
+// are shared between the main line code (ML) and interrupt line code (IL).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PIC16CLONER_H
+#define PIC16CLONER_H
+
+#include "llvm/ADT/DenseMap.h"
+
+using namespace llvm;
+using std::vector;
+using std::string;
+using std::map;
+
+namespace llvm {
+ // forward classes.
+ class Value;
+ class Function;
+ class Module;
+ class ModulePass;
+ class CallGraph;
+ class CallGraphNode;
+ class AnalysisUsage;
+
+ class PIC16Cloner : public ModulePass {
+ public:
+ static char ID; // Class identification
+ PIC16Cloner() : ModulePass(&ID) {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<CallGraph>();
+ }
+ virtual bool runOnModule(Module &M);
+
+ private: // Functions
+ // Mark reachable functions for the MainLine or InterruptLine.
+ void markCallGraph(CallGraphNode *CGN, string StringMark);
+
+ // Clone auto variables of function specified.
+ void CloneAutos(Function *F);
+
+ // Clone the body of a function.
+ Function *cloneFunction(Function *F);
+
+ // Clone all shared functions.
+ void cloneSharedFunctions(CallGraphNode *isrCGN);
+
+ // Remap all call sites to the shared function.
+ void remapAllSites(Function *Caller, Function *OrgF, Function *Clone);
+
+ // Error reporting for PIC16Pass
+ void reportError(string ErrorString, vector<string> &Values);
+ void reportError(string ErrorString);
+
+ private: //data
+ // Records if the interrupt function has already been found.
+ // If more than one interrupt function is found then an error
+ // should be thrown.
+ bool foundISR;
+
+ // This ValueMap maps the auto variables of the original functions with
+ // the corresponding cloned auto variable of the cloned function.
+ // This value map is passed during the function cloning so that all the
+ // uses of auto variables be updated properly.
+ DenseMap<const Value*, Value*> ValueMap;
+
+ // Map of a already cloned functions.
+ map<Function *, Function *> ClonedFunctionMap;
+ typedef map<Function *, Function *>::iterator cloned_map_iterator;
+ };
+} // End of anonymous namespace
+
+#endif
diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp
index 197c398..5ecb6aa 100644
--- a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp
+++ b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp
@@ -24,27 +24,27 @@
using namespace llvm;
namespace llvm {
- char PIC16FrameOverlay::ID = 0;
- ModulePass *createPIC16OverlayPass() { return new PIC16FrameOverlay(); }
+ char PIC16Overlay::ID = 0;
+ ModulePass *createPIC16OverlayPass() { return new PIC16Overlay(); }
}
-void PIC16FrameOverlay::getAnalysisUsage(AnalysisUsage &AU) const {
+void PIC16Overlay::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<CallGraph>();
}
-void PIC16FrameOverlay::DFSTraverse(CallGraphNode *CGN, unsigned Depth) {
+void PIC16Overlay::DFSTraverse(CallGraphNode *CGN, unsigned Depth) {
// Do not set any color for external calling node.
if (Depth != 0 && CGN->getFunction()) {
unsigned Color = getColor(CGN->getFunction());
// Handle indirectly called functions
- if (Color >= PIC16Overlay::StartIndirectCallColor ||
- Depth >= PIC16Overlay::StartIndirectCallColor) {
+ if (Color >= PIC16OVERLAY::StartIndirectCallColor ||
+ Depth >= PIC16OVERLAY::StartIndirectCallColor) {
// All functions called from an indirectly called function are given
// an unique color.
- if (Color < PIC16Overlay::StartIndirectCallColor &&
- Depth >= PIC16Overlay::StartIndirectCallColor)
+ if (Color < PIC16OVERLAY::StartIndirectCallColor &&
+ Depth >= PIC16OVERLAY::StartIndirectCallColor)
setColor(CGN->getFunction(), Depth);
for (unsigned int i = 0; i < CGN->size(); i++)
@@ -65,7 +65,7 @@ void PIC16FrameOverlay::DFSTraverse(CallGraphNode *CGN, unsigned Depth) {
DFSTraverse((*CGN)[i], Depth+1);
}
-unsigned PIC16FrameOverlay::ModifyDepthForInterrupt(CallGraphNode *CGN,
+unsigned PIC16Overlay::ModifyDepthForInterrupt(CallGraphNode *CGN,
unsigned Depth) {
Function *Fn = CGN->getFunction();
@@ -81,7 +81,7 @@ unsigned PIC16FrameOverlay::ModifyDepthForInterrupt(CallGraphNode *CGN,
return Depth;
}
-void PIC16FrameOverlay::setColor(Function *Fn, unsigned Color) {
+void PIC16Overlay::setColor(Function *Fn, unsigned Color) {
std::string Section = "";
if (Fn->hasSection())
Section = Fn->getSection();
@@ -119,7 +119,7 @@ void PIC16FrameOverlay::setColor(Function *Fn, unsigned Color) {
Fn->setSection(Section);
}
-unsigned PIC16FrameOverlay::getColor(Function *Fn) {
+unsigned PIC16Overlay::getColor(Function *Fn) {
int Color = 0;
if (!Fn->hasSection())
return 0;
@@ -150,7 +150,7 @@ unsigned PIC16FrameOverlay::getColor(Function *Fn) {
return Color;
}
-bool PIC16FrameOverlay::runOnModule(Module &M) {
+bool PIC16Overlay::runOnModule(Module &M) {
CallGraph &CG = getAnalysis<CallGraph>();
CallGraphNode *ECN = CG.getExternalCallingNode();
@@ -164,7 +164,7 @@ bool PIC16FrameOverlay::runOnModule(Module &M) {
return false;
}
-void PIC16FrameOverlay::MarkIndirectlyCalledFunctions(Module &M) {
+void PIC16Overlay::MarkIndirectlyCalledFunctions(Module &M) {
// If the use of a function is not a call instruction then this
// function might be called indirectly. In that case give it
// an unique color.
diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h
index d70c4e7..5a2551f 100644
--- a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h
+++ b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h
@@ -1,4 +1,4 @@
-//===-- PIC16FrameOverlay.h - Interface for PIC16 Frame Overlay -*- C++ -*-===//
+//===-- PIC16Overlay.h - Interface for PIC16 Frame Overlay -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,30 +14,35 @@
#ifndef PIC16FRAMEOVERLAY_H
#define PIC16FRAMEOVERLAY_H
-#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Pass.h"
-#include "llvm/CallGraphSCCPass.h"
using std::string;
using namespace llvm;
namespace llvm {
- namespace PIC16Overlay {
+ // Forward declarations.
+ class Function;
+ class Module;
+ class ModulePass;
+ class AnalysisUsage;
+ class CallGraphNode;
+ class CallGraph;
+
+ namespace PIC16OVERLAY {
enum OverlayConsts {
StartInterruptColor = 200,
StartIndirectCallColor = 300
};
}
- class PIC16FrameOverlay : public ModulePass {
+ class PIC16Overlay : public ModulePass {
std::string OverlayStr;
unsigned InterruptDepth;
unsigned IndirectCallColor;
public:
static char ID; // Class identification
- PIC16FrameOverlay() : ModulePass(&ID) {
+ PIC16Overlay() : ModulePass(&ID) {
OverlayStr = "Overlay=";
- InterruptDepth = PIC16Overlay::StartInterruptColor;
- IndirectCallColor = PIC16Overlay::StartIndirectCallColor;
+ InterruptDepth = PIC16OVERLAY::StartInterruptColor;
+ IndirectCallColor = PIC16OVERLAY::StartIndirectCallColor;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.cpp b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
index d7cfe02..b891c18 100644
--- a/lib/Target/PIC16/PIC16TargetObjectFile.cpp
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
@@ -315,8 +315,12 @@ PIC16TargetObjectFile::allocateSHARED(const GlobalVariable *GV,
// Interface used by AsmPrinter to get a code section for a function.
const PIC16Section *
-PIC16TargetObjectFile::SectionForCode(const std::string &FnName) const {
+PIC16TargetObjectFile::SectionForCode(const std::string &FnName,
+ bool isISR) const {
const std::string &sec_name = PAN::getCodeSectionName(FnName);
+ // If it is ISR, its code section starts at a specific address.
+ if (isISR)
+ return getPIC16Section(sec_name, CODE, PAN::getISRAddr());
return getPIC16Section(sec_name, CODE);
}
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.h b/lib/Target/PIC16/PIC16TargetObjectFile.h
index 0b0ad43..cf8bf84 100644
--- a/lib/Target/PIC16/PIC16TargetObjectFile.h
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.h
@@ -137,7 +137,8 @@ namespace llvm {
/// Return a code section for a function.
- const PIC16Section *SectionForCode (const std::string &FnName) const;
+ const PIC16Section *SectionForCode (const std::string &FnName,
+ bool isISR) const;
/// Return a frame section for a function.
const PIC16Section *SectionForFrame (const std::string &FnName) const;
diff --git a/lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp b/lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp
index 46cc819..f1bdb12 100644
--- a/lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp
+++ b/lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp
@@ -15,7 +15,8 @@ using namespace llvm;
Target llvm::ThePIC16Target, llvm::TheCooperTarget;
extern "C" void LLVMInitializePIC16TargetInfo() {
- RegisterTarget<> X(ThePIC16Target, "pic16", "PIC16 14-bit [experimental]");
+ RegisterTarget<Triple::pic16> X(ThePIC16Target, "pic16",
+ "PIC16 14-bit [experimental]");
RegisterTarget<> Y(TheCooperTarget, "cooper", "PIC16 Cooper [experimental]");
}
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index afc90b1..ac901d0 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -31,13 +31,13 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.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"
diff --git a/lib/Target/PowerPC/PPCCallingConv.td b/lib/Target/PowerPC/PPCCallingConv.td
index c7ce171..155fba2 100644
--- a/lib/Target/PowerPC/PPCCallingConv.td
+++ b/lib/Target/PowerPC/PPCCallingConv.td
@@ -66,28 +66,13 @@ def CC_PPC : CallingConv<[
// PowerPC System V Release 4 ABI
//===----------------------------------------------------------------------===//
-// _Complex arguments are never split, thus their two scalars are either
-// passed both in argument registers or both on the stack. Also _Complex
-// arguments are always passed in general purpose registers, never in
-// Floating-point registers or vector registers. Arguments which should go
-// on the stack are marked with the inreg parameter attribute.
-// Giving inreg this target-dependent (and counter-intuitive) meaning
-// simplifies things, because functions calls are not always coming from the
-// frontend but are also created implicitly e.g. for libcalls. If inreg would
-// actually mean that the argument is passed in a register, then all places
-// which create function calls/function definitions implicitly would need to
-// be aware of this fact and would need to mark arguments accordingly. With
-// inreg meaning that the argument is passed on the stack, this is not an
-// issue, except for calls which involve _Complex types.
-
def CC_PPC_SVR4_Common : CallingConv<[
// The ABI requires i64 to be passed in two adjacent registers with the first
// register having an odd register number.
CCIfType<[i32], CCIfSplit<CCCustom<"CC_PPC_SVR4_Custom_AlignArgRegs">>>,
// The first 8 integer arguments are passed in integer registers.
- CCIfType<[i32], CCIf<"!ArgFlags.isInReg()",
- CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>>,
+ CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>,
// Make sure the i64 words from a long double are either both passed in
// registers or both passed on the stack.
diff --git a/lib/Target/PowerPC/PPCHazardRecognizers.cpp b/lib/Target/PowerPC/PPCHazardRecognizers.cpp
index 3a15f7e..66dfd4b 100644
--- a/lib/Target/PowerPC/PPCHazardRecognizers.cpp
+++ b/lib/Target/PowerPC/PPCHazardRecognizers.cpp
@@ -257,7 +257,7 @@ void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
case PPC::STWX: case PPC::STWX8:
case PPC::STWUX:
case PPC::STW: case PPC::STW8:
- case PPC::STWU: case PPC::STWU8:
+ case PPC::STWU:
case PPC::STVEWX:
case PPC::STFIWX:
case PPC::STWBRX:
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 004997f..9d79c0d 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -156,10 +156,6 @@ namespace {
SDValue BuildSDIVSequence(SDNode *N);
SDValue BuildUDIVSequence(SDNode *N);
- /// InstructionSelect - This callback is invoked by
- /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
- virtual void InstructionSelect();
-
void InsertVRSaveCode(MachineFunction &MF);
virtual const char *getPassName() const {
@@ -184,14 +180,6 @@ private:
};
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void PPCDAGToDAGISel::InstructionSelect() {
- // Select target instructions for the DAG.
- SelectRoot(*CurDAG);
- CurDAG->RemoveDeadNodes();
-}
-
/// InsertVRSaveCode - Once the entire function has been instruction selected,
/// all virtual registers are created and all machine instructions are built,
/// check to see if we need to save/restore VRSAVE. If so, do it.
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index a11d624..3d81afa 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -25,13 +25,13 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -1243,7 +1243,8 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
// If the global is weak or external, we have to go through the lazy
// resolution stub.
- return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Lo, NULL, 0);
+ return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Lo, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
@@ -1333,7 +1334,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) {
false, false, false, false, 0, CallingConv::C, false,
/*isReturnValueUsed=*/true,
DAG.getExternalSymbol("__trampoline_setup", PtrVT),
- Args, DAG, dl, DAG.GetOrdering(Chain.getNode()));
+ Args, DAG, dl);
SDValue Ops[] =
{ CallResult.first, CallResult.second };
@@ -1355,7 +1356,8 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG,
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
// For the 32-bit SVR4 ABI we follow the layout of the va_list struct.
@@ -1405,25 +1407,29 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG,
// Store first byte : number of int regs
SDValue firstStore = DAG.getTruncStore(Op.getOperand(0), dl, ArgGPR,
- Op.getOperand(1), SV, 0, MVT::i8);
+ Op.getOperand(1), SV, 0, MVT::i8,
+ false, false, 0);
uint64_t nextOffset = FPROffset;
SDValue nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, Op.getOperand(1),
ConstFPROffset);
// Store second byte : number of float regs
SDValue secondStore =
- DAG.getTruncStore(firstStore, dl, ArgFPR, nextPtr, SV, nextOffset, MVT::i8);
+ DAG.getTruncStore(firstStore, dl, ArgFPR, nextPtr, SV, nextOffset, MVT::i8,
+ false, false, 0);
nextOffset += StackOffset;
nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
// Store second word : arguments given on stack
SDValue thirdStore =
- DAG.getStore(secondStore, dl, StackOffsetFI, nextPtr, SV, nextOffset);
+ DAG.getStore(secondStore, dl, StackOffsetFI, nextPtr, SV, nextOffset,
+ false, false, 0);
nextOffset += FrameOffset;
nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
// Store third word : arguments given in registers
- return DAG.getStore(thirdStore, dl, FR, nextPtr, SV, nextOffset);
+ return DAG.getStore(thirdStore, dl, FR, nextPtr, SV, nextOffset,
+ false, false, 0);
}
@@ -1628,7 +1634,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
// Create load nodes to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
- InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -1700,7 +1707,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned GPRIndex = 0;
for (; GPRIndex != VarArgsNumGPR; ++GPRIndex) {
SDValue Val = DAG.getRegister(GPArgRegs[GPRIndex], PtrVT);
- SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by four for the next argument to store
SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
@@ -1714,7 +1722,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned VReg = MF.addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by four for the next argument to store
SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
@@ -1729,7 +1738,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned FPRIndex = 0;
for (FPRIndex = 0; FPRIndex != VarArgsNumFPR; ++FPRIndex) {
SDValue Val = DAG.getRegister(FPArgRegs[FPRIndex], MVT::f64);
- SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by eight for the next argument to store
SDValue PtrOff = DAG.getConstant(EVT(MVT::f64).getSizeInBits()/8,
@@ -1741,7 +1751,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by eight for the next argument to store
SDValue PtrOff = DAG.getConstant(EVT(MVT::f64).getSizeInBits()/8,
@@ -1903,7 +1914,9 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
SDValue Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN,
- NULL, 0, ObjSize==1 ? MVT::i8 : MVT::i16 );
+ NULL, 0,
+ ObjSize==1 ? MVT::i8 : MVT::i16,
+ false, false, 0);
MemOps.push_back(Store);
++GPR_idx;
}
@@ -1921,7 +1934,8 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
int FI = MFI->CreateFixedObject(PtrByteSize, ArgOffset, true, false);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
++GPR_idx;
ArgOffset += PtrByteSize;
@@ -2045,7 +2059,8 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
CurArgOffset + (ArgSize - ObjSize),
isImmutable, false);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
- ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0);
+ ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0,
+ false, false, 0);
}
InVals.push_back(ArgVal);
@@ -2091,7 +2106,8 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by four for the next argument to store
SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
@@ -2271,7 +2287,7 @@ StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG,
// Store relative to framepointer.
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, FIN,
PseudoSourceValue::getFixedStack(FI),
- 0));
+ 0, false, false, 0));
}
}
@@ -2297,7 +2313,8 @@ static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG,
EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
SDValue NewRetAddrFrIdx = DAG.getFrameIndex(NewRetAddr, VT);
Chain = DAG.getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
- PseudoSourceValue::getFixedStack(NewRetAddr), 0);
+ PseudoSourceValue::getFixedStack(NewRetAddr), 0,
+ false, false, 0);
// When using the 32/64-bit SVR4 ABI there is no need to move the FP stack
// slot as the FP is never overwritten.
@@ -2308,7 +2325,8 @@ static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG,
true, false);
SDValue NewFramePtrIdx = DAG.getFrameIndex(NewFPIdx, VT);
Chain = DAG.getStore(Chain, dl, OldFP, NewFramePtrIdx,
- PseudoSourceValue::getFixedStack(NewFPIdx), 0);
+ PseudoSourceValue::getFixedStack(NewFPIdx), 0,
+ false, false, 0);
}
}
return Chain;
@@ -2346,14 +2364,16 @@ SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(SelectionDAG & DAG,
// Load the LR and FP stack slot for later adjusting.
EVT VT = PPCSubTarget.isPPC64() ? MVT::i64 : MVT::i32;
LROpOut = getReturnAddrFrameIndex(DAG);
- LROpOut = DAG.getLoad(VT, dl, Chain, LROpOut, NULL, 0);
+ LROpOut = DAG.getLoad(VT, dl, Chain, LROpOut, NULL, 0,
+ false, false, 0);
Chain = SDValue(LROpOut.getNode(), 1);
// When using the 32/64-bit SVR4 ABI there is no need to load the FP stack
// slot as the FP is never overwritten.
if (isDarwinABI) {
FPOpOut = getFramePointerFrameIndex(DAG);
- FPOpOut = DAG.getLoad(VT, dl, Chain, FPOpOut, NULL, 0);
+ FPOpOut = DAG.getLoad(VT, dl, Chain, FPOpOut, NULL, 0,
+ false, false, 0);
Chain = SDValue(FPOpOut.getNode(), 1);
}
}
@@ -2395,7 +2415,8 @@ LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain,
PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
DAG.getConstant(ArgOffset, PtrVT));
}
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
// Calculate and remember argument location.
} else CalculateTailCallArgDest(DAG, MF, isPPC64, Arg, SPDiff, ArgOffset,
TailCallArguments);
@@ -2862,7 +2883,8 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee,
PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff);
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), LocMemOffset));
+ PseudoSourceValue::getStack(), LocMemOffset,
+ false, false, 0));
} else {
// Calculate and remember argument location.
CalculateTailCallArgDest(DAG, MF, false, Arg, SPDiff, LocMemOffset,
@@ -3024,7 +3046,7 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
EVT VT = (Size==1) ? MVT::i8 : MVT::i16;
if (GPR_idx != NumGPRs) {
SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, PtrVT, Chain, Arg,
- NULL, 0, VT);
+ NULL, 0, VT, false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
@@ -3061,7 +3083,8 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
SDValue Const = DAG.getConstant(j, PtrOff.getValueType());
SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, Arg, Const);
if (GPR_idx != NumGPRs) {
- SDValue Load = DAG.getLoad(PtrVT, dl, Chain, AddArg, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Chain, AddArg, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
ArgOffset += PtrByteSize;
@@ -3092,19 +3115,22 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg));
if (isVarArg) {
- SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Store);
// Float varargs are always shadowed in available integer registers
if (GPR_idx != NumGPRs) {
- SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
}
if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64){
SDValue ConstFour = DAG.getConstant(4, PtrOff.getValueType());
PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, ConstFour);
- SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
}
@@ -3147,10 +3173,12 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
// entirely in R registers. Maybe later.
PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
DAG.getConstant(ArgOffset, PtrVT));
- SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Store);
if (VR_idx != NumVRs) {
- SDValue Load = DAG.getLoad(MVT::v4f32, dl, Store, PtrOff, NULL, 0);
+ SDValue Load = DAG.getLoad(MVT::v4f32, dl, Store, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(VR[VR_idx++], Load));
}
@@ -3160,7 +3188,8 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
break;
SDValue Ix = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff,
DAG.getConstant(i, PtrVT));
- SDValue Load = DAG.getLoad(PtrVT, dl, Store, Ix, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Store, Ix, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
}
@@ -3225,7 +3254,8 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
// TOC save area offset.
SDValue PtrOff = DAG.getIntPtrConstant(40);
SDValue AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
- Chain = DAG.getStore(Val.getValue(1), dl, Val, AddPtr, NULL, 0);
+ Chain = DAG.getStore(Val.getValue(1), dl, Val, AddPtr, NULL, 0,
+ false, false, 0);
}
// Build a sequence of copy-to-reg nodes chained together with token chain
@@ -3300,13 +3330,15 @@ SDValue PPCTargetLowering::LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG,
SDValue SaveSP = Op.getOperand(1);
// Load the old link SP.
- SDValue LoadLinkSP = DAG.getLoad(PtrVT, dl, Chain, StackPtr, NULL, 0);
+ SDValue LoadLinkSP = DAG.getLoad(PtrVT, dl, Chain, StackPtr, NULL, 0,
+ false, false, 0);
// Restore the stack pointer.
Chain = DAG.getCopyToReg(LoadLinkSP.getValue(1), dl, SP, SaveSP);
// Store the old link SP.
- return DAG.getStore(Chain, dl, LoadLinkSP, StackPtr, NULL, 0);
+ return DAG.getStore(Chain, dl, LoadLinkSP, StackPtr, NULL, 0,
+ false, false, 0);
}
@@ -3483,14 +3515,16 @@ SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
SDValue FIPtr = DAG.CreateStackTemporary(MVT::f64);
// Emit a store to the stack slot.
- SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr, NULL, 0);
+ SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr, NULL, 0,
+ false, false, 0);
// Result is a load from the stack slot. If loading 4 bytes, make sure to
// add in a bias.
if (Op.getValueType() == MVT::i32)
FIPtr = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr,
DAG.getConstant(4, FIPtr.getValueType()));
- return DAG.getLoad(Op.getValueType(), dl, Chain, FIPtr, NULL, 0);
+ return DAG.getLoad(Op.getValueType(), dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
@@ -3533,7 +3567,7 @@ SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
DAG.getMemIntrinsicNode(PPCISD::STD_32, dl, DAG.getVTList(MVT::Other),
Ops, 4, MVT::i64, MMO);
// Load the value as a double.
- SDValue Ld = DAG.getLoad(MVT::f64, dl, Store, FIdx, NULL, 0);
+ SDValue Ld = DAG.getLoad(MVT::f64, dl, Store, FIdx, NULL, 0, false, false, 0);
// FCFID it and return it.
SDValue FP = DAG.getNode(PPCISD::FCFID, dl, MVT::f64, Ld);
@@ -3578,12 +3612,13 @@ SDValue PPCTargetLowering::LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) {
int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8, false);
SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Chain,
- StackSlot, NULL, 0);
+ StackSlot, NULL, 0, false, false, 0);
// Load FP Control Word from low 32 bits of stack slot.
SDValue Four = DAG.getConstant(4, PtrVT);
SDValue Addr = DAG.getNode(ISD::ADD, dl, PtrVT, StackSlot, Four);
- SDValue CWD = DAG.getLoad(MVT::i32, dl, Store, Addr, NULL, 0);
+ SDValue CWD = DAG.getLoad(MVT::i32, dl, Store, Addr, NULL, 0,
+ false, false, 0);
// Transform as necessary
SDValue CWD1 =
@@ -4249,9 +4284,11 @@ SDValue PPCTargetLowering::LowerSCALAR_TO_VECTOR(SDValue Op,
// Store the input value into Value#0 of the stack slot.
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
- Op.getOperand(0), FIdx, NULL, 0);
+ Op.getOperand(0), FIdx, NULL, 0,
+ false, false, 0);
// Load it out.
- return DAG.getLoad(Op.getValueType(), dl, Store, FIdx, NULL, 0);
+ return DAG.getLoad(Op.getValueType(), dl, Store, FIdx, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) {
@@ -5460,7 +5497,8 @@ SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
// to the stack.
FuncInfo->setLRStoreRequired();
return DAG.getLoad(getPointerTy(), dl,
- DAG.getEntryNode(), RetAddrFI, NULL, 0);
+ DAG.getEntryNode(), RetAddrFI, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td
index 219efb9..a0781b9 100644
--- a/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -366,7 +366,7 @@ def ADDE8 : XOForm_1<31, 138, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB),
[(set G8RC:$rT, (adde G8RC:$rA, G8RC:$rB))]>;
def ADDME8 : XOForm_3<31, 234, 0, (outs G8RC:$rT), (ins G8RC:$rA),
"addme $rT, $rA", IntGeneral,
- [(set G8RC:$rT, (adde G8RC:$rA, immAllOnes))]>;
+ [(set G8RC:$rT, (adde G8RC:$rA, -1))]>;
def ADDZE8 : XOForm_3<31, 202, 0, (outs G8RC:$rT), (ins G8RC:$rA),
"addze $rT, $rA", IntGeneral,
[(set G8RC:$rT, (adde G8RC:$rA, 0))]>;
@@ -375,7 +375,7 @@ def SUBFE8 : XOForm_1<31, 136, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB),
[(set G8RC:$rT, (sube G8RC:$rB, G8RC:$rA))]>;
def SUBFME8 : XOForm_3<31, 232, 0, (outs G8RC:$rT), (ins G8RC:$rA),
"subfme $rT, $rA", IntGeneral,
- [(set G8RC:$rT, (sube immAllOnes, G8RC:$rA))]>;
+ [(set G8RC:$rT, (sube -1, G8RC:$rA))]>;
def SUBFZE8 : XOForm_3<31, 200, 0, (outs G8RC:$rT), (ins G8RC:$rA),
"subfze $rT, $rA", IntGeneral,
[(set G8RC:$rT, (sube 0, G8RC:$rA))]>;
@@ -635,13 +635,6 @@ def STHU8 : DForm_1<45, (outs ptr_rc:$ea_res), (ins G8RC:$rS,
(pre_truncsti16 G8RC:$rS, ptr_rc:$ptrreg,
iaddroff:$ptroff))]>,
RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
-def STWU8 : DForm_1<37, (outs ptr_rc:$ea_res), (ins G8RC:$rS,
- symbolLo:$ptroff, ptr_rc:$ptrreg),
- "stwu $rS, $ptroff($ptrreg)", LdStGeneral,
- [(set ptr_rc:$ea_res, (pre_store G8RC:$rS, ptr_rc:$ptrreg,
- iaddroff:$ptroff))]>,
- RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
-
def STDU : DSForm_1<62, 1, (outs ptr_rc:$ea_res), (ins G8RC:$rS,
s16immX4:$ptroff, ptr_rc:$ptrreg),
diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp
index af7d812..9895bea 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -19,6 +19,7 @@
#include "PPCTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -73,8 +74,7 @@ bool PPCInstrInfo::isMoveInstr(const MachineInstr& MI,
destReg = MI.getOperand(0).getReg();
return true;
}
- } else if (oc == PPC::FMRS || oc == PPC::FMRD ||
- oc == PPC::FMRSD) { // fmr r1, r2
+ } else if (oc == PPC::FMR || oc == PPC::FMRSD) { // fmr r1, r2
assert(MI.getNumOperands() >= 2 &&
MI.getOperand(0).isReg() &&
MI.getOperand(1).isReg() &&
@@ -344,10 +344,9 @@ bool PPCInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
BuildMI(MBB, MI, DL, get(PPC::OR), DestReg).addReg(SrcReg).addReg(SrcReg);
} else if (DestRC == PPC::G8RCRegisterClass) {
BuildMI(MBB, MI, DL, get(PPC::OR8), DestReg).addReg(SrcReg).addReg(SrcReg);
- } else if (DestRC == PPC::F4RCRegisterClass) {
- BuildMI(MBB, MI, DL, get(PPC::FMRS), DestReg).addReg(SrcReg);
- } else if (DestRC == PPC::F8RCRegisterClass) {
- BuildMI(MBB, MI, DL, get(PPC::FMRD), DestReg).addReg(SrcReg);
+ } else if (DestRC == PPC::F4RCRegisterClass ||
+ DestRC == PPC::F8RCRegisterClass) {
+ BuildMI(MBB, MI, DL, get(PPC::FMR), DestReg).addReg(SrcReg);
} else if (DestRC == PPC::CRRCRegisterClass) {
BuildMI(MBB, MI, DL, get(PPC::MCRF), DestReg).addReg(SrcReg);
} else if (DestRC == PPC::VRRCRegisterClass) {
@@ -421,22 +420,30 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF,
FrameIdx));
return true;
} else {
- // FIXME: We use R0 here, because it isn't available for RA. We need to
- // store the CR in the low 4-bits of the saved value. First, issue a MFCR
- // to save all of the CRBits.
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCR), PPC::R0));
+ // FIXME: We need a scatch reg here. The trouble with using R0 is that
+ // it's possible for the stack frame to be so big the save location is
+ // out of range of immediate offsets, necessitating another register.
+ // We hack this on Darwin by reserving R2. It's probably broken on Linux
+ // at the moment.
+
+ // We need to store the CR in the low 4-bits of the saved value. First,
+ // issue a MFCR to save all of the CRBits.
+ unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
+ PPC::R2 : PPC::R0;
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCR), ScratchReg));
// If the saved register wasn't CR0, shift the bits left so that they are
// in CR0's slot.
if (SrcReg != PPC::CR0) {
unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(SrcReg)*4;
- // rlwinm r0, r0, ShiftBits, 0, 31.
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), PPC::R0)
- .addReg(PPC::R0).addImm(ShiftBits).addImm(0).addImm(31));
+ // rlwinm scratch, scratch, ShiftBits, 0, 31.
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg)
+ .addReg(ScratchReg).addImm(ShiftBits)
+ .addImm(0).addImm(31));
}
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW))
- .addReg(PPC::R0,
+ .addReg(ScratchReg,
getKillRegState(isKill)),
FrameIdx));
}
@@ -540,20 +547,28 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg),
FrameIdx));
} else if (RC == PPC::CRRCRegisterClass) {
- // FIXME: We use R0 here, because it isn't available for RA.
- NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), PPC::R0),
- FrameIdx));
+ // FIXME: We need a scatch reg here. The trouble with using R0 is that
+ // it's possible for the stack frame to be so big the save location is
+ // out of range of immediate offsets, necessitating another register.
+ // We hack this on Darwin by reserving R2. It's probably broken on Linux
+ // at the moment.
+ unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
+ PPC::R2 : PPC::R0;
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ),
+ ScratchReg), FrameIdx));
// If the reloaded register isn't CR0, shift the bits right so that they are
// in the right CR's slot.
if (DestReg != PPC::CR0) {
unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(DestReg)*4;
// rlwinm r11, r11, 32-ShiftBits, 0, 31.
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), PPC::R0)
- .addReg(PPC::R0).addImm(32-ShiftBits).addImm(0).addImm(31));
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg)
+ .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0)
+ .addImm(31));
}
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg).addReg(PPC::R0));
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg)
+ .addReg(ScratchReg));
} else if (RC == PPC::CRBITRCRegisterClass) {
unsigned Reg = 0;
@@ -672,33 +687,21 @@ MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
getUndefRegState(isUndef)),
FrameIndex);
}
- } else if (Opc == PPC::FMRD) {
- if (OpNum == 0) { // move -> store
- unsigned InReg = MI->getOperand(1).getReg();
- bool isKill = MI->getOperand(1).isKill();
- bool isUndef = MI->getOperand(1).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFD))
- .addReg(InReg,
- getKillRegState(isKill) |
- getUndefRegState(isUndef)),
- FrameIndex);
- } else { // move -> load
- unsigned OutReg = MI->getOperand(0).getReg();
- bool isDead = MI->getOperand(0).isDead();
- bool isUndef = MI->getOperand(0).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFD))
- .addReg(OutReg,
- RegState::Define |
- getDeadRegState(isDead) |
- getUndefRegState(isUndef)),
- FrameIndex);
- }
- } else if (Opc == PPC::FMRS) {
+ } else if (Opc == PPC::FMR || Opc == PPC::FMRSD) {
+ // The register may be F4RC or F8RC, and that determines the memory op.
+ unsigned OrigReg = MI->getOperand(OpNum).getReg();
+ // We cannot tell the register class from a physreg alone.
+ if (TargetRegisterInfo::isPhysicalRegister(OrigReg))
+ return NULL;
+ const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(OrigReg);
+ const bool is64 = RC == PPC::F8RCRegisterClass;
+
if (OpNum == 0) { // move -> store
unsigned InReg = MI->getOperand(1).getReg();
bool isKill = MI->getOperand(1).isKill();
bool isUndef = MI->getOperand(1).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFS))
+ NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(),
+ get(is64 ? PPC::STFD : PPC::STFS))
.addReg(InReg,
getKillRegState(isKill) |
getUndefRegState(isUndef)),
@@ -707,7 +710,8 @@ MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
unsigned OutReg = MI->getOperand(0).getReg();
bool isDead = MI->getOperand(0).isDead();
bool isUndef = MI->getOperand(0).isUndef();
- NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFS))
+ NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(),
+ get(is64 ? PPC::LFD : PPC::LFS))
.addReg(OutReg,
RegState::Define |
getDeadRegState(isDead) |
@@ -733,7 +737,7 @@ bool PPCInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
else if ((Opc == PPC::OR8 &&
MI->getOperand(1).getReg() == MI->getOperand(2).getReg()))
return true;
- else if (Opc == PPC::FMRD || Opc == PPC::FMRS)
+ else if (Opc == PPC::FMR || Opc == PPC::FMRSD)
return true;
return false;
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 842f8ee..845cd8f 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -1019,20 +1019,16 @@ let Uses = [RM] in {
}
}
-/// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending.
+/// FMR is split into 2 versions, one for 4/8 byte FP, and one for extending.
///
/// Note that these are defined as pseudo-ops on the PPC970 because they are
/// often coalesced away and we don't want the dispatch group builder to think
/// that they will fill slots (which could cause the load of a LSU reject to
/// sneak into a d-group with a store).
-def FMRS : XForm_26<63, 72, (outs F4RC:$frD), (ins F4RC:$frB),
- "fmr $frD, $frB", FPGeneral,
- []>, // (set F4RC:$frD, F4RC:$frB)
- PPC970_Unit_Pseudo;
-def FMRD : XForm_26<63, 72, (outs F8RC:$frD), (ins F8RC:$frB),
- "fmr $frD, $frB", FPGeneral,
- []>, // (set F8RC:$frD, F8RC:$frB)
- PPC970_Unit_Pseudo;
+def FMR : XForm_26<63, 72, (outs F4RC:$frD), (ins F4RC:$frB),
+ "fmr $frD, $frB", FPGeneral,
+ []>, // (set F4RC:$frD, F4RC:$frB)
+ PPC970_Unit_Pseudo;
def FMRSD : XForm_26<63, 72, (outs F8RC:$frD), (ins F4RC:$frB),
"fmr $frD, $frB", FPGeneral,
[(set F8RC:$frD, (fextend F4RC:$frB))]>,
@@ -1215,7 +1211,7 @@ def ADDE : XOForm_1<31, 138, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB),
[(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>;
def ADDME : XOForm_3<31, 234, 0, (outs GPRC:$rT), (ins GPRC:$rA),
"addme $rT, $rA", IntGeneral,
- [(set GPRC:$rT, (adde GPRC:$rA, immAllOnes))]>;
+ [(set GPRC:$rT, (adde GPRC:$rA, -1))]>;
def ADDZE : XOForm_3<31, 202, 0, (outs GPRC:$rT), (ins GPRC:$rA),
"addze $rT, $rA", IntGeneral,
[(set GPRC:$rT, (adde GPRC:$rA, 0))]>;
@@ -1224,7 +1220,7 @@ def SUBFE : XOForm_1<31, 136, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB),
[(set GPRC:$rT, (sube GPRC:$rB, GPRC:$rA))]>;
def SUBFME : XOForm_3<31, 232, 0, (outs GPRC:$rT), (ins GPRC:$rA),
"subfme $rT, $rA", IntGeneral,
- [(set GPRC:$rT, (sube immAllOnes, GPRC:$rA))]>;
+ [(set GPRC:$rT, (sube -1, GPRC:$rA))]>;
def SUBFZE : XOForm_3<31, 200, 0, (outs GPRC:$rT), (ins GPRC:$rA),
"subfze $rT, $rA", IntGeneral,
[(set GPRC:$rT, (sube 0, GPRC:$rA))]>;
@@ -1480,11 +1476,11 @@ def : Pat<(extloadf32 xaddr:$src),
(FMRSD (LFSX xaddr:$src))>;
// Memory barriers
-def : Pat<(membarrier (i32 imm:$ll),
- (i32 imm:$ls),
- (i32 imm:$sl),
- (i32 imm:$ss),
- (i32 imm:$device)),
+def : Pat<(membarrier (i32 imm /*ll*/),
+ (i32 imm /*ls*/),
+ (i32 imm /*sl*/),
+ (i32 imm /*ss*/),
+ (i32 imm /*device*/)),
(SYNC)>;
include "PPCInstrAltivec.td"
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 20e77e7..0b509ac 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -427,6 +427,12 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(PPC::R2); // System-reserved register
Reserved.set(PPC::R13); // Small Data Area pointer register
}
+ // Reserve R2 on Darwin to hack around the problem of save/restore of CR
+ // when the stack frame is too big to address directly; we need two regs.
+ // This is a hack.
+ if (Subtarget.isDarwinABI()) {
+ Reserved.set(PPC::R2);
+ }
// On PPC64, r13 is the thread pointer. Never allocate this register.
// Note that this is over conservative, as it also prevents allocation of R31
@@ -447,6 +453,12 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
if (Subtarget.isSVR4ABI()) {
Reserved.set(PPC::X2);
}
+ // Reserve R2 on Darwin to hack around the problem of save/restore of CR
+ // when the stack frame is too big to address directly; we need two regs.
+ // This is a hack.
+ if (Subtarget.isDarwinABI()) {
+ Reserved.set(PPC::X2);
+ }
}
if (needsFP(MF))
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.td b/lib/Target/PowerPC/PPCRegisterInfo.td
index 049e893..1cb7340 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -287,10 +287,8 @@ def GPRC : RegisterClass<"PPC", [i32], 32,
GPRCClass::allocation_order_begin(const MachineFunction &MF) const {
// 32-bit SVR4 ABI: r2 is reserved for the OS.
// 64-bit SVR4 ABI: r2 is reserved for the TOC pointer.
- if (!MF.getTarget().getSubtarget<PPCSubtarget>().isDarwin())
- return begin()+1;
-
- return begin();
+ // Darwin: R2 is reserved for CR save/restore sequence.
+ return begin()+1;
}
GPRCClass::iterator
GPRCClass::allocation_order_end(const MachineFunction &MF) const {
@@ -325,10 +323,8 @@ def G8RC : RegisterClass<"PPC", [i64], 64,
G8RCClass::iterator
G8RCClass::allocation_order_begin(const MachineFunction &MF) const {
// 64-bit SVR4 ABI: r2 is reserved for the TOC pointer.
- if (!MF.getTarget().getSubtarget<PPCSubtarget>().isDarwin())
- return begin()+1;
-
- return begin();
+ // Darwin: r2 is reserved for CR save/restore sequence.
+ return begin()+1;
}
G8RCClass::iterator
G8RCClass::allocation_order_end(const MachineFunction &MF) const {
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index 22eecd4..cac6962 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -115,32 +115,3 @@ bool PPCTargetMachine::addCodeEmitter(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 a654435..ac9ae2b 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -57,18 +57,6 @@ public:
return InstrItins;
}
- /// 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/README.txt b/lib/Target/PowerPC/README.txt
index 8f265cf..3465779 100644
--- a/lib/Target/PowerPC/README.txt
+++ b/lib/Target/PowerPC/README.txt
@@ -889,9 +889,26 @@ entry:
; recognize a more elaborate tree than a simple SETxx.
define double @test_FNEG_sel(double %A, double %B, double %C) {
- %D = sub double -0.000000e+00, %A ; <double> [#uses=1]
+ %D = fsub double -0.000000e+00, %A ; <double> [#uses=1]
%Cond = fcmp ugt double %D, -0.000000e+00 ; <i1> [#uses=1]
%E = select i1 %Cond, double %B, double %C ; <double> [#uses=1]
ret double %E
}
+//===----------------------------------------------------------------------===//
+The save/restore sequence for CR in prolog/epilog is terrible:
+- Each CR subreg is saved individually, rather than doing one save as a unit.
+- On Darwin, the save is done after the decrement of SP, which means the offset
+from SP of the save slot can be too big for a store instruction, which means we
+need an additional register (currently hacked in 96015+96020; the solution there
+is correct, but poor).
+- On SVR4 the same thing can happen, and I don't think saving before the SP
+decrement is safe on that target, as there is no red zone. This is currently
+broken AFAIK, although it's not a target I can exercise.
+The following demonstrates the problem:
+extern void bar(char *p);
+void foo() {
+ char x[100000];
+ bar(x);
+ __asm__("" ::: "cr2");
+}
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index 9a2ce6b..f6753a6 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -56,6 +56,9 @@ namespace {
unsigned AsmVariant, const char *ExtraCode);
bool printGetPCX(const MachineInstr *MI, unsigned OpNo);
+
+ virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
+ const;
};
} // end of anonymous namespace
@@ -140,18 +143,19 @@ bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum) {
break;
}
+ unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber();
unsigned bbNum = MI->getParent()->getNumber();
- O << '\n' << ".LLGETPCH" << bbNum << ":\n";
- O << "\tcall\t.LLGETPC" << bbNum << '\n' ;
+ O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n";
+ O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
O << "\t sethi\t"
- << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << bbNum << ")), "
+ << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum << ")), "
<< operand << '\n' ;
- O << ".LLGETPC" << bbNum << ":\n" ;
+ O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
O << "\tor\t" << operand
- << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << bbNum << ")), "
+ << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum << ")), "
<< operand << '\n';
O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
@@ -197,6 +201,39 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
return false;
}
+/// isBlockOnlyReachableByFallthough - Return true if the basic block has
+/// exactly one predecessor and the control transfer mechanism between
+/// the predecessor and this block is a fall-through.
+///
+/// This overrides AsmPrinter's implementation to handle delay slots.
+bool SparcAsmPrinter::
+isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
+ // If this is a landing pad, it isn't a fall through. If it has no preds,
+ // then nothing falls through to it.
+ if (MBB->isLandingPad() || MBB->pred_empty())
+ return false;
+
+ // If there isn't exactly one predecessor, it can't be a fall through.
+ MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
+ ++PI2;
+ if (PI2 != MBB->pred_end())
+ return false;
+
+ // The predecessor has to be immediately before this block.
+ const MachineBasicBlock *Pred = *PI;
+
+ if (!Pred->isLayoutSuccessor(MBB))
+ return false;
+
+ // Check if the last terminator is an unconditional branch.
+ MachineBasicBlock::const_iterator I = Pred->end();
+ while (I != Pred->begin() && !(--I)->getDesc().isTerminator())
+ ; // Noop
+ return I == Pred->end() || !I->getDesc().isBarrier();
+}
+
+
+
// Force static initialization.
extern "C" void LLVMInitializeSparcAsmPrinter() {
RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget);
diff --git a/lib/Target/Sparc/README.txt b/lib/Target/Sparc/README.txt
index cc24abf..b4991fe 100644
--- a/lib/Target/Sparc/README.txt
+++ b/lib/Target/Sparc/README.txt
@@ -56,3 +56,4 @@ int %t1(int %a, int %b) {
leaf fns.
* Fill delay slots
+* Implement JIT support
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
index e1b3299..a7d1805 100644
--- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp
+++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
@@ -35,7 +35,6 @@ class SparcDAGToDAGISel : public SelectionDAGISel {
/// make the right decision when generating code for different targets.
const SparcSubtarget &Subtarget;
SparcTargetMachine& TM;
- MachineBasicBlock *CurBB;
public:
explicit SparcDAGToDAGISel(SparcTargetMachine &tm)
: SelectionDAGISel(tm),
@@ -56,10 +55,6 @@ public:
char ConstraintCode,
std::vector<SDValue> &OutOps);
- /// InstructionSelect - This callback is invoked by
- /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
- virtual void InstructionSelect();
-
virtual const char *getPassName() const {
return "SPARC DAG->DAG Pattern Instruction Selection";
}
@@ -72,17 +67,8 @@ private:
};
} // end anonymous namespace
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void SparcDAGToDAGISel::InstructionSelect() {
- CurBB = BB;
- // Select target instructions for the DAG.
- SelectRoot(*CurDAG);
- CurDAG->RemoveDeadNodes();
-}
-
SDNode* SparcDAGToDAGISel::getGlobalBaseReg() {
- MachineFunction *MF = CurBB->getParent();
+ MachineFunction *MF = BB->getParent();
unsigned GlobalBaseReg = TM.getInstrInfo()->getGlobalBaseReg(MF);
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index e67002a..4e93ef0 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -21,7 +21,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -134,7 +134,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
SDValue Load;
if (ObjectVT == MVT::i32) {
- Load = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0);
+ Load = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
} else {
ISD::LoadExtType LoadOp = ISD::SEXTLOAD;
@@ -143,7 +144,7 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr,
DAG.getConstant(Offset, MVT::i32));
Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr,
- NULL, 0, ObjectVT);
+ NULL, 0, ObjectVT, false, false, 0);
Load = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Load);
}
InVals.push_back(Load);
@@ -167,7 +168,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- SDValue Load = DAG.getLoad(MVT::f32, dl, Chain, FIPtr, NULL, 0);
+ SDValue Load = DAG.getLoad(MVT::f32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
InVals.push_back(Load);
}
ArgOffset += 4;
@@ -189,7 +191,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0);
+ HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
}
SDValue LoVal;
@@ -201,7 +204,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0);
+ LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
}
// Compose the two halves together into an i64 unit.
@@ -235,7 +239,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, NULL, 0));
+ OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, NULL, 0,
+ false, false, 0));
ArgOffset += 4;
}
@@ -339,7 +344,8 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// FIXME: VERIFY THAT 68 IS RIGHT.
SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+68);
PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
- MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0,
+ false, false, 0));
}
#else
@@ -385,14 +391,17 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// out the parts as integers. Top part goes in a reg.
SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32);
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
- Val, StackPtr, NULL, 0);
+ Val, StackPtr, NULL, 0,
+ false, false, 0);
// Sparc is big-endian, so the high part comes first.
- SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0, 0);
+ SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
// Increment the pointer to the other half.
StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
DAG.getIntPtrConstant(4));
// Load the low part.
- SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0, 0);
+ SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
@@ -435,7 +444,8 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
SDValue PtrOff = DAG.getConstant(ArgOffset, MVT::i32);
PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore,
- PtrOff, NULL, 0));
+ PtrOff, NULL, 0,
+ false, false, 0));
}
ArgOffset += ObjSize;
}
@@ -759,7 +769,7 @@ SDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op,
SDValue AbsAddr = DAG.getNode(ISD::ADD, dl, MVT::i32,
GlobalBase, RelAddr);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- AbsAddr, NULL, 0);
+ AbsAddr, NULL, 0, false, false, 0);
}
SDValue SparcTargetLowering::LowerConstantPool(SDValue Op,
@@ -780,7 +790,7 @@ SDValue SparcTargetLowering::LowerConstantPool(SDValue Op,
SDValue AbsAddr = DAG.getNode(ISD::ADD, dl, MVT::i32,
GlobalBase, RelAddr);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- AbsAddr, NULL, 0);
+ AbsAddr, NULL, 0, false, false, 0);
}
static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
@@ -872,7 +882,8 @@ static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
DAG.getConstant(TLI.getVarArgsFrameOffset(),
MVT::i32));
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, Offset, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, Offset, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
@@ -882,21 +893,23 @@ static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
SDValue VAListPtr = Node->getOperand(1);
const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
DebugLoc dl = Node->getDebugLoc();
- SDValue VAList = DAG.getLoad(MVT::i32, dl, InChain, VAListPtr, SV, 0);
+ SDValue VAList = DAG.getLoad(MVT::i32, dl, InChain, VAListPtr, SV, 0,
+ false, false, 0);
// Increment the pointer, VAList, to the next vaarg
SDValue NextPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, VAList,
DAG.getConstant(VT.getSizeInBits()/8,
MVT::i32));
// Store the incremented VAList to the legalized pointer
InChain = DAG.getStore(VAList.getValue(1), dl, NextPtr,
- VAListPtr, SV, 0);
+ VAListPtr, SV, 0, false, false, 0);
// Load the actual argument out of the pointer VAList, unless this is an
// f64 load.
if (VT != MVT::f64)
- return DAG.getLoad(VT, dl, InChain, VAList, NULL, 0);
+ return DAG.getLoad(VT, dl, InChain, VAList, NULL, 0, false, false, 0);
// Otherwise, load it as i64, then do a bitconvert.
- SDValue V = DAG.getLoad(MVT::i64, dl, InChain, VAList, NULL, 0);
+ SDValue V = DAG.getLoad(MVT::i64, dl, InChain, VAList, NULL, 0,
+ false, false, 0);
// Bit-Convert the value to f64.
SDValue Ops[2] = {
diff --git a/lib/Target/Sparc/SparcMachineFunctionInfo.h b/lib/Target/Sparc/SparcMachineFunctionInfo.h
index e457235..56d8708 100644
--- a/lib/Target/Sparc/SparcMachineFunctionInfo.h
+++ b/lib/Target/Sparc/SparcMachineFunctionInfo.h
@@ -22,7 +22,7 @@ namespace llvm {
unsigned GlobalBaseReg;
public:
SparcMachineFunctionInfo() : GlobalBaseReg(0) {}
- SparcMachineFunctionInfo(MachineFunction &MF) : GlobalBaseReg(0) {}
+ explicit SparcMachineFunctionInfo(MachineFunction &MF) : GlobalBaseReg(0) {}
unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index f6f632d..8152e1d 100644
--- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -100,8 +100,6 @@ namespace {
Lowering(*TM.getTargetLowering()),
Subtarget(*TM.getSubtargetImpl()) { }
- virtual void InstructionSelect();
-
virtual const char *getPassName() const {
return "SystemZ DAG->DAG Pattern Instruction Selection";
}
@@ -152,10 +150,6 @@ namespace {
bool MatchAddressBase(SDValue N, SystemZRRIAddressMode &AM);
bool MatchAddressRI(SDValue N, SystemZRRIAddressMode &AM,
bool is12Bit);
-
- #ifndef NDEBUG
- unsigned Indent;
- #endif
};
} // end anonymous namespace
@@ -594,41 +588,22 @@ bool SystemZDAGToDAGISel::SelectLAAddr(SDNode *Op, SDValue Addr,
bool SystemZDAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Disp, SDValue &Index) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P, P))
+ IsLegalToFold(N, P, P))
return SelectAddrRRI20(P, N.getOperand(1), Base, Disp, Index);
return false;
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void SystemZDAGToDAGISel::InstructionSelect() {
- // Codegen the basic block.
- DEBUG(errs() << "===== Instruction selection begins:\n");
- DEBUG(Indent = 0);
- SelectRoot(*CurDAG);
- DEBUG(errs() << "===== Instruction selection ends:\n");
-
- CurDAG->RemoveDeadNodes();
-}
-
SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
EVT NVT = Node->getValueType(0);
DebugLoc dl = Node->getDebugLoc();
unsigned Opcode = Node->getOpcode();
// Dump information about the Node being selected
- DEBUG(errs().indent(Indent) << "Selecting: ";
- Node->dump(CurDAG);
- errs() << "\n");
- DEBUG(Indent += 2);
+ DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
// If we have a custom node, we already have selected!
if (Node->isMachineOpcode()) {
- DEBUG(errs().indent(Indent-2) << "== ";
- Node->dump(CurDAG);
- errs() << "\n");
- DEBUG(Indent -= 2);
+ DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
return NULL; // Already selected.
}
@@ -694,9 +669,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
MVT::i32));
ReplaceUses(SDValue(Node, 0), SDValue(Div, 0));
- DEBUG(errs().indent(Indent-2) << "=> ";
- Result->dump(CurDAG);
- errs() << "\n");
+ DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
}
// Copy the remainder (even subreg) result, if it is needed.
@@ -709,15 +682,9 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
MVT::i32));
ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0));
- DEBUG(errs().indent(Indent-2) << "=> ";
- Result->dump(CurDAG);
- errs() << "\n");
+ DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
}
-#ifndef NDEBUG
- Indent -= 2;
-#endif
-
return NULL;
}
case ISD::UDIVREM: {
@@ -783,9 +750,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
CurDAG->getTargetConstant(SubRegIdx,
MVT::i32));
ReplaceUses(SDValue(Node, 0), SDValue(Div, 0));
- DEBUG(errs().indent(Indent-2) << "=> ";
- Result->dump(CurDAG);
- errs() << "\n");
+ DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
}
// Copy the remainder (even subreg) result, if it is needed.
@@ -797,15 +762,9 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
CurDAG->getTargetConstant(SubRegIdx,
MVT::i32));
ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0));
- DEBUG(errs().indent(Indent-2) << "=> ";
- Result->dump(CurDAG);
- errs() << "\n");
+ DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
}
-#ifndef NDEBUG
- Indent -= 2;
-#endif
-
return NULL;
}
}
@@ -813,14 +772,12 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
// Select the default instruction
SDNode *ResNode = SelectCode(Node);
- DEBUG(errs().indent(Indent-2) << "=> ";
+ DEBUG(errs() << "=> ";
if (ResNode == NULL || ResNode == Node)
Node->dump(CurDAG);
else
ResNode->dump(CurDAG);
errs() << "\n";
);
- DEBUG(Indent -= 2);
-
return ResNode;
}
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp
index f7405a5..6f4b30f 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -30,9 +30,9 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -337,7 +337,8 @@ SystemZTargetLowering::LowerCCCArguments(SDValue Chain,
// from this parameter
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
ArgValue = DAG.getLoad(LocVT, dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0);
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
}
// If this is an 8/16/32-bit value, it is really passed promoted to 64
@@ -435,7 +436,8 @@ SystemZTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
DAG.getIntPtrConstant(Offset));
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), Offset));
+ PseudoSourceValue::getStack(), Offset,
+ false, false, 0));
}
}
@@ -738,7 +740,7 @@ SDValue SystemZTargetLowering::LowerGlobalAddress(SDValue Op,
if (ExtraLoadRequired)
Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0, false, false, 0);
// If there was a non-zero offset that we didn't fold, create an explicit
// addition for it.
diff --git a/lib/Target/SystemZ/SystemZInstrFP.td b/lib/Target/SystemZ/SystemZInstrFP.td
index 336e20e..f46840c 100644
--- a/lib/Target/SystemZ/SystemZInstrFP.td
+++ b/lib/Target/SystemZ/SystemZInstrFP.td
@@ -58,7 +58,7 @@ def FMOV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
[]>;
}
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
+let canFoldAsLoad = 1, isReMaterializable = 1 in {
def FMOV32rm : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src),
"le\t{$dst, $src}",
[(set FP32:$dst, (load rriaddr12:$src))]>;
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index 1891bba..a44f6d9 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -257,7 +257,7 @@ def MOV64rihi32 : RILI<0xEC0, (outs GR64:$dst), (ins i64imm:$src),
[(set GR64:$dst, i64hi32:$src)]>;
}
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
+let canFoldAsLoad = 1, isReMaterializable = 1 in {
def MOV32rm : RXI<0x58,
(outs GR32:$dst), (ins rriaddr12:$src),
"l\t{$dst, $src}",
diff --git a/lib/Target/SystemZ/SystemZMachineFunctionInfo.h b/lib/Target/SystemZ/SystemZMachineFunctionInfo.h
index e47d419..fd6e330 100644
--- a/lib/Target/SystemZ/SystemZMachineFunctionInfo.h
+++ b/lib/Target/SystemZ/SystemZMachineFunctionInfo.h
@@ -33,7 +33,8 @@ class SystemZMachineFunctionInfo : public MachineFunctionInfo {
public:
SystemZMachineFunctionInfo() : CalleeSavedFrameSize(0) {}
- SystemZMachineFunctionInfo(MachineFunction &MF) : CalleeSavedFrameSize(0) {}
+ explicit SystemZMachineFunctionInfo(MachineFunction &MF)
+ : CalleeSavedFrameSize(0) {}
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp
index 295b30f..9a16808 100644
--- a/lib/Target/TargetData.cpp
+++ b/lib/Target/TargetData.cpp
@@ -580,7 +580,7 @@ const IntegerType *TargetData::getIntPtrType(LLVMContext &C) const {
uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices,
unsigned NumIndices) const {
const Type *Ty = ptrTy;
- assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
+ assert(Ty->isPointerTy() && "Illegal argument for getIndexedOffset()");
uint64_t Result = 0;
generic_gep_type_iterator<Value* const*>
diff --git a/lib/Target/TargetInstrInfo.cpp b/lib/Target/TargetInstrInfo.cpp
index 094a57e..18b0fa4 100644
--- a/lib/Target/TargetInstrInfo.cpp
+++ b/lib/Target/TargetInstrInfo.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/ErrorHandling.h"
+#include <ctype.h>
using namespace llvm;
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index a231ebc..82619c7 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -19,17 +19,15 @@
#include "llvm/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
-#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/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -289,832 +287,54 @@ TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind) const {
}
/// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a
-/// pc-relative reference to the specified global variable from exception
-/// handling information. In addition to the symbol, this returns
-/// by-reference:
-///
-/// IsIndirect - True if the returned symbol is actually a stub that contains
-/// the address of the symbol, false if the symbol is the global itself.
-///
-/// IsPCRel - True if the symbol reference is already pc-relative, false if
-/// the caller needs to subtract off the address of the reference from the
-/// symbol.
-///
+/// reference to the specified global variable from exception
+/// handling information.
const MCExpr *TargetLoweringObjectFile::
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
- // The generic implementation of this just returns a direct reference to the
- // symbol.
- IsIndirect = false;
- IsPCRel = false;
-
+ MachineModuleInfo *MMI, unsigned Encoding) const {
// FIXME: Use GetGlobalValueSymbol.
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, false);
- return MCSymbolRefExpr::Create(Name.str(), getContext());
-}
-
-
-//===----------------------------------------------------------------------===//
-// ELF
-//===----------------------------------------------------------------------===//
-typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
-
-TargetLoweringObjectFileELF::~TargetLoweringObjectFileELF() {
- // If we have the section uniquing map, free it.
- delete (ELFUniqueMapTy*)UniquingMap;
-}
-
-const MCSection *TargetLoweringObjectFileELF::
-getELFSection(StringRef Section, unsigned Type, unsigned Flags,
- SectionKind Kind, bool IsExplicit) const {
- if (UniquingMap == 0)
- UniquingMap = new ELFUniqueMapTy();
- ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)UniquingMap;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionELF *&Entry = Map[Section];
- if (Entry) return Entry;
-
- return Entry = MCSectionELF::Create(Section, Type, Flags, Kind, IsExplicit,
- getContext());
-}
-
-void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
- if (UniquingMap != 0)
- ((ELFUniqueMapTy*)UniquingMap)->clear();
- TargetLoweringObjectFile::Initialize(Ctx, TM);
-
- BSSSection =
- getELFSection(".bss", MCSectionELF::SHT_NOBITS,
- MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
- SectionKind::getBSS());
-
- TextSection =
- getELFSection(".text", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC,
- SectionKind::getText());
-
- DataSection =
- getELFSection(".data", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
- SectionKind::getDataRel());
-
- ReadOnlySection =
- getELFSection(".rodata", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC,
- SectionKind::getReadOnly());
-
- TLSDataSection =
- getELFSection(".tdata", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
- MCSectionELF::SHF_WRITE, SectionKind::getThreadData());
-
- TLSBSSSection =
- getELFSection(".tbss", MCSectionELF::SHT_NOBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
- MCSectionELF::SHF_WRITE, SectionKind::getThreadBSS());
-
- DataRelSection =
- getELFSection(".data.rel", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- DataRelLocalSection =
- getELFSection(".data.rel.local", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRelLocal());
-
- DataRelROSection =
- getELFSection(".data.rel.ro", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getReadOnlyWithRel());
-
- DataRelROLocalSection =
- getELFSection(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getReadOnlyWithRelLocal());
-
- MergeableConst4Section =
- getELFSection(".rodata.cst4", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
- SectionKind::getMergeableConst4());
-
- MergeableConst8Section =
- getELFSection(".rodata.cst8", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
- SectionKind::getMergeableConst8());
-
- MergeableConst16Section =
- getELFSection(".rodata.cst16", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
- SectionKind::getMergeableConst16());
-
- StaticCtorSection =
- getELFSection(".ctors", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- StaticDtorSection =
- getELFSection(".dtors", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- // Exception Handling Sections.
-
- // FIXME: We're emitting LSDA info into a readonly section on ELF, even though
- // it contains relocatable pointers. In PIC mode, this is probably a big
- // runtime hit for C++ apps. Either the contents of the LSDA need to be
- // adjusted or this should be a data section.
- LSDASection =
- getELFSection(".gcc_except_table", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
- EHFrameSection =
- getELFSection(".eh_frame", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- // Debug Info Sections.
- DwarfAbbrevSection =
- getELFSection(".debug_abbrev", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfInfoSection =
- getELFSection(".debug_info", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfLineSection =
- getELFSection(".debug_line", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfFrameSection =
- getELFSection(".debug_frame", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfPubNamesSection =
- getELFSection(".debug_pubnames", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfPubTypesSection =
- getELFSection(".debug_pubtypes", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfStrSection =
- getELFSection(".debug_str", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfLocSection =
- getELFSection(".debug_loc", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfARangesSection =
- getELFSection(".debug_aranges", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfRangesSection =
- getELFSection(".debug_ranges", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfMacroInfoSection =
- getELFSection(".debug_macinfo", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
-}
-
-
-static SectionKind
-getELFKindForNamedSection(StringRef Name, SectionKind K) {
- if (Name.empty() || Name[0] != '.') return K;
-
- // Some lame default implementation based on some magic section names.
- 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 (Name == ".tdata" ||
- Name.startswith(".tdata.") ||
- Name.startswith(".gnu.linkonce.td.") ||
- Name.startswith(".llvm.linkonce.td."))
- return SectionKind::getThreadData();
-
- if (Name == ".tbss" ||
- Name.startswith(".tbss.") ||
- Name.startswith(".gnu.linkonce.tb.") ||
- Name.startswith(".llvm.linkonce.tb."))
- return SectionKind::getThreadBSS();
-
- return K;
-}
-
-
-static unsigned getELFSectionType(StringRef Name, SectionKind K) {
-
- if (Name == ".init_array")
- return MCSectionELF::SHT_INIT_ARRAY;
-
- if (Name == ".fini_array")
- return MCSectionELF::SHT_FINI_ARRAY;
+ const MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
- if (Name == ".preinit_array")
- return MCSectionELF::SHT_PREINIT_ARRAY;
-
- if (K.isBSS() || K.isThreadBSS())
- return MCSectionELF::SHT_NOBITS;
-
- return MCSectionELF::SHT_PROGBITS;
-}
-
-
-static unsigned
-getELFSectionFlags(SectionKind K) {
- unsigned Flags = 0;
-
- if (!K.isMetadata())
- Flags |= MCSectionELF::SHF_ALLOC;
-
- if (K.isText())
- Flags |= MCSectionELF::SHF_EXECINSTR;
-
- if (K.isWriteable())
- Flags |= MCSectionELF::SHF_WRITE;
-
- if (K.isThreadLocal())
- Flags |= MCSectionELF::SHF_TLS;
-
- // K.isMergeableConst() is left out to honour PR4650
- if (K.isMergeableCString() || K.isMergeableConst4() ||
- K.isMergeableConst8() || K.isMergeableConst16())
- Flags |= MCSectionELF::SHF_MERGE;
-
- if (K.isMergeableCString())
- Flags |= MCSectionELF::SHF_STRINGS;
-
- return Flags;
-}
-
-
-const MCSection *TargetLoweringObjectFileELF::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- StringRef SectionName = GV->getSection();
-
- // Infer section flags from the section name if we can.
- Kind = getELFKindForNamedSection(SectionName, Kind);
-
- return getELFSection(SectionName,
- getELFSectionType(SectionName, Kind),
- getELFSectionFlags(Kind), Kind, true);
-}
-
-static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
- if (Kind.isText()) return ".gnu.linkonce.t.";
- if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
-
- if (Kind.isThreadData()) return ".gnu.linkonce.td.";
- if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
-
- if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
- if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
- if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
- if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
-
- assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
- return ".gnu.linkonce.d.rel.ro.";
+ return getSymbolForDwarfReference(Sym, MMI, Encoding);
}
-const MCSection *TargetLoweringObjectFileELF::
-SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
-
- // 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() && !Kind.isCommon() && !Kind.isBSS()) {
- const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
- SmallString<128> Name;
- Name.append(Prefix, Prefix+strlen(Prefix));
- Mang->getNameWithPrefix(Name, GV, false);
- return getELFSection(Name.str(), getELFSectionType(Name.str(), Kind),
- getELFSectionFlags(Kind), Kind);
- }
-
- if (Kind.isText()) return TextSection;
-
- if (Kind.isMergeable1ByteCString() ||
- Kind.isMergeable2ByteCString() ||
- Kind.isMergeable4ByteCString()) {
-
- // We also need alignment here.
- // FIXME: this is getting the alignment of the character, not the
- // alignment of the global!
- unsigned Align =
- TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
-
- const char *SizeSpec = ".rodata.str1.";
- if (Kind.isMergeable2ByteCString())
- SizeSpec = ".rodata.str2.";
- else if (Kind.isMergeable4ByteCString())
- SizeSpec = ".rodata.str4.";
- else
- assert(Kind.isMergeable1ByteCString() && "unknown string width");
-
-
- std::string Name = SizeSpec + utostr(Align);
- return getELFSection(Name, MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_MERGE |
- MCSectionELF::SHF_STRINGS,
- Kind);
- }
-
- if (Kind.isMergeableConst()) {
- if (Kind.isMergeableConst4() && MergeableConst4Section)
- return MergeableConst4Section;
- if (Kind.isMergeableConst8() && MergeableConst8Section)
- return MergeableConst8Section;
- if (Kind.isMergeableConst16() && MergeableConst16Section)
- return MergeableConst16Section;
- return ReadOnlySection; // .const
- }
-
- if (Kind.isReadOnly()) return ReadOnlySection;
-
- if (Kind.isThreadData()) return TLSDataSection;
- if (Kind.isThreadBSS()) return TLSBSSSection;
-
- // 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;
- if (Kind.isDataRel()) return DataRelSection;
- if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
-
- assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
- return DataRelROSection;
-}
-
-/// getSectionForConstant - Given a mergeable constant with the
-/// specified size and relocation information, return a section that it
-/// should be placed in.
-const MCSection *TargetLoweringObjectFileELF::
-getSectionForConstant(SectionKind Kind) const {
- if (Kind.isMergeableConst4() && MergeableConst4Section)
- return MergeableConst4Section;
- if (Kind.isMergeableConst8() && MergeableConst8Section)
- return MergeableConst8Section;
- if (Kind.isMergeableConst16() && MergeableConst16Section)
- return MergeableConst16Section;
- if (Kind.isReadOnly())
- return ReadOnlySection;
-
- if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
- assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
- return DataRelROSection;
-}
-
-//===----------------------------------------------------------------------===//
-// MachO
-//===----------------------------------------------------------------------===//
-
-typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
-
-TargetLoweringObjectFileMachO::~TargetLoweringObjectFileMachO() {
- // If we have the MachO uniquing map, free it.
- delete (MachOUniqueMapTy*)UniquingMap;
-}
-
-
-const MCSectionMachO *TargetLoweringObjectFileMachO::
-getMachOSection(StringRef Segment, 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 (UniquingMap == 0)
- UniquingMap = new MachOUniqueMapTy();
- MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)UniquingMap;
-
- // 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()];
- if (Entry) return Entry;
-
- // Otherwise, return a new section.
- return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
- Reserved2, Kind, getContext());
-}
-
-
-void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
- if (UniquingMap != 0)
- ((MachOUniqueMapTy*)UniquingMap)->clear();
- TargetLoweringObjectFile::Initialize(Ctx, TM);
-
- TextSection // .text
- = getMachOSection("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- SectionKind::getText());
- DataSection // .data
- = getMachOSection("__DATA", "__data", 0, SectionKind::getDataRel());
-
- CStringSection // .cstring
- = getMachOSection("__TEXT", "__cstring", MCSectionMachO::S_CSTRING_LITERALS,
- SectionKind::getMergeable1ByteCString());
- UStringSection
- = getMachOSection("__TEXT","__ustring", 0,
- SectionKind::getMergeable2ByteCString());
- FourByteConstantSection // .literal4
- = getMachOSection("__TEXT", "__literal4", MCSectionMachO::S_4BYTE_LITERALS,
- SectionKind::getMergeableConst4());
- EightByteConstantSection // .literal8
- = getMachOSection("__TEXT", "__literal8", MCSectionMachO::S_8BYTE_LITERALS,
- SectionKind::getMergeableConst8());
-
- // ld_classic doesn't support .literal16 in 32-bit mode, and ld64 falls back
- // to using it in -static mode.
- SixteenByteConstantSection = 0;
- if (TM.getRelocationModel() != Reloc::Static &&
- TM.getTargetData()->getPointerSize() == 32)
- SixteenByteConstantSection = // .literal16
- getMachOSection("__TEXT", "__literal16",MCSectionMachO::S_16BYTE_LITERALS,
- SectionKind::getMergeableConst16());
-
- ReadOnlySection // .const
- = getMachOSection("__TEXT", "__const", 0, SectionKind::getReadOnly());
-
- TextCoalSection
- = getMachOSection("__TEXT", "__textcoal_nt",
- MCSectionMachO::S_COALESCED |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- SectionKind::getText());
- ConstTextCoalSection
- = getMachOSection("__TEXT", "__const_coal", MCSectionMachO::S_COALESCED,
- SectionKind::getText());
- ConstDataCoalSection
- = getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED,
- SectionKind::getText());
- ConstDataSection // .const_data
- = getMachOSection("__DATA", "__const", 0,
- SectionKind::getReadOnlyWithRel());
- 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",
- MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
- SectionKind::getMetadata());
- NonLazySymbolPointerSection
- = getMachOSection("__DATA", "__nl_symbol_ptr",
- MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
- SectionKind::getMetadata());
-
- if (TM.getRelocationModel() == Reloc::Static) {
- StaticCtorSection
- = getMachOSection("__TEXT", "__constructor", 0,SectionKind::getDataRel());
- StaticDtorSection
- = getMachOSection("__TEXT", "__destructor", 0, SectionKind::getDataRel());
- } else {
- StaticCtorSection
- = getMachOSection("__DATA", "__mod_init_func",
- MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
- SectionKind::getDataRel());
- StaticDtorSection
- = getMachOSection("__DATA", "__mod_term_func",
- MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
- SectionKind::getDataRel());
- }
-
- // Exception Handling.
- LSDASection = getMachOSection("__DATA", "__gcc_except_tab", 0,
- SectionKind::getDataRel());
- EHFrameSection =
- getMachOSection("__TEXT", "__eh_frame",
- MCSectionMachO::S_COALESCED |
- MCSectionMachO::S_ATTR_NO_TOC |
- MCSectionMachO::S_ATTR_STRIP_STATIC_SYMS |
- MCSectionMachO::S_ATTR_LIVE_SUPPORT,
- SectionKind::getReadOnly());
-
- // Debug Information.
- DwarfAbbrevSection =
- getMachOSection("__DWARF", "__debug_abbrev", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfInfoSection =
- getMachOSection("__DWARF", "__debug_info", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfLineSection =
- getMachOSection("__DWARF", "__debug_line", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfFrameSection =
- getMachOSection("__DWARF", "__debug_frame", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfPubNamesSection =
- getMachOSection("__DWARF", "__debug_pubnames", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfPubTypesSection =
- getMachOSection("__DWARF", "__debug_pubtypes", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfStrSection =
- getMachOSection("__DWARF", "__debug_str", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfLocSection =
- getMachOSection("__DWARF", "__debug_loc", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfARangesSection =
- getMachOSection("__DWARF", "__debug_aranges", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfRangesSection =
- getMachOSection("__DWARF", "__debug_ranges", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfMacroInfoSection =
- getMachOSection("__DWARF", "__debug_macinfo", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfDebugInlineSection =
- getMachOSection("__DWARF", "__debug_inlined", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
-}
-
-const MCSection *TargetLoweringObjectFileMachO::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- // Parse the section specifier and create it if valid.
- StringRef Segment, Section;
- unsigned TAA, StubSize;
- std::string ErrorCode =
- MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section,
- TAA, StubSize);
- if (!ErrorCode.empty()) {
- // If invalid, report the error with llvm_report_error.
- llvm_report_error("Global variable '" + GV->getNameStr() +
- "' has an invalid section specifier '" + GV->getSection()+
- "': " + ErrorCode + ".");
- // Fall back to dropping it into the data section.
- return DataSection;
- }
-
- // Get the section.
- const MCSectionMachO *S =
- getMachOSection(Segment, Section, TAA, StubSize, Kind);
-
- // Okay, now that we got the section, verify that the TAA & StubSize agree.
- // If the user declared multiple globals with different section flags, we need
- // to reject it here.
- if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
- // If invalid, report the error with llvm_report_error.
- llvm_report_error("Global variable '" + GV->getNameStr() +
- "' section type or attributes does not match previous"
- " section specifier");
- }
-
- return S;
-}
-
-const MCSection *TargetLoweringObjectFileMachO::
-SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
-
- if (Kind.isText())
- return GV->isWeakForLinker() ? TextCoalSection : TextSection;
-
- // If this is weak/linkonce, put this in a coalescable section, either in text
- // or data depending on if it is writable.
- if (GV->isWeakForLinker()) {
- if (Kind.isReadOnly())
- return ConstTextCoalSection;
- return DataCoalSection;
- }
-
- // FIXME: Alignment check should be handled by section classifier.
- if (Kind.isMergeable1ByteCString() ||
- Kind.isMergeable2ByteCString()) {
- if (TM.getTargetData()->getPreferredAlignment(
- cast<GlobalVariable>(GV)) < 32) {
- if (Kind.isMergeable1ByteCString())
- return CStringSection;
- assert(Kind.isMergeable2ByteCString());
- return UStringSection;
- }
- }
-
- if (Kind.isMergeableConst()) {
- if (Kind.isMergeableConst4())
- return FourByteConstantSection;
- if (Kind.isMergeableConst8())
- return EightByteConstantSection;
- if (Kind.isMergeableConst16() && SixteenByteConstantSection)
- return SixteenByteConstantSection;
- }
-
- // Otherwise, if it is readonly, but not something we can specially optimize,
- // just drop it in .const.
- if (Kind.isReadOnly())
- return ReadOnlySection;
-
- // If this is marked const, put it into a const section. But if the dynamic
- // linker needs to write to it, put it in the data segment.
- 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;
-}
-
-const MCSection *
-TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const {
- // If this constant requires a relocation, we have to put it in the data
- // segment, not in the text segment.
- if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
- return ConstDataSection;
-
- if (Kind.isMergeableConst4())
- return FourByteConstantSection;
- if (Kind.isMergeableConst8())
- return EightByteConstantSection;
- if (Kind.isMergeableConst16() && SixteenByteConstantSection)
- return SixteenByteConstantSection;
- return ReadOnlySection; // .const
-}
-
-/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively decide
-/// not to emit the UsedDirective for some symbols in llvm.used.
-// FIXME: REMOVE this (rdar://7071300)
-bool TargetLoweringObjectFileMachO::
-shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
- /// On Darwin, internally linked data beginning with "L" or "l" does not have
- /// the directive emitted (this occurs in ObjC metadata).
- if (!GV) return false;
-
- // Check whether the mangled name has the "Private" or "LinkerPrivate" prefix.
- if (GV->hasLocalLinkage() && !isa<Function>(GV)) {
- // 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.
- SmallString<64> Name;
- Mang->getNameWithPrefix(Name, GV, false);
- if (Name[0] == 'L' || Name[0] == 'l')
- return false;
+const MCExpr *TargetLoweringObjectFile::
+getSymbolForDwarfReference(const MCSymbol *Sym, MachineModuleInfo *MMI,
+ unsigned Encoding) const {
+ const MCExpr *Res = MCSymbolRefExpr::Create(Sym, getContext());
+
+ switch (Encoding & 0xF0) {
+ default:
+ llvm_report_error("We do not support this DWARF encoding yet!");
+ break;
+ case dwarf::DW_EH_PE_absptr:
+ // Do nothing special
+ break;
+ case dwarf::DW_EH_PE_pcrel:
+ // FIXME: PCSymbol
+ const MCExpr *PC = MCSymbolRefExpr::Create(".", getContext());
+ Res = MCBinaryExpr::CreateSub(Res, PC, getContext());
+ break;
}
- return true;
+ return Res;
}
-const MCExpr *TargetLoweringObjectFileMachO::
-getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
- // The mach-o version of this method defaults to returning a stub reference.
- IsIndirect = true;
- IsPCRel = false;
-
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, true);
- Name += "$non_lazy_ptr";
- return MCSymbolRefExpr::Create(Name.str(), getContext());
+unsigned TargetLoweringObjectFile::getPersonalityEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
-
-//===----------------------------------------------------------------------===//
-// COFF
-//===----------------------------------------------------------------------===//
-
-typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
-
-TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
- delete (COFFUniqueMapTy*)UniquingMap;
+unsigned TargetLoweringObjectFile::getLSDAEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
-
-const MCSection *TargetLoweringObjectFileCOFF::
-getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
- // Create the map if it doesn't already exist.
- if (UniquingMap == 0)
- UniquingMap = new MachOUniqueMapTy();
- COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionCOFF *&Entry = Map[Name];
- if (Entry) return Entry;
-
- return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext());
+unsigned TargetLoweringObjectFile::getFDEEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
-void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
- if (UniquingMap != 0)
- ((COFFUniqueMapTy*)UniquingMap)->clear();
- TargetLoweringObjectFile::Initialize(Ctx, TM);
- TextSection = getCOFFSection("\t.text", true, SectionKind::getText());
- DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel());
- StaticCtorSection =
- getCOFFSection(".ctors", false, SectionKind::getDataRel());
- StaticDtorSection =
- getCOFFSection(".dtors", false, SectionKind::getDataRel());
-
- // FIXME: We're emitting LSDA info into a readonly section on COFF, even
- // though it contains relocatable pointers. In PIC mode, this is probably a
- // big runtime hit for C++ apps. Either the contents of the LSDA need to be
- // adjusted or this should be a data section.
- LSDASection =
- getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly());
- EHFrameSection =
- getCOFFSection(".eh_frame", false, SectionKind::getDataRel());
-
- // Debug info.
- // FIXME: Don't use 'directive' mode here.
- DwarfAbbrevSection =
- getCOFFSection("\t.section\t.debug_abbrev,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfInfoSection =
- getCOFFSection("\t.section\t.debug_info,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfLineSection =
- getCOFFSection("\t.section\t.debug_line,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfFrameSection =
- getCOFFSection("\t.section\t.debug_frame,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfPubNamesSection =
- getCOFFSection("\t.section\t.debug_pubnames,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfPubTypesSection =
- getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfStrSection =
- getCOFFSection("\t.section\t.debug_str,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfLocSection =
- getCOFFSection("\t.section\t.debug_loc,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfARangesSection =
- getCOFFSection("\t.section\t.debug_aranges,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfRangesSection =
- getCOFFSection("\t.section\t.debug_ranges,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfMacroInfoSection =
- getCOFFSection("\t.section\t.debug_macinfo,\"dr\"",
- true, SectionKind::getMetadata());
-}
-
-const MCSection *TargetLoweringObjectFileCOFF::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- return getCOFFSection(GV->getSection(), false, Kind);
-}
-
-static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
- if (Kind.isText())
- return ".text$linkonce";
- if (Kind.isWriteable())
- return ".data$linkonce";
- return ".rdata$linkonce";
-}
-
-
-const MCSection *TargetLoweringObjectFileCOFF::
-SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- assert(!Kind.isThreadLocal() && "Doesn't support TLS");
-
- // 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()) {
- const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
- SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
- Mang->getNameWithPrefix(Name, GV, false);
- return getCOFFSection(Name.str(), false, Kind);
- }
-
- if (Kind.isText())
- return getTextSection();
-
- return getDataSection();
+unsigned TargetLoweringObjectFile::getTTypeEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
diff --git a/lib/Target/X86/Android.mk b/lib/Target/X86/Android.mk
new file mode 100644
index 0000000..f5b8180
--- /dev/null
+++ b/lib/Target/X86/Android.mk
@@ -0,0 +1,47 @@
+LOCAL_PATH := $(call my-dir)
+
+# For the host only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES := \
+ X86GenRegisterInfo.h.inc \
+ X86GenRegisterNames.inc \
+ X86GenRegisterInfo.inc \
+ X86GenInstrNames.inc \
+ X86GenInstrInfo.inc \
+ X86GenAsmMatcher.inc \
+ X86GenDAGISel.inc \
+ X86GenDisassemblerTables.inc \
+ X86GenFastISel.inc \
+ X86GenCallingConv.inc \
+ X86GenSubtarget.inc \
+ X86GenEDInfo.inc
+
+LOCAL_SRC_FILES := \
+ X86AsmBackend.cpp \
+ X86COFFMachineModuleInfo.cpp \
+ X86CodeEmitter.cpp \
+ X86ELFWriterInfo.cpp \
+ X86FastISel.cpp \
+ X86FloatingPoint.cpp \
+ X86FloatingPointRegKill.cpp \
+ X86ISelDAGToDAG.cpp \
+ X86ISelLowering.cpp \
+ X86InstrInfo.cpp \
+ X86JITInfo.cpp \
+ X86MCAsmInfo.cpp \
+ X86MCCodeEmitter.cpp \
+ X86MCTargetExpr.cpp \
+ X86RegisterInfo.cpp \
+ X86Subtarget.cpp \
+ X86TargetMachine.cpp \
+ X86TargetObjectFile.cpp
+
+LOCAL_MODULE:= libLLVMX86CodeGen
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_TBLGEN_RULES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index acf497a..84d7bb7 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -10,6 +10,7 @@
#include "llvm/Target/TargetAsmParser.h"
#include "X86.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
@@ -183,6 +184,14 @@ struct X86Operand : public MCParsedAsmOperand {
bool isReg() const { return Kind == Register; }
+ void addExpr(MCInst &Inst, const MCExpr *Expr) const {
+ // Add as immediates when possible.
+ if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
+ Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
+ else
+ Inst.addOperand(MCOperand::CreateExpr(Expr));
+ }
+
void addRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateReg(getReg()));
@@ -190,13 +199,13 @@ struct X86Operand : public MCParsedAsmOperand {
void addImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
+ addExpr(Inst, getImm());
}
void addImmSExt8Operands(MCInst &Inst, unsigned N) const {
// FIXME: Support user customization of the render method.
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
+ addExpr(Inst, getImm());
}
void addMemOperands(MCInst &Inst, unsigned N) const {
@@ -204,7 +213,7 @@ struct X86Operand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
Inst.addOperand(MCOperand::CreateImm(getMemScale()));
Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
- Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
+ addExpr(Inst, getMemDisp());
Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
}
@@ -218,7 +227,7 @@ struct X86Operand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
Inst.addOperand(MCOperand::CreateImm(getMemScale()));
Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
- Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
+ addExpr(Inst, getMemDisp());
}
static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
@@ -492,24 +501,20 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
bool X86ATTAsmParser::
ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- // FIXME: Hack to recognize "sal..." for now. We need a way to represent
- // alternative syntaxes in the .td file, without requiring instruction
- // duplication.
- if (Name.startswith("sal")) {
- std::string Tmp = "shl" + Name.substr(3).str();
- Operands.push_back(X86Operand::CreateToken(Tmp, NameLoc));
- } else {
- // FIXME: This is a hack. We eventually want to add a general pattern
- // mechanism to be used in the table gen file for these assembly names that
- // use the same opcodes. Also we should only allow the "alternate names"
- // for rep and repne with the instructions they can only appear with.
- StringRef PatchedName = Name;
- if (Name == "repe" || Name == "repz")
- PatchedName = "rep";
- else if (Name == "repnz")
- PatchedName = "repne";
- Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
- }
+ // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
+ // represent alternative syntaxes in the .td file, without requiring
+ // instruction duplication.
+ StringRef PatchedName = StringSwitch<StringRef>(Name)
+ .Case("sal", "shl")
+ .Case("salb", "shlb")
+ .Case("sall", "shll")
+ .Case("salq", "shlq")
+ .Case("salw", "shlw")
+ .Case("repe", "rep")
+ .Case("repz", "rep")
+ .Case("repnz", "repne")
+ .Default(Name);
+ Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
if (getLexer().isNot(AsmToken::EndOfStatement)) {
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
index 38ccbf9..734a545 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
@@ -25,10 +25,15 @@ using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#define MachineInstr MCInst
+#define GET_INSTRUCTION_NAME
#include "X86GenAsmWriter.inc"
#undef MachineInstr
void X86ATTInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
+StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const {
+ return getInstructionName(Opcode);
+}
+
void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
switch (MI->getOperand(Op).getImm()) {
@@ -68,7 +73,7 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo) {
O << '$' << Op.getImm();
if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
- *CommentStream << format("imm = 0x%X\n", Op.getImm());
+ *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm());
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
index 3180618..d109a07 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
@@ -26,11 +26,12 @@ public:
virtual void printInst(const MCInst *MI);
-
+ virtual StringRef getOpcodeName(unsigned Opcode) const;
+
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI);
static const char *getRegisterName(unsigned RegNo);
-
+ static const char *getInstructionName(unsigned Opcode);
void printOperand(const MCInst *MI, unsigned OpNo);
void printMemReference(const MCInst *MI, unsigned Op);
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index 304306d..8cab24c 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -33,10 +33,11 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallString.h"
@@ -52,40 +53,42 @@ void X86AsmPrinter::PrintPICBaseSymbol() const {
OutContext);
}
+MCSymbol *X86AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const {
+ SmallString<60> NameStr;
+ Mang->getNameWithPrefix(NameStr, GV, false);
+ MCSymbol *Symb = OutContext.GetOrCreateSymbol(NameStr.str());
+
+ if (Subtarget->isTargetCygMing()) {
+ X86COFFMachineModuleInfo &COFFMMI =
+ MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
+ COFFMMI.DecorateCygMingName(Symb, OutContext, GV, *TM.getTargetData());
+
+ // Save function name for later type emission.
+ if (const Function *F = dyn_cast<Function>(GV))
+ if (F->isDeclaration())
+ COFFMMI.addExternalFunction(Symb->getName());
+
+ }
+
+ return Symb;
+}
+
/// runOnMachineFunction - Emit the function body.
///
bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
SetupMachineFunction(MF);
-
- // COFF and Cygwin specific mangling stuff. This should be moved out to the
- // mangler or handled some other way?
- if (Subtarget->isTargetCOFF()) {
- X86COFFMachineModuleInfo &COFFMMI =
- MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- // Populate function information map. Don't want to populate
- // non-stdcall or non-fastcall functions' information right now.
- const Function *F = MF.getFunction();
- CallingConv::ID CC = F->getCallingConv();
- if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall)
- COFFMMI.AddFunctionInfo(F, *MF.getInfo<X86MachineFunctionInfo>());
- }
- if (Subtarget->isTargetCygMing()) {
+ if (Subtarget->isTargetCOFF()) {
const Function *F = MF.getFunction();
- X86COFFMachineModuleInfo &COFFMMI =
- MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(CurrentFnSym, OutContext,F,*TM.getTargetData());
-
- O << "\t.def\t " << *CurrentFnSym;
- O << ";\t.scl\t" <<
+ O << "\t.def\t " << *CurrentFnSym << ";\t.scl\t" <<
(F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
<< ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
<< ";\t.endef\n";
}
-
+
// Have common code print out the function header with linkage info etc.
EmitFunctionHeader();
-
+
// Emit the rest of the function body.
EmitFunctionBody();
@@ -119,12 +122,6 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
else
GVSym = GetGlobalValueSymbol(GV);
- if (Subtarget->isTargetCygMing()) {
- X86COFFMachineModuleInfo &COFFMMI =
- MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(GVSym, OutContext, GV, *TM.getTargetData());
- }
-
// Handle dllimport linkage.
if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
@@ -585,7 +582,6 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
if (I->hasDLLExportLinkage()) {
MCSymbol *Sym = GetGlobalValueSymbol(I);
- COFFMMI.DecorateCygMingName(Sym, OutContext, I, *TM.getTargetData());
DLLExportedFns.push_back(Sym);
}
@@ -607,6 +603,28 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
}
}
}
+
+ if (Subtarget->isTargetELF()) {
+ TargetLoweringObjectFileELF &TLOFELF =
+ static_cast<TargetLoweringObjectFileELF &>(getObjFileLowering());
+
+ MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
+
+ // Output stubs for external and common global variables.
+ MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
+ if (!Stubs.empty()) {
+ OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
+ const TargetData *TD = TM.getTargetData();
+
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i)
+ O << *Stubs[i].first << ":\n"
+ << (TD->getPointerSize() == 8 ?
+ MAI->getData64bitsDirective() : MAI->getData32bitsDirective())
+ << *Stubs[i].second << '\n';
+
+ Stubs.clear();
+ }
+ }
}
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
index 1d32a5f..039214a 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
@@ -61,8 +61,7 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
virtual void EmitInstruction(const MachineInstr *MI);
void printSymbolOperand(const MachineOperand &MO);
-
-
+ virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
// These methods are used by the tablegen'erated instruction printer.
void printOperand(const MachineInstr *MI, unsigned OpNo,
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
index 4274d0a..610beb5 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
@@ -24,10 +24,14 @@ using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#define MachineInstr MCInst
+#define GET_INSTRUCTION_NAME
#include "X86GenAsmWriter1.inc"
#undef MachineInstr
void X86IntelInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
+StringRef X86IntelInstPrinter::getOpcodeName(unsigned Opcode) const {
+ return getInstructionName(Opcode);
+}
void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
switch (MI->getOperand(Op).getImm()) {
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
index 1976177..545bf84 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
@@ -26,10 +26,12 @@ public:
: MCInstPrinter(O, MAI) {}
virtual void printInst(const MCInst *MI);
+ virtual StringRef getOpcodeName(unsigned Opcode) const;
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI);
static const char *getRegisterName(unsigned RegNo);
+ static const char *getInstructionName(unsigned Opcode);
void printOperand(const MCInst *MI, unsigned OpNo,
diff --git a/lib/Target/X86/CMakeLists.txt b/lib/Target/X86/CMakeLists.txt
index 61f26a7..eed3b45 100644
--- a/lib/Target/X86/CMakeLists.txt
+++ b/lib/Target/X86/CMakeLists.txt
@@ -15,6 +15,7 @@ tablegen(X86GenCallingConv.inc -gen-callingconv)
tablegen(X86GenSubtarget.inc -gen-subtarget)
set(sources
+ X86AsmBackend.cpp
X86CodeEmitter.cpp
X86COFFMachineModuleInfo.cpp
X86ELFWriterInfo.cpp
diff --git a/lib/Target/X86/README-SSE.txt b/lib/Target/X86/README-SSE.txt
index 19eb05e..e5f84e8 100644
--- a/lib/Target/X86/README-SSE.txt
+++ b/lib/Target/X86/README-SSE.txt
@@ -67,8 +67,8 @@ no_exit.i7: ; preds = %no_exit.i7, %build_tree.exit
[ %tmp.34.i18, %no_exit.i7 ]
%tmp.0.0.0.i10 = phi double [ 0.000000e+00, %build_tree.exit ],
[ %tmp.28.i16, %no_exit.i7 ]
- %tmp.28.i16 = add double %tmp.0.0.0.i10, 0.000000e+00
- %tmp.34.i18 = add double %tmp.0.1.0.i9, 0.000000e+00
+ %tmp.28.i16 = fadd double %tmp.0.0.0.i10, 0.000000e+00
+ %tmp.34.i18 = fadd double %tmp.0.1.0.i9, 0.000000e+00
br i1 false, label %Compute_Tree.exit23, label %no_exit.i7
Compute_Tree.exit23: ; preds = %no_exit.i7
@@ -97,7 +97,7 @@ pcmp/pand/pandn/por to do a selection instead of a conditional branch:
double %X(double %Y, double %Z, double %A, double %B) {
%C = setlt double %A, %B
- %z = add double %Z, 0.0 ;; select operand is not a load
+ %z = fadd double %Z, 0.0 ;; select operand is not a load
%D = select bool %C, double %Y, double %z
ret double %D
}
@@ -545,7 +545,7 @@ eliminates a constant pool load. For example, consider:
define i64 @ccosf(float %z.0, float %z.1) nounwind readonly {
entry:
- %tmp6 = sub float -0.000000e+00, %z.1 ; <float> [#uses=1]
+ %tmp6 = fsub float -0.000000e+00, %z.1 ; <float> [#uses=1]
%tmp20 = tail call i64 @ccoshf( float %tmp6, float %z.0 ) nounwind readonly
ret i64 %tmp20
}
diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt
index aa7bb3d..d4545a6 100644
--- a/lib/Target/X86/README.txt
+++ b/lib/Target/X86/README.txt
@@ -227,11 +227,6 @@ lambda, siod, optimizer-eval, ackermann, hash2, nestedloop, strcat, and Treesor.
//===---------------------------------------------------------------------===//
-Teach the coalescer to coalesce vregs of different register classes. e.g. FR32 /
-FR64 to VR128.
-
-//===---------------------------------------------------------------------===//
-
Adding to the list of cmp / test poor codegen issues:
int test(__m128 *A, __m128 *B) {
@@ -1868,3 +1863,69 @@ carried over to machine instructions. Asm printer (or JIT) can use this
information to add the "lock" prefix.
//===---------------------------------------------------------------------===//
+
+_Bool bar(int *x) { return *x & 1; }
+
+define zeroext i1 @bar(i32* nocapture %x) nounwind readonly {
+entry:
+ %tmp1 = load i32* %x ; <i32> [#uses=1]
+ %and = and i32 %tmp1, 1 ; <i32> [#uses=1]
+ %tobool = icmp ne i32 %and, 0 ; <i1> [#uses=1]
+ ret i1 %tobool
+}
+
+bar: # @bar
+# BB#0: # %entry
+ movl 4(%esp), %eax
+ movb (%eax), %al
+ andb $1, %al
+ movzbl %al, %eax
+ ret
+
+Missed optimization: should be movl+andl.
+
+//===---------------------------------------------------------------------===//
+
+Consider the following two functions compiled with clang:
+_Bool foo(int *x) { return !(*x & 4); }
+unsigned bar(int *x) { return !(*x & 4); }
+
+foo:
+ movl 4(%esp), %eax
+ testb $4, (%eax)
+ sete %al
+ movzbl %al, %eax
+ ret
+
+bar:
+ movl 4(%esp), %eax
+ movl (%eax), %eax
+ shrl $2, %eax
+ andl $1, %eax
+ xorl $1, %eax
+ ret
+
+The second function generates more code even though the two functions are
+are functionally identical.
+
+//===---------------------------------------------------------------------===//
+
+Take the following C code:
+int x(int y) { return (y & 63) << 14; }
+
+Code produced by gcc:
+ andl $63, %edi
+ sall $14, %edi
+ movl %edi, %eax
+ ret
+
+Code produced by clang:
+ shll $14, %edi
+ movl %edi, %eax
+ andl $1032192, %eax
+ ret
+
+The code produced by gcc is 3 bytes shorter. This sort of construct often
+shows up with bitfields.
+
+//===---------------------------------------------------------------------===//
diff --git a/lib/Target/X86/TargetInfo/Android.mk b/lib/Target/X86/TargetInfo/Android.mk
new file mode 100644
index 0000000..ee53f0d
--- /dev/null
+++ b/lib/Target/X86/TargetInfo/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH := $(call my-dir)
+
+# For the device only
+# =====================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES := \
+ X86GenRegisterNames.inc \
+ X86GenInstrNames.inc
+
+TBLGEN_TD_DIR := $(LOCAL_PATH)/..
+
+LOCAL_SRC_FILES := \
+ X86TargetInfo.cpp
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/..
+
+LOCAL_MODULE:= libLLVMX86Info
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index 1d17a05..ba0ee6c 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -19,12 +19,15 @@
namespace llvm {
-class X86TargetMachine;
class FunctionPass;
-class MachineCodeEmitter;
-class MCCodeEmitter;
class JITCodeEmitter;
+class MCAssembler;
+class MCCodeEmitter;
+class MCContext;
+class MachineCodeEmitter;
class Target;
+class TargetAsmBackend;
+class X86TargetMachine;
class formatted_raw_ostream;
/// createX86ISelDag - This pass converts a legalized DAG into a
@@ -49,9 +52,13 @@ FunctionPass *createX87FPRegKillInserterPass();
FunctionPass *createX86JITCodeEmitterPass(X86TargetMachine &TM,
JITCodeEmitter &JCE);
-MCCodeEmitter *createHeinousX86MCCodeEmitter(const Target &, TargetMachine &TM);
-MCCodeEmitter *createX86_32MCCodeEmitter(const Target &, TargetMachine &TM);
-MCCodeEmitter *createX86_64MCCodeEmitter(const Target &, TargetMachine &TM);
+MCCodeEmitter *createX86_32MCCodeEmitter(const Target &, TargetMachine &TM,
+ MCContext &Ctx);
+MCCodeEmitter *createX86_64MCCodeEmitter(const Target &, TargetMachine &TM,
+ MCContext &Ctx);
+
+TargetAsmBackend *createX86_32AsmBackend(const Target &, MCAssembler &);
+TargetAsmBackend *createX86_64AsmBackend(const Target &, MCAssembler &);
/// createX86EmitCodeToMemory - Returns a pass that converts a register
/// allocated function into raw machine code in a dynamically
diff --git a/lib/Target/X86/X86AsmBackend.cpp b/lib/Target/X86/X86AsmBackend.cpp
new file mode 100644
index 0000000..e6654ef
--- /dev/null
+++ b/lib/Target/X86/X86AsmBackend.cpp
@@ -0,0 +1,34 @@
+//===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetAsmBackend.h"
+#include "X86.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetAsmBackend.h"
+using namespace llvm;
+
+namespace {
+
+class X86AsmBackend : public TargetAsmBackend {
+public:
+ X86AsmBackend(const Target &T, MCAssembler &A)
+ : TargetAsmBackend(T) {}
+};
+
+}
+
+TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
+ MCAssembler &A) {
+ return new X86AsmBackend(T, A);
+}
+
+TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
+ MCAssembler &A) {
+ return new X86AsmBackend(T, A);
+}
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.cpp b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
index ea52795..ab67acb 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.cpp
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
@@ -27,90 +27,55 @@ X86COFFMachineModuleInfo::X86COFFMachineModuleInfo(const MachineModuleInfo &) {
X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
}
-void X86COFFMachineModuleInfo::AddFunctionInfo(const Function *F,
- const X86MachineFunctionInfo &Val) {
- FunctionInfoMap[F] = Val;
+void X86COFFMachineModuleInfo::addExternalFunction(const StringRef& Name) {
+ CygMingStubs.insert(Name);
}
-
-
-static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
- const TargetData &TD) {
- X86MachineFunctionInfo Info;
- uint64_t Size = 0;
-
- switch (F->getCallingConv()) {
- case CallingConv::X86_StdCall:
- Info.setDecorationStyle(StdCall);
- break;
- case CallingConv::X86_FastCall:
- Info.setDecorationStyle(FastCall);
- break;
- default:
- return Info;
- }
-
- unsigned argNum = 1;
- for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
- AI != AE; ++AI, ++argNum) {
- const Type* Ty = AI->getType();
-
- // 'Dereference' type in case of byval parameter attribute
- if (F->paramHasAttr(argNum, Attribute::ByVal))
- Ty = cast<PointerType>(Ty)->getElementType();
-
- // Size should be aligned to DWORD boundary
- Size += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
- }
-
- // We're not supporting tooooo huge arguments :)
- Info.setBytesToPopOnReturn((unsigned int)Size);
- return Info;
-}
-
-
-/// DecorateCygMingName - Query FunctionInfoMap and use this information for
-/// various name decorations for Cygwin and MingW.
+/// DecorateCygMingName - Apply various name decorations if the function uses
+/// stdcall or fastcall calling convention.
void X86COFFMachineModuleInfo::DecorateCygMingName(SmallVectorImpl<char> &Name,
const GlobalValue *GV,
const TargetData &TD) {
const Function *F = dyn_cast<Function>(GV);
if (!F) return;
-
- // Save function name for later type emission.
- if (F->isDeclaration())
- CygMingStubs.insert(StringRef(Name.data(), Name.size()));
-
+
// We don't want to decorate non-stdcall or non-fastcall functions right now
CallingConv::ID CC = F->getCallingConv();
if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
return;
-
- const X86MachineFunctionInfo *Info;
-
- FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
- if (info_item == FunctionInfoMap.end()) {
- // Calculate apropriate function info and populate map
- FunctionInfoMap[F] = calculateFunctionInfo(F, TD);
- Info = &FunctionInfoMap[F];
- } else {
- Info = &info_item->second;
- }
-
- if (Info->getDecorationStyle() == None) return;
+
+ unsigned ArgWords = 0;
+ DenseMap<const Function*, unsigned>::const_iterator item = FnArgWords.find(F);
+ if (item == FnArgWords.end()) {
+ // Calculate arguments sizes
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI) {
+ const Type* Ty = AI->getType();
+
+ // 'Dereference' type in case of byval parameter attribute
+ if (AI->hasByValAttr())
+ Ty = cast<PointerType>(Ty)->getElementType();
+
+ // Size should be aligned to DWORD boundary
+ ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
+ }
+
+ FnArgWords[F] = ArgWords;
+ } else
+ ArgWords = item->second;
+
const FunctionType *FT = F->getFunctionType();
-
// "Pure" variadic functions do not receive @0 suffix.
if (!FT->isVarArg() || FT->getNumParams() == 0 ||
(FT->getNumParams() == 1 && F->hasStructRetAttr()))
- raw_svector_ostream(Name) << '@' << Info->getBytesToPopOnReturn();
-
- if (Info->getDecorationStyle() == FastCall) {
+ raw_svector_ostream(Name) << '@' << ArgWords;
+
+ if (CC == CallingConv::X86_FastCall) {
if (Name[0] == '_')
Name[0] = '@';
else
Name.insert(Name.begin(), '@');
- }
+ }
}
/// DecorateCygMingName - Query FunctionInfoMap and use this information for
@@ -121,6 +86,6 @@ void X86COFFMachineModuleInfo::DecorateCygMingName(MCSymbol *&Name,
const TargetData &TD) {
SmallString<128> NameStr(Name->getName().begin(), Name->getName().end());
DecorateCygMingName(NameStr, GV, TD);
-
+
Name = Ctx.GetOrCreateSymbol(NameStr.str());
}
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.h b/lib/Target/X86/X86COFFMachineModuleInfo.h
index 0e2009e..9de3dcd 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.h
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.h
@@ -21,44 +21,25 @@
namespace llvm {
class X86MachineFunctionInfo;
class TargetData;
-
+
/// X86COFFMachineModuleInfo - This is a MachineModuleInfoImpl implementation
/// for X86 COFF targets.
class X86COFFMachineModuleInfo : public MachineModuleInfoImpl {
StringSet<> CygMingStubs;
-
- // We have to propagate some information about MachineFunction to
- // AsmPrinter. It's ok, when we're printing the function, since we have
- // access to MachineFunction and can get the appropriate MachineFunctionInfo.
- // Unfortunately, this is not possible when we're printing reference to
- // Function (e.g. calling it and so on). Even more, there is no way to get the
- // corresponding MachineFunctions: it can even be not created at all. That's
- // why we should use additional structure, when we're collecting all necessary
- // information.
- //
- // This structure is using e.g. for name decoration for stdcall & fastcall'ed
- // function, since we have to use arguments' size for decoration.
- typedef std::map<const Function*, X86MachineFunctionInfo> FMFInfoMap;
- FMFInfoMap FunctionInfoMap;
-
+ DenseMap<const Function*, unsigned> FnArgWords;
public:
X86COFFMachineModuleInfo(const MachineModuleInfo &);
~X86COFFMachineModuleInfo();
-
-
+
void DecorateCygMingName(MCSymbol* &Name, MCContext &Ctx,
const GlobalValue *GV, const TargetData &TD);
void DecorateCygMingName(SmallVectorImpl<char> &Name, const GlobalValue *GV,
const TargetData &TD);
-
- void AddFunctionInfo(const Function *F, const X86MachineFunctionInfo &Val);
-
+ void addExternalFunction(const StringRef& Name);
typedef StringSet<>::const_iterator stub_iterator;
stub_iterator stub_begin() const { return CygMingStubs.begin(); }
stub_iterator stub_end() const { return CygMingStubs.end(); }
-
-
};
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index f0bceb1..8deadf6 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -387,10 +387,16 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
// If no BaseReg, issue a RIP relative instruction only if the MCE can
// resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
// 2-7) and absolute references.
+ unsigned BaseRegNo = -1U;
+ if (BaseReg != 0 && BaseReg != X86::RIP)
+ BaseRegNo = getX86RegNum(BaseReg);
+
if (// The SIB byte must be used if there is an index register.
IndexReg.getReg() == 0 &&
- // The SIB byte must be used if the base is ESP/RSP.
- BaseReg != X86::ESP && BaseReg != X86::RSP &&
+ // The SIB byte must be used if the base is ESP/RSP/R12, all of which
+ // encode to an R/M value of 4, which indicates that a SIB byte is
+ // present.
+ BaseRegNo != N86::ESP &&
// If there is no base register and we're in 64-bit mode, we need a SIB
// byte to emit an addr that is just 'disp32' (the non-RIP relative form).
(!Is64BitMode || BaseReg != 0)) {
@@ -401,7 +407,6 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
return;
}
- unsigned BaseRegNo = getX86RegNum(BaseReg);
// If the base is not EBP/ESP and there is no displacement, use simple
// indirect register encoding, this handles addresses like [EAX]. The
// encoding for [EBP] with no displacement means [disp32] so we handle it
@@ -757,27 +762,8 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
case X86II::MRM4r: case X86II::MRM5r:
case X86II::MRM6r: case X86II::MRM7r: {
MCE.emitByte(BaseOpcode);
-
- // Special handling of lfence, mfence, monitor, and mwait.
- if (Desc->getOpcode() == X86::LFENCE ||
- Desc->getOpcode() == X86::MFENCE ||
- Desc->getOpcode() == X86::MONITOR ||
- Desc->getOpcode() == X86::MWAIT) {
- emitRegModRMByte((Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
-
- switch (Desc->getOpcode()) {
- default: break;
- case X86::MONITOR:
- MCE.emitByte(0xC8);
- break;
- case X86::MWAIT:
- MCE.emitByte(0xC9);
- break;
- }
- } else {
- emitRegModRMByte(MI.getOperand(CurOp++).getReg(),
- (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
- }
+ emitRegModRMByte(MI.getOperand(CurOp++).getReg(),
+ (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
if (CurOp == NumOps)
break;
@@ -853,6 +839,27 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
getX86RegNum(MI.getOperand(CurOp).getReg()));
++CurOp;
break;
+
+ case X86II::MRM_C1:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC1);
+ break;
+ case X86II::MRM_C8:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC8);
+ break;
+ case X86II::MRM_C9:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC9);
+ break;
+ case X86II::MRM_E8:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xE8);
+ break;
+ case X86II::MRM_F0:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xF0);
+ break;
}
if (!Desc->isVariadic() && CurOp != NumOps) {
@@ -864,335 +871,3 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
-
-// Adapt the Emitter / CodeEmitter interfaces to MCCodeEmitter.
-//
-// FIXME: This is a total hack designed to allow work on llvm-mc to proceed
-// without being blocked on various cleanups needed to support a clean interface
-// to instruction encoding.
-//
-// Look away!
-
-#include "llvm/DerivedTypes.h"
-
-namespace {
-class MCSingleInstructionCodeEmitter : public MachineCodeEmitter {
- uint8_t Data[256];
- const MCInst *CurrentInst;
- SmallVectorImpl<MCFixup> *FixupList;
-
-public:
- MCSingleInstructionCodeEmitter() { reset(0, 0); }
-
- void reset(const MCInst *Inst, SmallVectorImpl<MCFixup> *Fixups) {
- CurrentInst = Inst;
- FixupList = Fixups;
- BufferBegin = Data;
- BufferEnd = array_endof(Data);
- CurBufferPtr = Data;
- }
-
- StringRef str() {
- return StringRef(reinterpret_cast<char*>(BufferBegin),
- CurBufferPtr - BufferBegin);
- }
-
- virtual void startFunction(MachineFunction &F) {}
- virtual bool finishFunction(MachineFunction &F) { return false; }
- virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {}
- virtual bool earlyResolveAddresses() const { return false; }
- virtual void addRelocation(const MachineRelocation &MR) {
- unsigned Offset = 0, OpIndex = 0, Kind = MR.getRelocationType();
-
- // This form is only used in one case, for branches.
- if (MR.isBasicBlock()) {
- Offset = unsigned(MR.getMachineCodeOffset());
- OpIndex = 0;
- } else {
- assert(MR.isJumpTableIndex() && "Unexpected relocation!");
-
- Offset = unsigned(MR.getMachineCodeOffset());
-
- // The operand index is encoded as the first byte of the fake operand.
- OpIndex = MR.getJumpTableIndex();
- }
-
- MCOperand Op = CurrentInst->getOperand(OpIndex);
- assert(Op.isExpr() && "FIXME: Not yet implemented!");
- FixupList->push_back(MCFixup::Create(Offset, Op.getExpr(),
- MCFixupKind(FirstTargetFixupKind + Kind)));
- }
- virtual void setModuleInfo(MachineModuleInfo* Info) {}
-
- // Interface functions which should never get called in our usage.
-
- virtual void emitLabel(uint64_t LabelID) {
- assert(0 && "Unexpected code emitter call!");
- }
- virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- assert(0 && "Unexpected code emitter call!");
- return 0;
- }
- virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
- assert(0 && "Unexpected code emitter call!");
- return 0;
- }
- virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
- assert(0 && "Unexpected code emitter call!");
- return 0;
- }
- virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
- assert(0 && "Unexpected code emitter call!");
- return 0;
- }
-};
-
-class X86MCCodeEmitter : public MCCodeEmitter {
- X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
- void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
-
-private:
- X86TargetMachine &TM;
- llvm::Function *DummyF;
- TargetData *DummyTD;
- mutable llvm::MachineFunction *DummyMF;
- llvm::MachineBasicBlock *DummyMBB;
-
- MCSingleInstructionCodeEmitter *InstrEmitter;
- Emitter<MachineCodeEmitter> *Emit;
-
-public:
- X86MCCodeEmitter(X86TargetMachine &_TM) : TM(_TM) {
- // Verily, thou shouldst avert thine eyes.
- const llvm::FunctionType *FTy =
- FunctionType::get(llvm::Type::getVoidTy(getGlobalContext()), false);
- DummyF = Function::Create(FTy, GlobalValue::InternalLinkage);
- DummyTD = new TargetData("");
- DummyMF = new MachineFunction(DummyF, TM, 0);
- DummyMBB = DummyMF->CreateMachineBasicBlock();
-
- InstrEmitter = new MCSingleInstructionCodeEmitter();
- Emit = new Emitter<MachineCodeEmitter>(TM, *InstrEmitter,
- *TM.getInstrInfo(),
- *DummyTD, false);
- }
- ~X86MCCodeEmitter() {
- delete Emit;
- delete InstrEmitter;
- delete DummyMF;
- delete DummyF;
- }
-
- unsigned getNumFixupKinds() const {
- return 5;
- }
-
- MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
- static MCFixupKindInfo Infos[] = {
- { "reloc_pcrel_word", 0, 4 * 8 },
- { "reloc_picrel_word", 0, 4 * 8 },
- { "reloc_absolute_word", 0, 4 * 8 },
- { "reloc_absolute_word_sext", 0, 4 * 8 },
- { "reloc_absolute_dword", 0, 8 * 8 }
- };
-
- assert(Kind >= FirstTargetFixupKind && Kind < MaxTargetFixupKind &&
- "Invalid kind!");
- return Infos[Kind - FirstTargetFixupKind];
- }
-
- bool AddRegToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- if (Start + 1 > MI.getNumOperands())
- return false;
-
- const MCOperand &Op = MI.getOperand(Start);
- if (!Op.isReg()) return false;
-
- Instr->addOperand(MachineOperand::CreateReg(Op.getReg(), false));
- return true;
- }
-
- bool AddImmToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- if (Start + 1 > MI.getNumOperands())
- return false;
-
- const MCOperand &Op = MI.getOperand(Start);
- if (Op.isImm()) {
- Instr->addOperand(MachineOperand::CreateImm(Op.getImm()));
- return true;
- }
- if (!Op.isExpr())
- return false;
-
- const MCExpr *Expr = Op.getExpr();
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
- Instr->addOperand(MachineOperand::CreateImm(CE->getValue()));
- return true;
- }
-
- // Fake this as an external symbol to the code emitter to add a relcoation
- // entry we will recognize.
- Instr->addOperand(MachineOperand::CreateJTI(Start, 0));
- return true;
- }
-
- bool AddLMemToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- return (AddRegToInstr(MI, Instr, Start + 0) &&
- AddImmToInstr(MI, Instr, Start + 1) &&
- AddRegToInstr(MI, Instr, Start + 2) &&
- AddImmToInstr(MI, Instr, Start + 3));
- }
-
- bool AddMemToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- return (AddRegToInstr(MI, Instr, Start + 0) &&
- AddImmToInstr(MI, Instr, Start + 1) &&
- AddRegToInstr(MI, Instr, Start + 2) &&
- AddImmToInstr(MI, Instr, Start + 3) &&
- AddRegToInstr(MI, Instr, Start + 4));
- }
-
- void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // Don't look yet!
-
- // Convert the MCInst to a MachineInstr so we can (ab)use the regular
- // emitter.
- const X86InstrInfo &II = *TM.getInstrInfo();
- const TargetInstrDesc &Desc = II.get(MI.getOpcode());
- MachineInstr *Instr = DummyMF->CreateMachineInstr(Desc, DebugLoc());
- DummyMBB->push_back(Instr);
-
- unsigned Opcode = MI.getOpcode();
- unsigned NumOps = MI.getNumOperands();
- unsigned CurOp = 0;
- bool AddTied = false;
- if (NumOps > 1 && Desc.getOperandConstraint(1, TOI::TIED_TO) != -1)
- AddTied = true;
- else if (NumOps > 2 &&
- Desc.getOperandConstraint(NumOps-1, TOI::TIED_TO)== 0)
- // Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
- --NumOps;
-
- bool OK = true;
- switch (Desc.TSFlags & X86II::FormMask) {
- case X86II::MRMDestReg:
- case X86II::MRMSrcReg:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (AddTied)
- OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::RawFrm:
- if (CurOp < NumOps) {
- // Hack to make branches work.
- if (!(Desc.TSFlags & X86II::ImmMask) &&
- MI.getOperand(0).isExpr() &&
- isa<MCSymbolRefExpr>(MI.getOperand(0).getExpr()))
- Instr->addOperand(MachineOperand::CreateMBB(DummyMBB));
- else
- OK &= AddImmToInstr(MI, Instr, CurOp);
- }
- break;
-
- case X86II::AddRegFrm:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (AddTied)
- OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRM0r: case X86II::MRM1r:
- case X86II::MRM2r: case X86II::MRM3r:
- case X86II::MRM4r: case X86II::MRM5r:
- case X86II::MRM6r: case X86II::MRM7r:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (AddTied)
- OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRM0m: case X86II::MRM1m:
- case X86II::MRM2m: case X86II::MRM3m:
- case X86II::MRM4m: case X86II::MRM5m:
- case X86II::MRM6m: case X86II::MRM7m:
- OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRMSrcMem:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (AddTied)
- OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
- if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r ||
- Opcode == X86::LEA16r || Opcode == X86::LEA32r)
- OK &= AddLMemToInstr(MI, Instr, CurOp);
- else
- OK &= AddMemToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRMDestMem:
- OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
- OK &= AddRegToInstr(MI, Instr, CurOp);
- break;
-
- default:
- case X86II::MRMInitReg:
- case X86II::Pseudo:
- OK = false;
- break;
- }
-
- if (!OK) {
- dbgs() << "couldn't convert inst '";
- MI.dump();
- dbgs() << "' to machine instr:\n";
- Instr->dump();
- }
-
- InstrEmitter->reset(&MI, &Fixups);
- if (OK)
- Emit->emitInstruction(*Instr, &Desc);
- OS << InstrEmitter->str();
-
- Instr->eraseFromParent();
- }
-};
-}
-
-#include "llvm/Support/CommandLine.h"
-
-static cl::opt<bool> EnableNewEncoder("enable-new-x86-encoder",
- cl::ReallyHidden);
-
-
-// Ok, now you can look.
-MCCodeEmitter *llvm::createHeinousX86MCCodeEmitter(const Target &T,
- TargetMachine &TM) {
-
- // FIXME: Remove the heinous one when the new one works.
- if (EnableNewEncoder) {
- if (TM.getTargetData()->getPointerSize() == 4)
- return createX86_32MCCodeEmitter(T, TM);
- return createX86_64MCCodeEmitter(T, TM);
- }
-
- return new X86MCCodeEmitter(static_cast<X86TargetMachine&>(TM));
-}
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index ea398e9..98e3f4e 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -388,6 +388,8 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM) {
}
case Instruction::GetElementPtr: {
+ X86AddressMode SavedAM = AM;
+
// Pattern-match simple GEPs.
uint64_t Disp = (int32_t)AM.Disp;
unsigned IndexReg = AM.IndexReg;
@@ -428,7 +430,13 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM) {
AM.IndexReg = IndexReg;
AM.Scale = Scale;
AM.Disp = (uint32_t)Disp;
- return X86SelectAddress(U->getOperand(0), AM);
+ if (X86SelectAddress(U->getOperand(0), AM))
+ return true;
+
+ // If we couldn't merge the sub value into this addr mode, revert back to
+ // our address and just match the value instead of completely failing.
+ AM = SavedAM;
+ break;
unsupported_gep:
// Ok, the GEP indices weren't all covered.
break;
@@ -786,8 +794,8 @@ bool X86FastISel::X86SelectCmp(Instruction *I) {
bool X86FastISel::X86SelectZExt(Instruction *I) {
// Handle zero-extension from i1 to i8, which is common.
- if (I->getType()->isInteger(8) &&
- I->getOperand(0)->getType()->isInteger(1)) {
+ if (I->getType()->isIntegerTy(8) &&
+ I->getOperand(0)->getType()->isIntegerTy(1)) {
unsigned ResultReg = getRegForValue(I->getOperand(0));
if (ResultReg == 0) return false;
// Set the high bits to zero.
@@ -828,30 +836,30 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
std::swap(TrueMBB, FalseMBB);
Predicate = CmpInst::FCMP_UNE;
// FALL THROUGH
- case CmpInst::FCMP_UNE: SwapArgs = false; BranchOpc = X86::JNE; break;
- case CmpInst::FCMP_OGT: SwapArgs = false; BranchOpc = X86::JA; break;
- case CmpInst::FCMP_OGE: SwapArgs = false; BranchOpc = X86::JAE; break;
- case CmpInst::FCMP_OLT: SwapArgs = true; BranchOpc = X86::JA; break;
- case CmpInst::FCMP_OLE: SwapArgs = true; BranchOpc = X86::JAE; break;
- case CmpInst::FCMP_ONE: SwapArgs = false; BranchOpc = X86::JNE; break;
- case CmpInst::FCMP_ORD: SwapArgs = false; BranchOpc = X86::JNP; break;
- case CmpInst::FCMP_UNO: SwapArgs = false; BranchOpc = X86::JP; break;
- case CmpInst::FCMP_UEQ: SwapArgs = false; BranchOpc = X86::JE; break;
- case CmpInst::FCMP_UGT: SwapArgs = true; BranchOpc = X86::JB; break;
- case CmpInst::FCMP_UGE: SwapArgs = true; BranchOpc = X86::JBE; break;
- case CmpInst::FCMP_ULT: SwapArgs = false; BranchOpc = X86::JB; break;
- case CmpInst::FCMP_ULE: SwapArgs = false; BranchOpc = X86::JBE; break;
+ case CmpInst::FCMP_UNE: SwapArgs = false; BranchOpc = X86::JNE_4; break;
+ case CmpInst::FCMP_OGT: SwapArgs = false; BranchOpc = X86::JA_4; break;
+ case CmpInst::FCMP_OGE: SwapArgs = false; BranchOpc = X86::JAE_4; break;
+ case CmpInst::FCMP_OLT: SwapArgs = true; BranchOpc = X86::JA_4; break;
+ case CmpInst::FCMP_OLE: SwapArgs = true; BranchOpc = X86::JAE_4; break;
+ case CmpInst::FCMP_ONE: SwapArgs = false; BranchOpc = X86::JNE_4; break;
+ case CmpInst::FCMP_ORD: SwapArgs = false; BranchOpc = X86::JNP_4; break;
+ case CmpInst::FCMP_UNO: SwapArgs = false; BranchOpc = X86::JP_4; break;
+ case CmpInst::FCMP_UEQ: SwapArgs = false; BranchOpc = X86::JE_4; break;
+ case CmpInst::FCMP_UGT: SwapArgs = true; BranchOpc = X86::JB_4; break;
+ case CmpInst::FCMP_UGE: SwapArgs = true; BranchOpc = X86::JBE_4; break;
+ case CmpInst::FCMP_ULT: SwapArgs = false; BranchOpc = X86::JB_4; break;
+ case CmpInst::FCMP_ULE: SwapArgs = false; BranchOpc = X86::JBE_4; break;
- case CmpInst::ICMP_EQ: SwapArgs = false; BranchOpc = X86::JE; break;
- case CmpInst::ICMP_NE: SwapArgs = false; BranchOpc = X86::JNE; break;
- case CmpInst::ICMP_UGT: SwapArgs = false; BranchOpc = X86::JA; break;
- case CmpInst::ICMP_UGE: SwapArgs = false; BranchOpc = X86::JAE; break;
- case CmpInst::ICMP_ULT: SwapArgs = false; BranchOpc = X86::JB; break;
- case CmpInst::ICMP_ULE: SwapArgs = false; BranchOpc = X86::JBE; break;
- case CmpInst::ICMP_SGT: SwapArgs = false; BranchOpc = X86::JG; break;
- case CmpInst::ICMP_SGE: SwapArgs = false; BranchOpc = X86::JGE; break;
- case CmpInst::ICMP_SLT: SwapArgs = false; BranchOpc = X86::JL; break;
- case CmpInst::ICMP_SLE: SwapArgs = false; BranchOpc = X86::JLE; break;
+ case CmpInst::ICMP_EQ: SwapArgs = false; BranchOpc = X86::JE_4; break;
+ case CmpInst::ICMP_NE: SwapArgs = false; BranchOpc = X86::JNE_4; break;
+ case CmpInst::ICMP_UGT: SwapArgs = false; BranchOpc = X86::JA_4; break;
+ case CmpInst::ICMP_UGE: SwapArgs = false; BranchOpc = X86::JAE_4; break;
+ case CmpInst::ICMP_ULT: SwapArgs = false; BranchOpc = X86::JB_4; break;
+ case CmpInst::ICMP_ULE: SwapArgs = false; BranchOpc = X86::JBE_4; break;
+ case CmpInst::ICMP_SGT: SwapArgs = false; BranchOpc = X86::JG_4; break;
+ case CmpInst::ICMP_SGE: SwapArgs = false; BranchOpc = X86::JGE_4; break;
+ case CmpInst::ICMP_SLT: SwapArgs = false; BranchOpc = X86::JL_4; break;
+ case CmpInst::ICMP_SLE: SwapArgs = false; BranchOpc = X86::JLE_4; break;
default:
return false;
}
@@ -869,7 +877,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
if (Predicate == CmpInst::FCMP_UNE) {
// X86 requires a second branch to handle UNE (and OEQ,
// which is mapped to UNE above).
- BuildMI(MBB, DL, TII.get(X86::JP)).addMBB(TrueMBB);
+ BuildMI(MBB, DL, TII.get(X86::JP_4)).addMBB(TrueMBB);
}
FastEmitBranch(FalseMBB);
@@ -923,7 +931,8 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
unsigned OpCode = SetMI->getOpcode();
if (OpCode == X86::SETOr || OpCode == X86::SETBr) {
- BuildMI(MBB, DL, TII.get(OpCode == X86::SETOr ? X86::JO : X86::JB))
+ BuildMI(MBB, DL, TII.get(OpCode == X86::SETOr ?
+ X86::JO_4 : X86::JB_4))
.addMBB(TrueMBB);
FastEmitBranch(FalseMBB);
MBB->addSuccessor(TrueMBB);
@@ -939,7 +948,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
if (OpReg == 0) return false;
BuildMI(MBB, DL, TII.get(X86::TEST8rr)).addReg(OpReg).addReg(OpReg);
- BuildMI(MBB, DL, TII.get(X86::JNE)).addMBB(TrueMBB);
+ BuildMI(MBB, DL, TII.get(X86::JNE_4)).addMBB(TrueMBB);
FastEmitBranch(FalseMBB);
MBB->addSuccessor(TrueMBB);
return true;
@@ -948,7 +957,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
bool X86FastISel::X86SelectShift(Instruction *I) {
unsigned CReg = 0, OpReg = 0, OpImm = 0;
const TargetRegisterClass *RC = NULL;
- if (I->getType()->isInteger(8)) {
+ if (I->getType()->isIntegerTy(8)) {
CReg = X86::CL;
RC = &X86::GR8RegClass;
switch (I->getOpcode()) {
@@ -957,7 +966,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL8rCL; OpImm = X86::SHL8ri; break;
default: return false;
}
- } else if (I->getType()->isInteger(16)) {
+ } else if (I->getType()->isIntegerTy(16)) {
CReg = X86::CX;
RC = &X86::GR16RegClass;
switch (I->getOpcode()) {
@@ -966,7 +975,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL16rCL; OpImm = X86::SHL16ri; break;
default: return false;
}
- } else if (I->getType()->isInteger(32)) {
+ } else if (I->getType()->isIntegerTy(32)) {
CReg = X86::ECX;
RC = &X86::GR32RegClass;
switch (I->getOpcode()) {
@@ -975,7 +984,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL32rCL; OpImm = X86::SHL32ri; break;
default: return false;
}
- } else if (I->getType()->isInteger(64)) {
+ } else if (I->getType()->isIntegerTy(64)) {
CReg = X86::RCX;
RC = &X86::GR64RegClass;
switch (I->getOpcode()) {
@@ -1160,6 +1169,8 @@ bool X86FastISel::X86VisitIntrinsicCall(IntrinsicInst &I) {
if (!X86SelectAddress(DI->getAddress(), AM))
return false;
const TargetInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
+ // FIXME may need to add RegState::Debug to any registers produced,
+ // although ESP/EBP should be the only ones at the moment.
addFullAddress(BuildMI(MBB, DL, II), AM).addImm(0).
addMetadata(DI->getVariable());
return true;
diff --git a/lib/Target/X86/X86FixupKinds.h b/lib/Target/X86/X86FixupKinds.h
new file mode 100644
index 0000000..c8dac3c
--- /dev/null
+++ b/lib/Target/X86/X86FixupKinds.h
@@ -0,0 +1,25 @@
+//===-- X86/X86FixupKinds.h - X86 Specific Fixup Entries --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_X86_X86FIXUPKINDS_H
+#define LLVM_X86_X86FIXUPKINDS_H
+
+#include "llvm/MC/MCFixup.h"
+
+namespace llvm {
+namespace X86 {
+enum Fixups {
+ reloc_pcrel_4byte = FirstTargetFixupKind, // 32-bit pcrel, e.g. a branch.
+ reloc_pcrel_1byte, // 8-bit pcrel, e.g. branch_1
+ reloc_riprel_4byte // 32-bit rip-relative
+};
+}
+}
+
+#endif
diff --git a/lib/Target/X86/X86FloatingPointRegKill.cpp b/lib/Target/X86/X86FloatingPointRegKill.cpp
index 34a0045..6a117dd 100644
--- a/lib/Target/X86/X86FloatingPointRegKill.cpp
+++ b/lib/Target/X86/X86FloatingPointRegKill.cpp
@@ -118,7 +118,7 @@ bool FPRegKiller::runOnMachineFunction(MachineFunction &MF) {
for (BasicBlock::const_iterator II = SI->begin();
(PN = dyn_cast<PHINode>(II)); ++II) {
if (PN->getType()==Type::getX86_FP80Ty(LLVMBB->getContext()) ||
- (!Subtarget.hasSSE1() && PN->getType()->isFloatingPoint()) ||
+ (!Subtarget.hasSSE1() && PN->getType()->isFloatingPointTy()) ||
(!Subtarget.hasSSE2() &&
PN->getType()==Type::getDoubleTy(LLVMBB->getContext()))) {
ContainsFPCode = true;
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index e44ce421..3fad8ad 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -12,15 +12,6 @@
//
//===----------------------------------------------------------------------===//
-// Force NDEBUG on in any optimized build on Darwin.
-//
-// FIXME: This is a huge hack, to work around ridiculously awful compile times
-// on this file with gcc-4.2 on Darwin, in Release mode.
-#if (!defined(__llvm__) && defined(__APPLE__) && \
- defined(__OPTIMIZE__) && !defined(NDEBUG))
-#define NDEBUG
-#endif
-
#define DEBUG_TYPE "x86-isel"
#include "X86.h"
#include "X86InstrBuilder.h"
@@ -177,14 +168,11 @@ namespace {
return "X86 DAG->DAG Instruction Selection";
}
- /// InstructionSelect - This callback is invoked by
- /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
- virtual void InstructionSelect();
-
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
- virtual
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const;
+ virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+ virtual void PreprocessISelDAG();
// Include the pieces autogenerated from the target description.
#include "X86GenDAGISel.inc"
@@ -208,18 +196,17 @@ namespace {
SDValue &Scale, SDValue &Index, SDValue &Disp);
bool SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp);
- bool SelectScalarSSELoad(SDNode *Op, SDValue Pred,
- SDValue N, SDValue &Base, SDValue &Scale,
+ bool SelectScalarSSELoad(SDNode *Root, SDValue N,
+ SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment,
- SDValue &InChain, SDValue &OutChain);
+ SDValue &NodeWithChain);
+
bool TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment);
- void PreprocessForRMW();
- void PreprocessForFPConvert();
-
+
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions.
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
@@ -295,19 +282,22 @@ namespace {
const X86InstrInfo *getInstrInfo() {
return getTargetMachine().getInstrInfo();
}
-
-#ifndef NDEBUG
- unsigned Indent;
-#endif
};
}
-bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+bool
+X86DAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const {
if (OptLevel == CodeGenOpt::None) return false;
- if (U == Root)
+ if (!N.hasOneUse())
+ return false;
+
+ if (N.getOpcode() != ISD::LOAD)
+ return true;
+
+ // If N is a load, do additional profitability checks.
+ if (U == Root) {
switch (U->getOpcode()) {
default: break;
case X86ISD::ADD:
@@ -354,60 +344,9 @@ bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
}
}
}
-
- // Proceed to 'generic' cycle finder code
- return SelectionDAGISel::IsLegalAndProfitableToFold(N, U, Root);
-}
-
-/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
-/// and move load below the TokenFactor. Replace store's chain operand with
-/// load's chain result.
-static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load,
- SDValue Store, SDValue TF) {
- SmallVector<SDValue, 4> Ops;
- for (unsigned i = 0, e = TF.getNode()->getNumOperands(); i != e; ++i)
- if (Load.getNode() == TF.getOperand(i).getNode())
- Ops.push_back(Load.getOperand(0));
- else
- Ops.push_back(TF.getOperand(i));
- SDValue NewTF = CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size());
- SDValue NewLoad = CurDAG->UpdateNodeOperands(Load, NewTF,
- Load.getOperand(1),
- Load.getOperand(2));
- CurDAG->UpdateNodeOperands(Store, NewLoad.getValue(1), Store.getOperand(1),
- Store.getOperand(2), Store.getOperand(3));
-}
-
-/// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG. The
-/// chain produced by the load must only be used by the store's chain operand,
-/// otherwise this may produce a cycle in the DAG.
-///
-static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
- SDValue &Load) {
- 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())
- return false;
- if (LD->getAddressingMode() != ISD::UNINDEXED)
- return false;
-
- ISD::LoadExtType ExtType = LD->getExtensionType();
- if (ExtType != ISD::NON_EXTLOAD && ExtType != ISD::EXTLOAD)
- return false;
-
- if (N.hasOneUse() &&
- LD->hasNUsesOfValue(1, 1) &&
- N.getOperand(1) == Address &&
- LD->isOperandOf(Chain.getNode())) {
- Load = N;
- return true;
- }
- return false;
+ return true;
}
/// MoveBelowCallSeqStart - Replace CALLSEQ_START operand with load's chain
@@ -473,51 +412,15 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain) {
return false;
}
-
-/// PreprocessForRMW - Preprocess the DAG to make instruction selection better.
-/// This is only run if not in -O0 mode.
-/// This allows the instruction selector to pick more read-modify-write
-/// instructions. This is a common case:
-///
-/// [Load chain]
-/// ^
-/// |
-/// [Load]
-/// ^ ^
-/// | |
-/// / \-
-/// / |
-/// [TokenFactor] [Op]
-/// ^ ^
-/// | |
-/// \ /
-/// \ /
-/// [Store]
-///
-/// The fact the store's chain operand != load's chain will prevent the
-/// (store (op (load))) instruction from being selected. We can transform it to:
-///
-/// [Load chain]
-/// ^
-/// |
-/// [TokenFactor]
-/// ^
-/// |
-/// [Load]
-/// ^ ^
-/// | |
-/// | \-
-/// | |
-/// | [Op]
-/// | ^
-/// | |
-/// \ /
-/// \ /
-/// [Store]
-void X86DAGToDAGISel::PreprocessForRMW() {
+void X86DAGToDAGISel::PreprocessISelDAG() {
+ // OptForSize is used in pattern predicates that isel is matching.
+ OptForSize = MF->getFunction()->hasFnAttr(Attribute::OptimizeForSize);
+
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
- E = CurDAG->allnodes_end(); I != E; ++I) {
- if (I->getOpcode() == X86ISD::CALL) {
+ E = CurDAG->allnodes_end(); I != E; ) {
+ SDNode *N = I++; // Preincrement iterator to avoid invalidation issues.
+
+ if (OptLevel != CodeGenOpt::None && N->getOpcode() == X86ISD::CALL) {
/// Also try moving call address load from outside callseq_start to just
/// before the call to allow it to be folded.
///
@@ -537,85 +440,23 @@ void X86DAGToDAGISel::PreprocessForRMW() {
/// \ /
/// \ /
/// [CALL]
- SDValue Chain = I->getOperand(0);
- SDValue Load = I->getOperand(1);
+ SDValue Chain = N->getOperand(0);
+ SDValue Load = N->getOperand(1);
if (!isCalleeLoad(Load, Chain))
continue;
- MoveBelowCallSeqStart(CurDAG, Load, SDValue(I, 0), Chain);
+ MoveBelowCallSeqStart(CurDAG, Load, SDValue(N, 0), Chain);
++NumLoadMoved;
continue;
}
-
- if (!ISD::isNON_TRUNCStore(I))
- continue;
- SDValue Chain = I->getOperand(0);
-
- if (Chain.getNode()->getOpcode() != ISD::TokenFactor)
- continue;
-
- SDValue N1 = I->getOperand(1);
- SDValue N2 = I->getOperand(2);
- if ((N1.getValueType().isFloatingPoint() &&
- !N1.getValueType().isVector()) ||
- !N1.hasOneUse())
- continue;
-
- bool RModW = false;
- SDValue Load;
- unsigned Opcode = N1.getNode()->getOpcode();
- switch (Opcode) {
- case ISD::ADD:
- case ISD::MUL:
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR:
- case ISD::ADDC:
- case ISD::ADDE:
- case ISD::VECTOR_SHUFFLE: {
- SDValue N10 = N1.getOperand(0);
- SDValue N11 = N1.getOperand(1);
- RModW = isRMWLoad(N10, Chain, N2, Load);
- if (!RModW)
- RModW = isRMWLoad(N11, Chain, N2, Load);
- break;
- }
- case ISD::SUB:
- case ISD::SHL:
- case ISD::SRA:
- case ISD::SRL:
- case ISD::ROTL:
- case ISD::ROTR:
- case ISD::SUBC:
- case ISD::SUBE:
- case X86ISD::SHLD:
- case X86ISD::SHRD: {
- SDValue N10 = N1.getOperand(0);
- RModW = isRMWLoad(N10, Chain, N2, Load);
- break;
- }
- }
-
- if (RModW) {
- MoveBelowTokenFactor(CurDAG, Load, SDValue(I, 0), Chain);
- ++NumLoadMoved;
- checkForCycles(I);
- }
- }
-}
-
-
-/// PreprocessForFPConvert - Walk over the dag lowering fpround and fpextend
-/// nodes that target the FP stack to be store and load to the stack. This is a
-/// gross hack. We would like to simply mark these as being illegal, but when
-/// we do that, legalize produces these when it expands calls, then expands
-/// these in the same legalize pass. We would like dag combine to be able to
-/// hack on these between the call expansion and the node legalization. As such
-/// this pass basically does "really late" legalization of these inline with the
-/// X86 isel pass.
-void X86DAGToDAGISel::PreprocessForFPConvert() {
- for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
- E = CurDAG->allnodes_end(); I != E; ) {
- SDNode *N = I++; // Preincrement iterator to avoid invalidation issues.
+
+ // Lower fpround and fpextend nodes that target the FP stack to be store and
+ // load to the stack. This is a gross hack. We would like to simply mark
+ // these as being illegal, but when we do that, legalize produces these when
+ // it expands calls, then expands these in the same legalize pass. We would
+ // like dag combine to be able to hack on these between the call expansion
+ // and the node legalization. As such this pass basically does "really
+ // late" legalization of these inline with the X86 isel pass.
+ // FIXME: This should only happen when not compiled with -O0.
if (N->getOpcode() != ISD::FP_ROUND && N->getOpcode() != ISD::FP_EXTEND)
continue;
@@ -652,9 +493,10 @@ void X86DAGToDAGISel::PreprocessForFPConvert() {
// FIXME: optimize the case where the src/dest is a load or store?
SDValue Store = CurDAG->getTruncStore(CurDAG->getEntryNode(), dl,
N->getOperand(0),
- MemTmp, NULL, 0, MemVT);
+ MemTmp, NULL, 0, MemVT,
+ false, false, 0);
SDValue Result = CurDAG->getExtLoad(ISD::EXTLOAD, dl, DstVT, Store, MemTmp,
- NULL, 0, MemVT);
+ NULL, 0, MemVT, false, false, 0);
// We're about to replace all uses of the FP_ROUND/FP_EXTEND with the
// extload we created. This will cause general havok on the dag because
@@ -670,30 +512,6 @@ void X86DAGToDAGISel::PreprocessForFPConvert() {
}
}
-/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
-/// when it has created a SelectionDAG for us to codegen.
-void X86DAGToDAGISel::InstructionSelect() {
- const Function *F = MF->getFunction();
- OptForSize = F->hasFnAttr(Attribute::OptimizeForSize);
-
- if (OptLevel != CodeGenOpt::None)
- PreprocessForRMW();
-
- // FIXME: This should only happen when not compiled with -O0.
- PreprocessForFPConvert();
-
- // Codegen the basic block.
-#ifndef NDEBUG
- DEBUG(dbgs() << "===== Instruction selection begins:\n");
- Indent = 0;
-#endif
- SelectRoot(*CurDAG);
-#ifndef NDEBUG
- DEBUG(dbgs() << "===== Instruction selection ends:\n");
-#endif
-
- CurDAG->RemoveDeadNodes();
-}
/// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
/// the main function.
@@ -1300,22 +1118,24 @@ bool X86DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base,
/// SelectScalarSSELoad - Match a scalar SSE load. In particular, we want to
/// match a load whose top elements are either undef or zeros. The load flavor
/// is derived from the type of N, which is either v4f32 or v2f64.
-bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Op, SDValue Pred,
+///
+/// We also return:
+/// PatternChainNode: this is the matched node that has a chain input and
+/// output.
+bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Root,
SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment,
- SDValue &InChain,
- SDValue &OutChain) {
+ SDValue &PatternNodeWithChain) {
if (N.getOpcode() == ISD::SCALAR_TO_VECTOR) {
- InChain = N.getOperand(0).getValue(1);
- if (ISD::isNON_EXTLoad(InChain.getNode()) &&
- InChain.getValue(0).hasOneUse() &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op)) {
- LoadSDNode *LD = cast<LoadSDNode>(InChain);
- if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
+ PatternNodeWithChain = N.getOperand(0);
+ if (ISD::isNON_EXTLoad(PatternNodeWithChain.getNode()) &&
+ PatternNodeWithChain.hasOneUse() &&
+ IsProfitableToFold(N.getOperand(0), N.getNode(), Root) &&
+ IsLegalToFold(N.getOperand(0), N.getNode(), Root)) {
+ LoadSDNode *LD = cast<LoadSDNode>(PatternNodeWithChain);
+ if (!SelectAddr(Root, LD->getBasePtr(), Base, Scale, Index, Disp,Segment))
return false;
- OutChain = LD->getChain();
return true;
}
}
@@ -1327,13 +1147,14 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Op, SDValue Pred,
N.getOperand(0).getOpcode() == ISD::SCALAR_TO_VECTOR &&
N.getOperand(0).getNode()->hasOneUse() &&
ISD::isNON_EXTLoad(N.getOperand(0).getOperand(0).getNode()) &&
- N.getOperand(0).getOperand(0).hasOneUse()) {
+ N.getOperand(0).getOperand(0).hasOneUse() &&
+ IsProfitableToFold(N.getOperand(0), N.getNode(), Root) &&
+ IsLegalToFold(N.getOperand(0), N.getNode(), Root)) {
// Okay, this is a zero extending load. Fold it.
LoadSDNode *LD = cast<LoadSDNode>(N.getOperand(0).getOperand(0));
- if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
+ if (!SelectAddr(Root, LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
return false;
- OutChain = LD->getChain();
- InChain = SDValue(LD, 1);
+ PatternNodeWithChain = SDValue(LD, 0);
return true;
}
return false;
@@ -1407,7 +1228,6 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDNode *Op, SDValue N,
bool X86DAGToDAGISel::SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp) {
- assert(Op->getOpcode() == X86ISD::TLSADDR);
assert(N.getOpcode() == ISD::TargetGlobalTLSAddress);
const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
@@ -1434,11 +1254,12 @@ bool X86DAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment) {
- if (ISD::isNON_EXTLoad(N.getNode()) &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P, P))
- return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment);
- return false;
+ if (!ISD::isNON_EXTLoad(N.getNode()) ||
+ !IsProfitableToFold(N, P, P) ||
+ !IsLegalToFold(N, P, P))
+ return false;
+
+ return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment);
}
/// getGlobalBaseReg - Return an SDNode that returns the value of
@@ -1541,7 +1362,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
Opc = X86::LOCK_DEC16m;
else if (isSub) {
if (isCN) {
- if (Predicate_i16immSExt8(Val.getNode()))
+ if (Predicate_immSext8(Val.getNode()))
Opc = X86::LOCK_SUB16mi8;
else
Opc = X86::LOCK_SUB16mi;
@@ -1549,7 +1370,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
Opc = X86::LOCK_SUB16mr;
} else {
if (isCN) {
- if (Predicate_i16immSExt8(Val.getNode()))
+ if (Predicate_immSext8(Val.getNode()))
Opc = X86::LOCK_ADD16mi8;
else
Opc = X86::LOCK_ADD16mi;
@@ -1564,7 +1385,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
Opc = X86::LOCK_DEC32m;
else if (isSub) {
if (isCN) {
- if (Predicate_i32immSExt8(Val.getNode()))
+ if (Predicate_immSext8(Val.getNode()))
Opc = X86::LOCK_SUB32mi8;
else
Opc = X86::LOCK_SUB32mi;
@@ -1572,7 +1393,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
Opc = X86::LOCK_SUB32mr;
} else {
if (isCN) {
- if (Predicate_i32immSExt8(Val.getNode()))
+ if (Predicate_immSext8(Val.getNode()))
Opc = X86::LOCK_ADD32mi8;
else
Opc = X86::LOCK_ADD32mi;
@@ -1588,7 +1409,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
else if (isSub) {
Opc = X86::LOCK_SUB64mr;
if (isCN) {
- if (Predicate_i64immSExt8(Val.getNode()))
+ if (Predicate_immSext8(Val.getNode()))
Opc = X86::LOCK_SUB64mi8;
else if (Predicate_i64immSExt32(Val.getNode()))
Opc = X86::LOCK_SUB64mi32;
@@ -1596,7 +1417,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
} else {
Opc = X86::LOCK_ADD64mr;
if (isCN) {
- if (Predicate_i64immSExt8(Val.getNode()))
+ if (Predicate_immSext8(Val.getNode()))
Opc = X86::LOCK_ADD64mi8;
else if (Predicate_i64immSExt32(Val.getNode()))
Opc = X86::LOCK_ADD64mi32;
@@ -1652,8 +1473,8 @@ static bool HasNoSignedComparisonUses(SDNode *N) {
case X86::SETEr: case X86::SETNEr: case X86::SETPr: case X86::SETNPr:
case X86::SETAm: case X86::SETAEm: case X86::SETBm: case X86::SETBEm:
case X86::SETEm: case X86::SETNEm: case X86::SETPm: case X86::SETNPm:
- case X86::JA: case X86::JAE: case X86::JB: case X86::JBE:
- case X86::JE: case X86::JNE: case X86::JP: case X86::JNP:
+ case X86::JA_4: case X86::JAE_4: case X86::JB_4: case X86::JBE_4:
+ case X86::JE_4: case X86::JNE_4: case X86::JP_4: case X86::JNP_4:
case X86::CMOVA16rr: case X86::CMOVA16rm:
case X86::CMOVA32rr: case X86::CMOVA32rm:
case X86::CMOVA64rr: case X86::CMOVA64rm:
@@ -1693,24 +1514,10 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
unsigned Opcode = Node->getOpcode();
DebugLoc dl = Node->getDebugLoc();
-#ifndef NDEBUG
- DEBUG({
- dbgs() << std::string(Indent, ' ') << "Selecting: ";
- Node->dump(CurDAG);
- dbgs() << '\n';
- });
- Indent += 2;
-#endif
+ DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << '\n');
if (Node->isMachineOpcode()) {
-#ifndef NDEBUG
- DEBUG({
- dbgs() << std::string(Indent-2, ' ') << "== ";
- Node->dump(CurDAG);
- dbgs() << '\n';
- });
- Indent -= 2;
-#endif
+ DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << '\n');
return NULL; // Already selected.
}
@@ -1806,13 +1613,7 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
LoReg, NVT, InFlag);
InFlag = Result.getValue(2);
ReplaceUses(SDValue(Node, 0), Result);
-#ifndef NDEBUG
- DEBUG({
- dbgs() << std::string(Indent-2, ' ') << "=> ";
- Result.getNode()->dump(CurDAG);
- dbgs() << '\n';
- });
-#endif
+ DEBUG(dbgs() << "=> "; Result.getNode()->dump(CurDAG); dbgs() << '\n');
}
// Copy the high half of the result, if it is needed.
if (!SDValue(Node, 1).use_empty()) {
@@ -1835,19 +1636,9 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
InFlag = Result.getValue(2);
}
ReplaceUses(SDValue(Node, 1), Result);
-#ifndef NDEBUG
- DEBUG({
- dbgs() << std::string(Indent-2, ' ') << "=> ";
- Result.getNode()->dump(CurDAG);
- dbgs() << '\n';
- });
-#endif
+ DEBUG(dbgs() << "=> "; Result.getNode()->dump(CurDAG); dbgs() << '\n');
}
-#ifndef NDEBUG
- Indent -= 2;
-#endif
-
return NULL;
}
@@ -1962,13 +1753,7 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
LoReg, NVT, InFlag);
InFlag = Result.getValue(2);
ReplaceUses(SDValue(Node, 0), Result);
-#ifndef NDEBUG
- DEBUG({
- dbgs() << std::string(Indent-2, ' ') << "=> ";
- Result.getNode()->dump(CurDAG);
- dbgs() << '\n';
- });
-#endif
+ DEBUG(dbgs() << "=> "; Result.getNode()->dump(CurDAG); dbgs() << '\n');
}
// Copy the remainder (high) result, if it is needed.
if (!SDValue(Node, 1).use_empty()) {
@@ -1992,19 +1777,8 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
InFlag = Result.getValue(2);
}
ReplaceUses(SDValue(Node, 1), Result);
-#ifndef NDEBUG
- DEBUG({
- dbgs() << std::string(Indent-2, ' ') << "=> ";
- Result.getNode()->dump(CurDAG);
- dbgs() << '\n';
- });
-#endif
+ DEBUG(dbgs() << "=> "; Result.getNode()->dump(CurDAG); dbgs() << '\n');
}
-
-#ifndef NDEBUG
- Indent -= 2;
-#endif
-
return NULL;
}
@@ -2117,17 +1891,12 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
SDNode *ResNode = SelectCode(Node);
-#ifndef NDEBUG
- DEBUG({
- dbgs() << std::string(Indent-2, ' ') << "=> ";
- if (ResNode == NULL || ResNode == Node)
- Node->dump(CurDAG);
- else
- ResNode->dump(CurDAG);
- dbgs() << '\n';
- });
- Indent -= 2;
-#endif
+ DEBUG(dbgs() << "=> ";
+ if (ResNode == NULL || ResNode == Node)
+ Node->dump(CurDAG);
+ else
+ ResNode->dump(CurDAG);
+ dbgs() << '\n');
return ResNode;
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 515bc84..802bedc 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -73,15 +73,16 @@ static TargetLoweringObjectFile *createTLOF(X86TargetMachine &TM) {
case X86Subtarget::isDarwin:
if (TM.getSubtarget<X86Subtarget>().is64Bit())
return new X8664_MachoTargetObjectFile();
- return new X8632_MachoTargetObjectFile();
+ return new TargetLoweringObjectFileMachO();
case X86Subtarget::isELF:
- return new TargetLoweringObjectFileELF();
+ if (TM.getSubtarget<X86Subtarget>().is64Bit())
+ return new X8664_ELFTargetObjectFile(TM);
+ return new X8632_ELFTargetObjectFile(TM);
case X86Subtarget::isMingw:
case X86Subtarget::isCygwin:
case X86Subtarget::isWindows:
return new TargetLoweringObjectFileCOFF();
}
-
}
X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
@@ -1001,19 +1002,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
computeRegisterProperties();
- // Divide and reminder operations have no vector equivalent and can
- // trap. Do a custom widening for these operations in which we never
- // generate more divides/remainder than the original vector width.
- for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
- VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
- if (!isTypeLegal((MVT::SimpleValueType)VT)) {
- setOperationAction(ISD::SDIV, (MVT::SimpleValueType) VT, Custom);
- setOperationAction(ISD::UDIV, (MVT::SimpleValueType) VT, Custom);
- setOperationAction(ISD::SREM, (MVT::SimpleValueType) VT, Custom);
- setOperationAction(ISD::UREM, (MVT::SimpleValueType) VT, Custom);
- }
- }
-
// FIXME: These should be based on subtarget info. Plus, the values should
// be smaller when we are in optimizing for size mode.
maxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
@@ -1411,18 +1399,6 @@ CCAssignFn *X86TargetLowering::CCAssignFnForNode(CallingConv::ID CC) const {
return CC_X86_32_C;
}
-/// NameDecorationForCallConv - Selects the appropriate decoration to
-/// apply to a MachineFunction containing a given calling convention.
-NameDecorationStyle
-X86TargetLowering::NameDecorationForCallConv(CallingConv::ID CallConv) {
- if (CallConv == CallingConv::X86_FastCall)
- return FastCall;
- else if (CallConv == CallingConv::X86_StdCall)
- return StdCall;
- return None;
-}
-
-
/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
/// by "Src" to address "Dst" with size and alignment information specified by
/// the specific parameter attribute. The copy will be passed as a byval
@@ -1476,7 +1452,8 @@ X86TargetLowering::LowerMemArgument(SDValue Chain,
VA.getLocMemOffset(), isImmutable, false);
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
return DAG.getLoad(ValVT, dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0);
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
}
}
@@ -1498,9 +1475,6 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
Fn->getName() == "main")
FuncInfo->setForceFramePointer(true);
- // Decorate the function name.
- FuncInfo->setDecorationStyle(NameDecorationForCallConv(CallConv));
-
MachineFrameInfo *MFI = MF.getFrameInfo();
bool Is64Bit = Subtarget->is64Bit();
bool IsWin64 = Subtarget->isTargetWin64();
@@ -1573,7 +1547,8 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
// If value is passed via pointer - do a load.
if (VA.getLocInfo() == CCValAssign::Indirect)
- ArgValue = DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue, NULL, 0);
+ ArgValue = DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue, NULL, 0,
+ false, false, 0);
InVals.push_back(ArgValue);
}
@@ -1668,7 +1643,7 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
SDValue Store =
DAG.getStore(Val.getValue(1), dl, Val, FIN,
PseudoSourceValue::getFixedStack(RegSaveFrameIndex),
- Offset);
+ Offset, false, false, 0);
MemOps.push_back(Store);
Offset += 8;
}
@@ -1737,7 +1712,8 @@ X86TargetLowering::LowerMemOpCallTo(SDValue Chain,
return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl);
}
return DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), LocMemOffset);
+ PseudoSourceValue::getStack(), LocMemOffset,
+ false, false, 0);
}
/// EmitTailCallLoadRetAddr - Emit a load of return address if tail call
@@ -1752,7 +1728,7 @@ X86TargetLowering::EmitTailCallLoadRetAddr(SelectionDAG &DAG,
OutRetAddr = getReturnAddressFrameIndex(DAG);
// Load the "old" Return address.
- OutRetAddr = DAG.getLoad(VT, dl, Chain, OutRetAddr, NULL, 0);
+ OutRetAddr = DAG.getLoad(VT, dl, Chain, OutRetAddr, NULL, 0, false, false, 0);
return SDValue(OutRetAddr.getNode(), 1);
}
@@ -1767,11 +1743,12 @@ EmitTailCallStoreRetAddr(SelectionDAG & DAG, MachineFunction &MF,
// Calculate the new stack slot for the return address.
int SlotSize = Is64Bit ? 8 : 4;
int NewReturnAddrFI =
- MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize, true,false);
+ MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize, false, false);
EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
SDValue NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
Chain = DAG.getStore(Chain, dl, RetAddrFrIdx, NewRetAddrFrIdx,
- PseudoSourceValue::getFixedStack(NewReturnAddrFI), 0);
+ PseudoSourceValue::getFixedStack(NewReturnAddrFI), 0,
+ false, false, 0);
return Chain;
}
@@ -1882,7 +1859,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT());
int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
Chain = DAG.getStore(Chain, dl, Arg, SpillSlot,
- PseudoSourceValue::getFixedStack(FI), 0);
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
Arg = SpillSlot;
break;
}
@@ -2013,7 +1991,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// Store relative to framepointer.
MemOpChains2.push_back(
DAG.getStore(ArgChain, dl, Arg, FIN,
- PseudoSourceValue::getFixedStack(FI), 0));
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0));
}
}
}
@@ -2256,7 +2235,8 @@ static
bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
MachineFrameInfo *MFI, const MachineRegisterInfo *MRI,
const X86InstrInfo *TII) {
- int FI;
+ unsigned Bytes = Arg.getValueType().getSizeInBits() / 8;
+ int FI = INT_MAX;
if (Arg.getOpcode() == ISD::CopyFromReg) {
unsigned VR = cast<RegisterSDNode>(Arg.getOperand(1))->getReg();
if (!VR || TargetRegisterInfo::isPhysicalRegister(VR))
@@ -2272,25 +2252,30 @@ bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r) &&
Def->getOperand(1).isFI()) {
FI = Def->getOperand(1).getIndex();
- if (MFI->getObjectSize(FI) != Flags.getByValSize())
- return false;
+ Bytes = Flags.getByValSize();
} else
return false;
}
- } else {
- LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg);
- if (!Ld)
+ } else if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg)) {
+ if (Flags.isByVal())
+ // ByVal argument is passed in as a pointer but it's now being
+ // dereferenced. e.g.
+ // define @foo(%struct.X* %A) {
+ // tail call @bar(%struct.X* byval %A)
+ // }
return false;
SDValue Ptr = Ld->getBasePtr();
FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
if (!FINode)
return false;
FI = FINode->getIndex();
- }
+ } else
+ return false;
+ assert(FI != INT_MAX);
if (!MFI->isFixedObjectIndex(FI))
return false;
- return Offset == MFI->getObjectOffset(FI);
+ return Offset == MFI->getObjectOffset(FI) && Bytes == MFI->getObjectSize(FI);
}
/// IsEligibleForTailCallOptimization - Check whether the call is eligible
@@ -2397,7 +2382,7 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
// Set up a frame object for the return address.
uint64_t SlotSize = TD->getPointerSize();
ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
- true, false);
+ false, false);
FuncInfo->setRAIndex(ReturnAddrIndex);
}
@@ -3592,7 +3577,8 @@ X86TargetLowering::LowerAsSplatVectorLoad(SDValue SrcOp, EVT VT, DebugLoc dl,
int EltNo = (Offset - StartOffset) >> 2;
int Mask[4] = { EltNo, EltNo, EltNo, EltNo };
EVT VT = (PVT == MVT::i32) ? MVT::v4i32 : MVT::v4f32;
- SDValue V1 = DAG.getLoad(VT, dl, Chain, Ptr,LD->getSrcValue(),0);
+ SDValue V1 = DAG.getLoad(VT, dl, Chain, Ptr,LD->getSrcValue(),0,
+ false, false, 0);
// Canonicalize it to a v4i32 shuffle.
V1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, V1);
return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
@@ -4836,8 +4822,16 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG){
if ((EltVT.getSizeInBits() == 8 || EltVT.getSizeInBits() == 16) &&
isa<ConstantSDNode>(N2)) {
- unsigned Opc = (EltVT.getSizeInBits() == 8) ? X86ISD::PINSRB
- : X86ISD::PINSRW;
+ unsigned Opc;
+ if (VT == MVT::v8i16)
+ Opc = X86ISD::PINSRW;
+ else if (VT == MVT::v4i16)
+ Opc = X86ISD::MMX_PINSRW;
+ else if (VT == MVT::v16i8)
+ Opc = X86ISD::PINSRB;
+ else
+ Opc = X86ISD::PINSRB;
+
// Transform it so it match pinsr{b,w} which expects a GR32 as its second
// argument.
if (N1.getValueType() != MVT::i32)
@@ -4888,7 +4882,8 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
N1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, N1);
if (N2.getValueType() != MVT::i32)
N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getZExtValue());
- return DAG.getNode(X86ISD::PINSRW, dl, VT, N0, N1, N2);
+ return DAG.getNode(VT == MVT::v8i16 ? X86ISD::PINSRW : X86ISD::MMX_PINSRW,
+ dl, VT, N0, N1, N2);
}
return SDValue();
}
@@ -5091,7 +5086,7 @@ X86TargetLowering::LowerGlobalAddress(const GlobalValue *GV, DebugLoc dl,
// load.
if (isGlobalStubReference(OpFlags))
Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0, false, false, 0);
// If there was a non-zero offset that we didn't fold, create an explicit
// addition for it.
@@ -5171,7 +5166,7 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
MVT::i32));
SDValue ThreadPointer = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Base,
- NULL, 0);
+ NULL, 0, false, false, 0);
unsigned char OperandFlags = 0;
// Most TLS accesses are not RIP relative, even on x86-64. One exception is
@@ -5196,7 +5191,7 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
if (model == TLSModel::InitialExec)
Offset = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Offset,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0, false, false, 0);
// The address of the thread local variable is the add of the thread
// pointer with the offset of the variable.
@@ -5264,7 +5259,7 @@ SDValue X86TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) {
SDValue AndNode = DAG.getNode(ISD::AND, dl, MVT::i8, ShAmt,
DAG.getConstant(VTBits, MVT::i8));
- SDValue Cond = DAG.getNode(X86ISD::CMP, dl, VT,
+ SDValue Cond = DAG.getNode(X86ISD::CMP, dl, MVT::i32,
AndNode, DAG.getConstant(0, MVT::i8));
SDValue Hi, Lo;
@@ -5313,7 +5308,8 @@ SDValue X86TargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
SDValue StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Op.getOperand(0),
StackSlot,
- PseudoSourceValue::getFixedStack(SSFI), 0);
+ PseudoSourceValue::getFixedStack(SSFI), 0,
+ false, false, 0);
return BuildFILD(Op, SrcVT, Chain, StackSlot, DAG);
}
@@ -5348,7 +5344,8 @@ SDValue X86TargetLowering::BuildFILD(SDValue Op, EVT SrcVT, SDValue Chain,
};
Chain = DAG.getNode(X86ISD::FST, dl, Tys, Ops, array_lengthof(Ops));
Result = DAG.getLoad(Op.getValueType(), dl, Chain, StackSlot,
- PseudoSourceValue::getFixedStack(SSFI), 0);
+ PseudoSourceValue::getFixedStack(SSFI), 0,
+ false, false, 0);
}
return Result;
@@ -5421,12 +5418,12 @@ SDValue X86TargetLowering::LowerUINT_TO_FP_i64(SDValue Op, SelectionDAG &DAG) {
SDValue Unpck1 = getUnpackl(DAG, dl, MVT::v4i32, XR1, XR2);
SDValue CLod0 = DAG.getLoad(MVT::v4i32, dl, DAG.getEntryNode(), CPIdx0,
PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ false, false, 16);
SDValue Unpck2 = getUnpackl(DAG, dl, MVT::v4i32, Unpck1, CLod0);
SDValue XR2F = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, Unpck2);
SDValue CLod1 = DAG.getLoad(MVT::v2f64, dl, CLod0.getValue(1), CPIdx1,
PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ false, false, 16);
SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::v2f64, XR2F, CLod1);
// Add the halves; easiest way is to swap them into another reg first.
@@ -5513,9 +5510,9 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
SDValue OffsetSlot = DAG.getNode(ISD::ADD, dl,
getPointerTy(), StackSlot, WordOff);
SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, Op.getOperand(0),
- StackSlot, NULL, 0);
+ StackSlot, NULL, 0, false, false, 0);
SDValue Store2 = DAG.getStore(Store1, dl, DAG.getConstant(0, MVT::i32),
- OffsetSlot, NULL, 0);
+ OffsetSlot, NULL, 0, false, false, 0);
return BuildFILD(Op, MVT::i64, Store2, StackSlot, DAG);
}
@@ -5563,7 +5560,8 @@ FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG, bool IsSigned) {
if (isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType())) {
assert(DstTy == MVT::i64 && "Invalid FP_TO_SINT to lower!");
Chain = DAG.getStore(Chain, dl, Value, StackSlot,
- PseudoSourceValue::getFixedStack(SSFI), 0);
+ PseudoSourceValue::getFixedStack(SSFI), 0,
+ false, false, 0);
SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
SDValue Ops[] = {
Chain, StackSlot, DAG.getValueType(Op.getOperand(0).getValueType())
@@ -5597,7 +5595,7 @@ SDValue X86TargetLowering::LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
// Load the result.
return DAG.getLoad(Op.getValueType(), Op.getDebugLoc(),
- FIST, StackSlot, NULL, 0);
+ FIST, StackSlot, NULL, 0, false, false, 0);
}
SDValue X86TargetLowering::LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) {
@@ -5607,7 +5605,7 @@ SDValue X86TargetLowering::LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) {
// Load the result.
return DAG.getLoad(Op.getValueType(), Op.getDebugLoc(),
- FIST, StackSlot, NULL, 0);
+ FIST, StackSlot, NULL, 0, false, false, 0);
}
SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) {
@@ -5632,8 +5630,8 @@ SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) {
Constant *C = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
return DAG.getNode(X86ISD::FAND, dl, VT, Op.getOperand(0), Mask);
}
@@ -5659,8 +5657,8 @@ SDValue X86TargetLowering::LowerFNEG(SDValue Op, SelectionDAG &DAG) {
Constant *C = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
if (VT.isVector()) {
return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
DAG.getNode(ISD::XOR, dl, MVT::v2i64,
@@ -5708,8 +5706,8 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
Constant *C = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask1 = DAG.getLoad(SrcVT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
SDValue SignBit = DAG.getNode(X86ISD::FAND, dl, SrcVT, Op1, Mask1);
// Shift sign bit right or left if the two operands have different types.
@@ -5737,8 +5735,8 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
C = ConstantVector::get(CV);
CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask2 = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
SDValue Val = DAG.getNode(X86ISD::FAND, dl, VT, Op0, Mask2);
// Or the value with the sign bit.
@@ -5890,26 +5888,31 @@ SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC,
/// LowerToBT - Result of 'and' is compared against zero. Turn it into a BT node
/// if it's possible.
-static SDValue LowerToBT(SDValue Op0, ISD::CondCode CC,
+static SDValue LowerToBT(SDValue And, ISD::CondCode CC,
DebugLoc dl, SelectionDAG &DAG) {
+ SDValue Op0 = And.getOperand(0);
+ SDValue Op1 = And.getOperand(1);
+ if (Op0.getOpcode() == ISD::TRUNCATE)
+ Op0 = Op0.getOperand(0);
+ if (Op1.getOpcode() == ISD::TRUNCATE)
+ Op1 = Op1.getOperand(0);
+
SDValue LHS, RHS;
- if (Op0.getOperand(1).getOpcode() == ISD::SHL) {
- if (ConstantSDNode *Op010C =
- dyn_cast<ConstantSDNode>(Op0.getOperand(1).getOperand(0)))
- if (Op010C->getZExtValue() == 1) {
- LHS = Op0.getOperand(0);
- RHS = Op0.getOperand(1).getOperand(1);
+ if (Op1.getOpcode() == ISD::SHL) {
+ if (ConstantSDNode *And10C = dyn_cast<ConstantSDNode>(Op1.getOperand(0)))
+ if (And10C->getZExtValue() == 1) {
+ LHS = Op0;
+ RHS = Op1.getOperand(1);
}
- } else if (Op0.getOperand(0).getOpcode() == ISD::SHL) {
- if (ConstantSDNode *Op000C =
- dyn_cast<ConstantSDNode>(Op0.getOperand(0).getOperand(0)))
- if (Op000C->getZExtValue() == 1) {
- LHS = Op0.getOperand(1);
- RHS = Op0.getOperand(0).getOperand(1);
+ } else if (Op0.getOpcode() == ISD::SHL) {
+ if (ConstantSDNode *And00C = dyn_cast<ConstantSDNode>(Op0.getOperand(0)))
+ if (And00C->getZExtValue() == 1) {
+ LHS = Op1;
+ RHS = Op0.getOperand(1);
}
- } else if (Op0.getOperand(1).getOpcode() == ISD::Constant) {
- ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
- SDValue AndLHS = Op0.getOperand(0);
+ } else if (Op1.getOpcode() == ISD::Constant) {
+ ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op1);
+ SDValue AndLHS = Op0;
if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
LHS = AndLHS.getOperand(0);
RHS = AndLHS.getOperand(1);
@@ -5959,6 +5962,21 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
return NewSetCC;
}
+ // Look for "(setcc) == / != 1" to avoid unncessary setcc.
+ if (Op0.getOpcode() == X86ISD::SETCC &&
+ Op1.getOpcode() == ISD::Constant &&
+ (cast<ConstantSDNode>(Op1)->getZExtValue() == 1 ||
+ cast<ConstantSDNode>(Op1)->isNullValue()) &&
+ (CC == ISD::SETEQ || CC == ISD::SETNE)) {
+ X86::CondCode CCode = (X86::CondCode)Op0.getConstantOperandVal(0);
+ bool Invert = (CC == ISD::SETNE) ^
+ cast<ConstantSDNode>(Op1)->isNullValue();
+ if (Invert)
+ CCode = X86::GetOppositeBranchCondition(CCode);
+ return DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
+ DAG.getConstant(CCode, MVT::i8), Op0.getOperand(1));
+ }
+
bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
unsigned X86CC = TranslateX86CC(CC, isFP, Op0, Op1, DAG);
if (X86CC == X86::COND_INVALID)
@@ -6400,24 +6418,13 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
EVT IntPtr = getPointerTy();
EVT SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
- Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true));
-
Chain = DAG.getCopyToReg(Chain, dl, X86::EAX, Size, Flag);
Flag = Chain.getValue(1);
- SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
- SDValue Ops[] = { Chain,
- DAG.getTargetExternalSymbol("_alloca", IntPtr),
- DAG.getRegister(X86::EAX, IntPtr),
- DAG.getRegister(X86StackPtr, SPTy),
- Flag };
- Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops, 5);
- Flag = Chain.getValue(1);
+ SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
- Chain = DAG.getCALLSEQ_END(Chain,
- DAG.getIntPtrConstant(0, true),
- DAG.getIntPtrConstant(0, true),
- Flag);
+ Chain = DAG.getNode(X86ISD::MINGW_ALLOCA, dl, NodeTys, Chain, Flag);
+ Flag = Chain.getValue(1);
Chain = DAG.getCopyFromReg(Chain, dl, X86StackPtr, SPTy).getValue(1);
@@ -6461,8 +6468,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()),
false, false, false, false,
0, CallingConv::C, false, /*isReturnValueUsed=*/false,
- DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl,
- DAG.GetOrdering(Chain.getNode()));
+ DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl);
return CallResult.second;
}
@@ -6646,7 +6652,8 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
// vastart just stores the address of the VarArgsFrameIndex slot into the
// memory location argument.
SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
- return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
// __va_list_tag:
@@ -6658,8 +6665,8 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
SDValue FIN = Op.getOperand(1);
// Store gp_offset
SDValue Store = DAG.getStore(Op.getOperand(0), dl,
- DAG.getConstant(VarArgsGPOffset, MVT::i32),
- FIN, SV, 0);
+ DAG.getConstant(VarArgsGPOffset, MVT::i32),
+ FIN, SV, 0, false, false, 0);
MemOps.push_back(Store);
// Store fp_offset
@@ -6667,21 +6674,23 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
FIN, DAG.getIntPtrConstant(4));
Store = DAG.getStore(Op.getOperand(0), dl,
DAG.getConstant(VarArgsFPOffset, MVT::i32),
- FIN, SV, 0);
+ FIN, SV, 0, false, false, 0);
MemOps.push_back(Store);
// Store ptr to overflow_arg_area
FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(),
FIN, DAG.getIntPtrConstant(4));
SDValue OVFIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
- Store = DAG.getStore(Op.getOperand(0), dl, OVFIN, FIN, SV, 0);
+ Store = DAG.getStore(Op.getOperand(0), dl, OVFIN, FIN, SV, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Store ptr to reg_save_area.
FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(),
FIN, DAG.getIntPtrConstant(8));
SDValue RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
- Store = DAG.getStore(Op.getOperand(0), dl, RSFIN, FIN, SV, 0);
+ Store = DAG.getStore(Op.getOperand(0), dl, RSFIN, FIN, SV, 0,
+ false, false, 0);
MemOps.push_back(Store);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&MemOps[0], MemOps.size());
@@ -6967,13 +6976,13 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
DAG.getNode(ISD::ADD, dl, getPointerTy(),
FrameAddr, Offset),
- NULL, 0);
+ NULL, 0, false, false, 0);
}
// Just load the return address.
SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- RetAddrFI, NULL, 0);
+ RetAddrFI, NULL, 0, false, false, 0);
}
SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
@@ -6985,7 +6994,8 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
unsigned FrameReg = Subtarget->is64Bit() ? X86::RBP : X86::EBP;
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
while (Depth--)
- FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
+ FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0,
+ false, false, 0);
return FrameAddr;
}
@@ -7009,7 +7019,7 @@ SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG)
SDValue StoreAddr = DAG.getNode(ISD::SUB, dl, getPointerTy(), Frame,
DAG.getIntPtrConstant(-TD->getPointerSize()));
StoreAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(), StoreAddr, Offset);
- Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, NULL, 0);
+ Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, NULL, 0, false, false, 0);
Chain = DAG.getCopyToReg(Chain, dl, StoreAddrReg, StoreAddr);
MF.getRegInfo().addLiveOut(StoreAddrReg);
@@ -7044,11 +7054,12 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
SDValue Addr = Trmp;
OutChains[0] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, MVT::i16),
- Addr, TrmpAddr, 0);
+ Addr, TrmpAddr, 0, false, false, 0);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(2, MVT::i64));
- OutChains[1] = DAG.getStore(Root, dl, FPtr, Addr, TrmpAddr, 2, false, 2);
+ OutChains[1] = DAG.getStore(Root, dl, FPtr, Addr, TrmpAddr, 2,
+ false, false, 2);
// Load the 'nest' parameter value into R10.
// R10 is specified in X86CallingConv.td
@@ -7056,24 +7067,25 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(10, MVT::i64));
OutChains[2] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, MVT::i16),
- Addr, TrmpAddr, 10);
+ Addr, TrmpAddr, 10, false, false, 0);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(12, MVT::i64));
- OutChains[3] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 12, false, 2);
+ OutChains[3] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 12,
+ false, false, 2);
// Jump to the nested function.
OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(20, MVT::i64));
OutChains[4] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, MVT::i16),
- Addr, TrmpAddr, 20);
+ Addr, TrmpAddr, 20, false, false, 0);
unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(22, MVT::i64));
OutChains[5] = DAG.getStore(Root, dl, DAG.getConstant(ModRM, MVT::i8), Addr,
- TrmpAddr, 22);
+ TrmpAddr, 22, false, false, 0);
SDValue Ops[] =
{ Trmp, DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 6) };
@@ -7133,21 +7145,23 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
const unsigned char N86Reg = RegInfo->getX86RegNum(NestReg);
OutChains[0] = DAG.getStore(Root, dl,
DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
- Trmp, TrmpAddr, 0);
+ Trmp, TrmpAddr, 0, false, false, 0);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(1, MVT::i32));
- OutChains[1] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 1, false, 1);
+ OutChains[1] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 1,
+ false, false, 1);
const unsigned char JMP = 0xE9; // jmp <32bit dst> opcode.
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(5, MVT::i32));
OutChains[2] = DAG.getStore(Root, dl, DAG.getConstant(JMP, MVT::i8), Addr,
- TrmpAddr, 5, false, 1);
+ TrmpAddr, 5, false, false, 1);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(6, MVT::i32));
- OutChains[3] = DAG.getStore(Root, dl, Disp, Addr, TrmpAddr, 6, false, 1);
+ OutChains[3] = DAG.getStore(Root, dl, Disp, Addr, TrmpAddr, 6,
+ false, false, 1);
SDValue Ops[] =
{ Trmp, DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 4) };
@@ -7190,7 +7204,8 @@ SDValue X86TargetLowering::LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) {
DAG.getEntryNode(), StackSlot);
// Load FP Control Word from stack slot
- SDValue CWD = DAG.getLoad(MVT::i16, dl, Chain, StackSlot, NULL, 0);
+ SDValue CWD = DAG.getLoad(MVT::i16, dl, Chain, StackSlot, NULL, 0,
+ false, false, 0);
// Transform as necessary
SDValue CWD1 =
@@ -7554,7 +7569,8 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
if (FIST.getNode() != 0) {
EVT VT = N->getValueType(0);
// Return a load from the stack slot.
- Results.push_back(DAG.getLoad(VT, dl, FIST, StackSlot, NULL, 0));
+ Results.push_back(DAG.getLoad(VT, dl, FIST, StackSlot, NULL, 0,
+ false, false, 0));
}
return;
}
@@ -7572,14 +7588,6 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
Results.push_back(edx.getValue(1));
return;
}
- case ISD::SDIV:
- case ISD::UDIV:
- case ISD::SREM:
- case ISD::UREM: {
- EVT WidenVT = getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
- Results.push_back(DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements()));
- return;
- }
case ISD::ATOMIC_CMP_SWAP: {
EVT T = N->getValueType(0);
assert (T == MVT::i64 && "Only know how to expand i64 Cmp and Swap");
@@ -7677,6 +7685,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
case X86ISD::INSERTPS: return "X86ISD::INSERTPS";
case X86ISD::PINSRB: return "X86ISD::PINSRB";
case X86ISD::PINSRW: return "X86ISD::PINSRW";
+ case X86ISD::MMX_PINSRW: return "X86ISD::MMX_PINSRW";
case X86ISD::PSHUFB: return "X86ISD::PSHUFB";
case X86ISD::FMAX: return "X86ISD::FMAX";
case X86ISD::FMIN: return "X86ISD::FMIN";
@@ -7721,6 +7730,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM";
case X86ISD::PTEST: return "X86ISD::PTEST";
case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS";
+ case X86ISD::MINGW_ALLOCA: return "X86ISD::MINGW_ALLOCA";
}
}
@@ -7778,13 +7788,13 @@ bool X86TargetLowering::isLegalAddressingMode(const AddrMode &AM,
bool X86TargetLowering::isTruncateFree(const Type *Ty1, const Type *Ty2) const {
- if (!Ty1->isInteger() || !Ty2->isInteger())
+ if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
return false;
unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
if (NumBits1 <= NumBits2)
return false;
- return Subtarget->is64Bit() || NumBits1 < 64;
+ return true;
}
bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
@@ -7794,12 +7804,12 @@ bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
unsigned NumBits2 = VT2.getSizeInBits();
if (NumBits1 <= NumBits2)
return false;
- return Subtarget->is64Bit() || NumBits1 < 64;
+ return true;
}
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(32) && Ty2->isInteger(64) && Subtarget->is64Bit();
+ return Ty1->isIntegerTy(32) && Ty2->isIntegerTy(64) && Subtarget->is64Bit();
}
bool X86TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
@@ -7955,7 +7965,7 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
MIB.addReg(EAXreg);
// insert branch
- BuildMI(newMBB, dl, TII->get(X86::JNE)).addMBB(newMBB);
+ BuildMI(newMBB, dl, TII->get(X86::JNE_4)).addMBB(newMBB);
F->DeleteMachineInstr(bInstr); // The pseudo instruction is gone now.
return nextMBB;
@@ -8112,7 +8122,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
MIB.addReg(X86::EDX);
// insert branch
- BuildMI(newMBB, dl, TII->get(X86::JNE)).addMBB(newMBB);
+ BuildMI(newMBB, dl, TII->get(X86::JNE_4)).addMBB(newMBB);
F->DeleteMachineInstr(bInstr); // The pseudo instruction is gone now.
return nextMBB;
@@ -8215,7 +8225,7 @@ X86TargetLowering::EmitAtomicMinMaxWithCustomInserter(MachineInstr *mInstr,
MIB.addReg(X86::EAX);
// insert branch
- BuildMI(newMBB, dl, TII->get(X86::JNE)).addMBB(newMBB);
+ BuildMI(newMBB, dl, TII->get(X86::JNE_4)).addMBB(newMBB);
F->DeleteMachineInstr(mInstr); // The pseudo instruction is gone now.
return nextMBB;
@@ -8297,7 +8307,7 @@ X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(
if (!Subtarget->isTargetWin64()) {
// If %al is 0, branch around the XMM save block.
BuildMI(MBB, DL, TII->get(X86::TEST8rr)).addReg(CountReg).addReg(CountReg);
- BuildMI(MBB, DL, TII->get(X86::JE)).addMBB(EndMBB);
+ BuildMI(MBB, DL, TII->get(X86::JE_4)).addMBB(EndMBB);
MBB->addSuccessor(EndMBB);
}
@@ -8390,6 +8400,29 @@ X86TargetLowering::EmitLoweredSelect(MachineInstr *MI,
return BB;
}
+MachineBasicBlock *
+X86TargetLowering::EmitLoweredMingwAlloca(MachineInstr *MI,
+ MachineBasicBlock *BB,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+ DebugLoc DL = MI->getDebugLoc();
+ MachineFunction *F = BB->getParent();
+
+ // The lowering is pretty easy: we're just emitting the call to _alloca. The
+ // non-trivial part is impdef of ESP.
+ // FIXME: The code should be tweaked as soon as we'll try to do codegen for
+ // mingw-w64.
+
+ BuildMI(BB, DL, TII->get(X86::CALLpcrel32))
+ .addExternalSymbol("_alloca")
+ .addReg(X86::EAX, RegState::Implicit)
+ .addReg(X86::ESP, RegState::Implicit)
+ .addReg(X86::EAX, RegState::Define | RegState::Implicit)
+ .addReg(X86::ESP, RegState::Define | RegState::Implicit);
+
+ F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
+ return BB;
+}
MachineBasicBlock *
X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
@@ -8397,6 +8430,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
switch (MI->getOpcode()) {
default: assert(false && "Unexpected instr type to insert");
+ case X86::MINGW_ALLOCA:
+ return EmitLoweredMingwAlloca(MI, BB, EM);
case X86::CMOV_GR8:
case X86::CMOV_V1I64:
case X86::CMOV_FR32:
@@ -8783,10 +8818,11 @@ static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
if (DAG.InferPtrAlignment(LD->getBasePtr()) >= 16)
return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(),
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile());
+ LD->isVolatile(), LD->isNonTemporal(), 0);
return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(),
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
} else if (NumElems == 4 && LastLoadedElt == 1) {
SDVTList Tys = DAG.getVTList(MVT::v2i64, MVT::Other);
SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
@@ -8806,10 +8842,9 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
SDValue RHS = N->getOperand(2);
// If we have SSE[12] support, try to form min/max nodes. SSE min/max
- // instructions have the peculiarity that if either operand is a NaN,
- // they chose what we call the RHS operand (and as such are not symmetric).
- // It happens that this matches the semantics of the common C idiom
- // x<y?x:y and related forms, so we can recognize these cases.
+ // instructions match the semantics of the common C idiom x<y?x:y but not
+ // x<=y?x:y, because of how they handle negative zero (which can be
+ // ignored in unsafe-math mode).
if (Subtarget->hasSSE2() &&
(LHS.getValueType() == MVT::f32 || LHS.getValueType() == MVT::f64) &&
Cond.getOpcode() == ISD::SETCC) {
@@ -8817,36 +8852,34 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
unsigned Opcode = 0;
// Check for x CC y ? x : y.
- if (LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
+ if (DAG.isEqualTo(LHS, Cond.getOperand(0)) &&
+ DAG.isEqualTo(RHS, Cond.getOperand(1))) {
switch (CC) {
default: break;
case ISD::SETULT:
- // This can be a min if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(RHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(LHS))
+ // Converting this to a min would handle NaNs incorrectly, and swapping
+ // the operands would cause it to handle comparisons between positive
+ // and negative zero incorrectly.
+ if (!FiniteOnlyFPMath() &&
+ (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))) {
+ if (!UnsafeFPMath &&
+ !(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS)))
break;
+ std::swap(LHS, RHS);
}
Opcode = X86ISD::FMIN;
break;
case ISD::SETOLE:
- // This can be a min if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(LHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(RHS))
- break;
- }
+ // Converting this to a min would handle comparisons between positive
+ // and negative zero incorrectly.
+ if (!UnsafeFPMath &&
+ !DAG.isKnownNeverZero(LHS) && !DAG.isKnownNeverZero(RHS))
+ break;
Opcode = X86ISD::FMIN;
break;
case ISD::SETULE:
- // This can be a min, but if either operand is a NaN we need it to
- // preserve the original LHS.
+ // Converting this to a min would handle both negative zeros and NaNs
+ // incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
case ISD::SETOLT:
case ISD::SETLT:
@@ -8855,32 +8888,29 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
break;
case ISD::SETOGE:
- // This can be a max if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(LHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(RHS))
- break;
- }
+ // Converting this to a max would handle comparisons between positive
+ // and negative zero incorrectly.
+ if (!UnsafeFPMath &&
+ !DAG.isKnownNeverZero(LHS) && !DAG.isKnownNeverZero(LHS))
+ break;
Opcode = X86ISD::FMAX;
break;
case ISD::SETUGT:
- // This can be a max if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(RHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(LHS))
+ // Converting this to a max would handle NaNs incorrectly, and swapping
+ // the operands would cause it to handle comparisons between positive
+ // and negative zero incorrectly.
+ if (!FiniteOnlyFPMath() &&
+ (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))) {
+ if (!UnsafeFPMath &&
+ !(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS)))
break;
+ std::swap(LHS, RHS);
}
Opcode = X86ISD::FMAX;
break;
case ISD::SETUGE:
- // This can be a max, but if either operand is a NaN we need it to
- // preserve the original LHS.
+ // Converting this to a max would handle both negative zeros and NaNs
+ // incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
case ISD::SETOGT:
case ISD::SETGT:
@@ -8889,36 +8919,33 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
break;
}
// Check for x CC y ? y : x -- a min/max with reversed arms.
- } else if (LHS == Cond.getOperand(1) && RHS == Cond.getOperand(0)) {
+ } else if (DAG.isEqualTo(LHS, Cond.getOperand(1)) &&
+ DAG.isEqualTo(RHS, Cond.getOperand(0))) {
switch (CC) {
default: break;
case ISD::SETOGE:
- // This can be a min if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(RHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(LHS))
+ // Converting this to a min would handle comparisons between positive
+ // and negative zero incorrectly, and swapping the operands would
+ // cause it to handle NaNs incorrectly.
+ if (!UnsafeFPMath &&
+ !(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS))) {
+ if (!FiniteOnlyFPMath() &&
+ (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)))
break;
+ std::swap(LHS, RHS);
}
Opcode = X86ISD::FMIN;
break;
case ISD::SETUGT:
- // This can be a min if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(LHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(RHS))
- break;
- }
+ // Converting this to a min would handle NaNs incorrectly.
+ if (!UnsafeFPMath &&
+ (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)))
+ break;
Opcode = X86ISD::FMIN;
break;
case ISD::SETUGE:
- // This can be a min, but if either operand is a NaN we need it to
- // preserve the original LHS.
+ // Converting this to a min would handle both negative zeros and NaNs
+ // incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
case ISD::SETOGT:
case ISD::SETGT:
@@ -8927,32 +8954,28 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
break;
case ISD::SETULT:
- // This can be a max if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(LHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(RHS))
- break;
- }
+ // Converting this to a max would handle NaNs incorrectly.
+ if (!FiniteOnlyFPMath() &&
+ (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)))
+ break;
Opcode = X86ISD::FMAX;
break;
case ISD::SETOLE:
- // This can be a max if we can prove that at least one of the operands
- // is not a nan.
- if (!FiniteOnlyFPMath()) {
- if (DAG.isKnownNeverNaN(RHS)) {
- // Put the potential NaN in the RHS so that SSE will preserve it.
- std::swap(LHS, RHS);
- } else if (!DAG.isKnownNeverNaN(LHS))
+ // Converting this to a max would handle comparisons between positive
+ // and negative zero incorrectly, and swapping the operands would
+ // cause it to handle NaNs incorrectly.
+ if (!UnsafeFPMath &&
+ !DAG.isKnownNeverZero(LHS) && !DAG.isKnownNeverZero(RHS)) {
+ if (!FiniteOnlyFPMath() &&
+ (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)))
break;
+ std::swap(LHS, RHS);
}
Opcode = X86ISD::FMAX;
break;
case ISD::SETULE:
- // This can be a max, but if either operand is a NaN we need it to
- // preserve the original LHS.
+ // Converting this to a max would handle both negative zeros and NaNs
+ // incorrectly, but we can swap the operands to fix both.
std::swap(LHS, RHS);
case ISD::SETOLT:
case ISD::SETLT:
@@ -9177,10 +9200,6 @@ static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG,
/// LEA + SHL, LEA + LEA.
static SDValue PerformMulCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI) {
- if (DAG.getMachineFunction().
- getFunction()->hasFnAttr(Attribute::OptimizeForSize))
- return SDValue();
-
if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
return SDValue();
@@ -9319,7 +9338,7 @@ static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG,
}
} else if (InVec.getOpcode() == ISD::INSERT_VECTOR_ELT) {
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(InVec.getOperand(2))) {
- unsigned SplatIdx = cast<ShuffleVectorSDNode>(ShAmtOp)->getSplatIndex();
+ unsigned SplatIdx= cast<ShuffleVectorSDNode>(ShAmtOp)->getSplatIndex();
if (C->getZExtValue() == SplatIdx)
BaseShAmt = InVec.getOperand(1);
}
@@ -9505,7 +9524,7 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
SDValue NewLd = DAG.getLoad(LdVT, LdDL, Ld->getChain(),
Ld->getBasePtr(), Ld->getSrcValue(),
Ld->getSrcValueOffset(), Ld->isVolatile(),
- Ld->getAlignment());
+ Ld->isNonTemporal(), Ld->getAlignment());
SDValue NewChain = NewLd.getValue(1);
if (TokenFactorIndex != -1) {
Ops.push_back(NewChain);
@@ -9514,7 +9533,8 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
}
return DAG.getStore(NewChain, StDL, NewLd, St->getBasePtr(),
St->getSrcValue(), St->getSrcValueOffset(),
- St->isVolatile(), St->getAlignment());
+ St->isVolatile(), St->isNonTemporal(),
+ St->getAlignment());
}
// Otherwise, lower to two pairs of 32-bit loads / stores.
@@ -9524,10 +9544,11 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
SDValue LoLd = DAG.getLoad(MVT::i32, LdDL, Ld->getChain(), LoAddr,
Ld->getSrcValue(), Ld->getSrcValueOffset(),
- Ld->isVolatile(), Ld->getAlignment());
+ Ld->isVolatile(), Ld->isNonTemporal(),
+ Ld->getAlignment());
SDValue HiLd = DAG.getLoad(MVT::i32, LdDL, Ld->getChain(), HiAddr,
Ld->getSrcValue(), Ld->getSrcValueOffset()+4,
- Ld->isVolatile(),
+ Ld->isVolatile(), Ld->isNonTemporal(),
MinAlign(Ld->getAlignment(), 4));
SDValue NewChain = LoLd.getValue(1);
@@ -9544,11 +9565,13 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
SDValue LoSt = DAG.getStore(NewChain, StDL, LoLd, LoAddr,
St->getSrcValue(), St->getSrcValueOffset(),
- St->isVolatile(), St->getAlignment());
+ St->isVolatile(), St->isNonTemporal(),
+ St->getAlignment());
SDValue HiSt = DAG.getStore(NewChain, StDL, HiLd, HiAddr,
St->getSrcValue(),
St->getSrcValueOffset() + 4,
St->isVolatile(),
+ St->isNonTemporal(),
MinAlign(St->getAlignment(), 4));
return DAG.getNode(ISD::TokenFactor, StDL, MVT::Other, LoSt, HiSt);
}
@@ -9731,7 +9754,7 @@ static bool LowerToBSwap(CallInst *CI) {
// Verify this is a simple bswap.
if (CI->getNumOperands() != 2 ||
CI->getType() != CI->getOperand(1)->getType() ||
- !CI->getType()->isInteger())
+ !CI->getType()->isIntegerTy())
return false;
const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
@@ -9780,17 +9803,26 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
return LowerToBSwap(CI);
}
// rorw $$8, ${0:w} --> llvm.bswap.i16
- if (CI->getType()->isInteger(16) &&
+ if (CI->getType()->isIntegerTy(16) &&
AsmPieces.size() == 3 &&
- AsmPieces[0] == "rorw" &&
+ (AsmPieces[0] == "rorw" || AsmPieces[0] == "rolw") &&
AsmPieces[1] == "$$8," &&
AsmPieces[2] == "${0:w}" &&
- IA->getConstraintString() == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") {
- return LowerToBSwap(CI);
+ IA->getConstraintString().compare(0, 5, "=r,0,") == 0) {
+ AsmPieces.clear();
+ SplitString(IA->getConstraintString().substr(5), AsmPieces, ",");
+ std::sort(AsmPieces.begin(), AsmPieces.end());
+ if (AsmPieces.size() == 4 &&
+ AsmPieces[0] == "~{cc}" &&
+ AsmPieces[1] == "~{dirflag}" &&
+ AsmPieces[2] == "~{flags}" &&
+ AsmPieces[3] == "~{fpsr}") {
+ return LowerToBSwap(CI);
+ }
}
break;
case 3:
- if (CI->getType()->isInteger(64) &&
+ if (CI->getType()->isIntegerTy(64) &&
Constraints.size() >= 2 &&
Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 193ef05..4c12fcc 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -180,7 +180,7 @@ namespace llvm {
/// PINSRW - Insert the lower 16-bits of a 32-bit value to a vector,
/// corresponds to X86::PINSRW.
- PINSRW,
+ PINSRW, MMX_PINSRW,
/// PSHUFB - Shuffle 16 8-bit values within a vector.
PSHUFB,
@@ -249,6 +249,9 @@ namespace llvm {
// with control flow.
VASTART_SAVE_XMM_REGS,
+ // MINGW_ALLOCA - MingW's __alloca call to do stack probing.
+ MINGW_ALLOCA,
+
// ATOMADD64_DAG, ATOMSUB64_DAG, ATOMOR64_DAG, ATOMAND64_DAG,
// ATOMXOR64_DAG, ATOMNAND64_DAG, ATOMSWAP64_DAG -
// Atomic 64-bit binary operations.
@@ -259,6 +262,10 @@ namespace llvm {
ATOMAND64_DAG,
ATOMNAND64_DAG,
ATOMSWAP64_DAG
+
+ // WARNING: Do not add anything in the end unless you want the node to
+ // have memop! In fact, starting from ATOMADD64_DAG all opcodes will be
+ // thought as target memory ops!
};
}
@@ -639,7 +646,6 @@ namespace llvm {
int FPDiff, DebugLoc dl);
CCAssignFn *CCAssignFnForNode(CallingConv::ID CallConv) const;
- NameDecorationStyle NameDecorationForCallConv(CallingConv::ID CallConv);
unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG);
std::pair<SDValue,SDValue> FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
@@ -790,7 +796,11 @@ namespace llvm {
MachineBasicBlock *EmitLoweredSelect(MachineInstr *I,
MachineBasicBlock *BB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
-
+
+ MachineBasicBlock *EmitLoweredMingwAlloca(MachineInstr *MI,
+ MachineBasicBlock *BB,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
+
/// Emit nodes that will be selected as "test Op0,Op0", or something
/// equivalent, for use with the given x86 condition code.
SDValue EmitTest(SDValue Op0, unsigned X86CC, SelectionDAG &DAG);
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 468dd67..8462255 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -59,10 +59,11 @@ def tls64addr : ComplexPattern<i64, 4, "SelectTLSADDRAddr",
// Pattern fragments.
//
-def i64immSExt8 : PatLeaf<(i64 imm), [{
- // i64immSExt8 predicate - True if the 64-bit immediate fits in a 8-bit
- // sign extended field.
- return (int64_t)N->getZExtValue() == (int8_t)N->getZExtValue();
+def i64immSExt8 : PatLeaf<(i64 immSext8)>;
+
+def GetLo32XForm : SDNodeXForm<imm, [{
+ // Transformation function: get the low 32 bits.
+ return getI32Imm((unsigned)N->getZExtValue());
}]>;
def i64immSExt32 : PatLeaf<(i64 imm), [{
@@ -71,6 +72,7 @@ def i64immSExt32 : PatLeaf<(i64 imm), [{
return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
}]>;
+
def i64immZExt32 : PatLeaf<(i64 imm), [{
// i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
// unsignedsign extended field.
@@ -325,7 +327,7 @@ def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
"mov{q}\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
"mov{q}\t{$src, $dst|$dst, $src}",
[(set GR64:$dst, (load addr:$src))]>;
@@ -556,7 +558,7 @@ def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
addr:$dst)]>;
def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
"adc{q}\t{$src2, $dst|$dst, $src2}",
- [(store (adde (load addr:$dst), i64immSExt8:$src2),
+ [(store (adde (load addr:$dst), i64immSExt32:$src2),
addr:$dst)]>;
} // Uses = [EFLAGS]
@@ -893,35 +895,38 @@ def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
let isTwoAddress = 1 in {
def RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src),
"rcl{q}\t{1, $dst|$dst, 1}", []>;
-def RCL64m1 : RI<0xD1, MRM2m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcl{q}\t{1, $dst|$dst, 1}", []>;
-let Uses = [CL] in {
-def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src),
- "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
-def RCL64mCL : RI<0xD3, MRM2m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
-}
def RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
"rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCL64mi : RIi8<0xC1, MRM2m, (outs i64mem:$dst),
- (ins i64mem:$src, i8imm:$cnt),
- "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src),
"rcr{q}\t{1, $dst|$dst, 1}", []>;
-def RCR64m1 : RI<0xD1, MRM3m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcr{q}\t{1, $dst|$dst, 1}", []>;
+def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
+ "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
+
let Uses = [CL] in {
+def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src),
+ "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
def RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src),
"rcr{q}\t{%cl, $dst|$dst, CL}", []>;
-def RCR64mCL : RI<0xD3, MRM3m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcr{q}\t{%cl, $dst|$dst, CL}", []>;
}
-def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
- "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCR64mi : RIi8<0xC1, MRM3m, (outs i64mem:$dst),
- (ins i64mem:$src, i8imm:$cnt),
+}
+
+let isTwoAddress = 0 in {
+def RCL64m1 : RI<0xD1, MRM2m, (outs), (ins i64mem:$dst),
+ "rcl{q}\t{1, $dst|$dst, 1}", []>;
+def RCL64mi : RIi8<0xC1, MRM2m, (outs), (ins i64mem:$dst, i8imm:$cnt),
+ "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst),
+ "rcr{q}\t{1, $dst|$dst, 1}", []>;
+def RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, i8imm:$cnt),
"rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
+
+let Uses = [CL] in {
+def RCL64mCL : RI<0xD3, MRM2m, (outs), (ins i64mem:$dst),
+ "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
+def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst),
+ "rcr{q}\t{%cl, $dst|$dst, CL}", []>;
+}
}
let isTwoAddress = 1 in {
@@ -1771,7 +1776,7 @@ def LSL64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
"lsl{q}\t{$src, $dst|$dst, $src}", []>, TB;
-def SWPGS : I<0x01, RawFrm, (outs), (ins), "swpgs", []>, TB;
+def SWAPGS : I<0x01, MRM_F8, (outs), (ins), "swapgs", []>, TB;
def PUSHFS64 : I<0xa0, RawFrm, (outs), (ins),
"push{q}\t%fs", []>, TB;
@@ -1978,7 +1983,7 @@ def : Pat<(and GR64:$src, i64immZExt32:$imm),
(i64 0),
(AND32ri
(EXTRACT_SUBREG GR64:$src, x86_subreg_32bit),
- imm:$imm),
+ (i32 (GetLo32XForm imm:$imm))),
x86_subreg_32bit)>;
// r & (2^32-1) ==> movz
@@ -2102,34 +2107,34 @@ def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
// (shl x (and y, 63)) ==> (shl x, y)
-def : Pat<(shl GR64:$src1, (and CL:$amt, 63)),
+def : Pat<(shl GR64:$src1, (and CL, 63)),
(SHL64rCL GR64:$src1)>;
-def : Pat<(store (shl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
+def : Pat<(store (shl (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
(SHL64mCL addr:$dst)>;
-def : Pat<(srl GR64:$src1, (and CL:$amt, 63)),
+def : Pat<(srl GR64:$src1, (and CL, 63)),
(SHR64rCL GR64:$src1)>;
-def : Pat<(store (srl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
+def : Pat<(store (srl (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
(SHR64mCL addr:$dst)>;
-def : Pat<(sra GR64:$src1, (and CL:$amt, 63)),
+def : Pat<(sra GR64:$src1, (and CL, 63)),
(SAR64rCL GR64:$src1)>;
-def : Pat<(store (sra (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
+def : Pat<(store (sra (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
(SAR64mCL addr:$dst)>;
// Double shift patterns
-def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
+def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm)),
(SHRD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
def : Pat<(store (shrd (loadi64 addr:$dst), (i8 imm:$amt1),
- GR64:$src2, (i8 imm:$amt2)), addr:$dst),
+ GR64:$src2, (i8 imm)), addr:$dst),
(SHRD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
-def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
+def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm)),
(SHLD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
def : Pat<(store (shld (loadi64 addr:$dst), (i8 imm:$amt1),
- GR64:$src2, (i8 imm:$amt2)), addr:$dst),
+ GR64:$src2, (i8 imm)), addr:$dst),
(SHLD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
// (or x1, x2) -> (add x1, x2) if two operands are known not to share bits.
diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td
index e22a903..ae24bfb 100644
--- a/lib/Target/X86/X86InstrFPStack.td
+++ b/lib/Target/X86/X86InstrFPStack.td
@@ -397,7 +397,7 @@ def CMOVNP_F : FPI<0xD8, AddRegFrm, (outs RST:$op), (ins),
let canFoldAsLoad = 1 in {
def LD_Fp32m : FpIf32<(outs RFP32:$dst), (ins f32mem:$src), ZeroArgFP,
[(set RFP32:$dst, (loadf32 addr:$src))]>;
-let isReMaterializable = 1, mayHaveSideEffects = 1 in
+let isReMaterializable = 1 in
def LD_Fp64m : FpIf64<(outs RFP64:$dst), (ins f64mem:$src), ZeroArgFP,
[(set RFP64:$dst, (loadf64 addr:$src))]>;
def LD_Fp80m : FpI_<(outs RFP80:$dst), (ins f80mem:$src), ZeroArgFP,
diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td
index a799f16..bb81cbf 100644
--- a/lib/Target/X86/X86InstrFormats.td
+++ b/lib/Target/X86/X86InstrFormats.td
@@ -29,7 +29,16 @@ def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
def MRM6m : Format<30>; def MRM7m : Format<31>;
def MRMInitReg : Format<32>;
-
+def MRM_C1 : Format<33>;
+def MRM_C2 : Format<34>;
+def MRM_C3 : Format<35>;
+def MRM_C4 : Format<36>;
+def MRM_C8 : Format<37>;
+def MRM_C9 : Format<38>;
+def MRM_E8 : Format<39>;
+def MRM_F0 : Format<40>;
+def MRM_F8 : Format<41>;
+def MRM_F9 : Format<42>;
// ImmType - This specifies the immediate type used by an instruction. This is
// part of the ad-hoc solution used to emit machine instruction encodings by our
@@ -37,11 +46,13 @@ def MRMInitReg : Format<32>;
class ImmType<bits<3> val> {
bits<3> Value = val;
}
-def NoImm : ImmType<0>;
-def Imm8 : ImmType<1>;
-def Imm16 : ImmType<2>;
-def Imm32 : ImmType<3>;
-def Imm64 : ImmType<4>;
+def NoImm : ImmType<0>;
+def Imm8 : ImmType<1>;
+def Imm8PCRel : ImmType<2>;
+def Imm16 : ImmType<3>;
+def Imm32 : ImmType<4>;
+def Imm32PCRel : ImmType<5>;
+def Imm64 : ImmType<6>;
// FPFormat - This specifies what form this FP instruction has. This is used by
// the Floating-Point stackifier pass.
@@ -121,6 +132,12 @@ class Ii8 <bits<8> o, Format f, dag outs, dag ins, string asm,
let Pattern = pattern;
let CodeSize = 3;
}
+class Ii8PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
+ list<dag> pattern>
+ : X86Inst<o, f, Imm8PCRel, outs, ins, asm> {
+ let Pattern = pattern;
+ let CodeSize = 3;
+}
class Ii16<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm16, outs, ins, asm> {
@@ -134,6 +151,13 @@ class Ii32<bits<8> o, Format f, dag outs, dag ins, string asm,
let CodeSize = 3;
}
+class Ii32PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
+ list<dag> pattern>
+ : X86Inst<o, f, Imm32PCRel, outs, ins, asm> {
+ let Pattern = pattern;
+ let CodeSize = 3;
+}
+
// FPStack Instruction Templates:
// FPI - Floating Point Instruction template.
class FPI<bits<8> o, Format F, dag outs, dag ins, string asm>
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 8d13c0f..39bda04 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -276,11 +276,8 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm)
{ X86::MOVDQArr, X86::MOVDQAmr, 0, 16 },
{ X86::MOVPDI2DIrr, X86::MOVPDI2DImr, 0, 0 },
{ X86::MOVPQIto64rr,X86::MOVPQI2QImr, 0, 0 },
- { X86::MOVPS2SSrr, X86::MOVPS2SSmr, 0, 0 },
- { X86::MOVSDrr, X86::MOVSDmr, 0, 0 },
{ X86::MOVSDto64rr, X86::MOVSDto64mr, 0, 0 },
{ X86::MOVSS2DIrr, X86::MOVSS2DImr, 0, 0 },
- { X86::MOVSSrr, X86::MOVSSmr, 0, 0 },
{ X86::MOVUPDrr, X86::MOVUPDmr, 0, 0 },
{ X86::MOVUPSrr, X86::MOVUPSmr, 0, 0 },
{ X86::MUL16r, X86::MUL16m, 1, 0 },
@@ -389,12 +386,8 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm)
{ X86::MOVDI2PDIrr, X86::MOVDI2PDIrm, 0 },
{ X86::MOVDI2SSrr, X86::MOVDI2SSrm, 0 },
{ X86::MOVDQArr, X86::MOVDQArm, 16 },
- { X86::MOVSD2PDrr, X86::MOVSD2PDrm, 0 },
- { X86::MOVSDrr, X86::MOVSDrm, 0 },
{ X86::MOVSHDUPrr, X86::MOVSHDUPrm, 16 },
{ X86::MOVSLDUPrr, X86::MOVSLDUPrm, 16 },
- { X86::MOVSS2PSrr, X86::MOVSS2PSrm, 0 },
- { X86::MOVSSrr, X86::MOVSSrm, 0 },
{ X86::MOVSX16rr8, X86::MOVSX16rm8, 0 },
{ X86::MOVSX32rr16, X86::MOVSX32rm16, 0 },
{ X86::MOVSX32rr8, X86::MOVSX32rm8, 0 },
@@ -682,23 +675,20 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
case X86::MOV16rr:
case X86::MOV32rr:
case X86::MOV64rr:
- case X86::MOVSSrr:
- case X86::MOVSDrr:
// FP Stack register class copies
case X86::MOV_Fp3232: case X86::MOV_Fp6464: case X86::MOV_Fp8080:
case X86::MOV_Fp3264: case X86::MOV_Fp3280:
case X86::MOV_Fp6432: case X86::MOV_Fp8032:
-
+
+ // Note that MOVSSrr and MOVSDrr are not considered copies. FR32 and FR64
+ // copies are done with FsMOVAPSrr and FsMOVAPDrr.
+
case X86::FsMOVAPSrr:
case X86::FsMOVAPDrr:
case X86::MOVAPSrr:
case X86::MOVAPDrr:
case X86::MOVDQArr:
- case X86::MOVSS2PSrr:
- case X86::MOVSD2PDrr:
- case X86::MOVPS2SSrr:
- case X86::MOVPD2SDrr:
case X86::MMX_MOVQ64rr:
assert(MI.getNumOperands() >= 2 &&
MI.getOperand(0).isReg() &&
@@ -1083,7 +1073,7 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
case X86::MOV8r0: Opc = X86::MOV8ri; break;
case X86::MOV16r0: Opc = X86::MOV16ri; break;
case X86::MOV32r0: Opc = X86::MOV32ri; break;
- case X86::MOV64r0: Opc = X86::MOV64ri; break;
+ case X86::MOV64r0: Opc = X86::MOV64ri64i32; break;
}
Clone = false;
}
@@ -1587,44 +1577,44 @@ X86InstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
static X86::CondCode GetCondFromBranchOpc(unsigned BrOpc) {
switch (BrOpc) {
default: return X86::COND_INVALID;
- case X86::JE: return X86::COND_E;
- case X86::JNE: return X86::COND_NE;
- case X86::JL: return X86::COND_L;
- case X86::JLE: return X86::COND_LE;
- case X86::JG: return X86::COND_G;
- case X86::JGE: return X86::COND_GE;
- case X86::JB: return X86::COND_B;
- case X86::JBE: return X86::COND_BE;
- case X86::JA: return X86::COND_A;
- case X86::JAE: return X86::COND_AE;
- case X86::JS: return X86::COND_S;
- case X86::JNS: return X86::COND_NS;
- case X86::JP: return X86::COND_P;
- case X86::JNP: return X86::COND_NP;
- case X86::JO: return X86::COND_O;
- case X86::JNO: return X86::COND_NO;
+ case X86::JE_4: return X86::COND_E;
+ case X86::JNE_4: return X86::COND_NE;
+ case X86::JL_4: return X86::COND_L;
+ case X86::JLE_4: return X86::COND_LE;
+ case X86::JG_4: return X86::COND_G;
+ case X86::JGE_4: return X86::COND_GE;
+ case X86::JB_4: return X86::COND_B;
+ case X86::JBE_4: return X86::COND_BE;
+ case X86::JA_4: return X86::COND_A;
+ case X86::JAE_4: return X86::COND_AE;
+ case X86::JS_4: return X86::COND_S;
+ case X86::JNS_4: return X86::COND_NS;
+ case X86::JP_4: return X86::COND_P;
+ case X86::JNP_4: return X86::COND_NP;
+ case X86::JO_4: return X86::COND_O;
+ case X86::JNO_4: return X86::COND_NO;
}
}
unsigned X86::GetCondBranchFromCond(X86::CondCode CC) {
switch (CC) {
default: llvm_unreachable("Illegal condition code!");
- case X86::COND_E: return X86::JE;
- case X86::COND_NE: return X86::JNE;
- case X86::COND_L: return X86::JL;
- case X86::COND_LE: return X86::JLE;
- case X86::COND_G: return X86::JG;
- case X86::COND_GE: return X86::JGE;
- case X86::COND_B: return X86::JB;
- case X86::COND_BE: return X86::JBE;
- case X86::COND_A: return X86::JA;
- case X86::COND_AE: return X86::JAE;
- case X86::COND_S: return X86::JS;
- case X86::COND_NS: return X86::JNS;
- case X86::COND_P: return X86::JP;
- case X86::COND_NP: return X86::JNP;
- case X86::COND_O: return X86::JO;
- case X86::COND_NO: return X86::JNO;
+ case X86::COND_E: return X86::JE_4;
+ case X86::COND_NE: return X86::JNE_4;
+ case X86::COND_L: return X86::JL_4;
+ case X86::COND_LE: return X86::JLE_4;
+ case X86::COND_G: return X86::JG_4;
+ case X86::COND_GE: return X86::JGE_4;
+ case X86::COND_B: return X86::JB_4;
+ case X86::COND_BE: return X86::JBE_4;
+ case X86::COND_A: return X86::JA_4;
+ case X86::COND_AE: return X86::JAE_4;
+ case X86::COND_S: return X86::JS_4;
+ case X86::COND_NS: return X86::JNS_4;
+ case X86::COND_P: return X86::JP_4;
+ case X86::COND_NP: return X86::JNP_4;
+ case X86::COND_O: return X86::JO_4;
+ case X86::COND_NO: return X86::JNO_4;
}
}
@@ -1694,7 +1684,7 @@ bool X86InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return true;
// Handle unconditional branches.
- if (I->getOpcode() == X86::JMP) {
+ if (I->getOpcode() == X86::JMP_4) {
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
@@ -1778,7 +1768,7 @@ unsigned X86InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
while (I != MBB.begin()) {
--I;
- if (I->getOpcode() != X86::JMP &&
+ if (I->getOpcode() != X86::JMP_4 &&
GetCondFromBranchOpc(I->getOpcode()) == X86::COND_INVALID)
break;
// Remove the branch.
@@ -1804,7 +1794,7 @@ X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
if (Cond.empty()) {
// Unconditional branch?
assert(!FBB && "Unconditional branch with multiple successors!");
- BuildMI(&MBB, dl, get(X86::JMP)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JMP_4)).addMBB(TBB);
return 1;
}
@@ -1814,16 +1804,16 @@ X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
switch (CC) {
case X86::COND_NP_OR_E:
// Synthesize NP_OR_E with two branches.
- BuildMI(&MBB, dl, get(X86::JNP)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JNP_4)).addMBB(TBB);
++Count;
- BuildMI(&MBB, dl, get(X86::JE)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JE_4)).addMBB(TBB);
++Count;
break;
case X86::COND_NE_OR_P:
// Synthesize NE_OR_P with two branches.
- BuildMI(&MBB, dl, get(X86::JNE)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JNE_4)).addMBB(TBB);
++Count;
- BuildMI(&MBB, dl, get(X86::JP)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JP_4)).addMBB(TBB);
++Count;
break;
default: {
@@ -1834,7 +1824,7 @@ X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
}
if (FBB) {
// Two-way Conditional branch. Insert the second branch.
- BuildMI(&MBB, dl, get(X86::JMP)).addMBB(FBB);
+ BuildMI(&MBB, dl, get(X86::JMP_4)).addMBB(FBB);
++Count;
}
return Count;
@@ -1860,7 +1850,7 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
CommonRC = SrcRC;
else if (!DestRC->hasSubClass(SrcRC)) {
// Neither of GR64_NOREX or GR64_NOSP is a superclass of the other,
- // but we want to copy then as GR64. Similarly, for GR32_NOREX and
+ // but we want to copy them as GR64. Similarly, for GR32_NOREX and
// GR32_NOSP, copy as GR32.
if (SrcRC->hasSuperClass(&X86::GR64RegClass) &&
DestRC->hasSuperClass(&X86::GR64RegClass))
@@ -3556,6 +3546,14 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
}
}
break;
+
+ case X86II::MRM_C1:
+ case X86II::MRM_C8:
+ case X86II::MRM_C9:
+ case X86II::MRM_E8:
+ case X86II::MRM_F0:
+ FinalSize += 2;
+ break;
}
case X86II::MRMInitReg:
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index a6b3863..5111719 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -268,6 +268,18 @@ namespace X86II {
// MRMInitReg - This form is used for instructions whose source and
// destinations are the same register.
MRMInitReg = 32,
+
+ //// MRM_C1 - A mod/rm byte of exactly 0xC1.
+ MRM_C1 = 33,
+ MRM_C2 = 34,
+ MRM_C3 = 35,
+ MRM_C4 = 36,
+ MRM_C8 = 37,
+ MRM_C9 = 38,
+ MRM_E8 = 39,
+ MRM_F0 = 40,
+ MRM_F8 = 41,
+ MRM_F9 = 42,
FormMask = 63,
@@ -331,11 +343,13 @@ namespace X86II {
// This three-bit field describes the size of an immediate operand. Zero is
// unused so that we can tell if we forgot to set a value.
ImmShift = 13,
- ImmMask = 7 << ImmShift,
- Imm8 = 1 << ImmShift,
- Imm16 = 2 << ImmShift,
- Imm32 = 3 << ImmShift,
- Imm64 = 4 << ImmShift,
+ ImmMask = 7 << ImmShift,
+ Imm8 = 1 << ImmShift,
+ Imm8PCRel = 2 << ImmShift,
+ Imm16 = 3 << ImmShift,
+ Imm32 = 4 << ImmShift,
+ Imm32PCRel = 5 << ImmShift,
+ Imm64 = 6 << ImmShift,
//===------------------------------------------------------------------===//
// FP Instruction Classification... Zero is non-fp instruction.
@@ -396,15 +410,37 @@ namespace X86II {
return TSFlags >> X86II::OpcodeShift;
}
+ static inline bool hasImm(unsigned TSFlags) {
+ return (TSFlags & X86II::ImmMask) != 0;
+ }
+
/// getSizeOfImm - Decode the "size of immediate" field from the TSFlags field
/// of the specified instruction.
static inline unsigned getSizeOfImm(unsigned TSFlags) {
switch (TSFlags & X86II::ImmMask) {
default: assert(0 && "Unknown immediate size");
- case X86II::Imm8: return 1;
- case X86II::Imm16: return 2;
- case X86II::Imm32: return 4;
- case X86II::Imm64: return 8;
+ case X86II::Imm8:
+ case X86II::Imm8PCRel: return 1;
+ case X86II::Imm16: return 2;
+ case X86II::Imm32:
+ case X86II::Imm32PCRel: return 4;
+ case X86II::Imm64: return 8;
+ }
+ }
+
+ /// isImmPCRel - Return true if the immediate of the specified instruction's
+ /// TSFlags indicates that it is pc relative.
+ static inline unsigned isImmPCRel(unsigned TSFlags) {
+ switch (TSFlags & X86II::ImmMask) {
+ default: assert(0 && "Unknown immediate size");
+ case X86II::Imm8PCRel:
+ case X86II::Imm32PCRel:
+ return true;
+ case X86II::Imm8:
+ case X86II::Imm16:
+ case X86II::Imm32:
+ case X86II::Imm64:
+ return false;
}
}
}
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index f0b4239..8a6ff54 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -65,7 +65,7 @@ def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
-def SDTX86RdTsc : SDTypeProfile<0, 0, []>;
+def SDTX86Void : SDTypeProfile<0, 0, []>;
def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
@@ -143,7 +143,7 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
[SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore,
SDNPMayLoad]>;
-def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
+def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
[SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
@@ -178,6 +178,9 @@ def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
+def X86MingwAlloca : SDNode<"X86ISD::MINGW_ALLOCA", SDTX86Void,
+ [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
+
//===----------------------------------------------------------------------===//
// X86 Operand Definitions.
//
@@ -343,18 +346,37 @@ def X86_COND_O : PatLeaf<(i8 13)>;
def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
def X86_COND_S : PatLeaf<(i8 15)>;
-def i16immSExt8 : PatLeaf<(i16 imm), [{
- // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit
- // sign extended field.
- return (int16_t)N->getZExtValue() == (int8_t)N->getZExtValue();
+def immSext8 : PatLeaf<(imm), [{
+ return N->getSExtValue() == (int8_t)N->getSExtValue();
}]>;
-def i32immSExt8 : PatLeaf<(i32 imm), [{
- // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
- // sign extended field.
- return (int32_t)N->getZExtValue() == (int8_t)N->getZExtValue();
+def i16immSExt8 : PatLeaf<(i16 immSext8)>;
+def i32immSExt8 : PatLeaf<(i32 immSext8)>;
+
+/// Load patterns: these constraint the match to the right address space.
+def dsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+ if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
+ if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
+ if (PT->getAddressSpace() > 255)
+ return false;
+ return true;
}]>;
+def gsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+ if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
+ if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
+ return PT->getAddressSpace() == 256;
+ return false;
+}]>;
+
+def fsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+ if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
+ if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
+ return PT->getAddressSpace() == 257;
+ return false;
+}]>;
+
+
// Helper fragments for loads.
// It's always safe to treat a anyext i16 load as a i32 load if the i16 is
// known to be 32-bit aligned or better. Ditto for i8 to i16.
@@ -372,8 +394,7 @@ def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
return false;
}]>;
-def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),
-[{
+def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
LoadSDNode *LD = cast<LoadSDNode>(N);
if (const Value *Src = LD->getSrcValue())
if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
@@ -399,72 +420,11 @@ def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
return false;
}]>;
-def nvloadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
- LoadSDNode *LD = cast<LoadSDNode>(N);
- if (const Value *Src = LD->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- if (PT->getAddressSpace() > 255)
- return false;
- if (LD->isVolatile())
- return false;
- ISD::LoadExtType ExtType = LD->getExtensionType();
- if (ExtType == ISD::NON_EXTLOAD)
- return true;
- if (ExtType == ISD::EXTLOAD)
- return LD->getAlignment() >= 4;
- return false;
-}]>;
-
-def gsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
- if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- return PT->getAddressSpace() == 256;
- return false;
-}]>;
-
-def fsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
- if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- return PT->getAddressSpace() == 257;
- return false;
-}]>;
-
-def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr)), [{
- if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- if (PT->getAddressSpace() > 255)
- return false;
- return true;
-}]>;
-def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr)), [{
- if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- if (PT->getAddressSpace() > 255)
- return false;
- return true;
-}]>;
-
-def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr)), [{
- if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- if (PT->getAddressSpace() > 255)
- return false;
- return true;
-}]>;
-def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr)), [{
- if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- if (PT->getAddressSpace() > 255)
- return false;
- return true;
-}]>;
-def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr)), [{
- if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
- if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
- if (PT->getAddressSpace() > 255)
- return false;
- return true;
-}]>;
+def loadi8 : PatFrag<(ops node:$ptr), (i8 (dsload node:$ptr))>;
+def loadi64 : PatFrag<(ops node:$ptr), (i64 (dsload node:$ptr))>;
+def loadf32 : PatFrag<(ops node:$ptr), (f32 (dsload node:$ptr))>;
+def loadf64 : PatFrag<(ops node:$ptr), (f64 (dsload node:$ptr))>;
+def loadf80 : PatFrag<(ops node:$ptr), (f80 (dsload node:$ptr))>;
def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
@@ -562,7 +522,7 @@ def ADJCALLSTACKUP32 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
}
// x86-64 va_start lowering magic.
-let usesCustomInserter = 1 in
+let usesCustomInserter = 1 in {
def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
(outs),
(ins GR8:$al,
@@ -573,6 +533,19 @@ def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
imm:$regsavefi,
imm:$offset)]>;
+// Dynamic stack allocation yields _alloca call for Cygwin/Mingw targets. Calls
+// to _alloca is needed to probe the stack when allocating more than 4k bytes in
+// one go. Touching the stack at 4K increments is necessary to ensure that the
+// guard pages used by the OS virtual memory manager are allocated in correct
+// sequence.
+// The main point of having separate instruction are extra unmodelled effects
+// (compared to ordinary calls) like stack pointer change.
+
+def MINGW_ALLOCA : I<0, Pseudo, (outs), (ins),
+ "# dynamic stack allocation",
+ [(X86MingwAlloca)]>;
+}
+
// Nop
let neverHasSideEffects = 1 in {
def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
@@ -596,7 +569,7 @@ let neverHasSideEffects = 1, isNotDuplicable = 1, Uses = [ESP] in
"", []>;
//===----------------------------------------------------------------------===//
-// Control Flow Instructions...
+// Control Flow Instructions.
//
// Return instructions.
@@ -614,16 +587,46 @@ let isTerminator = 1, isReturn = 1, isBarrier = 1,
"lret\t$amt", []>;
}
-// All branches are RawFrm, Void, Branch, and Terminators
-let isBranch = 1, isTerminator = 1 in
- class IBr<bits<8> opcode, dag ins, string asm, list<dag> pattern> :
- I<opcode, RawFrm, (outs), ins, asm, pattern>;
+// Unconditional branches.
+let isBarrier = 1, isBranch = 1, isTerminator = 1 in {
+ def JMP_4 : Ii32PCRel<0xE9, RawFrm, (outs), (ins brtarget:$dst),
+ "jmp\t$dst", [(br bb:$dst)]>;
+ def JMP_1 : Ii8PCRel<0xEB, RawFrm, (outs), (ins brtarget8:$dst),
+ "jmp\t$dst", []>;
+}
-let isBranch = 1, isBarrier = 1 in {
- def JMP : IBr<0xE9, (ins brtarget:$dst), "jmp\t$dst", [(br bb:$dst)]>;
- def JMP8 : IBr<0xEB, (ins brtarget8:$dst), "jmp\t$dst", []>;
+// Conditional Branches.
+let isBranch = 1, isTerminator = 1, Uses = [EFLAGS] in {
+ multiclass ICBr<bits<8> opc1, bits<8> opc4, string asm, PatFrag Cond> {
+ def _1 : Ii8PCRel <opc1, RawFrm, (outs), (ins brtarget8:$dst), asm, []>;
+ def _4 : Ii32PCRel<opc4, RawFrm, (outs), (ins brtarget:$dst), asm,
+ [(X86brcond bb:$dst, Cond, EFLAGS)]>, TB;
+ }
}
+defm JO : ICBr<0x70, 0x80, "jo\t$dst" , X86_COND_O>;
+defm JNO : ICBr<0x71, 0x81, "jno\t$dst" , X86_COND_NO>;
+defm JB : ICBr<0x72, 0x82, "jb\t$dst" , X86_COND_B>;
+defm JAE : ICBr<0x73, 0x83, "jae\t$dst", X86_COND_AE>;
+defm JE : ICBr<0x74, 0x84, "je\t$dst" , X86_COND_E>;
+defm JNE : ICBr<0x75, 0x85, "jne\t$dst", X86_COND_NE>;
+defm JBE : ICBr<0x76, 0x86, "jbe\t$dst", X86_COND_BE>;
+defm JA : ICBr<0x77, 0x87, "ja\t$dst" , X86_COND_A>;
+defm JS : ICBr<0x78, 0x88, "js\t$dst" , X86_COND_S>;
+defm JNS : ICBr<0x79, 0x89, "jns\t$dst", X86_COND_NS>;
+defm JP : ICBr<0x7A, 0x8A, "jp\t$dst" , X86_COND_P>;
+defm JNP : ICBr<0x7B, 0x8B, "jnp\t$dst", X86_COND_NP>;
+defm JL : ICBr<0x7C, 0x8C, "jl\t$dst" , X86_COND_L>;
+defm JGE : ICBr<0x7D, 0x8D, "jge\t$dst", X86_COND_GE>;
+defm JLE : ICBr<0x7E, 0x8E, "jle\t$dst", X86_COND_LE>;
+defm JG : ICBr<0x7F, 0x8F, "jg\t$dst" , X86_COND_G>;
+
+// FIXME: What about the CX/RCX versions of this instruction?
+let Uses = [ECX], isBranch = 1, isTerminator = 1 in
+ def JCXZ8 : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
+ "jcxz\t$dst", []>;
+
+
// Indirect branches
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def JMP32r : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst",
@@ -644,63 +647,6 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
"ljmp{l}\t{*}$dst", []>;
}
-// Conditional branches
-let Uses = [EFLAGS] in {
-// Short conditional jumps
-def JO8 : IBr<0x70, (ins brtarget8:$dst), "jo\t$dst", []>;
-def JNO8 : IBr<0x71, (ins brtarget8:$dst), "jno\t$dst", []>;
-def JB8 : IBr<0x72, (ins brtarget8:$dst), "jb\t$dst", []>;
-def JAE8 : IBr<0x73, (ins brtarget8:$dst), "jae\t$dst", []>;
-def JE8 : IBr<0x74, (ins brtarget8:$dst), "je\t$dst", []>;
-def JNE8 : IBr<0x75, (ins brtarget8:$dst), "jne\t$dst", []>;
-def JBE8 : IBr<0x76, (ins brtarget8:$dst), "jbe\t$dst", []>;
-def JA8 : IBr<0x77, (ins brtarget8:$dst), "ja\t$dst", []>;
-def JS8 : IBr<0x78, (ins brtarget8:$dst), "js\t$dst", []>;
-def JNS8 : IBr<0x79, (ins brtarget8:$dst), "jns\t$dst", []>;
-def JP8 : IBr<0x7A, (ins brtarget8:$dst), "jp\t$dst", []>;
-def JNP8 : IBr<0x7B, (ins brtarget8:$dst), "jnp\t$dst", []>;
-def JL8 : IBr<0x7C, (ins brtarget8:$dst), "jl\t$dst", []>;
-def JGE8 : IBr<0x7D, (ins brtarget8:$dst), "jge\t$dst", []>;
-def JLE8 : IBr<0x7E, (ins brtarget8:$dst), "jle\t$dst", []>;
-def JG8 : IBr<0x7F, (ins brtarget8:$dst), "jg\t$dst", []>;
-
-def JCXZ8 : IBr<0xE3, (ins brtarget8:$dst), "jcxz\t$dst", []>;
-
-def JE : IBr<0x84, (ins brtarget:$dst), "je\t$dst",
- [(X86brcond bb:$dst, X86_COND_E, EFLAGS)]>, TB;
-def JNE : IBr<0x85, (ins brtarget:$dst), "jne\t$dst",
- [(X86brcond bb:$dst, X86_COND_NE, EFLAGS)]>, TB;
-def JL : IBr<0x8C, (ins brtarget:$dst), "jl\t$dst",
- [(X86brcond bb:$dst, X86_COND_L, EFLAGS)]>, TB;
-def JLE : IBr<0x8E, (ins brtarget:$dst), "jle\t$dst",
- [(X86brcond bb:$dst, X86_COND_LE, EFLAGS)]>, TB;
-def JG : IBr<0x8F, (ins brtarget:$dst), "jg\t$dst",
- [(X86brcond bb:$dst, X86_COND_G, EFLAGS)]>, TB;
-def JGE : IBr<0x8D, (ins brtarget:$dst), "jge\t$dst",
- [(X86brcond bb:$dst, X86_COND_GE, EFLAGS)]>, TB;
-
-def JB : IBr<0x82, (ins brtarget:$dst), "jb\t$dst",
- [(X86brcond bb:$dst, X86_COND_B, EFLAGS)]>, TB;
-def JBE : IBr<0x86, (ins brtarget:$dst), "jbe\t$dst",
- [(X86brcond bb:$dst, X86_COND_BE, EFLAGS)]>, TB;
-def JA : IBr<0x87, (ins brtarget:$dst), "ja\t$dst",
- [(X86brcond bb:$dst, X86_COND_A, EFLAGS)]>, TB;
-def JAE : IBr<0x83, (ins brtarget:$dst), "jae\t$dst",
- [(X86brcond bb:$dst, X86_COND_AE, EFLAGS)]>, TB;
-
-def JS : IBr<0x88, (ins brtarget:$dst), "js\t$dst",
- [(X86brcond bb:$dst, X86_COND_S, EFLAGS)]>, TB;
-def JNS : IBr<0x89, (ins brtarget:$dst), "jns\t$dst",
- [(X86brcond bb:$dst, X86_COND_NS, EFLAGS)]>, TB;
-def JP : IBr<0x8A, (ins brtarget:$dst), "jp\t$dst",
- [(X86brcond bb:$dst, X86_COND_P, EFLAGS)]>, TB;
-def JNP : IBr<0x8B, (ins brtarget:$dst), "jnp\t$dst",
- [(X86brcond bb:$dst, X86_COND_NP, EFLAGS)]>, TB;
-def JO : IBr<0x80, (ins brtarget:$dst), "jo\t$dst",
- [(X86brcond bb:$dst, X86_COND_O, EFLAGS)]>, TB;
-def JNO : IBr<0x81, (ins brtarget:$dst), "jno\t$dst",
- [(X86brcond bb:$dst, X86_COND_NO, EFLAGS)]>, TB;
-} // Uses = [EFLAGS]
// Loop instructions
@@ -721,7 +667,7 @@ let isCall = 1 in
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
Uses = [ESP] in {
- def CALLpcrel32 : Ii32<0xE8, RawFrm,
+ def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm,
(outs), (ins i32imm_pcrel:$dst,variable_ops),
"call\t$dst", []>;
def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops),
@@ -761,8 +707,10 @@ def TCRETURNri : I<0, Pseudo, (outs),
"#TC_RETURN $dst $offset",
[]>;
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPd : IBr<0xE9, (ins i32imm_pcrel:$dst, variable_ops),
+// FIXME: The should be pseudo instructions that are lowered when going to
+// mcinst.
+let isCall = 1, isBranch = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
+ def TAILJMPd : Ii32<0xE9, RawFrm, (outs),(ins i32imm_pcrel:$dst,variable_ops),
"jmp\t$dst # TAILCALL",
[]>;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
@@ -929,6 +877,9 @@ let Defs = [RAX, RDX] in
def RDTSC : I<0x31, RawFrm, (outs), (ins), "rdtsc", [(X86rdtsc)]>,
TB;
+let Defs = [RAX, RCX, RDX] in
+def RDTSCP : I<0x01, MRM_F9, (outs), (ins), "rdtscp", []>, TB;
+
let isBarrier = 1, hasCtrlDep = 1 in {
def TRAP : I<0x0B, RawFrm, (outs), (ins), "ud2", [(trap)]>, TB;
}
@@ -1059,7 +1010,7 @@ def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
"mov{l}\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
+let canFoldAsLoad = 1, isReMaterializable = 1 in {
def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
"mov{b}\t{$src, $dst|$dst, $src}",
[(set GR8:$dst, (loadi8 addr:$src))]>;
@@ -1093,7 +1044,7 @@ def MOV8mr_NOREX : I<0x88, MRMDestMem,
(outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
"mov{b}\t{$src, $dst|$dst, $src} # NOREX", []>;
let mayLoad = 1,
- canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+ canFoldAsLoad = 1, isReMaterializable = 1 in
def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
(outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
"mov{b}\t{$src, $dst|$dst, $src} # NOREX", []>;
@@ -1115,7 +1066,10 @@ def MOV32cr : I<0x22, MRMSrcReg, (outs CONTROL_REG_32:$dst), (ins GR32:$src),
//
// Extra precision multiplication
-let Defs = [AL,AH,EFLAGS], Uses = [AL] in
+
+// AL is really implied by AX, by the registers in Defs must match the
+// SDNode results (i8, i32).
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
def MUL8r : I<0xF6, MRM4r, (outs), (ins GR8:$src), "mul{b}\t$src",
// FIXME: Used for 8-bit mul, ignore result upper 8 bits.
// This probably ought to be moved to a def : Pat<> if the
@@ -1133,7 +1087,7 @@ def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src),
"mul{l}\t$src",
[]>; // EAX,EDX = EAX*GR32
-let Defs = [AL,AH,EFLAGS], Uses = [AL] in
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
def MUL8m : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
"mul{b}\t$src",
// FIXME: Used for 8-bit mul, ignore result upper 8 bits.
@@ -1155,7 +1109,7 @@ def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
}
let neverHasSideEffects = 1 in {
-let Defs = [AL,AH,EFLAGS], Uses = [AL] in
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>;
// AL,AH = AL*GR8
let Defs = [AX,DX,EFLAGS], Uses = [AX] in
@@ -1165,7 +1119,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>;
// EAX,EDX = EAX*GR32
let mayLoad = 1 in {
-let Defs = [AL,AH,EFLAGS], Uses = [AL] in
+let Defs = [AL,EFLAGS,AX], Uses = [AL] in
def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
"imul{b}\t$src", []>; // AL,AH = AL*[mem8]
let Defs = [AX,DX,EFLAGS], Uses = [AX] in
@@ -1178,7 +1132,7 @@ def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
} // neverHasSideEffects
// unsigned division/remainder
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+let Defs = [AL,EFLAGS,AX], Uses = [AX] in
def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
"div{b}\t$src", []>;
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
@@ -1188,7 +1142,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
"div{l}\t$src", []>;
let mayLoad = 1 in {
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+let Defs = [AL,EFLAGS,AX], Uses = [AX] in
def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
"div{b}\t$src", []>;
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
@@ -1201,7 +1155,7 @@ def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
}
// Signed division/remainder.
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+let Defs = [AL,EFLAGS,AX], Uses = [AX] in
def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
"idiv{b}\t$src", []>;
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
@@ -1211,7 +1165,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
"idiv{l}\t$src", []>;
let mayLoad = 1, mayLoad = 1 in {
-let Defs = [AL,AH,EFLAGS], Uses = [AX] in
+let Defs = [AL,EFLAGS,AX], Uses = [AX] in
def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
"idiv{b}\t$src", []>;
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
@@ -2328,98 +2282,100 @@ let isTwoAddress = 0 in {
def RCL8r1 : I<0xD0, MRM2r, (outs GR8:$dst), (ins GR8:$src),
"rcl{b}\t{1, $dst|$dst, 1}", []>;
-def RCL8m1 : I<0xD0, MRM2m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcl{b}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCL8rCL : I<0xD2, MRM2r, (outs GR8:$dst), (ins GR8:$src),
"rcl{b}\t{%cl, $dst|$dst, CL}", []>;
-def RCL8mCL : I<0xD2, MRM2m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcl{b}\t{%cl, $dst|$dst, CL}", []>;
}
def RCL8ri : Ii8<0xC0, MRM2r, (outs GR8:$dst), (ins GR8:$src, i8imm:$cnt),
"rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCL8mi : Ii8<0xC0, MRM2m, (outs i8mem:$dst), (ins i8mem:$src, i8imm:$cnt),
- "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCL16r1 : I<0xD1, MRM2r, (outs GR16:$dst), (ins GR16:$src),
"rcl{w}\t{1, $dst|$dst, 1}", []>, OpSize;
-def RCL16m1 : I<0xD1, MRM2m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcl{w}\t{1, $dst|$dst, 1}", []>, OpSize;
let Uses = [CL] in {
def RCL16rCL : I<0xD3, MRM2r, (outs GR16:$dst), (ins GR16:$src),
"rcl{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
-def RCL16mCL : I<0xD3, MRM2m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcl{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
}
def RCL16ri : Ii8<0xC1, MRM2r, (outs GR16:$dst), (ins GR16:$src, i8imm:$cnt),
"rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
-def RCL16mi : Ii8<0xC1, MRM2m, (outs i16mem:$dst),
- (ins i16mem:$src, i8imm:$cnt),
- "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
def RCL32r1 : I<0xD1, MRM2r, (outs GR32:$dst), (ins GR32:$src),
"rcl{l}\t{1, $dst|$dst, 1}", []>;
-def RCL32m1 : I<0xD1, MRM2m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcl{l}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCL32rCL : I<0xD3, MRM2r, (outs GR32:$dst), (ins GR32:$src),
"rcl{l}\t{%cl, $dst|$dst, CL}", []>;
-def RCL32mCL : I<0xD3, MRM2m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcl{l}\t{%cl, $dst|$dst, CL}", []>;
}
def RCL32ri : Ii8<0xC1, MRM2r, (outs GR32:$dst), (ins GR32:$src, i8imm:$cnt),
"rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCL32mi : Ii8<0xC1, MRM2m, (outs i32mem:$dst),
- (ins i32mem:$src, i8imm:$cnt),
- "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCR8r1 : I<0xD0, MRM3r, (outs GR8:$dst), (ins GR8:$src),
"rcr{b}\t{1, $dst|$dst, 1}", []>;
-def RCR8m1 : I<0xD0, MRM3m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcr{b}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCR8rCL : I<0xD2, MRM3r, (outs GR8:$dst), (ins GR8:$src),
"rcr{b}\t{%cl, $dst|$dst, CL}", []>;
-def RCR8mCL : I<0xD2, MRM3m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcr{b}\t{%cl, $dst|$dst, CL}", []>;
}
def RCR8ri : Ii8<0xC0, MRM3r, (outs GR8:$dst), (ins GR8:$src, i8imm:$cnt),
"rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCR8mi : Ii8<0xC0, MRM3m, (outs i8mem:$dst), (ins i8mem:$src, i8imm:$cnt),
- "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCR16r1 : I<0xD1, MRM3r, (outs GR16:$dst), (ins GR16:$src),
"rcr{w}\t{1, $dst|$dst, 1}", []>, OpSize;
-def RCR16m1 : I<0xD1, MRM3m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcr{w}\t{1, $dst|$dst, 1}", []>, OpSize;
let Uses = [CL] in {
def RCR16rCL : I<0xD3, MRM3r, (outs GR16:$dst), (ins GR16:$src),
"rcr{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
-def RCR16mCL : I<0xD3, MRM3m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcr{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
}
def RCR16ri : Ii8<0xC1, MRM3r, (outs GR16:$dst), (ins GR16:$src, i8imm:$cnt),
"rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
-def RCR16mi : Ii8<0xC1, MRM3m, (outs i16mem:$dst),
- (ins i16mem:$src, i8imm:$cnt),
- "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
def RCR32r1 : I<0xD1, MRM3r, (outs GR32:$dst), (ins GR32:$src),
"rcr{l}\t{1, $dst|$dst, 1}", []>;
-def RCR32m1 : I<0xD1, MRM3m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcr{l}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCR32rCL : I<0xD3, MRM3r, (outs GR32:$dst), (ins GR32:$src),
"rcr{l}\t{%cl, $dst|$dst, CL}", []>;
-def RCR32mCL : I<0xD3, MRM3m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcr{l}\t{%cl, $dst|$dst, CL}", []>;
}
def RCR32ri : Ii8<0xC1, MRM3r, (outs GR32:$dst), (ins GR32:$src, i8imm:$cnt),
"rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCR32mi : Ii8<0xC1, MRM3m, (outs i32mem:$dst),
- (ins i32mem:$src, i8imm:$cnt),
+
+let isTwoAddress = 0 in {
+def RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst),
+ "rcl{b}\t{1, $dst|$dst, 1}", []>;
+def RCL8mi : Ii8<0xC0, MRM2m, (outs), (ins i8mem:$dst, i8imm:$cnt),
+ "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCL16m1 : I<0xD1, MRM2m, (outs), (ins i16mem:$dst),
+ "rcl{w}\t{1, $dst|$dst, 1}", []>, OpSize;
+def RCL16mi : Ii8<0xC1, MRM2m, (outs), (ins i16mem:$dst, i8imm:$cnt),
+ "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
+def RCL32m1 : I<0xD1, MRM2m, (outs), (ins i32mem:$dst),
+ "rcl{l}\t{1, $dst|$dst, 1}", []>;
+def RCL32mi : Ii8<0xC1, MRM2m, (outs), (ins i32mem:$dst, i8imm:$cnt),
+ "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCR8m1 : I<0xD0, MRM3m, (outs), (ins i8mem:$dst),
+ "rcr{b}\t{1, $dst|$dst, 1}", []>;
+def RCR8mi : Ii8<0xC0, MRM3m, (outs), (ins i8mem:$dst, i8imm:$cnt),
+ "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCR16m1 : I<0xD1, MRM3m, (outs), (ins i16mem:$dst),
+ "rcr{w}\t{1, $dst|$dst, 1}", []>, OpSize;
+def RCR16mi : Ii8<0xC1, MRM3m, (outs), (ins i16mem:$dst, i8imm:$cnt),
+ "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
+def RCR32m1 : I<0xD1, MRM3m, (outs), (ins i32mem:$dst),
+ "rcr{l}\t{1, $dst|$dst, 1}", []>;
+def RCR32mi : Ii8<0xC1, MRM3m, (outs), (ins i32mem:$dst, i8imm:$cnt),
"rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>;
+let Uses = [CL] in {
+def RCL8mCL : I<0xD2, MRM2m, (outs), (ins i8mem:$dst),
+ "rcl{b}\t{%cl, $dst|$dst, CL}", []>;
+def RCL16mCL : I<0xD3, MRM2m, (outs), (ins i16mem:$dst),
+ "rcl{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
+def RCL32mCL : I<0xD3, MRM2m, (outs), (ins i32mem:$dst),
+ "rcl{l}\t{%cl, $dst|$dst, CL}", []>;
+def RCR8mCL : I<0xD2, MRM3m, (outs), (ins i8mem:$dst),
+ "rcr{b}\t{%cl, $dst|$dst, CL}", []>;
+def RCR16mCL : I<0xD3, MRM3m, (outs), (ins i16mem:$dst),
+ "rcr{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
+def RCR32mCL : I<0xD3, MRM3m, (outs), (ins i32mem:$dst),
+ "rcr{l}\t{%cl, $dst|$dst, CL}", []>;
+}
+}
+
// FIXME: provide shorter instructions when imm8 == 1
let Uses = [CL] in {
def ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src),
@@ -4100,7 +4056,7 @@ def LSL32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
"lsl{l}\t{$src, $dst|$dst, $src}", []>, TB;
-def INVLPG : I<0x01, RawFrm, (outs), (ins), "invlpg", []>, TB;
+def INVLPG : I<0x01, MRM7m, (outs), (ins i8mem:$addr), "invlpg\t$addr", []>, TB;
def STRr : I<0x00, MRM1r, (outs GR16:$dst), (ins),
"str{w}\t{$dst}", []>, TB;
@@ -4262,17 +4218,17 @@ def WBINVD : I<0x09, RawFrm, (outs), (ins), "wbinvd", []>, TB;
// VMX instructions
// 66 0F 38 80
-def INVEPT : I<0x38, RawFrm, (outs), (ins), "invept", []>, OpSize, TB;
+def INVEPT : I<0x80, RawFrm, (outs), (ins), "invept", []>, OpSize, T8;
// 66 0F 38 81
-def INVVPID : I<0x38, RawFrm, (outs), (ins), "invvpid", []>, OpSize, TB;
+def INVVPID : I<0x81, RawFrm, (outs), (ins), "invvpid", []>, OpSize, T8;
// 0F 01 C1
-def VMCALL : I<0x01, RawFrm, (outs), (ins), "vmcall", []>, TB;
+def VMCALL : I<0x01, MRM_C1, (outs), (ins), "vmcall", []>, TB;
def VMCLEARm : I<0xC7, MRM6m, (outs), (ins i64mem:$vmcs),
"vmclear\t$vmcs", []>, OpSize, TB;
// 0F 01 C2
-def VMLAUNCH : I<0x01, RawFrm, (outs), (ins), "vmlaunch", []>, TB;
+def VMLAUNCH : I<0x01, MRM_C2, (outs), (ins), "vmlaunch", []>, TB;
// 0F 01 C3
-def VMRESUME : I<0x01, RawFrm, (outs), (ins), "vmresume", []>, TB;
+def VMRESUME : I<0x01, MRM_C3, (outs), (ins), "vmresume", []>, TB;
def VMPTRLDm : I<0xC7, MRM6m, (outs), (ins i64mem:$vmcs),
"vmptrld\t$vmcs", []>, TB;
def VMPTRSTm : I<0xC7, MRM7m, (outs i64mem:$vmcs), (ins),
@@ -4294,7 +4250,7 @@ def VMWRITE32rm : I<0x79, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
def VMWRITE32rr : I<0x79, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
"vmwrite{l}\t{$src, $dst|$dst, $src}", []>, TB;
// 0F 01 C4
-def VMXOFF : I<0x01, RawFrm, (outs), (ins), "vmxoff", []>, OpSize;
+def VMXOFF : I<0x01, MRM_C4, (outs), (ins), "vmxoff", []>, TB;
def VMXON : I<0xC7, MRM6m, (outs), (ins i64mem:$vmxon),
"vmxon\t{$vmxon}", []>, XD;
@@ -4462,12 +4418,6 @@ def : Pat<(i16 (anyext GR8 :$src)), (MOVZX16rr8 GR8 :$src)>;
def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8 GR8 :$src)>;
def : Pat<(i32 (anyext GR16:$src)), (MOVZX32rr16 GR16:$src)>;
-// (and (i32 load), 255) -> (zextload i8)
-def : Pat<(i32 (and (nvloadi32 addr:$src), (i32 255))),
- (MOVZX32rm8 addr:$src)>;
-def : Pat<(i32 (and (nvloadi32 addr:$src), (i32 65535))),
- (MOVZX32rm16 addr:$src)>;
-
//===----------------------------------------------------------------------===//
// Some peepholes
//===----------------------------------------------------------------------===//
@@ -4563,43 +4513,43 @@ def : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>;
def : Pat<(shl GR32:$src1, (i8 1)), (ADD32rr GR32:$src1, GR32:$src1)>;
// (shl x (and y, 31)) ==> (shl x, y)
-def : Pat<(shl GR8:$src1, (and CL:$amt, 31)),
+def : Pat<(shl GR8:$src1, (and CL, 31)),
(SHL8rCL GR8:$src1)>;
-def : Pat<(shl GR16:$src1, (and CL:$amt, 31)),
+def : Pat<(shl GR16:$src1, (and CL, 31)),
(SHL16rCL GR16:$src1)>;
-def : Pat<(shl GR32:$src1, (and CL:$amt, 31)),
+def : Pat<(shl GR32:$src1, (and CL, 31)),
(SHL32rCL GR32:$src1)>;
-def : Pat<(store (shl (loadi8 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (shl (loadi8 addr:$dst), (and CL, 31)), addr:$dst),
(SHL8mCL addr:$dst)>;
-def : Pat<(store (shl (loadi16 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (shl (loadi16 addr:$dst), (and CL, 31)), addr:$dst),
(SHL16mCL addr:$dst)>;
-def : Pat<(store (shl (loadi32 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (shl (loadi32 addr:$dst), (and CL, 31)), addr:$dst),
(SHL32mCL addr:$dst)>;
-def : Pat<(srl GR8:$src1, (and CL:$amt, 31)),
+def : Pat<(srl GR8:$src1, (and CL, 31)),
(SHR8rCL GR8:$src1)>;
-def : Pat<(srl GR16:$src1, (and CL:$amt, 31)),
+def : Pat<(srl GR16:$src1, (and CL, 31)),
(SHR16rCL GR16:$src1)>;
-def : Pat<(srl GR32:$src1, (and CL:$amt, 31)),
+def : Pat<(srl GR32:$src1, (and CL, 31)),
(SHR32rCL GR32:$src1)>;
-def : Pat<(store (srl (loadi8 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (srl (loadi8 addr:$dst), (and CL, 31)), addr:$dst),
(SHR8mCL addr:$dst)>;
-def : Pat<(store (srl (loadi16 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (srl (loadi16 addr:$dst), (and CL, 31)), addr:$dst),
(SHR16mCL addr:$dst)>;
-def : Pat<(store (srl (loadi32 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (srl (loadi32 addr:$dst), (and CL, 31)), addr:$dst),
(SHR32mCL addr:$dst)>;
-def : Pat<(sra GR8:$src1, (and CL:$amt, 31)),
+def : Pat<(sra GR8:$src1, (and CL, 31)),
(SAR8rCL GR8:$src1)>;
-def : Pat<(sra GR16:$src1, (and CL:$amt, 31)),
+def : Pat<(sra GR16:$src1, (and CL, 31)),
(SAR16rCL GR16:$src1)>;
-def : Pat<(sra GR32:$src1, (and CL:$amt, 31)),
+def : Pat<(sra GR32:$src1, (and CL, 31)),
(SAR32rCL GR32:$src1)>;
-def : Pat<(store (sra (loadi8 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (sra (loadi8 addr:$dst), (and CL, 31)), addr:$dst),
(SAR8mCL addr:$dst)>;
-def : Pat<(store (sra (loadi16 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (sra (loadi16 addr:$dst), (and CL, 31)), addr:$dst),
(SAR16mCL addr:$dst)>;
-def : Pat<(store (sra (loadi32 addr:$dst), (and CL:$amt, 31)), addr:$dst),
+def : Pat<(store (sra (loadi32 addr:$dst), (and CL, 31)), addr:$dst),
(SAR32mCL addr:$dst)>;
// (or (x >> c) | (y << (32 - c))) ==> (shrd32 x, y, c)
@@ -4620,11 +4570,11 @@ def : Pat<(store (or (srl (loadi32 addr:$dst), (i8 (trunc ECX:$amt))),
addr:$dst),
(SHRD32mrCL addr:$dst, GR32:$src2)>;
-def : Pat<(shrd GR32:$src1, (i8 imm:$amt1), GR32:$src2, (i8 imm:$amt2)),
+def : Pat<(shrd GR32:$src1, (i8 imm:$amt1), GR32:$src2, (i8 imm/*:$amt2*/)),
(SHRD32rri8 GR32:$src1, GR32:$src2, (i8 imm:$amt1))>;
def : Pat<(store (shrd (loadi32 addr:$dst), (i8 imm:$amt1),
- GR32:$src2, (i8 imm:$amt2)), addr:$dst),
+ GR32:$src2, (i8 imm/*:$amt2*/)), addr:$dst),
(SHRD32mri8 addr:$dst, GR32:$src2, (i8 imm:$amt1))>;
// (or (x << c) | (y >> (32 - c))) ==> (shld32 x, y, c)
@@ -4645,11 +4595,11 @@ def : Pat<(store (or (shl (loadi32 addr:$dst), (i8 (trunc ECX:$amt))),
addr:$dst),
(SHLD32mrCL addr:$dst, GR32:$src2)>;
-def : Pat<(shld GR32:$src1, (i8 imm:$amt1), GR32:$src2, (i8 imm:$amt2)),
+def : Pat<(shld GR32:$src1, (i8 imm:$amt1), GR32:$src2, (i8 imm/*:$amt2*/)),
(SHLD32rri8 GR32:$src1, GR32:$src2, (i8 imm:$amt1))>;
def : Pat<(store (shld (loadi32 addr:$dst), (i8 imm:$amt1),
- GR32:$src2, (i8 imm:$amt2)), addr:$dst),
+ GR32:$src2, (i8 imm/*:$amt2*/)), addr:$dst),
(SHLD32mri8 addr:$dst, GR32:$src2, (i8 imm:$amt1))>;
// (or (x >> c) | (y << (16 - c))) ==> (shrd16 x, y, c)
@@ -4670,11 +4620,11 @@ def : Pat<(store (or (srl (loadi16 addr:$dst), (i8 (trunc CX:$amt))),
addr:$dst),
(SHRD16mrCL addr:$dst, GR16:$src2)>;
-def : Pat<(shrd GR16:$src1, (i8 imm:$amt1), GR16:$src2, (i8 imm:$amt2)),
+def : Pat<(shrd GR16:$src1, (i8 imm:$amt1), GR16:$src2, (i8 imm/*:$amt2*/)),
(SHRD16rri8 GR16:$src1, GR16:$src2, (i8 imm:$amt1))>;
def : Pat<(store (shrd (loadi16 addr:$dst), (i8 imm:$amt1),
- GR16:$src2, (i8 imm:$amt2)), addr:$dst),
+ GR16:$src2, (i8 imm/*:$amt2*/)), addr:$dst),
(SHRD16mri8 addr:$dst, GR16:$src2, (i8 imm:$amt1))>;
// (or (x << c) | (y >> (16 - c))) ==> (shld16 x, y, c)
@@ -4695,11 +4645,11 @@ def : Pat<(store (or (shl (loadi16 addr:$dst), (i8 (trunc CX:$amt))),
addr:$dst),
(SHLD16mrCL addr:$dst, GR16:$src2)>;
-def : Pat<(shld GR16:$src1, (i8 imm:$amt1), GR16:$src2, (i8 imm:$amt2)),
+def : Pat<(shld GR16:$src1, (i8 imm:$amt1), GR16:$src2, (i8 imm/*:$amt2*/)),
(SHLD16rri8 GR16:$src1, GR16:$src2, (i8 imm:$amt1))>;
def : Pat<(store (shld (loadi16 addr:$dst), (i8 imm:$amt1),
- GR16:$src2, (i8 imm:$amt2)), addr:$dst),
+ GR16:$src2, (i8 imm/*:$amt2*/)), addr:$dst),
(SHLD16mri8 addr:$dst, GR16:$src2, (i8 imm:$amt1))>;
// (anyext (setcc_carry)) -> (setcc_carry)
diff --git a/lib/Target/X86/X86InstrMMX.td b/lib/Target/X86/X86InstrMMX.td
index 89f020c..c8e0723 100644
--- a/lib/Target/X86/X86InstrMMX.td
+++ b/lib/Target/X86/X86InstrMMX.td
@@ -141,7 +141,7 @@ def MMX_MOVD64rrv164 : MMXI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR64:$src),
let neverHasSideEffects = 1 in
def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src),
"movq\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def MMX_MOVQ64rm : MMXI<0x6F, MRMSrcMem, (outs VR64:$dst), (ins i64mem:$src),
"movq\t{$src, $dst|$dst, $src}",
[(set VR64:$dst, (load_mmx addr:$src))]>;
@@ -426,13 +426,15 @@ def MMX_CVTTPS2PIrm : MMXI<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src),
// Extract / Insert
-def MMX_X86pextrw : SDNode<"X86ISD::PEXTRW", SDTypeProfile<1, 2, []>, []>;
-def MMX_X86pinsrw : SDNode<"X86ISD::PINSRW", SDTypeProfile<1, 3, []>, []>;
+def MMX_X86pinsrw : SDNode<"X86ISD::MMX_PINSRW",
+ SDTypeProfile<1, 3, [SDTCisVT<0, v4i16>, SDTCisSameAs<0,1>,
+ SDTCisVT<2, i32>, SDTCisPtrTy<3>]>>;
+
def MMX_PEXTRWri : MMXIi8<0xC5, MRMSrcReg,
(outs GR32:$dst), (ins VR64:$src1, i16i8imm:$src2),
"pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
- [(set GR32:$dst, (MMX_X86pextrw (v4i16 VR64:$src1),
+ [(set GR32:$dst, (X86pextrw (v4i16 VR64:$src1),
(iPTR imm:$src2)))]>;
let Constraints = "$src1 = $dst" in {
def MMX_PINSRWrri : MMXIi8<0xC4, MRMSrcReg,
@@ -597,13 +599,6 @@ let AddedComplexity = 10 in {
(MMX_PUNPCKHDQrr VR64:$src, VR64:$src)>;
}
-// Patterns to perform vector shuffling with a zeroed out vector.
-let AddedComplexity = 20 in {
- def : Pat<(bc_v2i32 (mmx_unpckl immAllZerosV,
- (v2i32 (scalar_to_vector (load_mmx addr:$src))))),
- (MMX_PUNPCKLDQrm VR64:$src, VR64:$src)>;
-}
-
// Some special case PANDN patterns.
// FIXME: Get rid of these.
def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v2i32 immAllOnesV))),
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index e26c979..2743dba 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -160,6 +160,32 @@ def memopv4i16 : PatFrag<(ops node:$ptr), (v4i16 (memop64 node:$ptr))>;
def memopv8i16 : PatFrag<(ops node:$ptr), (v8i16 (memop64 node:$ptr))>;
def memopv2i32 : PatFrag<(ops node:$ptr), (v2i32 (memop64 node:$ptr))>;
+// MOVNT Support
+// Like 'store', but requires the non-temporal bit to be set
+def nontemporalstore : PatFrag<(ops node:$val, node:$ptr),
+ (st node:$val, node:$ptr), [{
+ if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
+ return ST->isNonTemporal();
+ return false;
+}]>;
+
+def alignednontemporalstore : PatFrag<(ops node:$val, node:$ptr),
+ (st node:$val, node:$ptr), [{
+ if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
+ return ST->isNonTemporal() && !ST->isTruncatingStore() &&
+ ST->getAddressingMode() == ISD::UNINDEXED &&
+ ST->getAlignment() >= 16;
+ return false;
+}]>;
+
+def unalignednontemporalstore : PatFrag<(ops node:$val, node:$ptr),
+ (st node:$val, node:$ptr), [{
+ if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
+ return ST->isNonTemporal() &&
+ ST->getAlignment() < 16;
+ return false;
+}]>;
+
def bc_v4f32 : PatFrag<(ops node:$in), (v4f32 (bitconvert node:$in))>;
def bc_v2f64 : PatFrag<(ops node:$in), (v2f64 (bitconvert node:$in))>;
def bc_v16i8 : PatFrag<(ops node:$in), (v16i8 (bitconvert node:$in))>;
@@ -344,18 +370,56 @@ let Uses = [EFLAGS], usesCustomInserter = 1 in {
// SSE1 Instructions
//===----------------------------------------------------------------------===//
-// Move Instructions
-let neverHasSideEffects = 1 in
-def MOVSSrr : SSI<0x10, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
- "movss\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+// Move Instructions. Register-to-register movss is not used for FR32
+// register copies because it's a partial register update; FsMOVAPSrr is
+// used instead. Register-to-register movss is not modeled as an INSERT_SUBREG
+// because INSERT_SUBREG requires that the insert be implementable in terms of
+// a copy, and just mentioned, we don't use movss for copies.
+let Constraints = "$src1 = $dst" in
+def MOVSSrr : SSI<0x10, MRMSrcReg,
+ (outs VR128:$dst), (ins VR128:$src1, FR32:$src2),
+ "movss\t{$src2, $dst|$dst, $src2}",
+ [(set VR128:$dst,
+ (movl VR128:$src1, (scalar_to_vector FR32:$src2)))]>;
+
+// Extract the low 32-bit value from one vector and insert it into another.
+let AddedComplexity = 15 in
+def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
+ (MOVSSrr VR128:$src1,
+ (EXTRACT_SUBREG (v4f32 VR128:$src2), x86_subreg_ss))>;
+
+// Implicitly promote a 32-bit scalar to a vector.
+def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
+ (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, x86_subreg_ss)>;
+
+// Loading from memory automatically zeroing upper bits.
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def MOVSSrm : SSI<0x10, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
"movss\t{$src, $dst|$dst, $src}",
[(set FR32:$dst, (loadf32 addr:$src))]>;
+
+// MOVSSrm zeros the high parts of the register; represent this
+// with SUBREG_TO_REG.
+let AddedComplexity = 20 in {
+def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
+ (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), x86_subreg_ss)>;
+def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
+ (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), x86_subreg_ss)>;
+def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
+ (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), x86_subreg_ss)>;
+}
+
+// Store scalar value to memory.
def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
"movss\t{$src, $dst|$dst, $src}",
[(store FR32:$src, addr:$dst)]>;
+// Extract and store.
+def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
+ addr:$dst),
+ (MOVSSmr addr:$dst,
+ (EXTRACT_SUBREG (v4f32 VR128:$src), x86_subreg_ss))>;
+
// Conversion instructions
def CVTTSS2SIrr : SSI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins FR32:$src),
"cvttss2si\t{$src, $dst|$dst, $src}",
@@ -518,7 +582,7 @@ def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
// Alias instruction to load FR32 from f128mem using movaps. Upper bits are
// disregarded.
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
"movaps\t{$src, $dst|$dst, $src}",
[(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
@@ -715,7 +779,7 @@ defm MIN : sse1_fp_binop_rm<0x5D, "min", X86fmin,
let neverHasSideEffects = 1 in
def MOVAPSrr : PSI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
"movaps\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def MOVAPSrm : PSI<0x28, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
"movaps\t{$src, $dst|$dst, $src}",
[(set VR128:$dst, (alignedloadv4f32 addr:$src))]>;
@@ -727,7 +791,7 @@ def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
let neverHasSideEffects = 1 in
def MOVUPSrr : PSI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
"movups\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def MOVUPSrm : PSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
"movups\t{$src, $dst|$dst, $src}",
[(set VR128:$dst, (loadv4f32 addr:$src))]>;
@@ -736,7 +800,7 @@ def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
[(store (v4f32 VR128:$src), addr:$dst)]>;
// Intrinsic forms of MOVUPS load and store
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def MOVUPSrm_Int : PSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
"movups\t{$src, $dst|$dst, $src}",
[(set VR128:$dst, (int_x86_sse_loadu_ps addr:$src))]>;
@@ -762,6 +826,9 @@ let Constraints = "$src1 = $dst" in {
} // Constraints = "$src1 = $dst"
+def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
+ (MOVHPSrm VR128:$src1, addr:$src2)>;
+
def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
"movlps\t{$src, $dst|$dst, $src}",
[(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
@@ -793,9 +860,9 @@ def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
let AddedComplexity = 20 in {
def : Pat<(v4f32 (movddup VR128:$src, (undef))),
- (MOVLHPSrr VR128:$src, VR128:$src)>, Requires<[HasSSE1]>;
+ (MOVLHPSrr VR128:$src, VR128:$src)>;
def : Pat<(v2i64 (movddup VR128:$src, (undef))),
- (MOVLHPSrr VR128:$src, VR128:$src)>, Requires<[HasSSE1]>;
+ (MOVLHPSrr VR128:$src, VR128:$src)>;
}
@@ -1010,10 +1077,33 @@ def PREFETCHNTA : PSI<0x18, MRM0m, (outs), (ins i8mem:$src),
"prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0))]>;
// Non-temporal stores
-def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
+def MOVNTPSmr_Int : PSI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
"movntps\t{$src, $dst|$dst, $src}",
[(int_x86_sse_movnt_ps addr:$dst, VR128:$src)]>;
+let AddedComplexity = 400 in { // Prefer non-temporal versions
+def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
+ "movntps\t{$src, $dst|$dst, $src}",
+ [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
+
+def MOVNTDQ_64mr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
+ "movntdq\t{$src, $dst|$dst, $src}",
+ [(alignednontemporalstore (v2f64 VR128:$src), addr:$dst)]>;
+
+def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
+ (MOVNTDQ_64mr VR128:$src, addr:$dst)>;
+
+def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
+ "movnti\t{$src, $dst|$dst, $src}",
+ [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
+ TB, Requires<[HasSSE2]>;
+
+def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
+ "movnti\t{$src, $dst|$dst, $src}",
+ [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
+ TB, Requires<[HasSSE2]>;
+}
+
// Load, store, and memory fence
def SFENCE : PSI<0xAE, MRM7r, (outs), (ins), "sfence", [(int_x86_sse_sfence)]>;
@@ -1032,84 +1122,73 @@ let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
[(set VR128:$dst, (v4i32 immAllZerosV))]>;
-let Predicates = [HasSSE1] in {
- def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
- def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
- def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
- def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
- def : Pat<(v4f32 immAllZerosV), (V_SET0)>;
-}
-
-// FR32 to 128-bit vector conversion.
-let isAsCheapAsAMove = 1 in
-def MOVSS2PSrr : SSI<0x10, MRMSrcReg, (outs VR128:$dst), (ins FR32:$src),
- "movss\t{$src, $dst|$dst, $src}",
- [(set VR128:$dst,
- (v4f32 (scalar_to_vector FR32:$src)))]>;
-def MOVSS2PSrm : SSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f32mem:$src),
- "movss\t{$src, $dst|$dst, $src}",
- [(set VR128:$dst,
- (v4f32 (scalar_to_vector (loadf32 addr:$src))))]>;
-
-// FIXME: may not be able to eliminate this movss with coalescing the src and
-// dest register classes are different. We really want to write this pattern
-// like this:
-// def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
-// (f32 FR32:$src)>;
-let isAsCheapAsAMove = 1 in
-def MOVPS2SSrr : SSI<0x10, MRMSrcReg, (outs FR32:$dst), (ins VR128:$src),
- "movss\t{$src, $dst|$dst, $src}",
- [(set FR32:$dst, (vector_extract (v4f32 VR128:$src),
- (iPTR 0)))]>;
-def MOVPS2SSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, VR128:$src),
- "movss\t{$src, $dst|$dst, $src}",
- [(store (f32 (vector_extract (v4f32 VR128:$src),
- (iPTR 0))), addr:$dst)]>;
-
-
-// Move to lower bits of a VR128, leaving upper bits alone.
-// Three operand (but two address) aliases.
-let Constraints = "$src1 = $dst" in {
-let neverHasSideEffects = 1 in
- def MOVLSS2PSrr : SSI<0x10, MRMSrcReg,
- (outs VR128:$dst), (ins VR128:$src1, FR32:$src2),
- "movss\t{$src2, $dst|$dst, $src2}", []>;
-
- let AddedComplexity = 15 in
- def MOVLPSrr : SSI<0x10, MRMSrcReg,
- (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
- "movss\t{$src2, $dst|$dst, $src2}",
- [(set VR128:$dst,
- (v4f32 (movl VR128:$src1, VR128:$src2)))]>;
-}
+def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
+def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
+def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
+def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
+def : Pat<(v4f32 immAllZerosV), (V_SET0)>;
-// Move to lower bits of a VR128 and zeroing upper bits.
-// Loading from memory automatically zeroing upper bits.
-let AddedComplexity = 20 in
-def MOVZSS2PSrm : SSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f32mem:$src),
- "movss\t{$src, $dst|$dst, $src}",
- [(set VR128:$dst, (v4f32 (X86vzmovl (v4f32 (scalar_to_vector
- (loadf32 addr:$src))))))]>;
-
-def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
- (MOVZSS2PSrm addr:$src)>;
+def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
+ (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), x86_subreg_ss))>;
//===---------------------------------------------------------------------===//
// SSE2 Instructions
//===---------------------------------------------------------------------===//
-// Move Instructions
-let neverHasSideEffects = 1 in
-def MOVSDrr : SDI<0x10, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
- "movsd\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+// Move Instructions. Register-to-register movsd is not used for FR64
+// register copies because it's a partial register update; FsMOVAPDrr is
+// used instead. Register-to-register movsd is not modeled as an INSERT_SUBREG
+// because INSERT_SUBREG requires that the insert be implementable in terms of
+// a copy, and just mentioned, we don't use movsd for copies.
+let Constraints = "$src1 = $dst" in
+def MOVSDrr : SDI<0x10, MRMSrcReg,
+ (outs VR128:$dst), (ins VR128:$src1, FR64:$src2),
+ "movsd\t{$src2, $dst|$dst, $src2}",
+ [(set VR128:$dst,
+ (movl VR128:$src1, (scalar_to_vector FR64:$src2)))]>;
+
+// Extract the low 64-bit value from one vector and insert it into another.
+let AddedComplexity = 15 in
+def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
+ (MOVSDrr VR128:$src1,
+ (EXTRACT_SUBREG (v2f64 VR128:$src2), x86_subreg_sd))>;
+
+// Implicitly promote a 64-bit scalar to a vector.
+def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
+ (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, x86_subreg_sd)>;
+
+// Loading from memory automatically zeroing upper bits.
+let canFoldAsLoad = 1, isReMaterializable = 1, AddedComplexity = 20 in
def MOVSDrm : SDI<0x10, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
"movsd\t{$src, $dst|$dst, $src}",
[(set FR64:$dst, (loadf64 addr:$src))]>;
+
+// MOVSDrm zeros the high parts of the register; represent this
+// with SUBREG_TO_REG.
+let AddedComplexity = 20 in {
+def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
+ (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>;
+def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
+ (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>;
+def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
+ (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>;
+def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
+ (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>;
+def : Pat<(v2f64 (X86vzload addr:$src)),
+ (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>;
+}
+
+// Store scalar value to memory.
def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
"movsd\t{$src, $dst|$dst, $src}",
[(store FR64:$src, addr:$dst)]>;
+// Extract and store.
+def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
+ addr:$dst),
+ (MOVSDmr addr:$dst,
+ (EXTRACT_SUBREG (v2f64 VR128:$src), x86_subreg_sd))>;
+
// Conversion instructions
def CVTTSD2SIrr : SDI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins FR64:$src),
"cvttsd2si\t{$src, $dst|$dst, $src}",
@@ -1163,7 +1242,8 @@ def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
Requires<[HasSSE2, OptForSize]>;
def : Pat<(extloadf32 addr:$src),
- (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[HasSSE2, OptForSpeed]>;
+ (CVTSS2SDrr (MOVSSrm addr:$src))>,
+ Requires<[HasSSE2, OptForSpeed]>;
// Match intrinsics which expect XMM operand(s).
def Int_CVTSD2SIrr : SDI<0x2D, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
@@ -1282,7 +1362,7 @@ def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
// Alias instruction to load FR64 from f128mem using movapd. Upper bits are
// disregarded.
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
"movapd\t{$src, $dst|$dst, $src}",
[(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
@@ -1480,7 +1560,7 @@ defm MIN : sse2_fp_binop_rm<0x5D, "min", X86fmin,
let neverHasSideEffects = 1 in
def MOVAPDrr : PDI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
"movapd\t{$src, $dst|$dst, $src}", []>;
-let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let canFoldAsLoad = 1, isReMaterializable = 1 in
def MOVAPDrm : PDI<0x28, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
"movapd\t{$src, $dst|$dst, $src}",
[(set VR128:$dst, (alignedloadv2f64 addr:$src))]>;
@@ -2295,34 +2375,47 @@ def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
[(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
// Non-temporal stores
-def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
- "movntpd\t{$src, $dst|$dst, $src}",
- [(int_x86_sse2_movnt_pd addr:$dst, VR128:$src)]>;
-def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
- "movntdq\t{$src, $dst|$dst, $src}",
- [(int_x86_sse2_movnt_dq addr:$dst, VR128:$src)]>;
-def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
+def MOVNTPDmr_Int : PDI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
+ "movntpd\t{$src, $dst|$dst, $src}",
+ [(int_x86_sse2_movnt_pd addr:$dst, VR128:$src)]>;
+def MOVNTDQmr_Int : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
+ "movntdq\t{$src, $dst|$dst, $src}",
+ [(int_x86_sse2_movnt_dq addr:$dst, VR128:$src)]>;
+def MOVNTImr_Int : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
"movnti\t{$src, $dst|$dst, $src}",
[(int_x86_sse2_movnt_i addr:$dst, GR32:$src)]>,
TB, Requires<[HasSSE2]>;
+let AddedComplexity = 400 in { // Prefer non-temporal versions
+def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
+ "movntpd\t{$src, $dst|$dst, $src}",
+ [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
+
+def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
+ "movntdq\t{$src, $dst|$dst, $src}",
+ [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
+
+def : Pat<(alignednontemporalstore (v4i32 VR128:$src), addr:$dst),
+ (MOVNTDQmr VR128:$src, addr:$dst)>;
+}
+
// Flush cache
def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
"clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
TB, Requires<[HasSSE2]>;
// Load, store, and memory fence
-def LFENCE : I<0xAE, MRM5r, (outs), (ins),
+def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
"lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
-def MFENCE : I<0xAE, MRM6r, (outs), (ins),
+def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
"mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
//TODO: custom lower this so as to never even generate the noop
-def : Pat<(membarrier (i8 imm:$ll), (i8 imm:$ls), (i8 imm:$sl), (i8 imm:$ss),
+def : Pat<(membarrier (i8 imm), (i8 imm), (i8 imm), (i8 imm),
(i8 0)), (NOOP)>;
def : Pat<(membarrier (i8 0), (i8 0), (i8 0), (i8 1), (i8 1)), (SFENCE)>;
def : Pat<(membarrier (i8 1), (i8 0), (i8 0), (i8 0), (i8 1)), (LFENCE)>;
-def : Pat<(membarrier (i8 imm:$ll), (i8 imm:$ls), (i8 imm:$sl), (i8 imm:$ss),
+def : Pat<(membarrier (i8 imm), (i8 imm), (i8 imm), (i8 imm),
(i8 1)), (MFENCE)>;
// Alias instructions that map zero vector to pxor / xorp* for sse.
@@ -2334,17 +2427,6 @@ let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
[(set VR128:$dst, (v4i32 immAllOnesV))]>;
-// FR64 to 128-bit vector conversion.
-let isAsCheapAsAMove = 1 in
-def MOVSD2PDrr : SDI<0x10, MRMSrcReg, (outs VR128:$dst), (ins FR64:$src),
- "movsd\t{$src, $dst|$dst, $src}",
- [(set VR128:$dst,
- (v2f64 (scalar_to_vector FR64:$src)))]>;
-def MOVSD2PDrm : SDI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
- "movsd\t{$src, $dst|$dst, $src}",
- [(set VR128:$dst,
- (v2f64 (scalar_to_vector (loadf64 addr:$src))))]>;
-
def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
"movd\t{$src, $dst|$dst, $src}",
[(set VR128:$dst,
@@ -2373,20 +2455,9 @@ def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
[(store (i64 (vector_extract (v2i64 VR128:$src),
(iPTR 0))), addr:$dst)]>;
-// FIXME: may not be able to eliminate this movss with coalescing the src and
-// dest register classes are different. We really want to write this pattern
-// like this:
-// def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
-// (f32 FR32:$src)>;
-let isAsCheapAsAMove = 1 in
-def MOVPD2SDrr : SDI<0x10, MRMSrcReg, (outs FR64:$dst), (ins VR128:$src),
- "movsd\t{$src, $dst|$dst, $src}",
- [(set FR64:$dst, (vector_extract (v2f64 VR128:$src),
- (iPTR 0)))]>;
-def MOVPD2SDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
- "movsd\t{$src, $dst|$dst, $src}",
- [(store (f64 (vector_extract (v2f64 VR128:$src),
- (iPTR 0))), addr:$dst)]>;
+def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
+ (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), x86_subreg_sd))>;
+
def MOVPDI2DIrr : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
"movd\t{$src, $dst|$dst, $src}",
[(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
@@ -2403,44 +2474,11 @@ def MOVSS2DImr : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
"movd\t{$src, $dst|$dst, $src}",
[(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
-
-// Move to lower bits of a VR128, leaving upper bits alone.
-// Three operand (but two address) aliases.
-let Constraints = "$src1 = $dst" in {
- let neverHasSideEffects = 1 in
- def MOVLSD2PDrr : SDI<0x10, MRMSrcReg,
- (outs VR128:$dst), (ins VR128:$src1, FR64:$src2),
- "movsd\t{$src2, $dst|$dst, $src2}", []>;
-
- let AddedComplexity = 15 in
- def MOVLPDrr : SDI<0x10, MRMSrcReg,
- (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
- "movsd\t{$src2, $dst|$dst, $src2}",
- [(set VR128:$dst,
- (v2f64 (movl VR128:$src1, VR128:$src2)))]>;
-}
-
// Store / copy lower 64-bits of a XMM register.
def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
"movq\t{$src, $dst|$dst, $src}",
[(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
-// Move to lower bits of a VR128 and zeroing upper bits.
-// Loading from memory automatically zeroing upper bits.
-let AddedComplexity = 20 in {
-def MOVZSD2PDrm : SDI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
- "movsd\t{$src, $dst|$dst, $src}",
- [(set VR128:$dst,
- (v2f64 (X86vzmovl (v2f64 (scalar_to_vector
- (loadf64 addr:$src))))))]>;
-
-def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
- (MOVZSD2PDrm addr:$src)>;
-def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
- (MOVZSD2PDrm addr:$src)>;
-def : Pat<(v2f64 (X86vzload addr:$src)), (MOVZSD2PDrm addr:$src)>;
-}
-
// movd / movq to XMM register zero-extends
let AddedComplexity = 15 in {
def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
@@ -2613,9 +2651,9 @@ let Constraints = "$src1 = $dst" in {
}
// Thread synchronization
-def MONITOR : I<0x01, MRM1r, (outs), (ins), "monitor",
+def MONITOR : I<0x01, MRM_C8, (outs), (ins), "monitor",
[(int_x86_sse3_monitor EAX, ECX, EDX)]>,TB, Requires<[HasSSE3]>;
-def MWAIT : I<0x01, MRM1r, (outs), (ins), "mwait",
+def MWAIT : I<0x01, MRM_C9, (outs), (ins), "mwait",
[(int_x86_sse3_mwait ECX, EAX)]>, TB, Requires<[HasSSE3]>;
// vector_shuffle v1, <undef> <1, 1, 3, 3>
@@ -2986,13 +3024,15 @@ let Predicates = [HasSSE2] in {
let AddedComplexity = 15 in {
// Zeroing a VR128 then do a MOVS{S|D} to the lower bits.
def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
- (MOVLSD2PDrr (V_SET0), FR64:$src)>, Requires<[HasSSE2]>;
+ (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
- (MOVLSS2PSrr (V_SET0), FR32:$src)>, Requires<[HasSSE1]>;
+ (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
- (MOVLPSrr (V_SET0), VR128:$src)>, Requires<[HasSSE1]>;
+ (MOVSSrr (v4f32 (V_SET0)),
+ (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), x86_subreg_ss)))>;
def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
- (MOVLPSrr (V_SET0), VR128:$src)>, Requires<[HasSSE1]>;
+ (MOVSSrr (v4i32 (V_SET0)),
+ (EXTRACT_SUBREG (v4i32 VR128:$src), x86_subreg_ss))>;
}
// Splat v2f64 / v2i64
@@ -3010,8 +3050,7 @@ def : Pat<(unpckh (v2i64 VR128:$src), (undef)),
// Special unary SHUFPSrri case.
def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
(SHUFPSrri VR128:$src1, VR128:$src1,
- (SHUFFLE_get_shuf_imm VR128:$src3))>,
- Requires<[HasSSE1]>;
+ (SHUFFLE_get_shuf_imm VR128:$src3))>;
let AddedComplexity = 5 in
def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
(PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>,
@@ -3057,13 +3096,13 @@ def : Pat<(v4f32 (unpckl_undef:$src2 VR128:$src, (undef))),
}
let AddedComplexity = 10 in {
def : Pat<(v4f32 (unpckl_undef VR128:$src, (undef))),
- (UNPCKLPSrr VR128:$src, VR128:$src)>, Requires<[HasSSE1]>;
+ (UNPCKLPSrr VR128:$src, VR128:$src)>;
def : Pat<(v16i8 (unpckl_undef VR128:$src, (undef))),
- (PUNPCKLBWrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
+ (PUNPCKLBWrr VR128:$src, VR128:$src)>;
def : Pat<(v8i16 (unpckl_undef VR128:$src, (undef))),
- (PUNPCKLWDrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
+ (PUNPCKLWDrr VR128:$src, VR128:$src)>;
def : Pat<(v4i32 (unpckl_undef VR128:$src, (undef))),
- (PUNPCKLDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
+ (PUNPCKLDQrr VR128:$src, VR128:$src)>;
}
// vector_shuffle v1, <undef>, <2, 2, 3, 3, ...>
@@ -3077,13 +3116,13 @@ def : Pat<(v4f32 (unpckh_undef:$src2 VR128:$src, (undef))),
}
let AddedComplexity = 10 in {
def : Pat<(v4f32 (unpckh_undef VR128:$src, (undef))),
- (UNPCKHPSrr VR128:$src, VR128:$src)>, Requires<[HasSSE1]>;
+ (UNPCKHPSrr VR128:$src, VR128:$src)>;
def : Pat<(v16i8 (unpckh_undef VR128:$src, (undef))),
- (PUNPCKHBWrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
+ (PUNPCKHBWrr VR128:$src, VR128:$src)>;
def : Pat<(v8i16 (unpckh_undef VR128:$src, (undef))),
- (PUNPCKHWDrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
+ (PUNPCKHWDrr VR128:$src, VR128:$src)>;
def : Pat<(v4i32 (unpckh_undef VR128:$src, (undef))),
- (PUNPCKHDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
+ (PUNPCKHDQrr VR128:$src, VR128:$src)>;
}
let AddedComplexity = 20 in {
@@ -3105,45 +3144,49 @@ def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
let AddedComplexity = 20 in {
// vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
- (MOVLPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE1]>;
+ (MOVLPSrm VR128:$src1, addr:$src2)>;
def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
- (MOVLPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
+ (MOVLPDrm VR128:$src1, addr:$src2)>;
def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
- (MOVLPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
+ (MOVLPSrm VR128:$src1, addr:$src2)>;
def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
- (MOVLPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
+ (MOVLPDrm VR128:$src1, addr:$src2)>;
}
// (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
- (MOVLPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
+ (MOVLPSmr addr:$src1, VR128:$src2)>;
def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
- (MOVLPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
+ (MOVLPDmr addr:$src1, VR128:$src2)>;
def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
addr:$src1),
- (MOVLPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
+ (MOVLPSmr addr:$src1, VR128:$src2)>;
def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
- (MOVLPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
+ (MOVLPDmr addr:$src1, VR128:$src2)>;
let AddedComplexity = 15 in {
// Setting the lowest element in the vector.
def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
- (MOVLPSrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
+ (MOVSSrr (v4i32 VR128:$src1),
+ (EXTRACT_SUBREG (v4i32 VR128:$src2), x86_subreg_ss))>;
def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
- (MOVLPDrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
+ (MOVSDrr (v2i64 VR128:$src1),
+ (EXTRACT_SUBREG (v2i64 VR128:$src2), x86_subreg_sd))>;
-// vector_shuffle v1, v2 <4, 5, 2, 3> using MOVLPDrr (movsd)
+// vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
- (MOVLPDrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
+ (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, x86_subreg_sd))>,
+ Requires<[HasSSE2]>;
def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
- (MOVLPDrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
+ (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, x86_subreg_sd))>,
+ Requires<[HasSSE2]>;
}
// vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
// fall back to this for SSE1)
def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
(SHUFPSrri VR128:$src2, VR128:$src1,
- (SHUFFLE_get_shuf_imm VR128:$src3))>, Requires<[HasSSE1]>;
+ (SHUFFLE_get_shuf_imm VR128:$src3))>;
// Set lowest element and zero upper elements.
let AddedComplexity = 15 in
@@ -3185,30 +3228,30 @@ def : Pat<(v2i32 (fp_to_sint (v2f64 VR128:$src))),
// Use movaps / movups for SSE integer load / store (one byte shorter).
def : Pat<(alignedloadv4i32 addr:$src),
- (MOVAPSrm addr:$src)>, Requires<[HasSSE1]>;
+ (MOVAPSrm addr:$src)>;
def : Pat<(loadv4i32 addr:$src),
- (MOVUPSrm addr:$src)>, Requires<[HasSSE1]>;
+ (MOVUPSrm addr:$src)>;
def : Pat<(alignedloadv2i64 addr:$src),
- (MOVAPSrm addr:$src)>, Requires<[HasSSE2]>;
+ (MOVAPSrm addr:$src)>;
def : Pat<(loadv2i64 addr:$src),
- (MOVUPSrm addr:$src)>, Requires<[HasSSE2]>;
+ (MOVUPSrm addr:$src)>;
def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
- (MOVAPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVAPSmr addr:$dst, VR128:$src)>;
def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
- (MOVAPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVAPSmr addr:$dst, VR128:$src)>;
def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
- (MOVAPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVAPSmr addr:$dst, VR128:$src)>;
def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
- (MOVAPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVAPSmr addr:$dst, VR128:$src)>;
def : Pat<(store (v2i64 VR128:$src), addr:$dst),
- (MOVUPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVUPSmr addr:$dst, VR128:$src)>;
def : Pat<(store (v4i32 VR128:$src), addr:$dst),
- (MOVUPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVUPSmr addr:$dst, VR128:$src)>;
def : Pat<(store (v8i16 VR128:$src), addr:$dst),
- (MOVUPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVUPSmr addr:$dst, VR128:$src)>;
def : Pat<(store (v16i8 VR128:$src), addr:$dst),
- (MOVUPSmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
+ (MOVUPSmr addr:$dst, VR128:$src)>;
//===----------------------------------------------------------------------===//
// SSE4.1 Instructions
@@ -3397,7 +3440,7 @@ let Constraints = "$src1 = $dst" in {
(ins VR128:$src1, i128mem:$src2),
!strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
[(set VR128:$dst,
- (OpNode VR128:$src1, (memop addr:$src2)))]>, OpSize;
+ (OpVT (OpNode VR128:$src1, (memop addr:$src2))))]>, OpSize;
def rm_int : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
(ins VR128:$src1, i128mem:$src2),
!strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp
index d3b0052..250634f 100644
--- a/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/lib/Target/X86/X86MCAsmInfo.cpp
@@ -55,6 +55,11 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &Triple) {
if (!is64Bit)
Data64bitsDirective = 0; // we can't emit a 64-bit unit
+ // Use ## as a comment string so that .s files generated by llvm can go
+ // through the GCC preprocessor without causing an error. This is needed
+ // because "clang foo.s" runs the C preprocessor, which is usually reserved
+ // for .S files on other systems. Perhaps this is because the file system
+ // wasn't always case preserving or something.
CommentString = "##";
PCSymbol = ".";
@@ -70,6 +75,8 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &Triple) {
AsmTransCBE = x86_asm_table;
AssemblerDialect = AsmWriterFlavor;
+ TextAlignFillValue = 0x90;
+
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
PCSymbol = ".";
@@ -94,27 +101,6 @@ MCSection *X86ELFMCAsmInfo::getNonexecutableStackSection(MCContext &Ctx) const {
X86MCAsmInfoCOFF::X86MCAsmInfoCOFF(const Triple &Triple) {
AsmTransCBE = x86_asm_table;
AssemblerDialect = AsmWriterFlavor;
-}
-
-
-X86WinMCAsmInfo::X86WinMCAsmInfo(const Triple &Triple) {
- AsmTransCBE = x86_asm_table;
- AssemblerDialect = AsmWriterFlavor;
- GlobalPrefix = "_";
- CommentString = ";";
-
- PrivateGlobalPrefix = "$";
- AlignDirective = "\tALIGN\t";
- ZeroDirective = "\tdb\t";
- AsciiDirective = "\tdb\t";
- AscizDirective = 0;
- Data8bitsDirective = "\tdb\t";
- Data16bitsDirective = "\tdw\t";
- Data32bitsDirective = "\tdd\t";
- Data64bitsDirective = "\tdq\t";
- HasDotTypeDotSizeDirective = false;
- HasSingleParameterDotFile = false;
-
- AlignmentIsInBytes = true;
+ TextAlignFillValue = 0x90;
}
diff --git a/lib/Target/X86/X86MCAsmInfo.h b/lib/Target/X86/X86MCAsmInfo.h
index ca227b7..69716bf 100644
--- a/lib/Target/X86/X86MCAsmInfo.h
+++ b/lib/Target/X86/X86MCAsmInfo.h
@@ -33,11 +33,6 @@ namespace llvm {
struct X86MCAsmInfoCOFF : public MCAsmInfoCOFF {
explicit X86MCAsmInfoCOFF(const Triple &Triple);
};
-
- struct X86WinMCAsmInfo : public MCAsmInfo {
- explicit X86WinMCAsmInfo(const Triple &Triple);
- };
-
} // namespace llvm
#endif
diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp
index 764c87a..3f18696 100644
--- a/lib/Target/X86/X86MCCodeEmitter.cpp
+++ b/lib/Target/X86/X86MCCodeEmitter.cpp
@@ -14,53 +14,44 @@
#define DEBUG_TYPE "x86-emitter"
#include "X86.h"
#include "X86InstrInfo.h"
+#include "X86FixupKinds.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-// FIXME: This should move to a header.
-namespace llvm {
-namespace X86 {
-enum Fixups {
- reloc_pcrel_word = FirstTargetFixupKind,
- reloc_picrel_word,
- reloc_absolute_word,
- reloc_absolute_word_sext,
- reloc_absolute_dword
-};
-}
-}
-
namespace {
class X86MCCodeEmitter : public MCCodeEmitter {
X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
const TargetMachine &TM;
const TargetInstrInfo &TII;
+ MCContext &Ctx;
bool Is64BitMode;
public:
- X86MCCodeEmitter(TargetMachine &tm, bool is64Bit)
- : TM(tm), TII(*TM.getInstrInfo()) {
+ X86MCCodeEmitter(TargetMachine &tm, MCContext &ctx, bool is64Bit)
+ : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) {
Is64BitMode = is64Bit;
}
~X86MCCodeEmitter() {}
unsigned getNumFixupKinds() const {
- return 5;
+ return 3;
}
- MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
- static MCFixupKindInfo Infos[] = {
- { "reloc_pcrel_word", 0, 4 * 8 },
- { "reloc_picrel_word", 0, 4 * 8 },
- { "reloc_absolute_word", 0, 4 * 8 },
- { "reloc_absolute_word_sext", 0, 4 * 8 },
- { "reloc_absolute_dword", 0, 8 * 8 }
+ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
+ const static MCFixupKindInfo Infos[] = {
+ { "reloc_pcrel_4byte", 0, 4 * 8 },
+ { "reloc_pcrel_1byte", 0, 1 * 8 },
+ { "reloc_riprel_4byte", 0, 4 * 8 }
};
+
+ if (Kind < FirstTargetFixupKind)
+ return MCCodeEmitter::getFixupKindInfo(Kind);
- assert(Kind >= FirstTargetFixupKind && Kind < MaxTargetFixupKind &&
+ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
return Infos[Kind - FirstTargetFixupKind];
}
@@ -83,9 +74,11 @@ public:
}
}
- void EmitDisplacementField(const MCOperand &Disp, int64_t Adj, bool IsPCRel,
- unsigned &CurByte, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups) const;
+ void EmitImmediate(const MCOperand &Disp,
+ unsigned ImmSize, MCFixupKind FixupKind,
+ unsigned &CurByte, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ int ImmOffset = 0) const;
inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
unsigned RM) {
@@ -106,8 +99,8 @@ public:
void EmitMemModRMByte(const MCInst &MI, unsigned Op,
- unsigned RegOpcodeField, intptr_t PCAdj,
- unsigned &CurByte, raw_ostream &OS,
+ unsigned RegOpcodeField,
+ unsigned TSFlags, unsigned &CurByte, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const;
void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
@@ -119,13 +112,15 @@ public:
MCCodeEmitter *llvm::createX86_32MCCodeEmitter(const Target &,
- TargetMachine &TM) {
- return new X86MCCodeEmitter(TM, false);
+ TargetMachine &TM,
+ MCContext &Ctx) {
+ return new X86MCCodeEmitter(TM, Ctx, false);
}
MCCodeEmitter *llvm::createX86_64MCCodeEmitter(const Target &,
- TargetMachine &TM) {
- return new X86MCCodeEmitter(TM, true);
+ TargetMachine &TM,
+ MCContext &Ctx) {
+ return new X86MCCodeEmitter(TM, Ctx, true);
}
@@ -135,36 +130,59 @@ static bool isDisp8(int Value) {
return Value == (signed char)Value;
}
+/// getImmFixupKind - Return the appropriate fixup kind to use for an immediate
+/// in an instruction with the specified TSFlags.
+static MCFixupKind getImmFixupKind(unsigned TSFlags) {
+ unsigned Size = X86II::getSizeOfImm(TSFlags);
+ bool isPCRel = X86II::isImmPCRel(TSFlags);
+
+ switch (Size) {
+ default: assert(0 && "Unknown immediate size");
+ case 1: return isPCRel ? MCFixupKind(X86::reloc_pcrel_1byte) : FK_Data_1;
+ case 4: return isPCRel ? MCFixupKind(X86::reloc_pcrel_4byte) : FK_Data_4;
+ case 2: assert(!isPCRel); return FK_Data_2;
+ case 8: assert(!isPCRel); return FK_Data_8;
+ }
+}
+
+
void X86MCCodeEmitter::
-EmitDisplacementField(const MCOperand &DispOp, int64_t Adj, bool IsPCRel,
- unsigned &CurByte, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups) const {
+EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
+ unsigned &CurByte, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const {
// If this is a simple integer displacement that doesn't require a relocation,
// emit it now.
if (DispOp.isImm()) {
- EmitConstant(DispOp.getImm(), 4, CurByte, OS);
+ // FIXME: is this right for pc-rel encoding?? Probably need to emit this as
+ // a fixup if so.
+ EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS);
return;
}
-#if 0
- // Otherwise, this is something that requires a relocation. Emit it as such
- // now.
- unsigned RelocType = Is64BitMode ?
- (IsPCRel ? X86::reloc_pcrel_word : X86::reloc_absolute_word_sext)
- : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
-#endif
+ // If we have an immoffset, add it to the expression.
+ const MCExpr *Expr = DispOp.getExpr();
+
+ // If the fixup is pc-relative, we need to bias the value to be relative to
+ // the start of the field, not the end of the field.
+ if (FixupKind == MCFixupKind(X86::reloc_pcrel_4byte) ||
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte))
+ ImmOffset -= 4;
+ if (FixupKind == MCFixupKind(X86::reloc_pcrel_1byte))
+ ImmOffset -= 1;
+
+ if (ImmOffset)
+ Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(ImmOffset, Ctx),
+ Ctx);
// Emit a symbolic constant as a fixup and 4 zeros.
- Fixups.push_back(MCFixup::Create(CurByte, DispOp.getExpr(),
- MCFixupKind(X86::reloc_absolute_word)));
- EmitConstant(0, 4, CurByte, OS);
+ Fixups.push_back(MCFixup::Create(CurByte, Expr, FixupKind));
+ EmitConstant(0, Size, CurByte, OS);
}
void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
unsigned RegOpcodeField,
- intptr_t PCAdj,
- unsigned &CurByte,
+ unsigned TSFlags, unsigned &CurByte,
raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const{
const MCOperand &Disp = MI.getOperand(Op+3);
@@ -172,31 +190,48 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
const MCOperand &Scale = MI.getOperand(Op+1);
const MCOperand &IndexReg = MI.getOperand(Op+2);
unsigned BaseReg = Base.getReg();
-
- // FIXME: Eliminate!
- bool IsPCRel = false;
+
+ // Handle %rip relative addressing.
+ if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
+ assert(IndexReg.getReg() == 0 && Is64BitMode &&
+ "Invalid rip-relative address");
+ EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
+
+ // rip-relative addressing is actually relative to the *next* instruction.
+ // Since an immediate can follow the mod/rm byte for an instruction, this
+ // means that we need to bias the immediate field of the instruction with
+ // the size of the immediate field. If we have this case, add it into the
+ // expression to emit.
+ int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0;
+ EmitImmediate(Disp, 4, MCFixupKind(X86::reloc_riprel_4byte),
+ CurByte, OS, Fixups, -ImmSize);
+ return;
+ }
+
+ unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U;
+
// Determine whether a SIB byte is needed.
// If no BaseReg, issue a RIP relative instruction only if the MCE can
// resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
// 2-7) and absolute references.
+
if (// The SIB byte must be used if there is an index register.
IndexReg.getReg() == 0 &&
- // The SIB byte must be used if the base is ESP/RSP.
- BaseReg != X86::ESP && BaseReg != X86::RSP &&
+ // The SIB byte must be used if the base is ESP/RSP/R12, all of which
+ // encode to an R/M value of 4, which indicates that a SIB byte is
+ // present.
+ BaseRegNo != N86::ESP &&
// If there is no base register and we're in 64-bit mode, we need a SIB
// byte to emit an addr that is just 'disp32' (the non-RIP relative form).
(!Is64BitMode || BaseReg != 0)) {
- if (BaseReg == 0 || // [disp32] in X86-32 mode
- BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
+ if (BaseReg == 0) { // [disp32] in X86-32 mode
EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
- EmitDisplacementField(Disp, PCAdj, true, CurByte, OS, Fixups);
+ EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups);
return;
}
- unsigned BaseRegNo = GetX86RegNum(Base);
-
// If the base is not EBP/ESP and there is no displacement, use simple
// indirect register encoding, this handles addresses like [EAX]. The
// encoding for [EBP] with no displacement means [disp32] so we handle it
@@ -209,13 +244,13 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
// Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
if (Disp.isImm() && isDisp8(Disp.getImm())) {
EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
- EmitConstant(Disp.getImm(), 1, CurByte, OS);
+ EmitImmediate(Disp, 1, FK_Data_1, CurByte, OS, Fixups);
return;
}
// Otherwise, emit the most general non-SIB encoding: [REG+disp32]
EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS);
- EmitDisplacementField(Disp, PCAdj, IsPCRel, CurByte, OS, Fixups);
+ EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups);
return;
}
@@ -270,9 +305,9 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
// Do we need to output a displacement?
if (ForceDisp8)
- EmitConstant(Disp.getImm(), 1, CurByte, OS);
+ EmitImmediate(Disp, 1, FK_Data_1, CurByte, OS, Fixups);
else if (ForceDisp32 || Disp.getImm() != 0)
- EmitDisplacementField(Disp, PCAdj, IsPCRel, CurByte, OS, Fixups);
+ EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups);
}
/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64
@@ -280,11 +315,11 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
/// size, and 3) use of X86-64 extended registers.
static unsigned DetermineREXPrefix(const MCInst &MI, unsigned TSFlags,
const TargetInstrDesc &Desc) {
- unsigned REX = 0;
-
- // Pseudo instructions do not need REX prefix byte.
+ // Pseudo instructions never have a rex byte.
if ((TSFlags & X86II::FormMask) == X86II::Pseudo)
return 0;
+
+ unsigned REX = 0;
if (TSFlags & X86II::REX_W)
REX |= 1 << 3;
@@ -482,52 +517,29 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
case X86II::MRMInitReg:
assert(0 && "FIXME: Remove this form when the JIT moves to MCCodeEmitter!");
default: errs() << "FORM: " << (TSFlags & X86II::FormMask) << "\n";
- assert(0 && "Unknown FormMask value in X86MCCodeEmitter!");
- case X86II::RawFrm: {
+ assert(0 && "Unknown FormMask value in X86MCCodeEmitter!");
+ case X86II::Pseudo: return; // Pseudo instructions encode to nothing.
+ case X86II::RawFrm:
EmitByte(BaseOpcode, CurByte, OS);
-
- if (CurOp == NumOps)
- break;
-
- assert(0 && "Unimpl RawFrm expr");
break;
- }
- case X86II::AddRegFrm: {
+ case X86II::AddRegFrm:
EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS);
- if (CurOp == NumOps)
- break;
-
- const MCOperand &MO1 = MI.getOperand(CurOp++);
- if (MO1.isImm()) {
- unsigned Size = X86II::getSizeOfImm(TSFlags);
- EmitConstant(MO1.getImm(), Size, CurByte, OS);
- break;
- }
-
- assert(0 && "Unimpl AddRegFrm expr");
break;
- }
case X86II::MRMDestReg:
EmitByte(BaseOpcode, CurByte, OS);
EmitRegModRMByte(MI.getOperand(CurOp),
GetX86RegNum(MI.getOperand(CurOp+1)), CurByte, OS);
CurOp += 2;
- if (CurOp != NumOps)
- EmitConstant(MI.getOperand(CurOp++).getImm(),
- X86II::getSizeOfImm(TSFlags), CurByte, OS);
break;
case X86II::MRMDestMem:
EmitByte(BaseOpcode, CurByte, OS);
EmitMemModRMByte(MI, CurOp,
GetX86RegNum(MI.getOperand(CurOp + X86AddrNumOperands)),
- 0, CurByte, OS, Fixups);
+ TSFlags, CurByte, OS, Fixups);
CurOp += X86AddrNumOperands + 1;
- if (CurOp != NumOps)
- EmitConstant(MI.getOperand(CurOp++).getImm(),
- X86II::getSizeOfImm(TSFlags), CurByte, OS);
break;
case X86II::MRMSrcReg:
@@ -535,9 +547,6 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitRegModRMByte(MI.getOperand(CurOp+1), GetX86RegNum(MI.getOperand(CurOp)),
CurByte, OS);
CurOp += 2;
- if (CurOp != NumOps)
- EmitConstant(MI.getOperand(CurOp++).getImm(),
- X86II::getSizeOfImm(TSFlags), CurByte, OS);
break;
case X86II::MRMSrcMem: {
@@ -551,117 +560,78 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
else
AddrOperands = X86AddrNumOperands;
- // FIXME: What is this actually doing?
- intptr_t PCAdj = (CurOp + AddrOperands + 1 != NumOps) ?
- X86II::getSizeOfImm(TSFlags) : 0;
-
EmitMemModRMByte(MI, CurOp+1, GetX86RegNum(MI.getOperand(CurOp)),
- PCAdj, CurByte, OS, Fixups);
+ TSFlags, CurByte, OS, Fixups);
CurOp += AddrOperands + 1;
- if (CurOp != NumOps)
- EmitConstant(MI.getOperand(CurOp++).getImm(),
- X86II::getSizeOfImm(TSFlags), CurByte, OS);
break;
}
case X86II::MRM0r: case X86II::MRM1r:
case X86II::MRM2r: case X86II::MRM3r:
case X86II::MRM4r: case X86II::MRM5r:
- case X86II::MRM6r: case X86II::MRM7r: {
+ case X86II::MRM6r: case X86II::MRM7r:
EmitByte(BaseOpcode, CurByte, OS);
-
- // Special handling of lfence, mfence, monitor, and mwait.
- // FIXME: This is terrible, they should get proper encoding bits in TSFlags.
- if (Opcode == X86::LFENCE || Opcode == X86::MFENCE ||
- Opcode == X86::MONITOR || Opcode == X86::MWAIT) {
- EmitByte(ModRMByte(3, (TSFlags & X86II::FormMask)-X86II::MRM0r, 0),
- CurByte, OS);
-
- switch (Opcode) {
- default: break;
- case X86::MONITOR: EmitByte(0xC8, CurByte, OS); break;
- case X86::MWAIT: EmitByte(0xC9, CurByte, OS); break;
- }
- } else {
- EmitRegModRMByte(MI.getOperand(CurOp++),
- (TSFlags & X86II::FormMask)-X86II::MRM0r,
- CurByte, OS);
- }
-
- if (CurOp == NumOps)
- break;
-
- const MCOperand &MO1 = MI.getOperand(CurOp++);
- if (MO1.isImm()) {
- EmitConstant(MO1.getImm(), X86II::getSizeOfImm(TSFlags), CurByte, OS);
- break;
- }
-
- assert(0 && "relo unimpl");
-#if 0
- unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
- : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
- if (Opcode == X86::MOV64ri32)
- rt = X86::reloc_absolute_word_sext; // FIXME: add X86II flag?
- if (MO1.isGlobal()) {
- bool Indirect = gvNeedsNonLazyPtr(MO1, TM);
- emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
- Indirect);
- } else if (MO1.isSymbol())
- emitExternalSymbolAddress(MO1.getSymbolName(), rt);
- else if (MO1.isCPI())
- emitConstPoolAddress(MO1.getIndex(), rt);
- else if (MO1.isJTI())
- emitJumpTableAddress(MO1.getIndex(), rt);
+ EmitRegModRMByte(MI.getOperand(CurOp++),
+ (TSFlags & X86II::FormMask)-X86II::MRM0r,
+ CurByte, OS);
break;
-#endif
- }
case X86II::MRM0m: case X86II::MRM1m:
case X86II::MRM2m: case X86II::MRM3m:
case X86II::MRM4m: case X86II::MRM5m:
- case X86II::MRM6m: case X86II::MRM7m: {
- intptr_t PCAdj = 0;
- if (CurOp + X86AddrNumOperands != NumOps) {
- if (MI.getOperand(CurOp+X86AddrNumOperands).isImm())
- PCAdj = X86II::getSizeOfImm(TSFlags);
- else
- PCAdj = 4;
- }
-
+ case X86II::MRM6m: case X86II::MRM7m:
EmitByte(BaseOpcode, CurByte, OS);
EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m,
- PCAdj, CurByte, OS, Fixups);
+ TSFlags, CurByte, OS, Fixups);
CurOp += X86AddrNumOperands;
-
- if (CurOp == NumOps)
- break;
-
- const MCOperand &MO = MI.getOperand(CurOp++);
- if (MO.isImm()) {
- EmitConstant(MO.getImm(), X86II::getSizeOfImm(TSFlags), CurByte, OS);
- break;
- }
-
- assert(0 && "relo not handled");
-#if 0
- unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
- : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
- if (Opcode == X86::MOV64mi32)
- rt = X86::reloc_absolute_word_sext; // FIXME: add X86II flag?
- if (MO.isGlobal()) {
- bool Indirect = gvNeedsNonLazyPtr(MO, TM);
- emitGlobalAddress(MO.getGlobal(), rt, MO.getOffset(), 0,
- Indirect);
- } else if (MO.isSymbol())
- emitExternalSymbolAddress(MO.getSymbolName(), rt);
- else if (MO.isCPI())
- emitConstPoolAddress(MO.getIndex(), rt);
- else if (MO.isJTI())
- emitJumpTableAddress(MO.getIndex(), rt);
-#endif
+ break;
+ case X86II::MRM_C1:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC1, CurByte, OS);
+ break;
+ case X86II::MRM_C2:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC2, CurByte, OS);
+ break;
+ case X86II::MRM_C3:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC3, CurByte, OS);
+ break;
+ case X86II::MRM_C4:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC4, CurByte, OS);
+ break;
+ case X86II::MRM_C8:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC8, CurByte, OS);
+ break;
+ case X86II::MRM_C9:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC9, CurByte, OS);
+ break;
+ case X86II::MRM_E8:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xE8, CurByte, OS);
+ break;
+ case X86II::MRM_F0:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xF0, CurByte, OS);
+ break;
+ case X86II::MRM_F8:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xF8, CurByte, OS);
+ break;
+ case X86II::MRM_F9:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xF9, CurByte, OS);
break;
}
- }
+
+ // If there is a remaining operand, it must be a trailing immediate. Emit it
+ // according to the right size for the instruction.
+ if (CurOp != NumOps)
+ EmitImmediate(MI.getOperand(CurOp++),
+ X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
+ CurByte, OS, Fixups);
#ifndef NDEBUG
// FIXME: Verify.
diff --git a/lib/Target/X86/X86MachineFunctionInfo.h b/lib/Target/X86/X86MachineFunctionInfo.h
index bb53bf1..4b2529b 100644
--- a/lib/Target/X86/X86MachineFunctionInfo.h
+++ b/lib/Target/X86/X86MachineFunctionInfo.h
@@ -18,12 +18,6 @@
namespace llvm {
-enum NameDecorationStyle {
- None,
- StdCall,
- FastCall
-};
-
/// X86MachineFunctionInfo - This class is derived from MachineFunction and
/// contains private X86 target-specific information for each MachineFunction.
class X86MachineFunctionInfo : public MachineFunctionInfo {
@@ -41,10 +35,6 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
/// Used on windows platform for stdcall & fastcall name decoration
unsigned BytesToPopOnReturn;
- /// DecorationStyle - If the function requires additional name decoration,
- /// DecorationStyle holds the right way to do so.
- NameDecorationStyle DecorationStyle;
-
/// ReturnAddrIndex - FrameIndex for return slot.
int ReturnAddrIndex;
@@ -66,7 +56,6 @@ public:
X86MachineFunctionInfo() : ForceFramePointer(false),
CalleeSavedFrameSize(0),
BytesToPopOnReturn(0),
- DecorationStyle(None),
ReturnAddrIndex(0),
TailCallReturnAddrDelta(0),
SRetReturnReg(0),
@@ -76,7 +65,6 @@ public:
: ForceFramePointer(false),
CalleeSavedFrameSize(0),
BytesToPopOnReturn(0),
- DecorationStyle(None),
ReturnAddrIndex(0),
TailCallReturnAddrDelta(0),
SRetReturnReg(0),
@@ -91,9 +79,6 @@ public:
unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
void setBytesToPopOnReturn (unsigned bytes) { BytesToPopOnReturn = bytes;}
- NameDecorationStyle getDecorationStyle() const { return DecorationStyle; }
- void setDecorationStyle(NameDecorationStyle style) { DecorationStyle = style;}
-
int getRAIndex() const { return ReturnAddrIndex; }
void setRAIndex(int Index) { ReturnAddrIndex = Index; }
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 081c6d9..0f4ce37 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -191,6 +191,8 @@ X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
return &X86::GR16_NOREXRegClass;
else if (A == &X86::GR16_ABCDRegClass)
return &X86::GR16_ABCDRegClass;
+ } else if (B == &X86::FR32RegClass) {
+ return A;
}
break;
case 2:
@@ -207,6 +209,8 @@ X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
A == &X86::GR16_NOREXRegClass)
return &X86::GR16_ABCDRegClass;
+ } else if (B == &X86::FR64RegClass) {
+ return A;
}
break;
case 3:
@@ -234,6 +238,8 @@ X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
return &X86::GR32_NOREXRegClass;
else if (A == &X86::GR32_ABCDRegClass)
return &X86::GR64_ABCDRegClass;
+ } else if (B == &X86::VR128RegClass) {
+ return A;
}
break;
case 4:
@@ -446,8 +452,10 @@ bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const Function *F = MF.getFunction();
bool requiresRealignment =
- RealignStack && (MFI->getMaxAlignment() > StackAlign);
+ RealignStack && ((MFI->getMaxAlignment() > StackAlign) ||
+ F->hasFnAttr(Attribute::StackAlignment));
// FIXME: Currently we don't support stack realignment for functions with
// variable-sized allocas.
@@ -485,7 +493,7 @@ X86RegisterInfo::getFrameIndexOffset(const MachineFunction &MF, int FI) const {
Offset += SlotSize;
} else {
unsigned Align = MFI->getObjectAlignment(FI);
- assert( (-(Offset + StackSize)) % Align == 0);
+ assert((-(Offset + StackSize)) % Align == 0);
Align = 0;
return Offset + StackSize;
}
@@ -627,10 +635,6 @@ X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- MFI->calculateMaxStackAlignment();
-
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
@@ -1053,7 +1057,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
.addImm(NumBytes);
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
- .addExternalSymbol("_alloca");
+ .addExternalSymbol("_alloca")
+ .addReg(StackPtr, RegState::Define | RegState::Implicit);
} else {
// Save EAX
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
@@ -1064,7 +1069,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
.addImm(NumBytes - 4);
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
- .addExternalSymbol("_alloca");
+ .addExternalSymbol("_alloca")
+ .addReg(StackPtr, RegState::Define | RegState::Implicit);
// Restore EAX
MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index 8fb5e92..e4bdb4e 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -35,7 +35,8 @@ namespace X86 {
/// these indices must be kept in sync with the class indices in the
/// X86RegisterInfo.td file.
enum SubregIndex {
- SUBREG_8BIT = 1, SUBREG_8BIT_HI = 2, SUBREG_16BIT = 3, SUBREG_32BIT = 4
+ SUBREG_8BIT = 1, SUBREG_8BIT_HI = 2, SUBREG_16BIT = 3, SUBREG_32BIT = 4,
+ SUBREG_SS = 1, SUBREG_SD = 2, SUBREG_XMM = 3
};
}
diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td
index 1559bf7..ed2ce6c 100644
--- a/lib/Target/X86/X86RegisterInfo.td
+++ b/lib/Target/X86/X86RegisterInfo.td
@@ -158,22 +158,22 @@ let Namespace = "X86" in {
def XMM15: Register<"xmm15">, DwarfRegNum<[32, -2, -2]>;
// YMM Registers, used by AVX instructions
- def YMM0: Register<"ymm0">, DwarfRegNum<[17, 21, 21]>;
- def YMM1: Register<"ymm1">, DwarfRegNum<[18, 22, 22]>;
- def YMM2: Register<"ymm2">, DwarfRegNum<[19, 23, 23]>;
- def YMM3: Register<"ymm3">, DwarfRegNum<[20, 24, 24]>;
- def YMM4: Register<"ymm4">, DwarfRegNum<[21, 25, 25]>;
- def YMM5: Register<"ymm5">, DwarfRegNum<[22, 26, 26]>;
- def YMM6: Register<"ymm6">, DwarfRegNum<[23, 27, 27]>;
- def YMM7: Register<"ymm7">, DwarfRegNum<[24, 28, 28]>;
- def YMM8: Register<"ymm8">, DwarfRegNum<[25, -2, -2]>;
- def YMM9: Register<"ymm9">, DwarfRegNum<[26, -2, -2]>;
- def YMM10: Register<"ymm10">, DwarfRegNum<[27, -2, -2]>;
- def YMM11: Register<"ymm11">, DwarfRegNum<[28, -2, -2]>;
- def YMM12: Register<"ymm12">, DwarfRegNum<[29, -2, -2]>;
- def YMM13: Register<"ymm13">, DwarfRegNum<[30, -2, -2]>;
- def YMM14: Register<"ymm14">, DwarfRegNum<[31, -2, -2]>;
- def YMM15: Register<"ymm15">, DwarfRegNum<[32, -2, -2]>;
+ def YMM0: RegisterWithSubRegs<"ymm0", [XMM0]>, DwarfRegNum<[17, 21, 21]>;
+ def YMM1: RegisterWithSubRegs<"ymm1", [XMM1]>, DwarfRegNum<[18, 22, 22]>;
+ def YMM2: RegisterWithSubRegs<"ymm2", [XMM2]>, DwarfRegNum<[19, 23, 23]>;
+ def YMM3: RegisterWithSubRegs<"ymm3", [XMM3]>, DwarfRegNum<[20, 24, 24]>;
+ def YMM4: RegisterWithSubRegs<"ymm4", [XMM4]>, DwarfRegNum<[21, 25, 25]>;
+ def YMM5: RegisterWithSubRegs<"ymm5", [XMM5]>, DwarfRegNum<[22, 26, 26]>;
+ def YMM6: RegisterWithSubRegs<"ymm6", [XMM6]>, DwarfRegNum<[23, 27, 27]>;
+ def YMM7: RegisterWithSubRegs<"ymm7", [XMM7]>, DwarfRegNum<[24, 28, 28]>;
+ def YMM8: RegisterWithSubRegs<"ymm8", [XMM8]>, DwarfRegNum<[25, -2, -2]>;
+ def YMM9: RegisterWithSubRegs<"ymm9", [XMM9]>, DwarfRegNum<[26, -2, -2]>;
+ def YMM10: RegisterWithSubRegs<"ymm10", [XMM10]>, DwarfRegNum<[27, -2, -2]>;
+ def YMM11: RegisterWithSubRegs<"ymm11", [XMM11]>, DwarfRegNum<[28, -2, -2]>;
+ def YMM12: RegisterWithSubRegs<"ymm12", [XMM12]>, DwarfRegNum<[29, -2, -2]>;
+ def YMM13: RegisterWithSubRegs<"ymm13", [XMM13]>, DwarfRegNum<[30, -2, -2]>;
+ def YMM14: RegisterWithSubRegs<"ymm14", [XMM14]>, DwarfRegNum<[31, -2, -2]>;
+ def YMM15: RegisterWithSubRegs<"ymm15", [XMM15]>, DwarfRegNum<[32, -2, -2]>;
// Floating point stack registers
def ST0 : Register<"st(0)">, DwarfRegNum<[33, 12, 11]>;
@@ -238,6 +238,10 @@ def x86_subreg_8bit_hi : PatLeaf<(i32 2)>;
def x86_subreg_16bit : PatLeaf<(i32 3)>;
def x86_subreg_32bit : PatLeaf<(i32 4)>;
+def x86_subreg_ss : PatLeaf<(i32 1)>;
+def x86_subreg_sd : PatLeaf<(i32 2)>;
+def x86_subreg_xmm : PatLeaf<(i32 3)>;
+
def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI,
R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
[AL, CL, DL, BL, SPL, BPL, SIL, DIL,
@@ -277,11 +281,31 @@ def : SubRegSet<4, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI,
[EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D]>;
-def : SubRegSet<1, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
+def : SubRegSet<1, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
+ YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15],
+ [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>;
+
+def : SubRegSet<2, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
+ YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15],
+ [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>;
+
+def : SubRegSet<3, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15],
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>;
+def : SubRegSet<1, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15],
+ [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>;
+
+def : SubRegSet<2, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15],
+ [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>;
+
//===----------------------------------------------------------------------===//
// Register Class Definitions... now that we have all of the pieces, define the
// top-level register classes. The order specified in the register list is
@@ -793,6 +817,7 @@ def VR128 : RegisterClass<"X86", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],128,
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11,
XMM12, XMM13, XMM14, XMM15]> {
+ let SubRegClassList = [FR32, FR64];
let MethodProtos = [{
iterator allocation_order_end(const MachineFunction &MF) const;
}];
@@ -811,7 +836,9 @@ def VR128 : RegisterClass<"X86", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],128,
def VR256 : RegisterClass<"X86", [ v8i32, v4i64, v8f32, v4f64],256,
[YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
YMM8, YMM9, YMM10, YMM11,
- YMM12, YMM13, YMM14, YMM15]>;
+ YMM12, YMM13, YMM14, YMM15]> {
+ let SubRegClassList = [FR32, FR64, VR128];
+}
// Status flags registers.
def CCR : RegisterClass<"X86", [i32], 32, [EFLAGS]> {
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 618dd10..594a470 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -20,9 +20,9 @@
namespace llvm {
class GlobalValue;
class TargetMachine;
-
+
/// PICStyles - The X86 backend supports a number of different styles of PIC.
-///
+///
namespace PICStyles {
enum Style {
StubPIC, // Used on i386-darwin in -fPIC mode.
@@ -46,7 +46,7 @@ protected:
/// PICStyle - Which PIC style to use
///
PICStyles::Style PICStyle;
-
+
/// X86SSELevel - MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or
/// none supported.
X86SSEEnum X86SSELevel;
@@ -58,7 +58,7 @@ protected:
/// HasCMov - True if this processor has conditional move instructions
/// (generally pentium pro+).
bool HasCMov;
-
+
/// HasX86_64 - True if the processor supports X86-64 instructions.
///
bool HasX86_64;
@@ -78,8 +78,9 @@ protected:
/// IsBTMemSlow - True if BT (bit test) of memory instructions are slow.
bool IsBTMemSlow;
- /// HasVectorUAMem - True if SIMD operations can have unaligned memory operands.
- /// This may require setting a feature bit in the processor.
+ /// HasVectorUAMem - True if SIMD operations can have unaligned memory
+ /// operands. This may require setting a feature bit in the
+ /// processor.
bool HasVectorUAMem;
/// DarwinVers - Nonzero if this is a darwin platform: the numeric
@@ -150,20 +151,20 @@ public:
bool isTargetDarwin() const { return TargetType == isDarwin; }
bool isTargetELF() const { return TargetType == isELF; }
-
+
bool isTargetWindows() const { return TargetType == isWindows; }
bool isTargetMingw() const { return TargetType == isMingw; }
bool isTargetCygwin() const { return TargetType == isCygwin; }
bool isTargetCygMing() const {
return TargetType == isMingw || TargetType == isCygwin;
}
-
+
/// isTargetCOFF - Return true if this is any COFF/Windows target variant.
bool isTargetCOFF() const {
return TargetType == isMingw || TargetType == isCygwin ||
TargetType == isWindows;
}
-
+
bool isTargetWin64() const {
return Is64Bit && (TargetType == isMingw || TargetType == isWindows);
}
@@ -175,7 +176,7 @@ public:
else if (isTargetDarwin())
p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-n8:16:32";
else if (isTargetMingw() || isTargetWindows())
- p = "e-p:32:32-f64:64:64-i64:64:64-f80:128:128-n8:16:32";
+ p = "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32";
else
p = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32";
@@ -196,11 +197,11 @@ public:
bool isPICStyleStubAny() const {
return PICStyle == PICStyles::StubDynamicNoPIC ||
PICStyle == PICStyles::StubPIC; }
-
+
/// getDarwinVers - Return the darwin version number, 8 = Tiger, 9 = Leopard,
/// 10 = Snow Leopard, etc.
unsigned getDarwinVers() const { return DarwinVers; }
-
+
/// ClassifyGlobalReference - Classify a global variable reference for the
/// current subtarget according to how we should reference it in a non-pcrel
/// context.
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index f835e29..56ddaf8 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -30,9 +30,8 @@ static const MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
case Triple::MinGW32:
case Triple::MinGW64:
case Triple::Cygwin:
- return new X86MCAsmInfoCOFF(TheTriple);
case Triple::Win32:
- return new X86WinMCAsmInfo(TheTriple);
+ return new X86MCAsmInfoCOFF(TheTriple);
default:
return new X86ELFMCAsmInfo(TheTriple);
}
@@ -48,11 +47,16 @@ extern "C" void LLVMInitializeX86Target() {
RegisterAsmInfoFn B(TheX86_64Target, createMCAsmInfo);
// Register the code emitter.
- // FIXME: Remove the heinous one when the new one works.
TargetRegistry::RegisterCodeEmitter(TheX86_32Target,
- createHeinousX86MCCodeEmitter);
+ createX86_32MCCodeEmitter);
TargetRegistry::RegisterCodeEmitter(TheX86_64Target,
- createHeinousX86MCCodeEmitter);
+ createX86_64MCCodeEmitter);
+
+ // Register the asm backend.
+ TargetRegistry::RegisterAsmBackend(TheX86_32Target,
+ createX86_32AsmBackend);
+ TargetRegistry::RegisterAsmBackend(TheX86_64Target,
+ createX86_64AsmBackend);
}
@@ -201,32 +205,3 @@ 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 eee29be..2bb5454 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -62,18 +62,6 @@ 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 b8cef7d..29a0be5 100644
--- a/lib/Target/X86/X86TargetObjectFile.cpp
+++ b/lib/Target/X86/X86TargetObjectFile.cpp
@@ -7,61 +7,112 @@
//
//===----------------------------------------------------------------------===//
-#include "X86TargetObjectFile.h"
#include "X86MCTargetExpr.h"
+#include "X86TargetObjectFile.h"
+#include "X86TargetMachine.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Target/Mangler.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Dwarf.h"
using namespace llvm;
+using namespace dwarf;
-const MCExpr *X8632_MachoTargetObjectFile::
+const MCExpr *X8664_MachoTargetObjectFile::
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
- // The mach-o version of this method defaults to returning a stub reference.
- IsIndirect = true;
- IsPCRel = false;
-
-
- MachineModuleInfoMachO &MachOMMI =
- MMI->getObjFileInfo<MachineModuleInfoMachO>();
-
- // FIXME: Use GetSymbolWithGlobalValueBase.
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, true);
- Name += "$non_lazy_ptr";
-
- // Add information about the stub reference to MachOMMI so that the stub gets
- // emitted by the asmprinter.
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = MachOMMI.getGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
+ MachineModuleInfo *MMI, unsigned Encoding) const {
+
+ // On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which
+ // is an indirect pc-relative reference.
+ if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {
+ SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, false);
- StubSym = getContext().GetOrCreateSymbol(Name.str());
+ const MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+ const MCExpr *Res =
+ X86MCTargetExpr::Create(Sym, X86MCTargetExpr::GOTPCREL, getContext());
+ const MCExpr *Four = MCConstantExpr::Create(4, getContext());
+ return MCBinaryExpr::CreateAdd(Res, Four, getContext());
}
-
- return MCSymbolRefExpr::Create(Sym, getContext());
+
+ return TargetLoweringObjectFileMachO::
+ getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
}
-const MCExpr *X8664_MachoTargetObjectFile::
-getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
-
- // On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which
- // is an indirect pc-relative reference.
- IsIndirect = true;
- IsPCRel = true;
-
- // FIXME: Use GetSymbolWithGlobalValueBase.
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, false);
- const MCSymbol *Sym = getContext().CreateSymbol(Name);
- const MCExpr *Res =
- X86MCTargetExpr::Create(Sym, X86MCTargetExpr::GOTPCREL, getContext());
- const MCExpr *Four = MCConstantExpr::Create(4, getContext());
- return MCBinaryExpr::CreateAdd(Res, Four, getContext());
+unsigned X8632_ELFTargetObjectFile::getPersonalityEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8632_ELFTargetObjectFile::getLSDAEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8632_ELFTargetObjectFile::getFDEEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8632_ELFTargetObjectFile::getTTypeEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8664_ELFTargetObjectFile::getPersonalityEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | (Model == CodeModel::Small ||
+ Model == CodeModel::Medium ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small || Model == CodeModel::Medium)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8664_ELFTargetObjectFile::getLSDAEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | (Model == CodeModel::Small ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8664_ELFTargetObjectFile::getFDEEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | (Model == CodeModel::Small ||
+ Model == CodeModel::Medium ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small || Model == CodeModel::Medium)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
}
+unsigned X8664_ELFTargetObjectFile::getTTypeEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | (Model == CodeModel::Small ||
+ Model == CodeModel::Medium ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
+}
diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h
index 377a93b..0444417 100644
--- a/lib/Target/X86/X86TargetObjectFile.h
+++ b/lib/Target/X86/X86TargetObjectFile.h
@@ -10,21 +10,13 @@
#ifndef LLVM_TARGET_X86_TARGETOBJECTFILE_H
#define LLVM_TARGET_X86_TARGETOBJECTFILE_H
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
namespace llvm {
-
- /// X8632_MachoTargetObjectFile - This TLOF implementation is used for
- /// Darwin/x86-32.
- class X8632_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
- public:
-
- virtual const MCExpr *
- getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
- };
-
+ class X86TargetMachine;
+
/// X8664_MachoTargetObjectFile - This TLOF implementation is used for
/// Darwin/x86-64.
class X8664_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
@@ -32,9 +24,31 @@ namespace llvm {
virtual const MCExpr *
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
+ MachineModuleInfo *MMI, unsigned Encoding) const;
+ };
+
+ class X8632_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
+ const X86TargetMachine &TM;
+ public:
+ X8632_ELFTargetObjectFile(const X86TargetMachine &tm)
+ :TM(tm) { }
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
+ };
+
+ class X8664_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
+ const X86TargetMachine &TM;
+ public:
+ X8664_ELFTargetObjectFile(const X86TargetMachine &tm)
+ :TM(tm) { }
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
};
+
} // end namespace llvm
#endif
diff --git a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
index d18f55d..82e23a1 100644
--- a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
@@ -27,6 +27,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
@@ -62,6 +63,11 @@ namespace {
}
void printMemOperand(const MachineInstr *MI, int opNum);
+ void printInlineJT(const MachineInstr *MI, int opNum,
+ const std::string &directive = ".jmptable");
+ void printInlineJT32(const MachineInstr *MI, int opNum) {
+ printInlineJT(MI, opNum, ".jmptable32");
+ }
void printOperand(const MachineInstr *MI, int opNum);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
@@ -257,6 +263,23 @@ void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum)
printOperand(MI, opNum+1);
}
+void XCoreAsmPrinter::
+printInlineJT(const MachineInstr *MI, int opNum, const std::string &directive)
+{
+ unsigned JTI = MI->getOperand(opNum).getIndex();
+ const MachineFunction *MF = MI->getParent()->getParent();
+ const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
+ O << "\t" << directive << " ";
+ for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
+ MachineBasicBlock *MBB = JTBBs[i];
+ if (i > 0)
+ O << ",";
+ O << *MBB->getSymbol(OutContext);
+ }
+}
+
void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
diff --git a/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
index 383fd91..b1ab132 100644
--- a/lib/Target/XCore/XCoreISelDAGToDAG.cpp
+++ b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
@@ -65,8 +65,6 @@ namespace {
bool SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base,
SDValue &Offset);
- virtual void InstructionSelect();
-
virtual const char *getPassName() const {
return "XCore DAG->DAG Pattern Instruction Selection";
}
@@ -147,15 +145,6 @@ bool XCoreDAGToDAGISel::SelectADDRcpii(SDNode *Op, SDValue Addr,
return false;
}
-/// InstructionSelect - This callback is invoked by
-/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void XCoreDAGToDAGISel::InstructionSelect() {
- // Select target instructions for the DAG.
- SelectRoot(*CurDAG);
-
- CurDAG->RemoveDeadNodes();
-}
-
SDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
EVT NVT = N->getValueType(0);
@@ -164,7 +153,11 @@ SDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
default: break;
case ISD::Constant: {
if (Predicate_immMskBitp(N)) {
- SDValue MskSize = Transform_msksize_xform(N);
+ // Transformation function: get the size of a mask
+ int64_t MaskVal = cast<ConstantSDNode>(N)->getZExtValue();
+ assert(isMask_32(MaskVal));
+ // Look for the first non-zero bit
+ SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(MaskVal));
return CurDAG->getMachineNode(XCore::MKMSK_rus, dl,
MVT::i32, MskSize);
}
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index bf8c38f..e6515d8 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -29,6 +29,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/ValueTypes.h"
@@ -53,6 +54,8 @@ getTargetNodeName(unsigned Opcode) const
case XCoreISD::RETSP : return "XCoreISD::RETSP";
case XCoreISD::LADD : return "XCoreISD::LADD";
case XCoreISD::LSUB : return "XCoreISD::LSUB";
+ case XCoreISD::BR_JT : return "XCoreISD::BR_JT";
+ case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32";
default : return NULL;
}
}
@@ -106,9 +109,8 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
setOperationAction(ISD::TRAP, MVT::Other, Legal);
- // Expand jump tables for now
- setOperationAction(ISD::BR_JT, MVT::Other, Expand);
- setOperationAction(ISD::JumpTable, MVT::i32, Custom);
+ // Jump tables.
+ setOperationAction(ISD::BR_JT, MVT::Other, Custom);
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::BlockAddress, MVT::i32 , Custom);
@@ -157,7 +159,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
- case ISD::JumpTable: return LowerJumpTable(Op, DAG);
+ case ISD::BR_JT: return LowerBR_JT(Op, DAG);
case ISD::LOAD: return LowerLOAD(Op, DAG);
case ISD::STORE: return LowerSTORE(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
@@ -315,14 +317,27 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG)
}
SDValue XCoreTargetLowering::
-LowerJumpTable(SDValue Op, SelectionDAG &DAG)
+LowerBR_JT(SDValue Op, SelectionDAG &DAG)
{
- // FIXME there isn't really debug info here
+ SDValue Chain = Op.getOperand(0);
+ SDValue Table = Op.getOperand(1);
+ SDValue Index = Op.getOperand(2);
DebugLoc dl = Op.getDebugLoc();
- EVT PtrVT = Op.getValueType();
- JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
- SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
- return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, JTI);
+ JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
+ unsigned JTI = JT->getIndex();
+ MachineFunction &MF = DAG.getMachineFunction();
+ const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
+ SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
+
+ unsigned NumEntries = MJTI->getJumpTables()[JTI].MBBs.size();
+ if (NumEntries <= 32) {
+ return DAG.getNode(XCoreISD::BR_JT, dl, MVT::Other, Chain, TargetJT, Index);
+ }
+ assert((NumEntries >> 31) == 0);
+ SDValue ScaledIndex = DAG.getNode(ISD::SHL, dl, MVT::i32, Index,
+ DAG.getConstant(1, MVT::i32));
+ return DAG.getNode(XCoreISD::BR_JT32, dl, MVT::Other, Chain, TargetJT,
+ ScaledIndex);
}
static bool
@@ -390,7 +405,12 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG)
if (Offset % 4 == 0) {
// We've managed to infer better alignment information than the load
// already has. Use an aligned load.
- return DAG.getLoad(getPointerTy(), dl, Chain, BasePtr, NULL, 4);
+ //
+ // FIXME: No new alignment information is actually passed here.
+ // Should the offset really be 4?
+ //
+ return DAG.getLoad(getPointerTy(), dl, Chain, BasePtr, NULL, 4,
+ false, false, 0);
}
// Lower to
// ldw low, base[offset >> 2]
@@ -407,9 +427,9 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG)
SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, HighOffset);
SDValue Low = DAG.getLoad(getPointerTy(), dl, Chain,
- LowAddr, NULL, 4);
+ LowAddr, NULL, 4, false, false, 0);
SDValue High = DAG.getLoad(getPointerTy(), dl, Chain,
- HighAddr, NULL, 4);
+ HighAddr, NULL, 4, false, false, 0);
SDValue LowShifted = DAG.getNode(ISD::SRL, dl, MVT::i32, Low, LowShift);
SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, HighShift);
SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, LowShifted, HighShifted);
@@ -423,12 +443,13 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG)
int SVOffset = LD->getSrcValueOffset();
SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, dl, MVT::i32, Chain,
BasePtr, LD->getSrcValue(), SVOffset, MVT::i16,
- LD->isVolatile(), 2);
+ LD->isVolatile(), LD->isNonTemporal(), 2);
SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr,
DAG.getConstant(2, MVT::i32));
SDValue High = DAG.getExtLoad(ISD::EXTLOAD, dl, MVT::i32, Chain,
HighAddr, LD->getSrcValue(), SVOffset + 2,
- MVT::i16, LD->isVolatile(), 2);
+ MVT::i16, LD->isVolatile(),
+ LD->isNonTemporal(), 2);
SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High,
DAG.getConstant(16, MVT::i32));
SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, Low, HighShifted);
@@ -452,7 +473,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG)
false, false, 0, CallingConv::C, false,
/*isReturnValueUsed=*/true,
DAG.getExternalSymbol("__misaligned_load", getPointerTy()),
- Args, DAG, dl, DAG.GetOrdering(Chain.getNode()));
+ Args, DAG, dl);
SDValue Ops[] =
{ CallResult.first, CallResult.second };
@@ -487,12 +508,14 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG)
DAG.getConstant(16, MVT::i32));
SDValue StoreLow = DAG.getTruncStore(Chain, dl, Low, BasePtr,
ST->getSrcValue(), SVOffset, MVT::i16,
- ST->isVolatile(), 2);
+ ST->isVolatile(), ST->isNonTemporal(),
+ 2);
SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr,
DAG.getConstant(2, MVT::i32));
SDValue StoreHigh = DAG.getTruncStore(Chain, dl, High, HighAddr,
ST->getSrcValue(), SVOffset + 2,
- MVT::i16, ST->isVolatile(), 2);
+ MVT::i16, ST->isVolatile(),
+ ST->isNonTemporal(), 2);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh);
}
@@ -513,7 +536,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG)
false, false, 0, CallingConv::C, false,
/*isReturnValueUsed=*/true,
DAG.getExternalSymbol("__misaligned_store", getPointerTy()),
- Args, DAG, dl, DAG.GetOrdering(Chain.getNode()));
+ Args, DAG, dl);
return CallResult.second;
}
@@ -561,15 +584,16 @@ LowerVAARG(SDValue Op, SelectionDAG &DAG)
const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
EVT VT = Node->getValueType(0);
SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0),
- Node->getOperand(1), V, 0);
+ Node->getOperand(1), V, 0, false, false, 0);
// Increment the pointer, VAList, to the next vararg
SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList,
DAG.getConstant(VT.getSizeInBits(),
getPointerTy()));
// Store the incremented VAList to the legalized pointer
- Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), V, 0);
+ Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), V, 0,
+ false, false, 0);
// Load the actual argument out of the pointer VAList
- return DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0);
+ return DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0, false, false, 0);
}
SDValue XCoreTargetLowering::
@@ -582,7 +606,8 @@ LowerVASTART(SDValue Op, SelectionDAG &DAG)
XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
SDValue Addr = DAG.getFrameIndex(XFI->getVarArgsFrameIndex(), MVT::i32);
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
@@ -877,7 +902,8 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain,
// Create the SelectionDAG nodes corresponding to a load
//from this parameter
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
- InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -908,7 +934,8 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain,
RegInfo.addLiveIn(ArgRegs[i], VReg);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
// Move argument from virt reg -> stack
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
}
if (!MemOps.empty())
@@ -1134,10 +1161,8 @@ static inline bool isImmUs4(int64_t val)
bool
XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM,
const Type *Ty) const {
- // Be conservative with void
- // FIXME: Can we be more aggressive?
if (Ty->getTypeID() == Type::VoidTyID)
- return false;
+ return AM.Scale == 0 && isImmUs(AM.BaseOffs) && isImmUs4(AM.BaseOffs);
const TargetData *TD = TM.getTargetData();
unsigned Size = TD->getTypeAllocSize(Ty);
diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h
index f7b620e..0c638af 100644
--- a/lib/Target/XCore/XCoreISelLowering.h
+++ b/lib/Target/XCore/XCoreISelLowering.h
@@ -28,7 +28,7 @@ namespace llvm {
namespace XCoreISD {
enum NodeType {
// Start the numbering where the builtin ops and target ops leave off.
- FIRST_NUMBER = ISD::BUILTIN_OP_END+XCore::INSTRUCTION_LIST_END,
+ FIRST_NUMBER = ISD::BUILTIN_OP_END,
// Branch and link (call)
BL,
@@ -52,7 +52,13 @@ namespace llvm {
LADD,
// Corresponds to LSUB instruction
- LSUB
+ LSUB,
+
+ // Jumptable branch.
+ BR_JT,
+
+ // Jumptable branch using long branches for each entry.
+ BR_JT32
};
}
@@ -122,7 +128,7 @@ namespace llvm {
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
- SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG);
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG);
diff --git a/lib/Target/XCore/XCoreInstrInfo.cpp b/lib/Target/XCore/XCoreInstrInfo.cpp
index 5a54844..722e747 100644
--- a/lib/Target/XCore/XCoreInstrInfo.cpp
+++ b/lib/Target/XCore/XCoreInstrInfo.cpp
@@ -145,6 +145,11 @@ static inline bool IsCondBranch(unsigned BrOpc) {
return IsBRF(BrOpc) || IsBRT(BrOpc);
}
+static inline bool IsBR_JT(unsigned BrOpc) {
+ return BrOpc == XCore::BR_JT
+ || BrOpc == XCore::BR_JT32;
+}
+
/// GetCondFromBranchOpc - Return the XCore CC that matches
/// the correspondent Branch instruction opcode.
static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc)
@@ -271,6 +276,14 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
return false;
}
+ // Likewise if it ends with a branch table followed by an unconditional branch.
+ if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) {
+ I = LastInst;
+ if (AllowModify)
+ I->eraseFromParent();
+ return true;
+ }
+
// Otherwise, can't handle this.
return true;
}
diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td
index 10dc18c..46805d5 100644
--- a/lib/Target/XCore/XCoreInstrInfo.td
+++ b/lib/Target/XCore/XCoreInstrInfo.td
@@ -34,6 +34,15 @@ def XCoreBranchLink : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink,
def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTNone,
[SDNPHasChain, SDNPOptInFlag]>;
+def SDT_XCoreBR_JT : SDTypeProfile<0, 2,
+ [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
+
+def XCoreBR_JT : SDNode<"XCoreISD::BR_JT", SDT_XCoreBR_JT,
+ [SDNPHasChain]>;
+
+def XCoreBR_JT32 : SDNode<"XCoreISD::BR_JT32", SDT_XCoreBR_JT,
+ [SDNPHasChain]>;
+
def SDT_XCoreAddress : SDTypeProfile<1, 1,
[SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
@@ -185,6 +194,15 @@ def MEMii : Operand<i32> {
let MIOperandInfo = (ops i32imm, i32imm);
}
+// Jump tables.
+def InlineJT : Operand<i32> {
+ let PrintMethod = "printInlineJT";
+}
+
+def InlineJT32 : Operand<i32> {
+ let PrintMethod = "printInlineJT32";
+}
+
//===----------------------------------------------------------------------===//
// Instruction Class Templates
//===----------------------------------------------------------------------===//
@@ -624,7 +642,7 @@ defm RETSP : FU6_LU6<"retsp", XCoreRetsp>;
// TODO extdp, kentsp, krestsp, blat, setsr
// clrsr, getsr, kalli
-let isBranch = 1, isTerminator = 1 in {
+let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
def BRBU_u6 : _FU6<
(outs),
(ins brtarget:$target),
@@ -756,24 +774,34 @@ def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
// One operand short
// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp
-// bru, setdp, setcp, setv, setev, kcall
+// setdp, setcp, setv, setev, kcall
// dgetreg
-let isBranch=1, isIndirectBranch=1, isTerminator=1 in
+let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
def BAU_1r : _F1R<(outs), (ins GRRegs:$addr),
"bau $addr",
[(brind GRRegs:$addr)]>;
+let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
+def BR_JT : PseudoInstXCore<(outs), (ins InlineJT:$t, GRRegs:$i),
+ "bru $i\n$t",
+ [(XCoreBR_JT tjumptable:$t, GRRegs:$i)]>;
+
+let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
+def BR_JT32 : PseudoInstXCore<(outs), (ins InlineJT32:$t, GRRegs:$i),
+ "bru $i\n$t",
+ [(XCoreBR_JT32 tjumptable:$t, GRRegs:$i)]>;
+
let Defs=[SP], neverHasSideEffects=1 in
def SETSP_1r : _F1R<(outs), (ins GRRegs:$src),
"set sp, $src",
[]>;
-let isBarrier = 1, hasCtrlDep = 1 in
+let hasCtrlDep = 1 in
def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src),
"ecallt $src",
[]>;
-let isBarrier = 1, hasCtrlDep = 1 in
+let hasCtrlDep = 1 in
def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src),
"ecallf $src",
[]>;
diff --git a/lib/Target/XCore/XCoreTargetObjectFile.h b/lib/Target/XCore/XCoreTargetObjectFile.h
index 7efb990..7424c78 100644
--- a/lib/Target/XCore/XCoreTargetObjectFile.h
+++ b/lib/Target/XCore/XCoreTargetObjectFile.h
@@ -10,13 +10,12 @@
#ifndef LLVM_TARGET_XCORE_TARGETOBJECTFILE_H
#define LLVM_TARGET_XCORE_TARGETOBJECTFILE_H
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
namespace llvm {
class XCoreTargetObjectFile : public TargetLoweringObjectFileELF {
public:
-
void Initialize(MCContext &Ctx, const TargetMachine &TM);
// TODO: Classify globals as xcore wishes.
diff --git a/lib/Transforms/Hello/Hello.cpp b/lib/Transforms/Hello/Hello.cpp
index eac4e17..37d7a00 100644
--- a/lib/Transforms/Hello/Hello.cpp
+++ b/lib/Transforms/Hello/Hello.cpp
@@ -15,7 +15,6 @@
#define DEBUG_TYPE "hello"
#include "llvm/Pass.h"
#include "llvm/Function.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
index 325d353..7cb1367 100644
--- a/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -124,7 +124,7 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
unsigned ArgNo = 0;
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
I != E; ++I, ++ArgNo)
- if (isa<PointerType>(I->getType()))
+ if (I->getType()->isPointerTy())
PointerArgs.push_back(std::pair<Argument*, unsigned>(I, ArgNo));
if (PointerArgs.empty()) return 0;
@@ -317,7 +317,7 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const {
GEPIndicesSet ToPromote;
// If the pointer is always valid, any load with first index 0 is valid.
- if(isByVal || AllCalleesPassInValidPointerForArgument(Arg))
+ if (isByVal || AllCalleesPassInValidPointerForArgument(Arg))
SafeToUnconditionallyLoad.insert(IndicesVector(1, 0));
// First, iterate the entry block and mark loads of (geps of) arguments as
@@ -673,7 +673,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
IE = SI->end(); II != IE; ++II) {
// Use i32 to index structs, and i64 for others (pointers/arrays).
// This satisfies GEP constraints.
- const Type *IdxTy = (isa<StructType>(ElTy) ?
+ const Type *IdxTy = (ElTy->isStructTy() ?
Type::getInt32Ty(F->getContext()) :
Type::getInt64Ty(F->getContext()));
Ops.push_back(ConstantInt::get(IdxTy, *II));
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
index 4972687..3c05f88 100644
--- a/lib/Transforms/IPO/ConstantMerge.cpp
+++ b/lib/Transforms/IPO/ConstantMerge.cpp
@@ -19,10 +19,11 @@
#define DEBUG_TYPE "constmerge"
#include "llvm/Transforms/IPO.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
-#include <map>
using namespace llvm;
STATISTIC(NumMerged, "Number of global constants merged");
@@ -48,10 +49,10 @@ ModulePass *llvm::createConstantMergePass() { return new ConstantMerge(); }
bool ConstantMerge::runOnModule(Module &M) {
// Map unique constant/section pairs to globals. We don't want to merge
// globals in different sections.
- std::map<std::pair<Constant*, std::string>, GlobalVariable*> CMap;
+ DenseMap<Constant*, GlobalVariable*> CMap;
// Replacements - This vector contains a list of replacements to perform.
- std::vector<std::pair<GlobalVariable*, GlobalVariable*> > Replacements;
+ SmallVector<std::pair<GlobalVariable*, GlobalVariable*>, 32> Replacements;
bool MadeChange = false;
@@ -76,19 +77,21 @@ bool ConstantMerge::runOnModule(Module &M) {
continue;
}
- // Only process constants with initializers.
- if (GV->isConstant() && GV->hasDefinitiveInitializer()) {
- Constant *Init = GV->getInitializer();
-
- // Check to see if the initializer is already known.
- GlobalVariable *&Slot = CMap[std::make_pair(Init, GV->getSection())];
-
- if (Slot == 0) { // Nope, add it to the map.
- Slot = GV;
- } else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate!
- // Make all uses of the duplicate constant use the canonical version.
- Replacements.push_back(std::make_pair(GV, Slot));
- }
+ // Only process constants with initializers in the default addres space.
+ if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() ||
+ GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty())
+ continue;
+
+ Constant *Init = GV->getInitializer();
+
+ // Check to see if the initializer is already known.
+ GlobalVariable *&Slot = CMap[Init];
+
+ if (Slot == 0) { // Nope, add it to the map.
+ Slot = GV;
+ } else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate!
+ // Make all uses of the duplicate constant use the canonical version.
+ Replacements.push_back(std::make_pair(GV, Slot));
}
}
@@ -100,11 +103,11 @@ bool ConstantMerge::runOnModule(Module &M) {
// now. This avoid invalidating the pointers in CMap, which are unneeded
// now.
for (unsigned i = 0, e = Replacements.size(); i != e; ++i) {
- // Eliminate any uses of the dead global...
+ // Eliminate any uses of the dead global.
Replacements[i].first->replaceAllUsesWith(Replacements[i].second);
- // Delete the global value from the module...
- M.getGlobalList().erase(Replacements[i].first);
+ // Delete the global value from the module.
+ Replacements[i].first->eraseFromParent();
}
NumMerged += Replacements.size();
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 1749b1e..f386ed7 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -796,7 +796,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
// Replace by null for now.
Call->replaceAllUsesWith(Constant::getNullValue(Call->getType()));
} else {
- assert(isa<StructType>(RetTy) &&
+ assert(RetTy->isStructTy() &&
"Return type changed, but not into a void. The old return type"
" must have been a struct!");
Instruction *InsertPt = Call;
@@ -870,7 +870,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
if (NFTy->getReturnType() == Type::getVoidTy(F->getContext())) {
RetVal = 0;
} else {
- assert (isa<StructType>(RetTy));
+ assert (RetTy->isStructTy());
// The original return value was a struct, insert
// extractvalue/insertvalue chains to extract only the values we need
// to return and insert them into our new result.
diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp
index 025d77e..662fbb5 100644
--- a/lib/Transforms/IPO/DeadTypeElimination.cpp
+++ b/lib/Transforms/IPO/DeadTypeElimination.cpp
@@ -57,13 +57,13 @@ ModulePass *llvm::createDeadTypeEliminationPass() {
//
static inline bool ShouldNukeSymtabEntry(const Type *Ty){
// Nuke all names for primitive types!
- if (Ty->isPrimitiveType() || Ty->isInteger())
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy())
return true;
// Nuke all pointers to primitive types as well...
if (const PointerType *PT = dyn_cast<PointerType>(Ty))
if (PT->getElementType()->isPrimitiveType() ||
- PT->getElementType()->isInteger())
+ PT->getElementType()->isIntegerTy())
return true;
return false;
diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp
index 64a6d78..298d5cf 100644
--- a/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -175,7 +175,7 @@ bool FunctionAttrs::AddReadAttrs(const std::vector<CallGraphNode *> &SCC) {
for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
CI != CE; ++CI) {
Value *Arg = *CI;
- if (isa<PointerType>(Arg->getType()) && !PointsToLocalMemory(Arg))
+ if (Arg->getType()->isPointerTy() && !PointsToLocalMemory(Arg))
// Writes memory. Just give up.
return false;
}
@@ -257,7 +257,7 @@ bool FunctionAttrs::AddNoCaptureAttrs(const std::vector<CallGraphNode *> &SCC) {
continue;
for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A!=E; ++A)
- if (isa<PointerType>(A->getType()) && !A->hasNoCaptureAttr() &&
+ if (A->getType()->isPointerTy() && !A->hasNoCaptureAttr() &&
!PointerMayBeCaptured(A, true, /*StoreCaptures=*/false)) {
A->addAttr(Attribute::NoCapture);
++NumNoCapture;
@@ -362,7 +362,7 @@ bool FunctionAttrs::AddNoAliasAttrs(const std::vector<CallGraphNode *> &SCC) {
// We annotate noalias return values, which are only applicable to
// pointer types.
- if (!isa<PointerType>(F->getReturnType()))
+ if (!F->getReturnType()->isPointerTy())
continue;
if (!IsFunctionMallocLike(F, SCCNodes))
@@ -372,7 +372,7 @@ bool FunctionAttrs::AddNoAliasAttrs(const std::vector<CallGraphNode *> &SCC) {
bool MadeChange = false;
for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
Function *F = SCC[i]->getFunction();
- if (F->doesNotAlias(0) || !isa<PointerType>(F->getReturnType()))
+ if (F->doesNotAlias(0) || !F->getReturnType()->isPointerTy())
continue;
F->setDoesNotAlias(0);
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index ac91631..7b1e9c0 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -303,7 +303,7 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
Changed |= CleanupConstantGlobalUsers(CE, SubInit);
} else if (CE->getOpcode() == Instruction::BitCast &&
- isa<PointerType>(CE->getType())) {
+ CE->getType()->isPointerTy()) {
// Pointer cast, delete any stores and memsets to the global.
Changed |= CleanupConstantGlobalUsers(CE, 0);
}
@@ -431,7 +431,7 @@ static bool IsUserOfGlobalSafeForSRA(User *U, GlobalValue *GV) {
else if (const VectorType *SubVectorTy = dyn_cast<VectorType>(*GEPI))
NumElements = SubVectorTy->getNumElements();
else {
- assert(isa<StructType>(*GEPI) &&
+ assert((*GEPI)->isStructTy() &&
"Indexed GEP type is not array, vector, or struct!");
continue;
}
@@ -543,7 +543,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) {
if (NewGlobals.empty())
return 0;
-
+
DEBUG(dbgs() << "PERFORMING GLOBAL SRA ON: " << *GV);
Constant *NullInt =Constant::getNullValue(Type::getInt32Ty(GV->getContext()));
@@ -642,7 +642,7 @@ static bool AllUsesOfValueWillTrapIfNull(Value *V,
return false;
} else if (isa<ICmpInst>(*UI) &&
isa<ConstantPointerNull>(UI->getOperand(1))) {
- // Ignore setcc X, null
+ // Ignore icmp X, null
} else {
//cerr << "NONTRAPPING USE: " << **UI;
return false;
@@ -813,57 +813,47 @@ static void ConstantPropUsersOf(Value *V) {
static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
CallInst *CI,
const Type *AllocTy,
- Value* NElems,
+ ConstantInt *NElements,
TargetData* TD) {
- DEBUG(dbgs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
-
- const Type *IntPtrTy = TD->getIntPtrType(GV->getContext());
+ DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
- // CI has either 0 or 1 bitcast uses (getMallocType() would otherwise have
- // returned NULL and we would not be here).
- BitCastInst *BCI = NULL;
- for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); UI != E; )
- if ((BCI = dyn_cast<BitCastInst>(cast<Instruction>(*UI++))))
- break;
-
- ConstantInt *NElements = cast<ConstantInt>(NElems);
- if (NElements->getZExtValue() != 1) {
- // If we have an array allocation, transform it to a single element
- // allocation to make the code below simpler.
- Type *NewTy = ArrayType::get(AllocTy, NElements->getZExtValue());
- unsigned TypeSize = TD->getTypeAllocSize(NewTy);
- if (const StructType *ST = dyn_cast<StructType>(NewTy))
- TypeSize = TD->getStructLayout(ST)->getSizeInBytes();
- Instruction *NewCI = CallInst::CreateMalloc(CI, IntPtrTy, NewTy,
- ConstantInt::get(IntPtrTy, TypeSize));
- Value* Indices[2];
- Indices[0] = Indices[1] = Constant::getNullValue(IntPtrTy);
- Value *NewGEP = GetElementPtrInst::Create(NewCI, Indices, Indices + 2,
- NewCI->getName()+".el0", CI);
- Value *Cast = new BitCastInst(NewGEP, CI->getType(), "el0", CI);
- if (BCI) BCI->replaceAllUsesWith(NewGEP);
- CI->replaceAllUsesWith(Cast);
- if (BCI) BCI->eraseFromParent();
- CI->eraseFromParent();
- BCI = dyn_cast<BitCastInst>(NewCI);
- CI = BCI ? extractMallocCallFromBitCast(BCI) : cast<CallInst>(NewCI);
- }
+ const Type *GlobalType;
+ if (NElements->getZExtValue() == 1)
+ GlobalType = AllocTy;
+ else
+ // If we have an array allocation, the global variable is of an array.
+ GlobalType = ArrayType::get(AllocTy, NElements->getZExtValue());
// Create the new global variable. The contents of the malloc'd memory is
// undefined, so initialize with an undef value.
- const Type *MAT = getMallocAllocatedType(CI);
- Constant *Init = UndefValue::get(MAT);
GlobalVariable *NewGV = new GlobalVariable(*GV->getParent(),
- MAT, false,
- GlobalValue::InternalLinkage, Init,
+ GlobalType, false,
+ GlobalValue::InternalLinkage,
+ UndefValue::get(GlobalType),
GV->getName()+".body",
GV,
GV->isThreadLocal());
- // Anything that used the malloc or its bitcast now uses the global directly.
- if (BCI) BCI->replaceAllUsesWith(NewGV);
- CI->replaceAllUsesWith(new BitCastInst(NewGV, CI->getType(), "newgv", CI));
-
+ // If there are bitcast users of the malloc (which is typical, usually we have
+ // a malloc + bitcast) then replace them with uses of the new global. Update
+ // other users to use the global as well.
+ BitCastInst *TheBC = 0;
+ while (!CI->use_empty()) {
+ Instruction *User = cast<Instruction>(CI->use_back());
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
+ if (BCI->getType() == NewGV->getType()) {
+ BCI->replaceAllUsesWith(NewGV);
+ BCI->eraseFromParent();
+ } else {
+ BCI->setOperand(0, NewGV);
+ }
+ } else {
+ if (TheBC == 0)
+ TheBC = new BitCastInst(NewGV, CI->getType(), "newgv", CI);
+ User->replaceUsesOfWith(CI, TheBC);
+ }
+ }
+
Constant *RepValue = NewGV;
if (NewGV->getType() != GV->getType()->getElementType())
RepValue = ConstantExpr::getBitCast(RepValue,
@@ -879,60 +869,60 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
bool InitBoolUsed = false;
// Loop over all uses of GV, processing them in turn.
- std::vector<StoreInst*> Stores;
- while (!GV->use_empty())
- if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
- while (!LI->use_empty()) {
- Use &LoadUse = LI->use_begin().getUse();
- if (!isa<ICmpInst>(LoadUse.getUser()))
- LoadUse = RepValue;
- else {
- ICmpInst *ICI = cast<ICmpInst>(LoadUse.getUser());
- // Replace the cmp X, 0 with a use of the bool value.
- Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", ICI);
- InitBoolUsed = true;
- switch (ICI->getPredicate()) {
- default: llvm_unreachable("Unknown ICmp Predicate!");
- case ICmpInst::ICMP_ULT:
- case ICmpInst::ICMP_SLT: // X < null -> always false
- LV = ConstantInt::getFalse(GV->getContext());
- break;
- case ICmpInst::ICMP_ULE:
- case ICmpInst::ICMP_SLE:
- case ICmpInst::ICMP_EQ:
- LV = BinaryOperator::CreateNot(LV, "notinit", ICI);
- break;
- case ICmpInst::ICMP_NE:
- case ICmpInst::ICMP_UGE:
- case ICmpInst::ICMP_SGE:
- case ICmpInst::ICMP_UGT:
- case ICmpInst::ICMP_SGT:
- break; // no change.
- }
- ICI->replaceAllUsesWith(LV);
- ICI->eraseFromParent();
- }
- }
- LI->eraseFromParent();
- } else {
- StoreInst *SI = cast<StoreInst>(GV->use_back());
+ while (!GV->use_empty()) {
+ if (StoreInst *SI = dyn_cast<StoreInst>(GV->use_back())) {
// The global is initialized when the store to it occurs.
new StoreInst(ConstantInt::getTrue(GV->getContext()), InitBool, SI);
SI->eraseFromParent();
+ continue;
}
+
+ LoadInst *LI = cast<LoadInst>(GV->use_back());
+ while (!LI->use_empty()) {
+ Use &LoadUse = LI->use_begin().getUse();
+ if (!isa<ICmpInst>(LoadUse.getUser())) {
+ LoadUse = RepValue;
+ continue;
+ }
+
+ ICmpInst *ICI = cast<ICmpInst>(LoadUse.getUser());
+ // Replace the cmp X, 0 with a use of the bool value.
+ Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", ICI);
+ InitBoolUsed = true;
+ switch (ICI->getPredicate()) {
+ default: llvm_unreachable("Unknown ICmp Predicate!");
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SLT: // X < null -> always false
+ LV = ConstantInt::getFalse(GV->getContext());
+ break;
+ case ICmpInst::ICMP_ULE:
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::ICMP_EQ:
+ LV = BinaryOperator::CreateNot(LV, "notinit", ICI);
+ break;
+ case ICmpInst::ICMP_NE:
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_SGE:
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SGT:
+ break; // no change.
+ }
+ ICI->replaceAllUsesWith(LV);
+ ICI->eraseFromParent();
+ }
+ LI->eraseFromParent();
+ }
// If the initialization boolean was used, insert it, otherwise delete it.
if (!InitBoolUsed) {
while (!InitBool->use_empty()) // Delete initializations
- cast<Instruction>(InitBool->use_back())->eraseFromParent();
+ cast<StoreInst>(InitBool->use_back())->eraseFromParent();
delete InitBool;
} else
GV->getParent()->getGlobalList().insert(GV, InitBool);
-
- // Now the GV is dead, nuke it and the malloc (both CI and BCI).
+ // Now the GV is dead, nuke it and the malloc..
GV->eraseFromParent();
- if (BCI) BCI->eraseFromParent();
CI->eraseFromParent();
// To further other optimizations, loop over all users of NewGV and try to
@@ -1303,9 +1293,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI,
ConstantInt::get(IntPtrTy, TypeSize),
NElems,
CI->getName() + ".f" + Twine(FieldNo));
- CallInst *NCI = dyn_cast<BitCastInst>(NMI) ?
- extractMallocCallFromBitCast(NMI) : cast<CallInst>(NMI);
- FieldMallocs.push_back(NCI);
+ FieldMallocs.push_back(NMI);
new StoreInst(NMI, NGV, CI);
}
@@ -1497,7 +1485,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
// something.
if (TD &&
NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) {
- GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElems, TD);
+ GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElements, TD);
return true;
}
@@ -1556,7 +1544,7 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
// only has one (non-null) value stored into it, then we can optimize any
// users of the loaded value (often calls and loads) that would trap if the
// value was null.
- if (isa<PointerType>(GV->getInitializer()->getType()) &&
+ if (GV->getInitializer()->getType()->isPointerTy() &&
GV->getInitializer()->isNullValue()) {
if (Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
if (GV->getInitializer()->getType() != SOVC->getType())
@@ -1590,8 +1578,8 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
// simplification. In these cases, we typically end up with "cond ? v1 : v2"
// where v1 and v2 both require constant pool loads, a big loss.
if (GVElType == Type::getInt1Ty(GV->getContext()) ||
- GVElType->isFloatingPoint() ||
- isa<PointerType>(GVElType) || isa<VectorType>(GVElType))
+ GVElType->isFloatingPointTy() ||
+ GVElType->isPointerTy() || GVElType->isVectorTy())
return false;
// Walk the use list of the global seeing if all the uses are load or store.
@@ -1925,7 +1913,7 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) {
if (!ATy) return 0;
const StructType *STy = dyn_cast<StructType>(ATy->getElementType());
if (!STy || STy->getNumElements() != 2 ||
- !STy->getElementType(0)->isInteger(32)) return 0;
+ !STy->getElementType(0)->isIntegerTy(32)) return 0;
const PointerType *PFTy = dyn_cast<PointerType>(STy->getElementType(1));
if (!PFTy) return 0;
const FunctionType *FTy = dyn_cast<FunctionType>(PFTy->getElementType());
@@ -2148,7 +2136,7 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
Elts[CI->getZExtValue()] =
EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1);
- if (isa<ArrayType>(Init->getType()))
+ if (Init->getType()->isArrayTy())
return ConstantArray::get(cast<ArrayType>(InitTy), Elts);
else
return ConstantVector::get(&Elts[0], Elts.size());
diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp
index 97e2f06..752a97c 100644
--- a/lib/Transforms/IPO/Inliner.cpp
+++ b/lib/Transforms/IPO/Inliner.cpp
@@ -41,12 +41,9 @@ static cl::opt<int>
InlineLimit("inline-threshold", cl::Hidden, cl::init(225), cl::ZeroOrMore,
cl::desc("Control the amount of inlining to perform (default = 225)"));
-static cl::opt<bool>
-RespectHint("respect-inlinehint", cl::Hidden,
- cl::desc("Respect the inlinehint attribute"));
-
-// Threshold to use when inlinehint is given.
-const int HintThreshold = 300;
+static cl::opt<int>
+HintThreshold("inlinehint-threshold", cl::Hidden, cl::init(325),
+ cl::desc("Threshold for inlining functions with inline hint"));
// Threshold to use when optsize is specified (and there is no -inline-limit).
const int OptSizeThreshold = 75;
@@ -183,20 +180,22 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
}
unsigned Inliner::getInlineThreshold(CallSite CS) const {
- // Listen to inlinehint when -respect-inlinehint is given.
- Function *Callee = CS.getCalledFunction();
- if (RespectHint && Callee && !Callee->isDeclaration() &&
- Callee->hasFnAttr(Attribute::InlineHint))
- return HintThreshold;
+ int thres = InlineThreshold;
// Listen to optsize when -inline-limit is not given.
Function *Caller = CS.getCaller();
if (Caller && !Caller->isDeclaration() &&
Caller->hasFnAttr(Attribute::OptimizeForSize) &&
InlineLimit.getNumOccurrences() == 0)
- return OptSizeThreshold;
+ thres = OptSizeThreshold;
+
+ // Listen to inlinehint when it would increase the threshold.
+ Function *Callee = CS.getCalledFunction();
+ if (HintThreshold > thres && Callee && !Callee->isDeclaration() &&
+ Callee->hasFnAttr(Attribute::InlineHint))
+ thres = HintThreshold;
- return InlineThreshold;
+ return thres;
}
/// shouldInline - Return true if the inliner should attempt to inline
diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp
index 0e0d83a..310e4a2 100644
--- a/lib/Transforms/IPO/StripSymbols.cpp
+++ b/lib/Transforms/IPO/StripSymbols.cpp
@@ -214,6 +214,15 @@ static bool StripDebugInfo(Module &M) {
Changed = true;
}
+ if (Function *DbgVal = M.getFunction("llvm.dbg.value")) {
+ while (!DbgVal->use_empty()) {
+ CallInst *CI = cast<CallInst>(DbgVal->use_back());
+ CI->eraseFromParent();
+ }
+ DbgVal->eraseFromParent();
+ Changed = true;
+ }
+
NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv");
if (NMD) {
Changed = true;
diff --git a/lib/Transforms/InstCombine/InstCombine.h b/lib/Transforms/InstCombine/InstCombine.h
index 5367900..bd06499 100644
--- a/lib/Transforms/InstCombine/InstCombine.h
+++ b/lib/Transforms/InstCombine/InstCombine.h
@@ -117,11 +117,11 @@ public:
Instruction *visitUDiv(BinaryOperator &I);
Instruction *visitSDiv(BinaryOperator &I);
Instruction *visitFDiv(BinaryOperator &I);
- Instruction *FoldAndOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS);
- Instruction *FoldAndOfFCmps(Instruction &I, FCmpInst *LHS, FCmpInst *RHS);
+ Value *FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS);
+ Value *FoldAndOfFCmps(FCmpInst *LHS, FCmpInst *RHS);
Instruction *visitAnd(BinaryOperator &I);
- Instruction *FoldOrOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS);
- Instruction *FoldOrOfFCmps(Instruction &I, FCmpInst *LHS, FCmpInst *RHS);
+ Value *FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS);
+ Value *FoldOrOfFCmps(FCmpInst *LHS, FCmpInst *RHS);
Instruction *FoldOrWithConstants(BinaryOperator &I, Value *Op,
Value *A, Value *B, Value *C);
Instruction *visitOr (BinaryOperator &I);
@@ -199,13 +199,15 @@ private:
SmallVectorImpl<Value*> &NewIndices);
Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
- /// ValueRequiresCast - Return true if the cast from "V to Ty" actually
- /// results in any code being generated. It does not require codegen if V is
- /// simple enough or if the cast can be folded into other casts.
- bool ValueRequiresCast(Instruction::CastOps opcode,const Value *V,
- const Type *Ty);
+ /// ShouldOptimizeCast - Return true if the cast from "V to Ty" actually
+ /// results in any code being generated and is interesting to optimize out. If
+ /// the cast can be eliminated by some other simple transformation, we prefer
+ /// to do the simplification first.
+ bool ShouldOptimizeCast(Instruction::CastOps opcode,const Value *V,
+ const Type *Ty);
Instruction *visitCallSite(CallSite CS);
+ Instruction *tryOptimizeCall(CallInst *CI, const TargetData *TD);
bool transformConstExprCastCall(CallSite CS);
Instruction *transformCallThroughTrampoline(CallSite CS);
Instruction *transformZExtICmp(ICmpInst *ICI, Instruction &CI,
@@ -326,8 +328,8 @@ private:
Value *FoldLogicalPlusAnd(Value *LHS, Value *RHS, ConstantInt *Mask,
bool isSub, Instruction &I);
- Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
- bool isSigned, bool Inside, Instruction &IB);
+ Value *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
+ bool isSigned, bool Inside);
Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocaInst &AI);
Instruction *MatchBSwap(BinaryOperator &I);
bool SimplifyStoreAtEndOfBlock(StoreInst &SI);
diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index c2924ab..4d2c89e 100644
--- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -35,7 +35,7 @@ static Constant *SubOne(ConstantInt *C) {
// Otherwise, return null.
//
static inline Value *dyn_castFoldableMul(Value *V, ConstantInt *&CST) {
- if (!V->hasOneUse() || !V->getType()->isInteger())
+ if (!V->hasOneUse() || !V->getType()->isIntegerTy())
return 0;
Instruction *I = dyn_cast<Instruction>(V);
@@ -145,10 +145,10 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
}
}
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return BinaryOperator::CreateXor(LHS, RHS);
- if (I.getType()->isInteger()) {
+ if (I.getType()->isIntegerTy()) {
// X + X --> X << 1
if (LHS == RHS)
return BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1));
@@ -168,7 +168,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
// -A + B --> B - A
// -A + -B --> -(A + B)
if (Value *LHSV = dyn_castNegVal(LHS)) {
- if (LHS->getType()->isIntOrIntVector()) {
+ if (LHS->getType()->isIntOrIntVectorTy()) {
if (Value *RHSV = dyn_castNegVal(RHS)) {
Value *NewAdd = Builder->CreateAdd(LHSV, RHSV, "sum");
return BinaryOperator::CreateNeg(NewAdd);
@@ -222,7 +222,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
}
// W*X + Y*Z --> W * (X+Z) iff W == Y
- if (I.getType()->isIntOrIntVector()) {
+ if (I.getType()->isIntOrIntVectorTy()) {
Value *W, *X, *Y, *Z;
if (match(LHS, m_Mul(m_Value(W), m_Value(X))) &&
match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) {
@@ -373,10 +373,10 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {
if (CFP->getValueAPF().isPosZero() && CannotBeNegativeZero(LHS))
return ReplaceInstUsesWith(I, LHS);
- // Check for (add double (sitofp x), y), see if we can merge this into an
+ // Check for (fadd double (sitofp x), y), see if we can merge this into an
// integer add followed by a promotion.
if (SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
- // (add double (sitofp x), fpcst) --> (sitofp (add int x, intcst))
+ // (fadd double (sitofp x), fpcst) --> (sitofp (add int x, intcst))
// ... if the constant fits in the integer value. This is useful for things
// like (double)(x & 1234) + 4.0 -> (double)((X & 1234)+4) which no longer
// requires a constant pool load, and generally allows the add to be better
@@ -394,7 +394,7 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {
}
}
- // (add double (sitofp x), (sitofp y)) --> (sitofp (add int x, y))
+ // (fadd double (sitofp x), (sitofp y)) --> (sitofp (add int x, y))
if (SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) {
// Only do this if x/y have the same type, if at last one of them has a
// single use (so we don't increase the number of int->fp conversions),
@@ -560,7 +560,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return ReplaceInstUsesWith(I, Op0); // undef - X -> undef
if (isa<UndefValue>(Op1))
return ReplaceInstUsesWith(I, Op1); // X - undef -> undef
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return BinaryOperator::CreateXor(Op0, Op1);
if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 28fd70e..3fb3de7 100644
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -137,80 +137,44 @@ static unsigned getFCmpCode(FCmpInst::Predicate CC, bool &isOrdered) {
/// opcode and two operands into either a constant true or false, or a brand
/// new ICmp instruction. The sign is passed in to determine which kind
/// of predicate to use in the new icmp instruction.
-static Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS) {
+static Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
+ InstCombiner::BuilderTy *Builder) {
+ CmpInst::Predicate Pred;
switch (Code) {
default: assert(0 && "Illegal ICmp code!");
- case 0:
- return ConstantInt::getFalse(LHS->getContext());
- case 1:
- if (Sign)
- return new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS);
- return new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS);
- case 2:
- return new ICmpInst(ICmpInst::ICMP_EQ, LHS, RHS);
- case 3:
- if (Sign)
- return new ICmpInst(ICmpInst::ICMP_SGE, LHS, RHS);
- return new ICmpInst(ICmpInst::ICMP_UGE, LHS, RHS);
- case 4:
- if (Sign)
- return new ICmpInst(ICmpInst::ICMP_SLT, LHS, RHS);
- return new ICmpInst(ICmpInst::ICMP_ULT, LHS, RHS);
- case 5:
- return new ICmpInst(ICmpInst::ICMP_NE, LHS, RHS);
- case 6:
- if (Sign)
- return new ICmpInst(ICmpInst::ICMP_SLE, LHS, RHS);
- return new ICmpInst(ICmpInst::ICMP_ULE, LHS, RHS);
- case 7:
- return ConstantInt::getTrue(LHS->getContext());
+ case 0: // False.
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
+ case 1: Pred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
+ case 2: Pred = ICmpInst::ICMP_EQ; break;
+ case 3: Pred = Sign ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
+ case 4: Pred = Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
+ case 5: Pred = ICmpInst::ICMP_NE; break;
+ case 6: Pred = Sign ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
+ case 7: // True.
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 1);
}
+ return Builder->CreateICmp(Pred, LHS, RHS);
}
/// getFCmpValue - This is the complement of getFCmpCode, which turns an
/// opcode and two operands into either a FCmp instruction. isordered is passed
/// in to determine which kind of predicate to use in the new fcmp instruction.
static Value *getFCmpValue(bool isordered, unsigned code,
- Value *LHS, Value *RHS) {
+ Value *LHS, Value *RHS,
+ InstCombiner::BuilderTy *Builder) {
+ CmpInst::Predicate Pred;
switch (code) {
- default: llvm_unreachable("Illegal FCmp code!");
- case 0:
- if (isordered)
- return new FCmpInst(FCmpInst::FCMP_ORD, LHS, RHS);
- else
- return new FCmpInst(FCmpInst::FCMP_UNO, LHS, RHS);
- case 1:
- if (isordered)
- return new FCmpInst(FCmpInst::FCMP_OGT, LHS, RHS);
- else
- return new FCmpInst(FCmpInst::FCMP_UGT, LHS, RHS);
- case 2:
- if (isordered)
- return new FCmpInst(FCmpInst::FCMP_OEQ, LHS, RHS);
- else
- return new FCmpInst(FCmpInst::FCMP_UEQ, LHS, RHS);
- case 3:
- if (isordered)
- return new FCmpInst(FCmpInst::FCMP_OGE, LHS, RHS);
- else
- return new FCmpInst(FCmpInst::FCMP_UGE, LHS, RHS);
- case 4:
- if (isordered)
- return new FCmpInst(FCmpInst::FCMP_OLT, LHS, RHS);
- else
- return new FCmpInst(FCmpInst::FCMP_ULT, LHS, RHS);
- case 5:
- if (isordered)
- return new FCmpInst(FCmpInst::FCMP_ONE, LHS, RHS);
- else
- return new FCmpInst(FCmpInst::FCMP_UNE, LHS, RHS);
- case 6:
- if (isordered)
- return new FCmpInst(FCmpInst::FCMP_OLE, LHS, RHS);
- else
- return new FCmpInst(FCmpInst::FCMP_ULE, LHS, RHS);
- case 7: return ConstantInt::getTrue(LHS->getContext());
+ default: assert(0 && "Illegal FCmp code!");
+ case 0: Pred = isordered ? FCmpInst::FCMP_ORD : FCmpInst::FCMP_UNO; break;
+ case 1: Pred = isordered ? FCmpInst::FCMP_OGT : FCmpInst::FCMP_UGT; break;
+ case 2: Pred = isordered ? FCmpInst::FCMP_OEQ : FCmpInst::FCMP_UEQ; break;
+ case 3: Pred = isordered ? FCmpInst::FCMP_OGE : FCmpInst::FCMP_UGE; break;
+ case 4: Pred = isordered ? FCmpInst::FCMP_OLT : FCmpInst::FCMP_ULT; break;
+ case 5: Pred = isordered ? FCmpInst::FCMP_ONE : FCmpInst::FCMP_UNE; break;
+ case 6: Pred = isordered ? FCmpInst::FCMP_OLE : FCmpInst::FCMP_ULE; break;
+ case 7: return ConstantInt::getTrue(LHS->getContext());
}
+ return Builder->CreateFCmp(Pred, LHS, RHS);
}
/// PredicatesFoldable - Return true if both predicates match sign or if at
@@ -355,40 +319,39 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op,
/// (V-Lo) <u Hi-Lo. This method expects that Lo <= Hi. isSigned indicates
/// whether to treat the V, Lo and HI as signed or not. IB is the location to
/// insert new instructions.
-Instruction *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
- bool isSigned, bool Inside,
- Instruction &IB) {
+Value *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
+ bool isSigned, bool Inside) {
assert(cast<ConstantInt>(ConstantExpr::getICmp((isSigned ?
ICmpInst::ICMP_SLE:ICmpInst::ICMP_ULE), Lo, Hi))->getZExtValue() &&
"Lo is not <= Hi in range emission code!");
if (Inside) {
if (Lo == Hi) // Trivially false.
- return new ICmpInst(ICmpInst::ICMP_NE, V, V);
+ return ConstantInt::getFalse(V->getContext());
// V >= Min && V < Hi --> V < Hi
if (cast<ConstantInt>(Lo)->isMinValue(isSigned)) {
ICmpInst::Predicate pred = (isSigned ?
ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT);
- return new ICmpInst(pred, V, Hi);
+ return Builder->CreateICmp(pred, V, Hi);
}
// Emit V-Lo <u Hi-Lo
Constant *NegLo = ConstantExpr::getNeg(Lo);
Value *Add = Builder->CreateAdd(V, NegLo, V->getName()+".off");
Constant *UpperBound = ConstantExpr::getAdd(NegLo, Hi);
- return new ICmpInst(ICmpInst::ICMP_ULT, Add, UpperBound);
+ return Builder->CreateICmpULT(Add, UpperBound);
}
if (Lo == Hi) // Trivially true.
- return new ICmpInst(ICmpInst::ICMP_EQ, V, V);
+ return ConstantInt::getTrue(V->getContext());
// V < Min || V >= Hi -> V > Hi-1
Hi = SubOne(cast<ConstantInt>(Hi));
if (cast<ConstantInt>(Lo)->isMinValue(isSigned)) {
ICmpInst::Predicate pred = (isSigned ?
ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT);
- return new ICmpInst(pred, V, Hi);
+ return Builder->CreateICmp(pred, V, Hi);
}
// Emit V-Lo >u Hi-1-Lo
@@ -396,7 +359,7 @@ Instruction *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
ConstantInt *NegLo = cast<ConstantInt>(ConstantExpr::getNeg(Lo));
Value *Add = Builder->CreateAdd(V, NegLo, V->getName()+".off");
Constant *LowerBound = ConstantExpr::getAdd(NegLo, Hi);
- return new ICmpInst(ICmpInst::ICMP_UGT, Add, LowerBound);
+ return Builder->CreateICmpUGT(Add, LowerBound);
}
// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s with
@@ -472,8 +435,7 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS,
}
/// FoldAndOfICmps - Fold (icmp)&(icmp) if possible.
-Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
- ICmpInst *LHS, ICmpInst *RHS) {
+Value *InstCombiner::FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
ICmpInst::Predicate LHSCC = LHS->getPredicate(), RHSCC = RHS->getPredicate();
// (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B)
@@ -486,11 +448,7 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1);
unsigned Code = getICmpCode(LHS) & getICmpCode(RHS);
bool isSigned = LHS->isSigned() || RHS->isSigned();
- Value *RV = getICmpValue(isSigned, Code, Op0, Op1);
- if (Instruction *I = dyn_cast<Instruction>(RV))
- return I;
- // Otherwise, it's a constant boolean value.
- return ReplaceInstUsesWith(I, RV);
+ return getICmpValue(isSigned, Code, Op0, Op1, Builder);
}
}
@@ -506,13 +464,13 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
if (LHSCC == ICmpInst::ICMP_ULT &&
LHSCst->getValue().isPowerOf2()) {
Value *NewOr = Builder->CreateOr(Val, Val2);
- return new ICmpInst(LHSCC, NewOr, LHSCst);
+ return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
}
// (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0)
if (LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero()) {
Value *NewOr = Builder->CreateOr(Val, Val2);
- return new ICmpInst(LHSCC, NewOr, LHSCst);
+ return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
}
}
@@ -562,33 +520,32 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
case ICmpInst::ICMP_EQ: // (X == 13 & X == 15) -> false
case ICmpInst::ICMP_UGT: // (X == 13 & X > 15) -> false
case ICmpInst::ICMP_SGT: // (X == 13 & X > 15) -> false
- return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
case ICmpInst::ICMP_NE: // (X == 13 & X != 15) -> X == 13
case ICmpInst::ICMP_ULT: // (X == 13 & X < 15) -> X == 13
case ICmpInst::ICMP_SLT: // (X == 13 & X < 15) -> X == 13
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
}
case ICmpInst::ICMP_NE:
switch (RHSCC) {
default: llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_ULT:
if (LHSCst == SubOne(RHSCst)) // (X != 13 & X u< 14) -> X < 13
- return new ICmpInst(ICmpInst::ICMP_ULT, Val, LHSCst);
+ return Builder->CreateICmpULT(Val, LHSCst);
break; // (X != 13 & X u< 15) -> no change
case ICmpInst::ICMP_SLT:
if (LHSCst == SubOne(RHSCst)) // (X != 13 & X s< 14) -> X < 13
- return new ICmpInst(ICmpInst::ICMP_SLT, Val, LHSCst);
+ return Builder->CreateICmpSLT(Val, LHSCst);
break; // (X != 13 & X s< 15) -> no change
case ICmpInst::ICMP_EQ: // (X != 13 & X == 15) -> X == 15
case ICmpInst::ICMP_UGT: // (X != 13 & X u> 15) -> X u> 15
case ICmpInst::ICMP_SGT: // (X != 13 & X s> 15) -> X s> 15
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
case ICmpInst::ICMP_NE:
if (LHSCst == SubOne(RHSCst)){// (X != 13 & X != 14) -> X-13 >u 1
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
Value *Add = Builder->CreateAdd(Val, AddCST, Val->getName()+".off");
- return new ICmpInst(ICmpInst::ICMP_UGT, Add,
- ConstantInt::get(Add->getType(), 1));
+ return Builder->CreateICmpUGT(Add, ConstantInt::get(Add->getType(), 1));
}
break; // (X != 13 & X != 15) -> no change
}
@@ -598,12 +555,12 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
default: llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_EQ: // (X u< 13 & X == 15) -> false
case ICmpInst::ICMP_UGT: // (X u< 13 & X u> 15) -> false
- return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
case ICmpInst::ICMP_SGT: // (X u< 13 & X s> 15) -> no change
break;
case ICmpInst::ICMP_NE: // (X u< 13 & X != 15) -> X u< 13
case ICmpInst::ICMP_ULT: // (X u< 13 & X u< 15) -> X u< 13
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
case ICmpInst::ICMP_SLT: // (X u< 13 & X s< 15) -> no change
break;
}
@@ -613,12 +570,12 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
default: llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_EQ: // (X s< 13 & X == 15) -> false
case ICmpInst::ICMP_SGT: // (X s< 13 & X s> 15) -> false
- return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
case ICmpInst::ICMP_UGT: // (X s< 13 & X u> 15) -> no change
break;
case ICmpInst::ICMP_NE: // (X s< 13 & X != 15) -> X < 13
case ICmpInst::ICMP_SLT: // (X s< 13 & X s< 15) -> X < 13
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
case ICmpInst::ICMP_ULT: // (X s< 13 & X u< 15) -> no change
break;
}
@@ -628,16 +585,15 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
default: llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_EQ: // (X u> 13 & X == 15) -> X == 15
case ICmpInst::ICMP_UGT: // (X u> 13 & X u> 15) -> X u> 15
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
case ICmpInst::ICMP_SGT: // (X u> 13 & X s> 15) -> no change
break;
case ICmpInst::ICMP_NE:
if (RHSCst == AddOne(LHSCst)) // (X u> 13 & X != 14) -> X u> 14
- return new ICmpInst(LHSCC, Val, RHSCst);
+ return Builder->CreateICmp(LHSCC, Val, RHSCst);
break; // (X u> 13 & X != 15) -> no change
case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) -> (X-14) <u 1
- return InsertRangeTest(Val, AddOne(LHSCst),
- RHSCst, false, true, I);
+ return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, false, true);
case ICmpInst::ICMP_SLT: // (X u> 13 & X s< 15) -> no change
break;
}
@@ -647,16 +603,15 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
default: llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_EQ: // (X s> 13 & X == 15) -> X == 15
case ICmpInst::ICMP_SGT: // (X s> 13 & X s> 15) -> X s> 15
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
case ICmpInst::ICMP_UGT: // (X s> 13 & X u> 15) -> no change
break;
case ICmpInst::ICMP_NE:
if (RHSCst == AddOne(LHSCst)) // (X s> 13 & X != 14) -> X s> 14
- return new ICmpInst(LHSCC, Val, RHSCst);
+ return Builder->CreateICmp(LHSCC, Val, RHSCst);
break; // (X s> 13 & X != 15) -> no change
case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) -> (X-14) s< 1
- return InsertRangeTest(Val, AddOne(LHSCst),
- RHSCst, true, true, I);
+ return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, true, true);
case ICmpInst::ICMP_ULT: // (X s> 13 & X u< 15) -> no change
break;
}
@@ -666,9 +621,10 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
return 0;
}
-Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS,
- FCmpInst *RHS) {
-
+/// FoldAndOfFCmps - Optimize (fcmp)&(fcmp). NOTE: Unlike the rest of
+/// instcombine, this returns a Value which should already be inserted into the
+/// function.
+Value *InstCombiner::FoldAndOfFCmps(FCmpInst *LHS, FCmpInst *RHS) {
if (LHS->getPredicate() == FCmpInst::FCMP_ORD &&
RHS->getPredicate() == FCmpInst::FCMP_ORD) {
// (fcmp ord x, c) & (fcmp ord y, c) -> (fcmp ord x, y)
@@ -677,17 +633,15 @@ Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS,
// If either of the constants are nans, then the whole thing returns
// false.
if (LHSC->getValueAPF().isNaN() || RHSC->getValueAPF().isNaN())
- return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
- return new FCmpInst(FCmpInst::FCMP_ORD,
- LHS->getOperand(0), RHS->getOperand(0));
+ return ConstantInt::getFalse(LHS->getContext());
+ return Builder->CreateFCmpORD(LHS->getOperand(0), RHS->getOperand(0));
}
// Handle vector zeros. This occurs because the canonical form of
// "fcmp ord x,x" is "fcmp ord x, 0".
if (isa<ConstantAggregateZero>(LHS->getOperand(1)) &&
isa<ConstantAggregateZero>(RHS->getOperand(1)))
- return new FCmpInst(FCmpInst::FCMP_ORD,
- LHS->getOperand(0), RHS->getOperand(0));
+ return Builder->CreateFCmpORD(LHS->getOperand(0), RHS->getOperand(0));
return 0;
}
@@ -705,14 +659,13 @@ Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS,
if (Op0LHS == Op1LHS && Op0RHS == Op1RHS) {
// Simplify (fcmp cc0 x, y) & (fcmp cc1 x, y).
if (Op0CC == Op1CC)
- return new FCmpInst((FCmpInst::Predicate)Op0CC, Op0LHS, Op0RHS);
-
+ return Builder->CreateFCmp((FCmpInst::Predicate)Op0CC, Op0LHS, Op0RHS);
if (Op0CC == FCmpInst::FCMP_FALSE || Op1CC == FCmpInst::FCMP_FALSE)
- return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
if (Op0CC == FCmpInst::FCMP_TRUE)
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
if (Op1CC == FCmpInst::FCMP_TRUE)
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
bool Op0Ordered;
bool Op1Ordered;
@@ -727,14 +680,14 @@ Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS,
// uno && ueq -> uno && (uno || eq) -> ueq
// ord && olt -> ord && (ord && lt) -> olt
if (Op0Ordered == Op1Ordered)
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
// uno && oeq -> uno && (ord && eq) -> false
// uno && ord -> false
if (!Op0Ordered)
- return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
// ord && ueq -> ord && (uno || eq) -> oeq
- return cast<Instruction>(getFCmpValue(true, Op1Pred, Op0LHS, Op0RHS));
+ return getFCmpValue(true, Op1Pred, Op0LHS, Op0RHS, Builder);
}
}
@@ -930,26 +883,47 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1))
if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0))
- if (Instruction *Res = FoldAndOfICmps(I, LHS, RHS))
- return Res;
-
+ if (Value *Res = FoldAndOfICmps(LHS, RHS))
+ return ReplaceInstUsesWith(I, Res);
+
+ // If and'ing two fcmp, try combine them into one.
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0)))
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
+ if (Value *Res = FoldAndOfFCmps(LHS, RHS))
+ return ReplaceInstUsesWith(I, Res);
+
+
// fold (and (cast A), (cast B)) -> (cast (and A, B))
if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
- if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
- if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind ?
- const Type *SrcTy = Op0C->getOperand(0)->getType();
- if (SrcTy == Op1C->getOperand(0)->getType() &&
- SrcTy->isIntOrIntVector() &&
- // Only do this if the casts both really cause code to be generated.
- ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
- I.getType()) &&
- ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
- I.getType())) {
- Value *NewOp = Builder->CreateAnd(Op0C->getOperand(0),
- Op1C->getOperand(0), I.getName());
+ if (CastInst *Op1C = dyn_cast<CastInst>(Op1)) {
+ const Type *SrcTy = Op0C->getOperand(0)->getType();
+ if (Op0C->getOpcode() == Op1C->getOpcode() && // same cast kind ?
+ SrcTy == Op1C->getOperand(0)->getType() &&
+ SrcTy->isIntOrIntVectorTy()) {
+ Value *Op0COp = Op0C->getOperand(0), *Op1COp = Op1C->getOperand(0);
+
+ // Only do this if the casts both really cause code to be generated.
+ if (ShouldOptimizeCast(Op0C->getOpcode(), Op0COp, I.getType()) &&
+ ShouldOptimizeCast(Op1C->getOpcode(), Op1COp, I.getType())) {
+ Value *NewOp = Builder->CreateAnd(Op0COp, Op1COp, I.getName());
return CastInst::Create(Op0C->getOpcode(), NewOp, I.getType());
}
+
+ // If this is and(cast(icmp), cast(icmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1COp))
+ if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0COp))
+ if (Value *Res = FoldAndOfICmps(LHS, RHS))
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
+
+ // If this is and(cast(fcmp), cast(fcmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(Op1COp))
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(Op0COp))
+ if (Value *Res = FoldAndOfFCmps(LHS, RHS))
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
}
+ }
// (X >> Z) & (Y >> Z) -> (X&Y) >> Z for all shifts.
if (BinaryOperator *SI1 = dyn_cast<BinaryOperator>(Op1)) {
@@ -965,13 +939,6 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
}
}
- // If and'ing two fcmp, try combine them into one.
- if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) {
- if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
- if (Instruction *Res = FoldAndOfFCmps(I, LHS, RHS))
- return Res;
- }
-
return Changed ? &I : 0;
}
@@ -1143,7 +1110,7 @@ static Instruction *MatchSelectFromAndOr(Value *A, Value *B,
// If A is not a select of -1/0, this cannot match.
Value *Cond = 0;
if (!match(A, m_SExt(m_Value(Cond))) ||
- !Cond->getType()->isInteger(1))
+ !Cond->getType()->isIntegerTy(1))
return 0;
// ((cond?-1:0)&C) | (B&(cond?0:-1)) -> cond ? C : B.
@@ -1161,8 +1128,7 @@ static Instruction *MatchSelectFromAndOr(Value *A, Value *B,
}
/// FoldOrOfICmps - Fold (icmp)|(icmp) if possible.
-Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
- ICmpInst *LHS, ICmpInst *RHS) {
+Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
ICmpInst::Predicate LHSCC = LHS->getPredicate(), RHSCC = RHS->getPredicate();
// (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B)
@@ -1175,11 +1141,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1);
unsigned Code = getICmpCode(LHS) | getICmpCode(RHS);
bool isSigned = LHS->isSigned() || RHS->isSigned();
- Value *RV = getICmpValue(isSigned, Code, Op0, Op1);
- if (Instruction *I = dyn_cast<Instruction>(RV))
- return I;
- // Otherwise, it's a constant boolean value.
- return ReplaceInstUsesWith(I, RV);
+ return getICmpValue(isSigned, Code, Op0, Op1, Builder);
}
}
@@ -1193,7 +1155,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
if (LHSCst == RHSCst && LHSCC == RHSCC &&
LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero()) {
Value *NewOr = Builder->CreateOr(Val, Val2);
- return new ICmpInst(LHSCC, NewOr, LHSCst);
+ return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
}
// From here on, we only handle:
@@ -1245,7 +1207,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
Value *Add = Builder->CreateAdd(Val, AddCST, Val->getName()+".off");
AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst);
- return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST);
+ return Builder->CreateICmpULT(Add, AddCST);
}
break; // (X == 13 | X == 15) -> no change
case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change
@@ -1254,7 +1216,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
case ICmpInst::ICMP_NE: // (X == 13 | X != 15) -> X != 15
case ICmpInst::ICMP_ULT: // (X == 13 | X u< 15) -> X u< 15
case ICmpInst::ICMP_SLT: // (X == 13 | X s< 15) -> X s< 15
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
}
break;
case ICmpInst::ICMP_NE:
@@ -1263,11 +1225,11 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
case ICmpInst::ICMP_EQ: // (X != 13 | X == 15) -> X != 13
case ICmpInst::ICMP_UGT: // (X != 13 | X u> 15) -> X != 13
case ICmpInst::ICMP_SGT: // (X != 13 | X s> 15) -> X != 13
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
case ICmpInst::ICMP_NE: // (X != 13 | X != 15) -> true
case ICmpInst::ICMP_ULT: // (X != 13 | X u< 15) -> true
case ICmpInst::ICMP_SLT: // (X != 13 | X s< 15) -> true
- return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext()));
+ return ConstantInt::getTrue(LHS->getContext());
}
break;
case ICmpInst::ICMP_ULT:
@@ -1279,14 +1241,13 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
// If RHSCst is [us]MAXINT, it is always false. Not handling
// this can cause overflow.
if (RHSCst->isMaxValue(false))
- return ReplaceInstUsesWith(I, LHS);
- return InsertRangeTest(Val, LHSCst, AddOne(RHSCst),
- false, false, I);
+ return LHS;
+ return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), false, false);
case ICmpInst::ICMP_SGT: // (X u< 13 | X s> 15) -> no change
break;
case ICmpInst::ICMP_NE: // (X u< 13 | X != 15) -> X != 15
case ICmpInst::ICMP_ULT: // (X u< 13 | X u< 15) -> X u< 15
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
case ICmpInst::ICMP_SLT: // (X u< 13 | X s< 15) -> no change
break;
}
@@ -1300,14 +1261,13 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
// If RHSCst is [us]MAXINT, it is always false. Not handling
// this can cause overflow.
if (RHSCst->isMaxValue(true))
- return ReplaceInstUsesWith(I, LHS);
- return InsertRangeTest(Val, LHSCst, AddOne(RHSCst),
- true, false, I);
+ return LHS;
+ return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), true, false);
case ICmpInst::ICMP_UGT: // (X s< 13 | X u> 15) -> no change
break;
case ICmpInst::ICMP_NE: // (X s< 13 | X != 15) -> X != 15
case ICmpInst::ICMP_SLT: // (X s< 13 | X s< 15) -> X s< 15
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
case ICmpInst::ICMP_ULT: // (X s< 13 | X u< 15) -> no change
break;
}
@@ -1317,12 +1277,12 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
default: llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_EQ: // (X u> 13 | X == 15) -> X u> 13
case ICmpInst::ICMP_UGT: // (X u> 13 | X u> 15) -> X u> 13
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
case ICmpInst::ICMP_SGT: // (X u> 13 | X s> 15) -> no change
break;
case ICmpInst::ICMP_NE: // (X u> 13 | X != 15) -> true
case ICmpInst::ICMP_ULT: // (X u> 13 | X u< 15) -> true
- return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext()));
+ return ConstantInt::getTrue(LHS->getContext());
case ICmpInst::ICMP_SLT: // (X u> 13 | X s< 15) -> no change
break;
}
@@ -1332,12 +1292,12 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
default: llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_EQ: // (X s> 13 | X == 15) -> X > 13
case ICmpInst::ICMP_SGT: // (X s> 13 | X s> 15) -> X > 13
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
case ICmpInst::ICMP_UGT: // (X s> 13 | X u> 15) -> no change
break;
case ICmpInst::ICMP_NE: // (X s> 13 | X != 15) -> true
case ICmpInst::ICMP_SLT: // (X s> 13 | X s< 15) -> true
- return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext()));
+ return ConstantInt::getTrue(LHS->getContext());
case ICmpInst::ICMP_ULT: // (X s> 13 | X u< 15) -> no change
break;
}
@@ -1346,8 +1306,10 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
return 0;
}
-Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS,
- FCmpInst *RHS) {
+/// FoldOrOfFCmps - Optimize (fcmp)|(fcmp). NOTE: Unlike the rest of
+/// instcombine, this returns a Value which should already be inserted into the
+/// function.
+Value *InstCombiner::FoldOrOfFCmps(FCmpInst *LHS, FCmpInst *RHS) {
if (LHS->getPredicate() == FCmpInst::FCMP_UNO &&
RHS->getPredicate() == FCmpInst::FCMP_UNO &&
LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType()) {
@@ -1356,20 +1318,18 @@ Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS,
// If either of the constants are nans, then the whole thing returns
// true.
if (LHSC->getValueAPF().isNaN() || RHSC->getValueAPF().isNaN())
- return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext()));
+ return ConstantInt::getTrue(LHS->getContext());
// Otherwise, no need to compare the two constants, compare the
// rest.
- return new FCmpInst(FCmpInst::FCMP_UNO,
- LHS->getOperand(0), RHS->getOperand(0));
+ return Builder->CreateFCmpUNO(LHS->getOperand(0), RHS->getOperand(0));
}
// Handle vector zeros. This occurs because the canonical form of
// "fcmp uno x,x" is "fcmp uno x, 0".
if (isa<ConstantAggregateZero>(LHS->getOperand(1)) &&
isa<ConstantAggregateZero>(RHS->getOperand(1)))
- return new FCmpInst(FCmpInst::FCMP_UNO,
- LHS->getOperand(0), RHS->getOperand(0));
+ return Builder->CreateFCmpUNO(LHS->getOperand(0), RHS->getOperand(0));
return 0;
}
@@ -1386,14 +1346,13 @@ Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS,
if (Op0LHS == Op1LHS && Op0RHS == Op1RHS) {
// Simplify (fcmp cc0 x, y) | (fcmp cc1 x, y).
if (Op0CC == Op1CC)
- return new FCmpInst((FCmpInst::Predicate)Op0CC,
- Op0LHS, Op0RHS);
+ return Builder->CreateFCmp((FCmpInst::Predicate)Op0CC, Op0LHS, Op0RHS);
if (Op0CC == FCmpInst::FCMP_TRUE || Op1CC == FCmpInst::FCMP_TRUE)
- return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext()));
+ return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 1);
if (Op0CC == FCmpInst::FCMP_FALSE)
- return ReplaceInstUsesWith(I, RHS);
+ return RHS;
if (Op1CC == FCmpInst::FCMP_FALSE)
- return ReplaceInstUsesWith(I, LHS);
+ return LHS;
bool Op0Ordered;
bool Op1Ordered;
unsigned Op0Pred = getFCmpCode(Op0CC, Op0Ordered);
@@ -1401,11 +1360,7 @@ Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS,
if (Op0Ordered == Op1Ordered) {
// If both are ordered or unordered, return a new fcmp with
// or'ed predicates.
- Value *RV = getFCmpValue(Op0Ordered, Op0Pred|Op1Pred, Op0LHS, Op0RHS);
- if (Instruction *I = dyn_cast<Instruction>(RV))
- return I;
- // Otherwise, it's a constant boolean value...
- return ReplaceInstUsesWith(I, RV);
+ return getFCmpValue(Op0Ordered, Op0Pred|Op1Pred, Op0LHS, Op0RHS, Builder);
}
}
return 0;
@@ -1446,8 +1401,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if (Value *V = SimplifyOrInst(Op0, Op1, TD))
return ReplaceInstUsesWith(I, V);
-
-
+
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
if (SimplifyDemandedInstructionBits(I))
@@ -1456,7 +1410,9 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
ConstantInt *C1 = 0; Value *X = 0;
// (X & C1) | C2 --> (X | C2) & (C1|C2)
+ // iff (C1 & C2) == 0.
if (match(Op0, m_And(m_Value(X), m_ConstantInt(C1))) &&
+ (RHS->getValue() & C1->getValue()) != 0 &&
Op0->hasOneUse()) {
Value *Or = Builder->CreateOr(X, RHS);
Or->takeName(Op0);
@@ -1479,6 +1435,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
if (Instruction *R = FoldOpIntoSelect(I, SI))
return R;
+
if (isa<PHINode>(Op0))
if (Instruction *NV = FoldOpIntoPhi(I))
return NV;
@@ -1600,7 +1557,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
// (A & (C0?-1:0)) | (B & ~(C0?-1:0)) -> C0 ? A : B, and commuted variants.
// Don't do this for vector select idioms, the code generator doesn't handle
// them well yet.
- if (!isa<VectorType>(I.getType())) {
+ if (!I.getType()->isVectorTy()) {
if (Instruction *Match = MatchSelectFromAndOr(A, B, C, D))
return Match;
if (Instruction *Match = MatchSelectFromAndOr(B, A, D, C))
@@ -1666,40 +1623,50 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
if (ICmpInst *LHS = dyn_cast<ICmpInst>(I.getOperand(0)))
- if (Instruction *Res = FoldOrOfICmps(I, LHS, RHS))
- return Res;
+ if (Value *Res = FoldOrOfICmps(LHS, RHS))
+ return ReplaceInstUsesWith(I, Res);
+ // (fcmp uno x, c) | (fcmp uno y, c) -> (fcmp uno x, y)
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0)))
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
+ if (Value *Res = FoldOrOfFCmps(LHS, RHS))
+ return ReplaceInstUsesWith(I, Res);
+
// fold (or (cast A), (cast B)) -> (cast (or A, B))
if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
if (Op0C->getOpcode() == Op1C->getOpcode()) {// same cast kind ?
- if (!isa<ICmpInst>(Op0C->getOperand(0)) ||
- !isa<ICmpInst>(Op1C->getOperand(0))) {
- const Type *SrcTy = Op0C->getOperand(0)->getType();
- if (SrcTy == Op1C->getOperand(0)->getType() &&
- SrcTy->isIntOrIntVector() &&
+ const Type *SrcTy = Op0C->getOperand(0)->getType();
+ if (SrcTy == Op1C->getOperand(0)->getType() &&
+ SrcTy->isIntOrIntVectorTy()) {
+ Value *Op0COp = Op0C->getOperand(0), *Op1COp = Op1C->getOperand(0);
+
+ if ((!isa<ICmpInst>(Op0COp) || !isa<ICmpInst>(Op1COp)) &&
// Only do this if the casts both really cause code to be
// generated.
- ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
- I.getType()) &&
- ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
- I.getType())) {
- Value *NewOp = Builder->CreateOr(Op0C->getOperand(0),
- Op1C->getOperand(0), I.getName());
+ ShouldOptimizeCast(Op0C->getOpcode(), Op0COp, I.getType()) &&
+ ShouldOptimizeCast(Op1C->getOpcode(), Op1COp, I.getType())) {
+ Value *NewOp = Builder->CreateOr(Op0COp, Op1COp, I.getName());
return CastInst::Create(Op0C->getOpcode(), NewOp, I.getType());
}
+
+ // If this is or(cast(icmp), cast(icmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1COp))
+ if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0COp))
+ if (Value *Res = FoldOrOfICmps(LHS, RHS))
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
+
+ // If this is or(cast(fcmp), cast(fcmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(Op1COp))
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(Op0COp))
+ if (Value *Res = FoldOrOfFCmps(LHS, RHS))
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
}
}
}
-
- // (fcmp uno x, c) | (fcmp uno y, c) -> (fcmp uno x, y)
- if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) {
- if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
- if (Instruction *Res = FoldOrOfFCmps(I, LHS, RHS))
- return Res;
- }
-
return Changed ? &I : 0;
}
@@ -1723,7 +1690,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
// purpose is to compute bits we don't care about.
if (SimplifyDemandedInstructionBits(I))
return &I;
- if (isa<VectorType>(I.getType()))
+ if (I.getType()->isVectorTy())
if (isa<ConstantAggregateZero>(Op1))
return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X
@@ -1971,11 +1938,8 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1);
unsigned Code = getICmpCode(LHS) ^ getICmpCode(RHS);
bool isSigned = LHS->isSigned() || RHS->isSigned();
- Value *RV = getICmpValue(isSigned, Code, Op0, Op1);
- if (Instruction *I = dyn_cast<Instruction>(RV))
- return I;
- // Otherwise, it's a constant boolean value.
- return ReplaceInstUsesWith(I, RV);
+ return ReplaceInstUsesWith(I,
+ getICmpValue(isSigned, Code, Op0, Op1, Builder));
}
}
@@ -1984,12 +1948,12 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind?
const Type *SrcTy = Op0C->getOperand(0)->getType();
- if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isInteger() &&
+ if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegerTy() &&
// Only do this if the casts both really cause code to be generated.
- ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
- I.getType()) &&
- ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
- I.getType())) {
+ ShouldOptimizeCast(Op0C->getOpcode(), Op0C->getOperand(0),
+ I.getType()) &&
+ ShouldOptimizeCast(Op1C->getOpcode(), Op1C->getOperand(0),
+ I.getType())) {
Value *NewOp = Builder->CreateXor(Op0C->getOperand(0),
Op1C->getOperand(0), I.getName());
return CastInst::Create(Op0C->getOpcode(), NewOp, I.getType());
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 4929f40..e2b7d3d 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -16,6 +16,7 @@
#include "llvm/Support/CallSite.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Analysis/MemoryBuiltins.h"
+#include "llvm/Transforms/Utils/BuildLibCalls.h"
using namespace llvm;
/// getPromotedType - Return the specified type promoted as it would be to pass
@@ -199,7 +200,7 @@ Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
// Extract the length and alignment and fill if they are constant.
ConstantInt *LenC = dyn_cast<ConstantInt>(MI->getLength());
ConstantInt *FillC = dyn_cast<ConstantInt>(MI->getValue());
- if (!LenC || !FillC || !FillC->getType()->isInteger(8))
+ if (!LenC || !FillC || !FillC->getType()->isIntegerTy(8))
return 0;
uint64_t Len = LenC->getZExtValue();
Alignment = MI->getAlignment();
@@ -304,23 +305,77 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::objectsize: {
+ // We need target data for just about everything so depend on it.
+ if (!TD) break;
+
const Type *ReturnTy = CI.getType();
- Value *Op1 = II->getOperand(1);
bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1);
+
+ // Get to the real allocated thing and offset as fast as possible.
+ Value *Op1 = II->getOperand(1)->stripPointerCasts();
- if (!TD) break;
- Op1 = Op1->stripPointerCasts();
-
+ // If we've stripped down to a single global variable that we
+ // can know the size of then just return that.
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op1)) {
if (GV->hasDefinitiveInitializer()) {
Constant *C = GV->getInitializer();
- size_t globalSize = TD->getTypeAllocSize(C->getType());
- return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, globalSize));
+ uint64_t GlobalSize = TD->getTypeAllocSize(C->getType());
+ return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, GlobalSize));
} else {
+ // Can't determine size of the GV.
Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
return ReplaceInstUsesWith(CI, RetVal);
}
- }
+ } else if (AllocaInst *AI = dyn_cast<AllocaInst>(Op1)) {
+ // Get alloca size.
+ if (AI->getAllocatedType()->isSized()) {
+ uint64_t AllocaSize = TD->getTypeAllocSize(AI->getAllocatedType());
+ if (AI->isArrayAllocation()) {
+ const ConstantInt *C = dyn_cast<ConstantInt>(AI->getArraySize());
+ if (!C) break;
+ AllocaSize *= C->getZExtValue();
+ }
+ return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, AllocaSize));
+ }
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op1)) {
+ // Only handle constant GEPs here.
+ if (CE->getOpcode() != Instruction::GetElementPtr) break;
+ GEPOperator *GEP = cast<GEPOperator>(CE);
+
+ // Make sure we're not a constant offset from an external
+ // global.
+ Value *Operand = GEP->getPointerOperand();
+ Operand = Operand->stripPointerCasts();
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand))
+ if (!GV->hasDefinitiveInitializer()) break;
+
+ // Get what we're pointing to and its size.
+ const PointerType *BaseType =
+ cast<PointerType>(Operand->getType());
+ uint64_t Size = TD->getTypeAllocSize(BaseType->getElementType());
+
+ // Get the current byte offset into the thing. Use the original
+ // operand in case we're looking through a bitcast.
+ SmallVector<Value*, 8> Ops(CE->op_begin()+1, CE->op_end());
+ const PointerType *OffsetType =
+ cast<PointerType>(GEP->getPointerOperand()->getType());
+ uint64_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size());
+
+ if (Size < Offset) {
+ // Out of bound reference? Negative index normalized to large
+ // index? Just return "I don't know".
+ Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
+ return ReplaceInstUsesWith(CI, RetVal);
+ }
+
+ Constant *RetVal = ConstantInt::get(ReturnTy, Size-Offset);
+ return ReplaceInstUsesWith(CI, RetVal);
+
+ }
+
+ // Do not return "I don't know" here. Later optimization passes could
+ // make it possible to evaluate objectsize to a constant.
+ break;
}
case Intrinsic::bswap:
// bswap(bswap(x)) -> x
@@ -686,6 +741,122 @@ static bool isSafeToEliminateVarargsCast(const CallSite CS,
return true;
}
+// Try to fold some different type of calls here.
+// Currently we're only working with the checking functions, memcpy_chk,
+// mempcpy_chk, memmove_chk, memset_chk, strcpy_chk, stpcpy_chk, strncpy_chk,
+// strcat_chk and strncat_chk.
+Instruction *InstCombiner::tryOptimizeCall(CallInst *CI, const TargetData *TD) {
+ if (CI->getCalledFunction() == 0) return 0;
+
+ StringRef Name = CI->getCalledFunction()->getName();
+ BasicBlock *BB = CI->getParent();
+ IRBuilder<> B(CI->getParent()->getContext());
+
+ // Set the builder to the instruction after the call.
+ B.SetInsertPoint(BB, CI);
+
+ if (Name == "__memcpy_chk") {
+ ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+ if (!SizeCI)
+ return 0;
+ ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+ if (!SizeArg)
+ return 0;
+ if (SizeCI->isAllOnesValue() ||
+ SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+ EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
+ 1, B, TD);
+ return ReplaceInstUsesWith(*CI, CI->getOperand(1));
+ }
+ return 0;
+ }
+
+ // Should be similar to memcpy.
+ if (Name == "__mempcpy_chk") {
+ return 0;
+ }
+
+ if (Name == "__memmove_chk") {
+ ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+ if (!SizeCI)
+ return 0;
+ ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+ if (!SizeArg)
+ return 0;
+ if (SizeCI->isAllOnesValue() ||
+ SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+ EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
+ 1, B, TD);
+ return ReplaceInstUsesWith(*CI, CI->getOperand(1));
+ }
+ return 0;
+ }
+
+ if (Name == "__memset_chk") {
+ ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+ if (!SizeCI)
+ return 0;
+ ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+ if (!SizeArg)
+ return 0;
+ if (SizeCI->isAllOnesValue() ||
+ SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+ Value *Val = B.CreateIntCast(CI->getOperand(2), B.getInt8Ty(),
+ false);
+ EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B, TD);
+ return ReplaceInstUsesWith(*CI, CI->getOperand(1));
+ }
+ return 0;
+ }
+
+ if (Name == "__strcpy_chk") {
+ ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
+ if (!SizeCI)
+ return 0;
+ // If a) we don't have any length information, or b) we know this will
+ // fit then just lower to a plain strcpy. Otherwise we'll keep our
+ // strcpy_chk call which may fail at runtime if the size is too long.
+ // TODO: It might be nice to get a maximum length out of the possible
+ // string lengths for varying.
+ if (SizeCI->isAllOnesValue() ||
+ SizeCI->getZExtValue() >= GetStringLength(CI->getOperand(2))) {
+ Value *Ret = EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B, TD);
+ return ReplaceInstUsesWith(*CI, Ret);
+ }
+ return 0;
+ }
+
+ // Should be similar to strcpy.
+ if (Name == "__stpcpy_chk") {
+ return 0;
+ }
+
+ if (Name == "__strncpy_chk") {
+ ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+ if (!SizeCI)
+ return 0;
+ ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+ if (!SizeArg)
+ return 0;
+ if (SizeCI->isAllOnesValue() ||
+ SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+ Value *Ret = EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B, TD);
+ return ReplaceInstUsesWith(*CI, Ret);
+ }
+ return 0;
+ }
+
+ if (Name == "__strcat_chk") {
+ return 0;
+ }
+
+ if (Name == "__strncat_chk") {
+ return 0;
+ }
+
+ return 0;
+}
+
// visitCallSite - Improvements for call and invoke instructions.
//
Instruction *InstCombiner::visitCallSite(CallSite CS) {
@@ -772,6 +943,16 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
Changed = true;
}
+ // Try to optimize the call if possible, we require TargetData for most of
+ // this. None of these calls are seen as possibly dead so go ahead and
+ // delete the instruction now.
+ if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction())) {
+ Instruction *I = tryOptimizeCall(CI, TD);
+ // If we changed something return the result, etc. Otherwise let
+ // the fallthrough check.
+ if (I) return EraseInstFromFunction(*I);
+ }
+
return Changed ? CS.getInstruction() : 0;
}
@@ -796,7 +977,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
const Type *OldRetTy = Caller->getType();
const Type *NewRetTy = FT->getReturnType();
- if (isa<StructType>(NewRetTy))
+ if (NewRetTy->isStructTy())
return false; // TODO: Handle multiple return values.
// Check to see if we are changing the return type...
@@ -804,9 +985,9 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (Callee->isDeclaration() &&
// Conversion is ok if changing from one pointer type to another or from
// a pointer to an integer of the same size.
- !((isa<PointerType>(OldRetTy) || !TD ||
+ !((OldRetTy->isPointerTy() || !TD ||
OldRetTy == TD->getIntPtrType(Caller->getContext())) &&
- (isa<PointerType>(NewRetTy) || !TD ||
+ (NewRetTy->isPointerTy() || !TD ||
NewRetTy == TD->getIntPtrType(Caller->getContext()))))
return false; // Cannot transform this return value.
@@ -853,9 +1034,9 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
// Converting from one pointer type to another or between a pointer and an
// integer of the same size is safe even if we do not have a body.
bool isConvertible = ActTy == ParamTy ||
- (TD && ((isa<PointerType>(ParamTy) ||
+ (TD && ((ParamTy->isPointerTy() ||
ParamTy == TD->getIntPtrType(Caller->getContext())) &&
- (isa<PointerType>(ActTy) ||
+ (ActTy->isPointerTy() ||
ActTy == TD->getIntPtrType(Caller->getContext()))));
if (Callee->isDeclaration() && !isConvertible) return false;
}
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 09cd21f..a68fc6d 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -23,7 +23,7 @@ using namespace PatternMatch;
///
static Value *DecomposeSimpleLinearExpr(Value *Val, unsigned &Scale,
int &Offset) {
- assert(Val->getType()->isInteger(32) && "Unexpected allocation size type!");
+ assert(Val->getType()->isIntegerTy(32) && "Unexpected allocation size type!");
if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
Offset = CI->getZExtValue();
Scale = 0;
@@ -255,17 +255,26 @@ isEliminableCastPair(
return Instruction::CastOps(Res);
}
-/// ValueRequiresCast - Return true if the cast from "V to Ty" actually results
-/// in any code being generated. It does not require codegen if V is simple
-/// enough or if the cast can be folded into other casts.
-bool InstCombiner::ValueRequiresCast(Instruction::CastOps opcode,const Value *V,
- const Type *Ty) {
+/// ShouldOptimizeCast - Return true if the cast from "V to Ty" actually
+/// results in any code being generated and is interesting to optimize out. If
+/// the cast can be eliminated by some other simple transformation, we prefer
+/// to do the simplification first.
+bool InstCombiner::ShouldOptimizeCast(Instruction::CastOps opc, const Value *V,
+ const Type *Ty) {
+ // Noop casts and casts of constants should be eliminated trivially.
if (V->getType() == Ty || isa<Constant>(V)) return false;
- // If this is another cast that can be eliminated, it isn't codegen either.
+ // If this is another cast that can be eliminated, we prefer to have it
+ // eliminated.
if (const CastInst *CI = dyn_cast<CastInst>(V))
- if (isEliminableCastPair(CI, opcode, Ty, TD))
+ if (isEliminableCastPair(CI, opc, Ty, TD))
return false;
+
+ // If this is a vector sext from a compare, then we don't want to break the
+ // idiom where each element of the extended vector is either zero or all ones.
+ if (opc == Instruction::SExt && isa<CmpInst>(V) && Ty->isVectorTy())
+ return false;
+
return true;
}
@@ -294,8 +303,8 @@ Instruction *InstCombiner::commonCastTransforms(CastInst &CI) {
if (isa<PHINode>(Src)) {
// We don't do this if this would create a PHI node with an illegal type if
// it is currently legal.
- if (!isa<IntegerType>(Src->getType()) ||
- !isa<IntegerType>(CI.getType()) ||
+ if (!Src->getType()->isIntegerTy() ||
+ !CI.getType()->isIntegerTy() ||
ShouldChangeType(CI.getType(), Src->getType()))
if (Instruction *NV = FoldOpIntoPhi(CI))
return NV;
@@ -427,7 +436,7 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
// type. Only do this if the dest type is a simple type, don't convert the
// expression tree to something weird like i93 unless the source is also
// strange.
- if ((isa<VectorType>(DestTy) || ShouldChangeType(SrcTy, DestTy)) &&
+ if ((DestTy->isVectorTy() || ShouldChangeType(SrcTy, DestTy)) &&
CanEvaluateTruncated(Src, DestTy)) {
// If this cast is a truncate, evaluting in a different type always
@@ -719,7 +728,7 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
// expression tree to something weird like i93 unless the source is also
// strange.
unsigned BitsToClear;
- if ((isa<VectorType>(DestTy) || ShouldChangeType(SrcTy, DestTy)) &&
+ if ((DestTy->isVectorTy() || ShouldChangeType(SrcTy, DestTy)) &&
CanEvaluateZExtd(Src, DestTy, BitsToClear)) {
assert(BitsToClear < SrcTy->getScalarSizeInBits() &&
"Unreasonable BitsToClear");
@@ -828,7 +837,7 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
// zext (xor i1 X, true) to i32 --> xor (zext i1 X to i32), 1
Value *X;
- if (SrcI && SrcI->hasOneUse() && SrcI->getType()->isInteger(1) &&
+ if (SrcI && SrcI->hasOneUse() && SrcI->getType()->isIntegerTy(1) &&
match(SrcI, m_Not(m_Value(X))) &&
(!X->hasOneUse() || !isa<CmpInst>(X))) {
Value *New = Builder->CreateZExt(X, CI.getType());
@@ -927,7 +936,7 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
// type. Only do this if the dest type is a simple type, don't convert the
// expression tree to something weird like i93 unless the source is also
// strange.
- if ((isa<VectorType>(DestTy) || ShouldChangeType(SrcTy, DestTy)) &&
+ if ((DestTy->isVectorTy() || ShouldChangeType(SrcTy, DestTy)) &&
CanEvaluateSExtd(Src, DestTy)) {
// Okay, we can transform this! Insert the new expression now.
DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
@@ -1280,7 +1289,7 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
Constant::getNullValue(Type::getInt32Ty(CI.getContext()));
unsigned NumZeros = 0;
while (SrcElTy != DstElTy &&
- isa<CompositeType>(SrcElTy) && !isa<PointerType>(SrcElTy) &&
+ isa<CompositeType>(SrcElTy) && !SrcElTy->isPointerTy() &&
SrcElTy->getNumContainedTypes() /* not "{}" */) {
SrcElTy = cast<CompositeType>(SrcElTy)->getTypeAtIndex(ZeroUInt);
++NumZeros;
@@ -1295,7 +1304,7 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
}
if (const VectorType *DestVTy = dyn_cast<VectorType>(DestTy)) {
- if (DestVTy->getNumElements() == 1 && !isa<VectorType>(SrcTy)) {
+ if (DestVTy->getNumElements() == 1 && !SrcTy->isVectorTy()) {
Value *Elem = Builder->CreateBitCast(Src, DestVTy->getElementType());
return InsertElementInst::Create(UndefValue::get(DestTy), Elem,
Constant::getNullValue(Type::getInt32Ty(CI.getContext())));
@@ -1304,7 +1313,7 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
}
if (const VectorType *SrcVTy = dyn_cast<VectorType>(SrcTy)) {
- if (SrcVTy->getNumElements() == 1 && !isa<VectorType>(DestTy)) {
+ if (SrcVTy->getNumElements() == 1 && !DestTy->isVectorTy()) {
Value *Elem =
Builder->CreateExtractElement(Src,
Constant::getNullValue(Type::getInt32Ty(CI.getContext())));
@@ -1315,7 +1324,7 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(Src)) {
// Okay, we have (bitcast (shuffle ..)). Check to see if this is
// a bitconvert to a vector with the same # elts.
- if (SVI->hasOneUse() && isa<VectorType>(DestTy) &&
+ if (SVI->hasOneUse() && DestTy->isVectorTy() &&
cast<VectorType>(DestTy)->getNumElements() ==
SVI->getType()->getNumElements() &&
SVI->getType()->getNumElements() ==
@@ -1337,7 +1346,7 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
}
}
- if (isa<PointerType>(SrcTy))
+ if (SrcTy->isPointerTy())
return commonPointerCastTransforms(CI);
return commonCastTransforms(CI);
}
diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 7c00c2c..72fd558 100644
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -877,25 +877,26 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
case ICmpInst::ICMP_EQ:
if (LoOverflow && HiOverflow)
return ReplaceInstUsesWith(ICI, ConstantInt::getFalse(ICI.getContext()));
- else if (HiOverflow)
+ if (HiOverflow)
return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE :
ICmpInst::ICMP_UGE, X, LoBound);
- else if (LoOverflow)
+ if (LoOverflow)
return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT :
ICmpInst::ICMP_ULT, X, HiBound);
- else
- return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, true, ICI);
+ return ReplaceInstUsesWith(ICI,
+ InsertRangeTest(X, LoBound, HiBound, DivIsSigned,
+ true));
case ICmpInst::ICMP_NE:
if (LoOverflow && HiOverflow)
return ReplaceInstUsesWith(ICI, ConstantInt::getTrue(ICI.getContext()));
- else if (HiOverflow)
+ if (HiOverflow)
return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT :
ICmpInst::ICMP_ULT, X, LoBound);
- else if (LoOverflow)
+ if (LoOverflow)
return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE :
ICmpInst::ICMP_UGE, X, HiBound);
- else
- return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, false, ICI);
+ return ReplaceInstUsesWith(ICI, InsertRangeTest(X, LoBound, HiBound,
+ DivIsSigned, false));
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
if (LoOverflow == +1) // Low bound is greater than input range.
@@ -1606,7 +1607,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
const Type *Ty = Op0->getType();
// icmp's with boolean values can always be turned into bitwise operations
- if (Ty->isInteger(1)) {
+ if (Ty->isIntegerTy(1)) {
switch (I.getPredicate()) {
default: llvm_unreachable("Invalid icmp instruction!");
case ICmpInst::ICMP_EQ: { // icmp eq i1 A, B -> ~(A^B)
@@ -1650,7 +1651,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
unsigned BitWidth = 0;
if (TD)
BitWidth = TD->getTypeSizeInBits(Ty->getScalarType());
- else if (Ty->isIntOrIntVector())
+ else if (Ty->isIntOrIntVectorTy())
BitWidth = Ty->getScalarSizeInBits();
bool isSignBit = false;
@@ -1988,7 +1989,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
// values. If the ptr->ptr cast can be stripped off both arguments, we do so
// now.
if (BitCastInst *CI = dyn_cast<BitCastInst>(Op0)) {
- if (isa<PointerType>(Op0->getType()) &&
+ if (Op0->getType()->isPointerTy() &&
(isa<Constant>(Op1) || isa<BitCastInst>(Op1))) {
// We keep moving the cast from the left operand over to the right
// operand, where it can often be eliminated completely.
@@ -2458,17 +2459,17 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
return SelectInst::Create(LHSI->getOperand(0), Op1, Op2);
break;
}
- case Instruction::Load:
- if (GetElementPtrInst *GEP =
- dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) {
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
- if (GV->isConstant() && GV->hasDefinitiveInitializer() &&
- !cast<LoadInst>(LHSI)->isVolatile())
- if (Instruction *Res = FoldCmpLoadFromIndexedGlobal(GEP, GV, I))
- return Res;
+ case Instruction::Load:
+ if (GetElementPtrInst *GEP =
+ dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
+ if (GV->isConstant() && GV->hasDefinitiveInitializer() &&
+ !cast<LoadInst>(LHSI)->isVolatile())
+ if (Instruction *Res = FoldCmpLoadFromIndexedGlobal(GEP, GV, I))
+ return Res;
+ }
+ break;
}
- break;
- }
}
return Changed ? &I : 0;
diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 2d13298..0f2a24f 100644
--- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -87,8 +87,8 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
const Type *SrcPTy = SrcTy->getElementType();
- if (DestPTy->isInteger() || isa<PointerType>(DestPTy) ||
- isa<VectorType>(DestPTy)) {
+ if (DestPTy->isIntegerTy() || DestPTy->isPointerTy() ||
+ DestPTy->isVectorTy()) {
// If the source is an array, the code below will not succeed. Check to
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
// constants.
@@ -104,11 +104,11 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
}
if (IC.getTargetData() &&
- (SrcPTy->isInteger() || isa<PointerType>(SrcPTy) ||
- isa<VectorType>(SrcPTy)) &&
+ (SrcPTy->isIntegerTy() || SrcPTy->isPointerTy() ||
+ SrcPTy->isVectorTy()) &&
// Do not allow turning this into a load of an integer, which is then
// casted to a pointer, this pessimizes pointer analysis a lot.
- (isa<PointerType>(SrcPTy) == isa<PointerType>(LI.getType())) &&
+ (SrcPTy->isPointerTy() == LI.getType()->isPointerTy()) &&
IC.getTargetData()->getTypeSizeInBits(SrcPTy) ==
IC.getTargetData()->getTypeSizeInBits(DestPTy)) {
@@ -243,7 +243,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
const Type *SrcPTy = SrcTy->getElementType();
- if (!DestPTy->isInteger() && !isa<PointerType>(DestPTy))
+ if (!DestPTy->isIntegerTy() && !DestPTy->isPointerTy())
return 0;
/// NewGEPIndices - If SrcPTy is an aggregate type, we can emit a "noop gep"
@@ -255,7 +255,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
// If the source is an array, the code below will not succeed. Check to
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
// constants.
- if (isa<ArrayType>(SrcPTy) || isa<StructType>(SrcPTy)) {
+ if (SrcPTy->isArrayTy() || SrcPTy->isStructTy()) {
// Index through pointer.
Constant *Zero = Constant::getNullValue(Type::getInt32Ty(SI.getContext()));
NewGEPIndices.push_back(Zero);
@@ -277,7 +277,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
SrcTy = PointerType::get(SrcPTy, SrcTy->getAddressSpace());
}
- if (!SrcPTy->isInteger() && !isa<PointerType>(SrcPTy))
+ if (!SrcPTy->isIntegerTy() && !SrcPTy->isPointerTy())
return 0;
// If the pointers point into different address spaces or if they point to
@@ -297,11 +297,11 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
Instruction::CastOps opcode = Instruction::BitCast;
const Type* CastSrcTy = SIOp0->getType();
const Type* CastDstTy = SrcPTy;
- if (isa<PointerType>(CastDstTy)) {
- if (CastSrcTy->isInteger())
+ if (CastDstTy->isPointerTy()) {
+ if (CastSrcTy->isIntegerTy())
opcode = Instruction::IntToPtr;
- } else if (isa<IntegerType>(CastDstTy)) {
- if (isa<PointerType>(SIOp0->getType()))
+ } else if (CastDstTy->isIntegerTy()) {
+ if (SIOp0->getType()->isPointerTy())
opcode = Instruction::PtrToInt;
}
@@ -413,7 +413,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
// Don't count debug info directives, lest they affect codegen,
// and we skip pointer-to-pointer bitcasts, which are NOPs.
if (isa<DbgInfoIntrinsic>(BBI) ||
- (isa<BitCastInst>(BBI) && isa<PointerType>(BBI->getType()))) {
+ (isa<BitCastInst>(BBI) && BBI->getType()->isPointerTy())) {
ScanInsts++;
continue;
}
@@ -483,7 +483,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
do {
++BBI;
} while (isa<DbgInfoIntrinsic>(BBI) ||
- (isa<BitCastInst>(BBI) && isa<PointerType>(BBI->getType())));
+ (isa<BitCastInst>(BBI) && BBI->getType()->isPointerTy()));
if (BranchInst *BI = dyn_cast<BranchInst>(BBI))
if (BI->isUnconditional())
if (SimplifyStoreAtEndOfBlock(SI))
@@ -544,7 +544,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
--BBI;
// Skip over debugging info.
while (isa<DbgInfoIntrinsic>(BBI) ||
- (isa<BitCastInst>(BBI) && isa<PointerType>(BBI->getType()))) {
+ (isa<BitCastInst>(BBI) && BBI->getType()->isPointerTy())) {
if (BBI==OtherBB->begin())
return false;
--BBI;
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 2e26a75..b3974e8 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -76,7 +76,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
return BinaryOperator::CreateShl(Op0,
ConstantInt::get(Op0->getType(), Val.logBase2()));
}
- } else if (isa<VectorType>(Op1C->getType())) {
+ } else if (Op1C->getType()->isVectorTy()) {
if (Op1C->isNullValue())
return ReplaceInstUsesWith(I, Op1C);
@@ -157,7 +157,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
}
/// i1 mul -> i1 and.
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return BinaryOperator::CreateAnd(Op0, Op1);
// X*(1 << Y) --> X << Y
@@ -173,7 +173,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
// If one of the operands of the multiply is a cast from a boolean value, then
// we know the bool is either zero or one, so this is a 'masking' multiply.
// X * Y (where Y is 0 or 1) -> X & (0-Y)
- if (!isa<VectorType>(I.getType())) {
+ if (!I.getType()->isVectorTy()) {
// -2 is "-1 << 1" so it is all bits set except the low one.
APInt Negative2(I.getType()->getPrimitiveSizeInBits(), (uint64_t)-2, true);
@@ -203,8 +203,8 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
// "In IEEE floating point, x*1 is not equivalent to x for nans. However,
// ANSI says we can drop signals, so we can do this anyway." (from GCC)
if (Op1F->isExactlyValue(1.0))
- return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0'
- } else if (isa<VectorType>(Op1C->getType())) {
+ return ReplaceInstUsesWith(I, Op0); // Eliminate 'fmul double %X, 1.0'
+ } else if (Op1C->getType()->isVectorTy()) {
if (ConstantVector *Op1V = dyn_cast<ConstantVector>(Op1C)) {
// As above, vector X*splat(1.0) -> X in all defined cases.
if (Constant *Splat = Op1V->getSplatValue()) {
@@ -314,7 +314,7 @@ Instruction *InstCombiner::commonDivTransforms(BinaryOperator &I) {
// undef / X -> 0 for integer.
// undef / X -> undef for FP (the undef could be a snan).
if (isa<UndefValue>(Op0)) {
- if (Op0->getType()->isFPOrFPVector())
+ if (Op0->getType()->isFPOrFPVectorTy())
return ReplaceInstUsesWith(I, Op0);
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
}
@@ -386,7 +386,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
// It can't be division by zero, hence it must be division by one.
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return ReplaceInstUsesWith(I, Op0);
if (ConstantVector *Op1V = dyn_cast<ConstantVector>(Op1)) {
@@ -493,7 +493,7 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
// If the sign bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a udiv.
- if (I.getType()->isInteger()) {
+ if (I.getType()->isIntegerTy()) {
APInt Mask(APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()));
if (MaskedValueIsZero(Op0, Mask)) {
if (MaskedValueIsZero(Op1, Mask)) {
@@ -527,7 +527,7 @@ Instruction *InstCombiner::commonRemTransforms(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
if (isa<UndefValue>(Op0)) { // undef % X -> 0
- if (I.getType()->isFPOrFPVector())
+ if (I.getType()->isFPOrFPVectorTy())
return ReplaceInstUsesWith(I, Op0); // X % undef -> undef (could be SNaN)
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
}
@@ -648,7 +648,7 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
// If the sign bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a urem.
- if (I.getType()->isInteger()) {
+ if (I.getType()->isIntegerTy()) {
APInt Mask(APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()));
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
// X srem Y -> X urem Y, iff X and Y don't have sign bit set
diff --git a/lib/Transforms/InstCombine/InstCombinePHI.cpp b/lib/Transforms/InstCombine/InstCombinePHI.cpp
index bb7632f..65f0393 100644
--- a/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -266,6 +266,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
// and if TD isn't around, we can't handle the mixed case.
bool isVolatile = FirstLI->isVolatile();
unsigned LoadAlignment = FirstLI->getAlignment();
+ unsigned LoadAddrSpace = FirstLI->getPointerAddressSpace();
// We can't sink the load if the loaded value could be modified between the
// load and the PHI.
@@ -290,6 +291,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
// the load and the PHI.
if (LI->isVolatile() != isVolatile ||
LI->getParent() != PN.getIncomingBlock(i) ||
+ LI->getPointerAddressSpace() != LoadAddrSpace ||
!isSafeAndProfitableToSinkLoad(LI))
return 0;
@@ -371,7 +373,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
// Be careful about transforming integer PHIs. We don't want to pessimize
// the code by turning an i32 into an i1293.
- if (isa<IntegerType>(PN.getType()) && isa<IntegerType>(CastSrcTy)) {
+ if (PN.getType()->isIntegerTy() && CastSrcTy->isIntegerTy()) {
if (!ShouldChangeType(PN.getType(), CastSrcTy))
return 0;
}
@@ -832,7 +834,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
// it is only used by trunc or trunc(lshr) operations. If so, we split the
// PHI into the various pieces being extracted. This sort of thing is
// introduced when SROA promotes an aggregate to a single large integer type.
- if (isa<IntegerType>(PN.getType()) && TD &&
+ if (PN.getType()->isIntegerTy() && TD &&
!TD->isLegalInteger(PN.getType()->getPrimitiveSizeInBits()))
if (Instruction *Res = SliceUpIllegalIntegerPHI(PN))
return Res;
diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 9a02b33..2fc9325 100644
--- a/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -441,7 +441,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
return ReplaceInstUsesWith(SI, FalseVal);
}
- if (SI.getType()->isInteger(1)) {
+ if (SI.getType()->isIntegerTy(1)) {
if (ConstantInt *C = dyn_cast<ConstantInt>(TrueVal)) {
if (C->getZExtValue()) {
// Change: A = select B, true, C --> A = or B, C
@@ -539,9 +539,18 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
!CFPf->getValueAPF().isZero()))
return ReplaceInstUsesWith(SI, FalseVal);
}
- // Transform (X != Y) ? X : Y -> X
- if (FCI->getPredicate() == FCmpInst::FCMP_ONE)
+ // Transform (X une Y) ? X : Y -> X
+ if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
+ // This is not safe in general for floating point:
+ // consider X== -0, Y== +0.
+ // It becomes safe if either operand is a nonzero constant.
+ ConstantFP *CFPt, *CFPf;
+ if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
+ !CFPt->getValueAPF().isZero()) ||
+ ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
+ !CFPf->getValueAPF().isZero()))
return ReplaceInstUsesWith(SI, TrueVal);
+ }
// NOTE: if we wanted to, this is where to detect MIN/MAX
} else if (FCI->getOperand(0) == FalseVal && FCI->getOperand(1) == TrueVal){
@@ -557,9 +566,18 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
!CFPf->getValueAPF().isZero()))
return ReplaceInstUsesWith(SI, FalseVal);
}
- // Transform (X != Y) ? Y : X -> Y
- if (FCI->getPredicate() == FCmpInst::FCMP_ONE)
- return ReplaceInstUsesWith(SI, TrueVal);
+ // Transform (X une Y) ? Y : X -> Y
+ if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
+ // This is not safe in general for floating point:
+ // consider X== -0, Y== +0.
+ // It becomes safe if either operand is a nonzero constant.
+ ConstantFP *CFPt, *CFPf;
+ if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
+ !CFPt->getValueAPF().isZero()) ||
+ ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
+ !CFPf->getValueAPF().isZero()))
+ return ReplaceInstUsesWith(SI, TrueVal);
+ }
// NOTE: if we wanted to, this is where to detect MIN/MAX
}
// NOTE: if we wanted to, this is where to detect ABS
@@ -629,7 +647,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
}
// See if we can fold the select into one of our operands.
- if (SI.getType()->isInteger()) {
+ if (SI.getType()->isIntegerTy()) {
if (Instruction *FoldI = FoldSelectIntoOp(SI, TrueVal, FalseVal))
return FoldI;
diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 53a5684..cd41844 100644
--- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -104,10 +104,10 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
assert(Depth <= 6 && "Limit Search Depth");
uint32_t BitWidth = DemandedMask.getBitWidth();
const Type *VTy = V->getType();
- assert((TD || !isa<PointerType>(VTy)) &&
+ assert((TD || !VTy->isPointerTy()) &&
"SimplifyDemandedBits needs to know bit widths!");
assert((!TD || TD->getTypeSizeInBits(VTy->getScalarType()) == BitWidth) &&
- (!VTy->isIntOrIntVector() ||
+ (!VTy->isIntOrIntVectorTy() ||
VTy->getScalarSizeInBits() == BitWidth) &&
KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth &&
@@ -401,7 +401,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
break;
}
case Instruction::BitCast:
- if (!I->getOperand(0)->getType()->isIntOrIntVector())
+ if (!I->getOperand(0)->getType()->isIntOrIntVectorTy())
return 0; // vector->int or fp->int?
if (const VectorType *DstVTy = dyn_cast<VectorType>(I->getType())) {
@@ -413,7 +413,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
} else
// Don't touch a scalar-to-vector bitcast.
return 0;
- } else if (isa<VectorType>(I->getOperand(0)->getType()))
+ } else if (I->getOperand(0)->getType()->isVectorTy())
// Don't touch a vector-to-scalar bitcast.
return 0;
diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 20fda1a..a58124d 100644
--- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -78,7 +78,7 @@ static std::vector<unsigned> getShuffleMask(const ShuffleVectorInst *SVI) {
/// value is already around as a register, for example if it were inserted then
/// extracted from the vector.
static Value *FindScalarElement(Value *V, unsigned EltNo) {
- assert(isa<VectorType>(V->getType()) && "Not looking at a vector?");
+ assert(V->getType()->isVectorTy() && "Not looking at a vector?");
const VectorType *PTy = cast<VectorType>(V->getType());
unsigned Width = PTy->getNumElements();
if (EltNo >= Width) // Out of range access.
@@ -322,7 +322,7 @@ static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS,
/// that computes V and the LHS value of the shuffle.
static Value *CollectShuffleElements(Value *V, std::vector<Constant*> &Mask,
Value *&RHS) {
- assert(isa<VectorType>(V->getType()) &&
+ assert(V->getType()->isVectorTy() &&
(RHS == 0 || V->getType() == RHS->getType()) &&
"Invalid shuffle!");
unsigned NumElts = cast<VectorType>(V->getType())->getNumElements();
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index 93b1961..af9ec5c 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -73,7 +73,7 @@ void InstCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
/// from 'From' to 'To'. We don't want to convert from a legal to an illegal
/// type for example, or from a smaller to a larger illegal type.
bool InstCombiner::ShouldChangeType(const Type *From, const Type *To) const {
- assert(isa<IntegerType>(From) && isa<IntegerType>(To));
+ assert(From->isIntegerTy() && To->isIntegerTy());
// If we don't have TD, we don't know if the source/dest are legal.
if (!TD) return false;
@@ -158,7 +158,7 @@ Value *InstCombiner::dyn_castNegVal(Value *V) const {
return ConstantExpr::getNeg(C);
if (ConstantVector *C = dyn_cast<ConstantVector>(V))
- if (C->getType()->getElementType()->isInteger())
+ if (C->getType()->getElementType()->isIntegerTy())
return ConstantExpr::getNeg(C);
return 0;
@@ -177,7 +177,7 @@ Value *InstCombiner::dyn_castFNegVal(Value *V) const {
return ConstantExpr::getFNeg(C);
if (ConstantVector *C = dyn_cast<ConstantVector>(V))
- if (C->getType()->getElementType()->isFloatingPoint())
+ if (C->getType()->getElementType()->isFloatingPointTy())
return ConstantExpr::getFNeg(C);
return 0;
@@ -226,7 +226,7 @@ Instruction *InstCombiner::FoldOpIntoSelect(Instruction &Op, SelectInst *SI) {
if (isa<Constant>(TV) || isa<Constant>(FV)) {
// Bool selects with constant operands can be folded to logical ops.
- if (SI->getType()->isInteger(1)) return 0;
+ if (SI->getType()->isIntegerTy(1)) return 0;
Value *SelectTrueVal = FoldOperationIntoSelectOperand(Op, TV, this);
Value *SelectFalseVal = FoldOperationIntoSelectOperand(Op, FV, this);
@@ -478,7 +478,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
bool EndsWithSequential = false;
for (gep_type_iterator I = gep_type_begin(*Src), E = gep_type_end(*Src);
I != E; ++I)
- EndsWithSequential = !isa<StructType>(*I);
+ EndsWithSequential = !(*I)->isStructTy();
// Can we combine the two pointer arithmetics offsets?
if (EndsWithSequential) {
@@ -578,7 +578,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast
const Type *SrcElTy = StrippedPtrTy->getElementType();
const Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType();
- if (TD && isa<ArrayType>(SrcElTy) &&
+ if (TD && SrcElTy->isArrayTy() &&
TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()) ==
TD->getTypeAllocSize(ResElTy)) {
Value *Idx[2];
@@ -596,7 +596,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// (where tmp = 8*tmp2) into:
// getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast
- if (TD && isa<ArrayType>(SrcElTy) && ResElTy->isInteger(8)) {
+ if (TD && SrcElTy->isArrayTy() && ResElTy->isIntegerTy(8)) {
uint64_t ArrayEltSize =
TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType());
diff --git a/lib/Transforms/Instrumentation/ProfilingUtils.cpp b/lib/Transforms/Instrumentation/ProfilingUtils.cpp
index 3214c8c..8662a82 100644
--- a/lib/Transforms/Instrumentation/ProfilingUtils.cpp
+++ b/lib/Transforms/Instrumentation/ProfilingUtils.cpp
@@ -84,7 +84,7 @@ void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName,
AI = MainFn->arg_begin();
// If the program looked at argc, have it look at the return value of the
// init call instead.
- if (!AI->getType()->isInteger(32)) {
+ if (!AI->getType()->isIntegerTy(32)) {
Instruction::CastOps opcode;
if (!AI->use_empty()) {
opcode = CastInst::getCastOpcode(InitCall, true, AI->getType(), true);
diff --git a/lib/Transforms/Scalar/ABCD.cpp b/lib/Transforms/Scalar/ABCD.cpp
index cf5e8c0..ea8e5c3 100644
--- a/lib/Transforms/Scalar/ABCD.cpp
+++ b/lib/Transforms/Scalar/ABCD.cpp
@@ -505,7 +505,7 @@ void ABCD::executeABCD(Function &F) {
continue;
ICmpInst *ICI = dyn_cast<ICmpInst>(TI->getOperand(0));
- if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType()))
+ if (!ICI || !ICI->getOperand(0)->getType()->isIntegerTy())
continue;
createConstraintCmpInst(ICI, TI);
@@ -713,7 +713,7 @@ void ABCD::createConstraintCmpInst(ICmpInst *ICI, TerminatorInst *TI) {
Value *V_op1 = ICI->getOperand(0);
Value *V_op2 = ICI->getOperand(1);
- if (!isa<IntegerType>(V_op1->getType()))
+ if (!V_op1->getType()->isIntegerTy())
return;
Instruction *I_op1 = dyn_cast<Instruction>(V_op1);
diff --git a/lib/Transforms/Scalar/Android.mk b/lib/Transforms/Scalar/Android.mk
new file mode 100644
index 0000000..dea9b8f
--- /dev/null
+++ b/lib/Transforms/Scalar/Android.mk
@@ -0,0 +1,55 @@
+LOCAL_PATH:= $(call my-dir)
+
+transforms_scalar_SRC_FILES := \
+ ABCD.cpp \
+ ADCE.cpp \
+ BasicBlockPlacement.cpp \
+ CodeGenPrepare.cpp \
+ ConstantProp.cpp \
+ DCE.cpp \
+ DeadStoreElimination.cpp \
+ GEPSplitter.cpp \
+ GVN.cpp \
+ IndVarSimplify.cpp \
+ JumpThreading.cpp \
+ LICM.cpp \
+ LoopDeletion.cpp \
+ LoopIndexSplit.cpp \
+ LoopRotation.cpp \
+ LoopStrengthReduce.cpp \
+ LoopUnrollPass.cpp \
+ LoopUnswitch.cpp \
+ MemCpyOptimizer.cpp \
+ Reassociate.cpp \
+ Reg2Mem.cpp \
+ SCCP.cpp \
+ SCCVN.cpp \
+ Scalar.cpp \
+ ScalarReplAggregates.cpp \
+ SimplifyCFGPass.cpp \
+ SimplifyHalfPowrLibCalls.cpp \
+ SimplifyLibCalls.cpp \
+ TailDuplication.cpp \
+ TailRecursionElimination.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(transforms_scalar_SRC_FILES)
+LOCAL_MODULE:= libLLVMScalarOpts
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(transforms_scalar_SRC_FILES)
+LOCAL_MODULE:= libLLVMScalarOpts
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp
index fa60d3f..7ceda1f 100644
--- a/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -32,7 +32,6 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CallSite.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/PatternMatch.h"
@@ -40,9 +39,6 @@
using namespace llvm;
using namespace llvm::PatternMatch;
-static cl::opt<bool> FactorCommonPreds("split-critical-paths-tweak",
- cl::init(false), cl::Hidden);
-
namespace {
class CodeGenPrepare : public FunctionPass {
/// TLI - Keep a pointer of a TargetLowering to consult for determining
@@ -301,6 +297,70 @@ void CodeGenPrepare::EliminateMostlyEmptyBlock(BasicBlock *BB) {
DEBUG(dbgs() << "AFTER:\n" << *DestBB << "\n\n\n");
}
+/// FindReusablePredBB - Check all of the predecessors of the block DestPHI
+/// lives in to see if there is a block that we can reuse as a critical edge
+/// from TIBB.
+static BasicBlock *FindReusablePredBB(PHINode *DestPHI, BasicBlock *TIBB) {
+ BasicBlock *Dest = DestPHI->getParent();
+
+ /// TIPHIValues - This array is lazily computed to determine the values of
+ /// PHIs in Dest that TI would provide.
+ SmallVector<Value*, 32> TIPHIValues;
+
+ /// TIBBEntryNo - This is a cache to speed up pred queries for TIBB.
+ unsigned TIBBEntryNo = 0;
+
+ // Check to see if Dest has any blocks that can be used as a split edge for
+ // this terminator.
+ for (unsigned pi = 0, e = DestPHI->getNumIncomingValues(); pi != e; ++pi) {
+ BasicBlock *Pred = DestPHI->getIncomingBlock(pi);
+ // To be usable, the pred has to end with an uncond branch to the dest.
+ BranchInst *PredBr = dyn_cast<BranchInst>(Pred->getTerminator());
+ if (!PredBr || !PredBr->isUnconditional())
+ continue;
+ // Must be empty other than the branch and debug info.
+ BasicBlock::iterator I = Pred->begin();
+ while (isa<DbgInfoIntrinsic>(I))
+ I++;
+ if (&*I != PredBr)
+ continue;
+ // Cannot be the entry block; its label does not get emitted.
+ if (Pred == &Dest->getParent()->getEntryBlock())
+ continue;
+
+ // Finally, since we know that Dest has phi nodes in it, we have to make
+ // sure that jumping to Pred will have the same effect as going to Dest in
+ // terms of PHI values.
+ PHINode *PN;
+ unsigned PHINo = 0;
+ unsigned PredEntryNo = pi;
+
+ bool FoundMatch = true;
+ for (BasicBlock::iterator I = Dest->begin();
+ (PN = dyn_cast<PHINode>(I)); ++I, ++PHINo) {
+ if (PHINo == TIPHIValues.size()) {
+ if (PN->getIncomingBlock(TIBBEntryNo) != TIBB)
+ TIBBEntryNo = PN->getBasicBlockIndex(TIBB);
+ TIPHIValues.push_back(PN->getIncomingValue(TIBBEntryNo));
+ }
+
+ // If the PHI entry doesn't work, we can't use this pred.
+ if (PN->getIncomingBlock(PredEntryNo) != Pred)
+ PredEntryNo = PN->getBasicBlockIndex(Pred);
+
+ if (TIPHIValues[PHINo] != PN->getIncomingValue(PredEntryNo)) {
+ FoundMatch = false;
+ break;
+ }
+ }
+
+ // If we found a workable predecessor, change TI to branch to Succ.
+ if (FoundMatch)
+ return Pred;
+ }
+ return 0;
+}
+
/// SplitEdgeNicely - Split the critical edge from TI to its specified
/// successor if it will improve codegen. We only do this if the successor has
@@ -315,13 +375,12 @@ static void SplitEdgeNicely(TerminatorInst *TI, unsigned SuccNum,
BasicBlock *Dest = TI->getSuccessor(SuccNum);
assert(isa<PHINode>(Dest->begin()) &&
"This should only be called if Dest has a PHI!");
+ PHINode *DestPHI = cast<PHINode>(Dest->begin());
// Do not split edges to EH landing pads.
- if (InvokeInst *Invoke = dyn_cast<InvokeInst>(TI)) {
+ if (InvokeInst *Invoke = dyn_cast<InvokeInst>(TI))
if (Invoke->getSuccessor(1) == Dest)
return;
- }
-
// As a hack, never split backedges of loops. Even though the copy for any
// PHIs inserted on the backedge would be dead for exits from the loop, we
@@ -329,92 +388,16 @@ static void SplitEdgeNicely(TerminatorInst *TI, unsigned SuccNum,
if (BackEdges.count(std::make_pair(TIBB, Dest)))
return;
- if (!FactorCommonPreds) {
- /// TIPHIValues - This array is lazily computed to determine the values of
- /// PHIs in Dest that TI would provide.
- SmallVector<Value*, 32> TIPHIValues;
-
- // Check to see if Dest has any blocks that can be used as a split edge for
- // this terminator.
- for (pred_iterator PI = pred_begin(Dest), E = pred_end(Dest); PI != E; ++PI) {
- BasicBlock *Pred = *PI;
- // To be usable, the pred has to end with an uncond branch to the dest.
- BranchInst *PredBr = dyn_cast<BranchInst>(Pred->getTerminator());
- if (!PredBr || !PredBr->isUnconditional())
- continue;
- // Must be empty other than the branch and debug info.
- BasicBlock::iterator I = Pred->begin();
- while (isa<DbgInfoIntrinsic>(I))
- I++;
- if (dyn_cast<Instruction>(I) != PredBr)
- continue;
- // Cannot be the entry block; its label does not get emitted.
- if (Pred == &(Dest->getParent()->getEntryBlock()))
- continue;
-
- // Finally, since we know that Dest has phi nodes in it, we have to make
- // sure that jumping to Pred will have the same effect as going to Dest in
- // terms of PHI values.
- PHINode *PN;
- unsigned PHINo = 0;
- bool FoundMatch = true;
- for (BasicBlock::iterator I = Dest->begin();
- (PN = dyn_cast<PHINode>(I)); ++I, ++PHINo) {
- if (PHINo == TIPHIValues.size())
- TIPHIValues.push_back(PN->getIncomingValueForBlock(TIBB));
-
- // If the PHI entry doesn't work, we can't use this pred.
- if (TIPHIValues[PHINo] != PN->getIncomingValueForBlock(Pred)) {
- FoundMatch = false;
- break;
- }
- }
-
- // If we found a workable predecessor, change TI to branch to Succ.
- if (FoundMatch) {
- ProfileInfo *PFI = P->getAnalysisIfAvailable<ProfileInfo>();
- if (PFI)
- PFI->splitEdge(TIBB, Dest, Pred);
- Dest->removePredecessor(TIBB);
- TI->setSuccessor(SuccNum, Pred);
- return;
- }
- }
-
- SplitCriticalEdge(TI, SuccNum, P, true);
+ if (BasicBlock *ReuseBB = FindReusablePredBB(DestPHI, TIBB)) {
+ ProfileInfo *PFI = P->getAnalysisIfAvailable<ProfileInfo>();
+ if (PFI)
+ PFI->splitEdge(TIBB, Dest, ReuseBB);
+ Dest->removePredecessor(TIBB);
+ TI->setSuccessor(SuccNum, ReuseBB);
return;
}
- PHINode *PN;
- SmallVector<Value*, 8> TIPHIValues;
- for (BasicBlock::iterator I = Dest->begin();
- (PN = dyn_cast<PHINode>(I)); ++I)
- TIPHIValues.push_back(PN->getIncomingValueForBlock(TIBB));
-
- SmallVector<BasicBlock*, 8> IdenticalPreds;
- for (pred_iterator PI = pred_begin(Dest), E = pred_end(Dest); PI != E; ++PI) {
- BasicBlock *Pred = *PI;
- if (BackEdges.count(std::make_pair(Pred, Dest)))
- continue;
- if (PI == TIBB)
- IdenticalPreds.push_back(Pred);
- else {
- bool Identical = true;
- unsigned PHINo = 0;
- for (BasicBlock::iterator I = Dest->begin();
- (PN = dyn_cast<PHINode>(I)); ++I, ++PHINo)
- if (TIPHIValues[PHINo] != PN->getIncomingValueForBlock(Pred)) {
- Identical = false;
- break;
- }
- if (Identical)
- IdenticalPreds.push_back(Pred);
- }
- }
-
- assert(!IdenticalPreds.empty());
- SplitBlockPredecessors(Dest, &IdenticalPreds[0], IdenticalPreds.size(),
- ".critedge", P);
+ SplitCriticalEdge(TI, SuccNum, P, true);
}
@@ -629,7 +612,7 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
// we'd end up sinking both muls.
if (AddrMode.BaseReg) {
Value *V = AddrMode.BaseReg;
- if (isa<PointerType>(V->getType()))
+ if (V->getType()->isPointerTy())
V = new PtrToIntInst(V, IntPtrTy, "sunkaddr", InsertPt);
if (V->getType() != IntPtrTy)
V = CastInst::CreateIntegerCast(V, IntPtrTy, /*isSigned=*/true,
@@ -642,7 +625,7 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
Value *V = AddrMode.ScaledReg;
if (V->getType() == IntPtrTy) {
// done.
- } else if (isa<PointerType>(V->getType())) {
+ } else if (V->getType()->isPointerTy()) {
V = new PtrToIntInst(V, IntPtrTy, "sunkaddr", InsertPt);
} else if (cast<IntegerType>(IntPtrTy)->getBitWidth() <
cast<IntegerType>(V->getType())->getBitWidth()) {
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 320afa1..09c01d3 100644
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -44,8 +44,14 @@ namespace {
virtual bool runOnFunction(Function &F) {
bool Changed = false;
+
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- Changed |= runOnBasicBlock(*I);
+ // Only check non-dead blocks. Dead blocks may have strange pointer
+ // cycles that will confuse alias analysis.
+ if (DT.isReachableFromEntry(I))
+ Changed |= runOnBasicBlock(*I);
return Changed;
}
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index 80e0027..fcb802a 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -662,11 +662,10 @@ namespace {
bool runOnFunction(Function &F);
public:
static char ID; // Pass identification, replacement for typeid
- explicit GVN(bool nopre = false, bool noloads = false)
- : FunctionPass(&ID), NoPRE(nopre), NoLoads(noloads), MD(0) { }
+ explicit GVN(bool noloads = false)
+ : FunctionPass(&ID), NoLoads(noloads), MD(0) { }
private:
- bool NoPRE;
bool NoLoads;
MemoryDependenceAnalysis *MD;
DominatorTree *DT;
@@ -674,6 +673,9 @@ namespace {
ValueTable VN;
DenseMap<BasicBlock*, ValueNumberScope*> localAvail;
+ // List of critical edges to be split between iterations.
+ SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit;
+
// This transformation requires dominator postdominator info
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DominatorTree>();
@@ -701,14 +703,15 @@ namespace {
Value *lookupNumber(BasicBlock *BB, uint32_t num);
void cleanupGlobalSets();
void verifyRemoved(const Instruction *I) const;
+ bool splitCriticalEdges();
};
char GVN::ID = 0;
}
// createGVNPass - The public interface to this file...
-FunctionPass *llvm::createGVNPass(bool NoPRE, bool NoLoads) {
- return new GVN(NoPRE, NoLoads);
+FunctionPass *llvm::createGVNPass(bool NoLoads) {
+ return new GVN(NoLoads);
}
static RegisterPass<GVN> X("gvn",
@@ -836,9 +839,9 @@ static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal,
const TargetData &TD) {
// If the loaded or stored value is an first class array or struct, don't try
// to transform them. We need to be able to bitcast to integer.
- if (isa<StructType>(LoadTy) || isa<ArrayType>(LoadTy) ||
- isa<StructType>(StoredVal->getType()) ||
- isa<ArrayType>(StoredVal->getType()))
+ if (LoadTy->isStructTy() || LoadTy->isArrayTy() ||
+ StoredVal->getType()->isStructTy() ||
+ StoredVal->getType()->isArrayTy())
return false;
// The store has to be at least as big as the load.
@@ -870,26 +873,26 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal,
// If the store and reload are the same size, we can always reuse it.
if (StoreSize == LoadSize) {
- if (isa<PointerType>(StoredValTy) && isa<PointerType>(LoadedTy)) {
+ if (StoredValTy->isPointerTy() && LoadedTy->isPointerTy()) {
// Pointer to Pointer -> use bitcast.
return new BitCastInst(StoredVal, LoadedTy, "", InsertPt);
}
// Convert source pointers to integers, which can be bitcast.
- if (isa<PointerType>(StoredValTy)) {
+ if (StoredValTy->isPointerTy()) {
StoredValTy = TD.getIntPtrType(StoredValTy->getContext());
StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt);
}
const Type *TypeToCastTo = LoadedTy;
- if (isa<PointerType>(TypeToCastTo))
+ if (TypeToCastTo->isPointerTy())
TypeToCastTo = TD.getIntPtrType(StoredValTy->getContext());
if (StoredValTy != TypeToCastTo)
StoredVal = new BitCastInst(StoredVal, TypeToCastTo, "", InsertPt);
// Cast to pointer if the load needs a pointer type.
- if (isa<PointerType>(LoadedTy))
+ if (LoadedTy->isPointerTy())
StoredVal = new IntToPtrInst(StoredVal, LoadedTy, "", InsertPt);
return StoredVal;
@@ -901,13 +904,13 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal,
assert(StoreSize >= LoadSize && "CanCoerceMustAliasedValueToLoad fail");
// Convert source pointers to integers, which can be manipulated.
- if (isa<PointerType>(StoredValTy)) {
+ if (StoredValTy->isPointerTy()) {
StoredValTy = TD.getIntPtrType(StoredValTy->getContext());
StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt);
}
// Convert vectors and fp to integer, which can be manipulated.
- if (!isa<IntegerType>(StoredValTy)) {
+ if (!StoredValTy->isIntegerTy()) {
StoredValTy = IntegerType::get(StoredValTy->getContext(), StoreSize);
StoredVal = new BitCastInst(StoredVal, StoredValTy, "", InsertPt);
}
@@ -927,7 +930,7 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal,
return StoredVal;
// If the result is a pointer, inttoptr.
- if (isa<PointerType>(LoadedTy))
+ if (LoadedTy->isPointerTy())
return new IntToPtrInst(StoredVal, LoadedTy, "inttoptr", InsertPt);
// Otherwise, bitcast.
@@ -989,7 +992,7 @@ static int AnalyzeLoadFromClobberingWrite(const Type *LoadTy, Value *LoadPtr,
const TargetData &TD) {
// If the loaded or stored value is an first class array or struct, don't try
// to transform them. We need to be able to bitcast to integer.
- if (isa<StructType>(LoadTy) || isa<ArrayType>(LoadTy))
+ if (LoadTy->isStructTy() || LoadTy->isArrayTy())
return -1;
int64_t StoreOffset = 0, LoadOffset = 0;
@@ -1064,8 +1067,8 @@ static int AnalyzeLoadFromClobberingStore(const Type *LoadTy, Value *LoadPtr,
StoreInst *DepSI,
const TargetData &TD) {
// Cannot handle reading from store of first-class aggregate yet.
- if (isa<StructType>(DepSI->getOperand(0)->getType()) ||
- isa<ArrayType>(DepSI->getOperand(0)->getType()))
+ if (DepSI->getOperand(0)->getType()->isStructTy() ||
+ DepSI->getOperand(0)->getType()->isArrayTy())
return -1;
Value *StorePtr = DepSI->getPointerOperand();
@@ -1136,9 +1139,9 @@ static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset,
// Compute which bits of the stored value are being used by the load. Convert
// to an integer type to start with.
- if (isa<PointerType>(SrcVal->getType()))
+ if (SrcVal->getType()->isPointerTy())
SrcVal = Builder.CreatePtrToInt(SrcVal, TD.getIntPtrType(Ctx), "tmp");
- if (!isa<IntegerType>(SrcVal->getType()))
+ if (!SrcVal->getType()->isIntegerTy())
SrcVal = Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize*8),
"tmp");
@@ -1323,7 +1326,7 @@ static Value *ConstructSSAForLoadSet(LoadInst *LI,
Value *V = SSAUpdate.GetValueInMiddleOfBlock(LI->getParent());
// If new PHI nodes were created, notify alias analysis.
- if (isa<PointerType>(V->getType()))
+ if (V->getType()->isPointerTy())
for (unsigned i = 0, e = NewPHIs.size(); i != e; ++i)
AA->copyValue(LI, NewPHIs[i]);
@@ -1491,8 +1494,9 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
if (isa<PHINode>(V))
V->takeName(LI);
- if (isa<PointerType>(V->getType()))
+ if (V->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(V);
+ VN.erase(LI);
toErase.push_back(LI);
NumGVNLoad++;
return true;
@@ -1538,11 +1542,13 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
// at least one of the values is LI. Since this means that we won't be able
// to eliminate LI even if we insert uses in the other predecessors, we will
// end up increasing code size. Reject this by scanning for LI.
- if (!EnableFullLoadPRE) {
- for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i)
- if (ValuesPerBlock[i].isSimpleValue() &&
- ValuesPerBlock[i].getSimpleValue() == LI)
+ for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) {
+ if (ValuesPerBlock[i].isSimpleValue() &&
+ ValuesPerBlock[i].getSimpleValue() == LI) {
+ // Skip cases where LI is the only definition, even for EnableFullLoadPRE.
+ if (!EnableFullLoadPRE || e == 1)
return false;
+ }
}
// FIXME: It is extremely unclear what this loop is doing, other than
@@ -1576,6 +1582,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
for (unsigned i = 0, e = UnavailableBlocks.size(); i != e; ++i)
FullyAvailableBlocks[UnavailableBlocks[i]] = false;
+ bool NeedToSplitEdges = false;
for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB);
PI != E; ++PI) {
BasicBlock *Pred = *PI;
@@ -1583,13 +1590,20 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
continue;
}
PredLoads[Pred] = 0;
- // We don't currently handle critical edges :(
+
if (Pred->getTerminator()->getNumSuccessors() != 1) {
- DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '"
- << Pred->getName() << "': " << *LI << '\n');
- return false;
+ if (isa<IndirectBrInst>(Pred->getTerminator())) {
+ DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
+ << Pred->getName() << "': " << *LI << '\n');
+ return false;
+ }
+ unsigned SuccNum = GetSuccessorNumber(Pred, LoadBB);
+ toSplit.push_back(std::make_pair(Pred->getTerminator(), SuccNum));
+ NeedToSplitEdges = true;
}
}
+ if (NeedToSplitEdges)
+ return false;
// Decide whether PRE is profitable for this load.
unsigned NumUnavailablePreds = PredLoads.size();
@@ -1623,13 +1637,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
LoadPtr = Address.PHITranslateWithInsertion(LoadBB, UnavailablePred,
*DT, NewInsts);
} else {
- Address.PHITranslateValue(LoadBB, UnavailablePred);
+ Address.PHITranslateValue(LoadBB, UnavailablePred, DT);
LoadPtr = Address.getAddr();
-
- // Make sure the value is live in the predecessor.
- if (Instruction *Inst = dyn_cast_or_null<Instruction>(LoadPtr))
- if (!DT->dominates(Inst->getParent(), UnavailablePred))
- LoadPtr = 0;
}
// If we couldn't find or insert a computation of this phi translated value,
@@ -1697,6 +1706,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
// Add the newly created load.
ValuesPerBlock.push_back(AvailableValueInBlock::get(UnavailablePred,
NewLoad));
+ MD->invalidateCachedPointerInfo(LoadPtr);
+ DEBUG(dbgs() << "GVN INSERTED " << *NewLoad << '\n');
}
// Perform PHI construction.
@@ -1705,8 +1716,9 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
LI->replaceAllUsesWith(V);
if (isa<PHINode>(V))
V->takeName(LI);
- if (isa<PointerType>(V->getType()))
+ if (V->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(V);
+ VN.erase(LI);
toErase.push_back(LI);
NumPRELoad++;
return true;
@@ -1765,8 +1777,9 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
// Replace the load!
L->replaceAllUsesWith(AvailVal);
- if (isa<PointerType>(AvailVal->getType()))
+ if (AvailVal->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(AvailVal);
+ VN.erase(L);
toErase.push_back(L);
NumGVNLoad++;
return true;
@@ -1810,8 +1823,9 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
// Remove it!
L->replaceAllUsesWith(StoredVal);
- if (isa<PointerType>(StoredVal->getType()))
+ if (StoredVal->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(StoredVal);
+ VN.erase(L);
toErase.push_back(L);
NumGVNLoad++;
return true;
@@ -1839,8 +1853,9 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
// Remove it!
L->replaceAllUsesWith(AvailableVal);
- if (isa<PointerType>(DepLI->getType()))
+ if (DepLI->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(DepLI);
+ VN.erase(L);
toErase.push_back(L);
NumGVNLoad++;
return true;
@@ -1851,6 +1866,7 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
// intervening stores, for example.
if (isa<AllocaInst>(DepInst) || isMalloc(DepInst)) {
L->replaceAllUsesWith(UndefValue::get(L->getType()));
+ VN.erase(L);
toErase.push_back(L);
NumGVNLoad++;
return true;
@@ -1861,6 +1877,7 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) {
if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(DepInst)) {
if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
L->replaceAllUsesWith(UndefValue::get(L->getType()));
+ VN.erase(L);
toErase.push_back(L);
NumGVNLoad++;
return true;
@@ -1891,6 +1908,10 @@ Value *GVN::lookupNumber(BasicBlock *BB, uint32_t num) {
/// by inserting it into the appropriate sets
bool GVN::processInstruction(Instruction *I,
SmallVectorImpl<Instruction*> &toErase) {
+ // Ignore dbg info intrinsics.
+ if (isa<DbgInfoIntrinsic>(I))
+ return false;
+
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
bool Changed = processLoad(LI, toErase);
@@ -1939,7 +1960,7 @@ bool GVN::processInstruction(Instruction *I,
if (constVal) {
p->replaceAllUsesWith(constVal);
- if (MD && isa<PointerType>(constVal->getType()))
+ if (MD && constVal->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(constVal);
VN.erase(p);
@@ -1960,7 +1981,7 @@ bool GVN::processInstruction(Instruction *I,
// Remove it!
VN.erase(I);
I->replaceAllUsesWith(repl);
- if (MD && isa<PointerType>(repl->getType()))
+ if (MD && repl->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(repl);
toErase.push_back(I);
return true;
@@ -2000,6 +2021,8 @@ bool GVN::runOnFunction(Function& F) {
while (ShouldContinue) {
DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n");
ShouldContinue = iterateOnFunction(F);
+ if (splitCriticalEdges())
+ ShouldContinue = true;
Changed |= ShouldContinue;
++Iteration;
}
@@ -2066,7 +2089,6 @@ bool GVN::processBlock(BasicBlock *BB) {
/// control flow patterns and attempts to perform simple PRE at the join point.
bool GVN::performPRE(Function &F) {
bool Changed = false;
- SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit;
DenseMap<BasicBlock*, Value*> predMap;
for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()),
DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) {
@@ -2137,14 +2159,7 @@ bool GVN::performPRE(Function &F) {
// We can't do PRE safely on a critical edge, so instead we schedule
// the edge to be split and perform the PRE the next time we iterate
// on the function.
- unsigned SuccNum = 0;
- for (unsigned i = 0, e = PREPred->getTerminator()->getNumSuccessors();
- i != e; ++i)
- if (PREPred->getTerminator()->getSuccessor(i) == CurrentBlock) {
- SuccNum = i;
- break;
- }
-
+ unsigned SuccNum = GetSuccessorNumber(PREPred, CurrentBlock);
if (isCriticalEdge(PREPred->getTerminator(), SuccNum)) {
toSplit.push_back(std::make_pair(PREPred->getTerminator(), SuccNum));
continue;
@@ -2200,7 +2215,7 @@ bool GVN::performPRE(Function &F) {
localAvail[CurrentBlock]->table[ValNo] = Phi;
CurInst->replaceAllUsesWith(Phi);
- if (MD && isa<PointerType>(Phi->getType()))
+ if (MD && Phi->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(Phi);
VN.erase(CurInst);
@@ -2212,11 +2227,23 @@ bool GVN::performPRE(Function &F) {
}
}
- for (SmallVector<std::pair<TerminatorInst*, unsigned>, 4>::iterator
- I = toSplit.begin(), E = toSplit.end(); I != E; ++I)
- SplitCriticalEdge(I->first, I->second, this);
+ if (splitCriticalEdges())
+ Changed = true;
+
+ return Changed;
+}
- return Changed || toSplit.size();
+/// splitCriticalEdges - Split critical edges found during the previous
+/// iteration that may enable further optimization.
+bool GVN::splitCriticalEdges() {
+ if (toSplit.empty())
+ return false;
+ do {
+ std::pair<TerminatorInst*, unsigned> Edge = toSplit.pop_back_val();
+ SplitCriticalEdge(Edge.first, Edge.second, this);
+ } while (!toSplit.empty());
+ if (MD) MD->invalidateCachedPredecessors();
+ return true;
}
/// iterateOnFunction - Executes one iteration of GVN
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index c54f596..cb563c3 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -103,11 +103,9 @@ namespace {
BasicBlock *ExitingBlock,
BranchInst *BI,
SCEVExpander &Rewriter);
- void RewriteLoopExitValues(Loop *L, const SCEV *BackedgeTakenCount,
- SCEVExpander &Rewriter);
+ void RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter);
- void RewriteIVExpressions(Loop *L, const Type *LargestType,
- SCEVExpander &Rewriter);
+ void RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter);
void SinkUnusedInvariants(Loop *L);
@@ -190,7 +188,7 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
ICmpInst *Cond = new ICmpInst(BI, Opcode, CmpIndVar, ExitCnt, "exitcond");
- Instruction *OrigCond = cast<Instruction>(BI->getCondition());
+ Value *OrigCond = BI->getCondition();
// It's tempting to use replaceAllUsesWith here to fully replace the old
// comparison, but that's not immediately safe, since users of the old
// comparison may not be dominated by the new comparison. Instead, just
@@ -215,7 +213,6 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
/// able to brute-force evaluate arbitrary instructions as long as they have
/// constant operands at the beginning of the loop.
void IndVarSimplify::RewriteLoopExitValues(Loop *L,
- const SCEV *BackedgeTakenCount,
SCEVExpander &Rewriter) {
// Verify the input to the pass in already in LCSSA form.
assert(L->isLCSSAForm());
@@ -241,15 +238,24 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L,
while ((PN = dyn_cast<PHINode>(BBI++))) {
if (PN->use_empty())
continue; // dead use, don't replace it
+
+ // SCEV only supports integer expressions for now.
+ if (!PN->getType()->isIntegerTy() && !PN->getType()->isPointerTy())
+ continue;
+
+ // It's necessary to tell ScalarEvolution about this explicitly so that
+ // it can walk the def-use list and forget all SCEVs, as it may not be
+ // watching the PHI itself. Once the new exit value is in place, there
+ // may not be a def-use connection between the loop and every instruction
+ // which got a SCEVAddRecExpr for that loop.
+ SE->forgetValue(PN);
+
// Iterate over all of the values in all the PHI nodes.
for (unsigned i = 0; i != NumPreds; ++i) {
// If the value being merged in is not integer or is not defined
// in the loop, skip it.
Value *InVal = PN->getIncomingValue(i);
- if (!isa<Instruction>(InVal) ||
- // SCEV only supports integer expressions for now.
- (!isa<IntegerType>(InVal->getType()) &&
- !isa<PointerType>(InVal->getType())))
+ if (!isa<Instruction>(InVal))
continue;
// If this pred is for a subloop, not L itself, skip it.
@@ -349,7 +355,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
// the current expressions.
//
if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount))
- RewriteLoopExitValues(L, BackedgeTakenCount, Rewriter);
+ RewriteLoopExitValues(L, Rewriter);
// Compute the type of the largest recurrence expression, and decide whether
// a canonical induction variable should be inserted.
@@ -364,37 +370,32 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
if (ExitingBlock)
NeedCannIV = true;
}
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *Stride = IU->StrideOrder[i];
- const Type *Ty = SE->getEffectiveSCEVType(Stride->getType());
+ for (IVUsers::const_iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
+ const Type *Ty =
+ SE->getEffectiveSCEVType(I->getOperandValToReplace()->getType());
if (!LargestType ||
SE->getTypeSizeInBits(Ty) >
SE->getTypeSizeInBits(LargestType))
LargestType = Ty;
-
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
-
- if (!SI->second->Users.empty())
- NeedCannIV = true;
+ NeedCannIV = true;
}
// Now that we know the largest of the induction variable expressions
// in this loop, insert a canonical induction variable of the largest size.
Value *IndVar = 0;
if (NeedCannIV) {
- // Check to see if the loop already has a canonical-looking induction
- // variable. If one is present and it's wider than the planned canonical
- // induction variable, temporarily remove it, so that the Rewriter
- // doesn't attempt to reuse it.
- PHINode *OldCannIV = L->getCanonicalInductionVariable();
- if (OldCannIV) {
+ // Check to see if the loop already has any canonical-looking induction
+ // variables. If any are present and wider than the planned canonical
+ // induction variable, temporarily remove them, so that the Rewriter
+ // doesn't attempt to reuse them.
+ SmallVector<PHINode *, 2> OldCannIVs;
+ while (PHINode *OldCannIV = L->getCanonicalInductionVariable()) {
if (SE->getTypeSizeInBits(OldCannIV->getType()) >
SE->getTypeSizeInBits(LargestType))
OldCannIV->removeFromParent();
else
- OldCannIV = 0;
+ break;
+ OldCannIVs.push_back(OldCannIV);
}
IndVar = Rewriter.getOrInsertCanonicalInductionVariable(L, LargestType);
@@ -404,17 +405,21 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
DEBUG(dbgs() << "INDVARS: New CanIV: " << *IndVar << '\n');
// Now that the official induction variable is established, reinsert
- // the old canonical-looking variable after it so that the IR remains
- // consistent. It will be deleted as part of the dead-PHI deletion at
+ // any old canonical-looking variables after it so that the IR remains
+ // consistent. They will be deleted as part of the dead-PHI deletion at
// the end of the pass.
- if (OldCannIV)
- OldCannIV->insertAfter(cast<Instruction>(IndVar));
+ while (!OldCannIVs.empty()) {
+ PHINode *OldCannIV = OldCannIVs.pop_back_val();
+ OldCannIV->insertBefore(L->getHeader()->getFirstNonPHI());
+ }
}
// If we have a trip count expression, rewrite the loop's exit condition
// using it. We can currently only handle loops with a single exit.
ICmpInst *NewICmp = 0;
- if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount) && ExitingBlock) {
+ if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount) &&
+ !BackedgeTakenCount->isZero() &&
+ ExitingBlock) {
assert(NeedCannIV &&
"LinearFunctionTestReplace requires a canonical induction variable");
// Can't rewrite non-branch yet.
@@ -424,7 +429,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
}
// Rewrite IV-derived expressions. Clears the rewriter cache.
- RewriteIVExpressions(L, LargestType, Rewriter);
+ RewriteIVExpressions(L, Rewriter);
// The Rewriter may not be used from this point on.
@@ -444,8 +449,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
return Changed;
}
-void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
- SCEVExpander &Rewriter) {
+void IndVarSimplify::RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter) {
SmallVector<WeakVH, 16> DeadInsts;
// Rewrite all induction variable expressions in terms of the canonical
@@ -455,72 +459,64 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
// add the offsets to the primary induction variable and cast, avoiding
// the need for the code evaluation methods to insert induction variables
// of different sizes.
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *Stride = IU->StrideOrder[i];
-
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- ilist<IVStrideUse> &List = SI->second->Users;
- for (ilist<IVStrideUse>::iterator UI = List.begin(),
- E = List.end(); UI != E; ++UI) {
- Value *Op = UI->getOperandValToReplace();
- const Type *UseTy = Op->getType();
- Instruction *User = UI->getUser();
-
- // 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;
- }
+ for (IVUsers::iterator UI = IU->begin(), E = IU->end(); UI != E; ++UI) {
+ const SCEV *Stride = UI->getStride();
+ Value *Op = UI->getOperandValToReplace();
+ const Type *UseTy = Op->getType();
+ Instruction *User = UI->getUser();
+
+ // 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
- // currently can only reduce affine polynomials. For now just disable
- // indvar subst on anything more complex than an affine addrec, unless
- // it can be expanded to a trivial value.
- if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
- continue;
+ // 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
+ // currently can only reduce affine polynomials. For now just disable
+ // indvar subst on anything more complex than an affine addrec, unless
+ // it can be expanded to a trivial value.
+ if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
+ continue;
- // Determine the insertion point for this user. By default, insert
- // immediately before the user. The SCEVExpander class will automatically
- // hoist loop invariants out of the loop. For PHI nodes, there may be
- // multiple uses, so compute the nearest common dominator for the
- // incoming blocks.
- Instruction *InsertPt = User;
- if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
- for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
- if (PHI->getIncomingValue(i) == Op) {
- if (InsertPt == User)
- InsertPt = PHI->getIncomingBlock(i)->getTerminator();
- else
- InsertPt =
- DT->findNearestCommonDominator(InsertPt->getParent(),
- PHI->getIncomingBlock(i))
- ->getTerminator();
- }
-
- // Now expand it into actual Instructions and patch it into place.
- Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
-
- // Patch the new value into place.
- if (Op->hasName())
- NewVal->takeName(Op);
- User->replaceUsesOfWith(Op, NewVal);
- UI->setOperandValToReplace(NewVal);
- DEBUG(dbgs() << "INDVARS: Rewrote IV '" << *AR << "' " << *Op << '\n'
- << " into = " << *NewVal << "\n");
- ++NumRemoved;
- Changed = true;
-
- // The old value may be dead now.
- DeadInsts.push_back(Op);
- }
+ // Determine the insertion point for this user. By default, insert
+ // immediately before the user. The SCEVExpander class will automatically
+ // hoist loop invariants out of the loop. For PHI nodes, there may be
+ // multiple uses, so compute the nearest common dominator for the
+ // incoming blocks.
+ Instruction *InsertPt = User;
+ if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
+ for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
+ if (PHI->getIncomingValue(i) == Op) {
+ if (InsertPt == User)
+ InsertPt = PHI->getIncomingBlock(i)->getTerminator();
+ else
+ InsertPt =
+ DT->findNearestCommonDominator(InsertPt->getParent(),
+ PHI->getIncomingBlock(i))
+ ->getTerminator();
+ }
+
+ // Now expand it into actual Instructions and patch it into place.
+ Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
+
+ // Patch the new value into place.
+ if (Op->hasName())
+ NewVal->takeName(Op);
+ User->replaceUsesOfWith(Op, NewVal);
+ UI->setOperandValToReplace(NewVal);
+ DEBUG(dbgs() << "INDVARS: Rewrote IV '" << *AR << "' " << *Op << '\n'
+ << " into = " << *NewVal << "\n");
+ ++NumRemoved;
+ Changed = true;
+
+ // The old value may be dead now.
+ DeadInsts.push_back(Op);
}
// Clear the rewriter cache, because values that are in the rewriter's cache
@@ -598,8 +594,8 @@ void IndVarSimplify::SinkUnusedInvariants(Loop *L) {
}
}
-/// Return true if it is OK to use SIToFPInst for an inducation variable
-/// with given inital and exit values.
+/// Return true if it is OK to use SIToFPInst for an induction variable
+/// with given initial and exit values.
static bool useSIToFPInst(ConstantFP &InitV, ConstantFP &ExitV,
uint64_t intIV, uint64_t intEV) {
@@ -652,7 +648,7 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH) {
if (!convertToInt(InitValue->getValueAPF(), &newInitValue))
return;
- // Check IV increment. Reject this PH if increement operation is not
+ // Check IV increment. Reject this PH if increment operation is not
// an add or increment value can not be represented by an integer.
BinaryOperator *Incr =
dyn_cast<BinaryOperator>(PH->getIncomingValue(BackEdge));
@@ -688,7 +684,7 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH) {
if (BI->getCondition() != EC) return;
}
- // Find exit value. If exit value can not be represented as an interger then
+ // Find exit value. If exit value can not be represented as an integer then
// do not handle this floating point PH.
ConstantFP *EV = NULL;
unsigned EVIndex = 1;
@@ -750,11 +746,11 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH) {
ICmpInst *NewEC = new ICmpInst(EC->getParent()->getTerminator(),
NewPred, LHS, RHS, EC->getName());
- // In the following deltions, PH may become dead and may be deleted.
+ // In the following deletions, PH may become dead and may be deleted.
// Use a WeakVH to observe whether this happens.
WeakVH WeakPH = PH;
- // Delete old, floating point, exit comparision instruction.
+ // Delete old, floating point, exit comparison instruction.
NewEC->takeName(EC);
EC->replaceAllUsesWith(NewEC);
RecursivelyDeleteTriviallyDeadInstructions(EC);
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp
index 3eff3d8..a6489ec 100644
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -201,7 +201,7 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB) {
if (isa<DbgInfoIntrinsic>(I)) continue;
// If this is a pointer->pointer bitcast, it is free.
- if (isa<BitCastInst>(I) && isa<PointerType>(I->getType()))
+ if (isa<BitCastInst>(I) && I->getType()->isPointerTy())
continue;
// All other instructions count for at least one unit.
@@ -214,7 +214,7 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB) {
if (const CallInst *CI = dyn_cast<CallInst>(I)) {
if (!isa<IntrinsicInst>(CI))
Size += 3;
- else if (!isa<VectorType>(CI->getType()))
+ else if (!CI->getType()->isVectorTy())
Size += 1;
}
}
@@ -336,13 +336,18 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){
else
InterestingVal = ConstantInt::getFalse(I->getContext());
- // Scan for the sentinel.
+ // Scan for the sentinel. If we find an undef, force it to the
+ // interesting value: x|undef -> true and x&undef -> false.
for (unsigned i = 0, e = LHSVals.size(); i != e; ++i)
- if (LHSVals[i].first == InterestingVal || LHSVals[i].first == 0)
+ if (LHSVals[i].first == InterestingVal || LHSVals[i].first == 0) {
Result.push_back(LHSVals[i]);
+ Result.back().first = InterestingVal;
+ }
for (unsigned i = 0, e = RHSVals.size(); i != e; ++i)
- if (RHSVals[i].first == InterestingVal || RHSVals[i].first == 0)
+ if (RHSVals[i].first == InterestingVal || RHSVals[i].first == 0) {
Result.push_back(RHSVals[i]);
+ Result.back().first = InterestingVal;
+ }
return !Result.empty();
}
@@ -400,7 +405,7 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){
// If comparing a live-in value against a constant, see if we know the
// live-in value on any predecessors.
if (LVI && isa<Constant>(Cmp->getOperand(1)) &&
- Cmp->getType()->isInteger() && // Not vector compare.
+ Cmp->getType()->isIntegerTy() && // Not vector compare.
(!isa<Instruction>(Cmp->getOperand(0)) ||
cast<Instruction>(Cmp->getOperand(0))->getParent() != BB)) {
Constant *RHSCst = cast<Constant>(Cmp->getOperand(1));
diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp
index 81f9ae6..d7ace34 100644
--- a/lib/Transforms/Scalar/LICM.cpp
+++ b/lib/Transforms/Scalar/LICM.cpp
@@ -678,7 +678,7 @@ void LICM::PromoteValuesInLoop() {
// If we are promoting a pointer value, update alias information for the
// inserted load.
Value *LoadValue = 0;
- if (isa<PointerType>(cast<PointerType>(Ptr->getType())->getElementType())) {
+ if (cast<PointerType>(Ptr->getType())->getElementType()->isPointerTy()) {
// Locate a load or store through the pointer, and assign the same value
// to LI as we are loading or storing. Since we know that the value is
// stored in this loop, this will always succeed.
@@ -751,7 +751,7 @@ void LICM::PromoteValuesInLoop() {
LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos);
// If this is a pointer type, update alias info appropriately.
- if (isa<PointerType>(LI->getType()))
+ if (LI->getType()->isPointerTy())
CurAST->copyValue(PointerValueNumbers[PVN++], LI);
// Store into the memory we promoted.
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index a5611ff..f920dca 100644
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -17,6 +17,40 @@
// available on the target, and it performs a variety of other optimizations
// related to loop induction variables.
//
+// Terminology note: this code has a lot of handling for "post-increment" or
+// "post-inc" users. This is not talking about post-increment addressing modes;
+// it is instead talking about code like this:
+//
+// %i = phi [ 0, %entry ], [ %i.next, %latch ]
+// ...
+// %i.next = add %i, 1
+// %c = icmp eq %i.next, %n
+//
+// The SCEV for %i is {0,+,1}<%L>. The SCEV for %i.next is {1,+,1}<%L>, however
+// it's useful to think about these as the same register, with some uses using
+// the value of the register before the add and some using // it after. In this
+// example, the icmp is a post-increment user, since it uses %i.next, which is
+// the value of the induction variable after the increment. The other common
+// case of post-increment users is users outside the loop.
+//
+// TODO: More sophistication in the way Formulae are generated and filtered.
+//
+// TODO: Handle multiple loops at a time.
+//
+// TODO: Should TargetLowering::AddrMode::BaseGV be changed to a ConstantExpr
+// instead of a GlobalValue?
+//
+// TODO: When truncation is free, truncate ICmp users' operands to make it a
+// smaller encoding (on x86 at least).
+//
+// TODO: When a negated register is used by an add (such as in a list of
+// multiple base registers, or as the increment expression in an addrec),
+// we may not actually need both reg and (-1 * reg) in registers; the
+// negation can be implemented by using a sub instead of an add. The
+// lack of support for taking this into consideration when making
+// register pressure decisions is partly worked around by the "Special"
+// use kind.
+//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "loop-reduce"
@@ -26,208 +60,434 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/IVUsers.h"
+#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpander.h"
-#include "llvm/Transforms/Utils/AddrModeMatcher.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
#include <algorithm>
using namespace llvm;
-STATISTIC(NumReduced , "Number of IV uses strength reduced");
-STATISTIC(NumInserted, "Number of PHIs inserted");
-STATISTIC(NumVariable, "Number of PHIs with variable strides");
-STATISTIC(NumEliminated, "Number of strides eliminated");
-STATISTIC(NumShadow, "Number of Shadow IVs optimized");
-STATISTIC(NumImmSunk, "Number of common expr immediates sunk into uses");
-STATISTIC(NumLoopCond, "Number of loop terminating conds optimized");
-STATISTIC(NumCountZero, "Number of count iv optimized to count toward zero");
+namespace {
+
+/// RegSortData - This class holds data which is used to order reuse candidates.
+class RegSortData {
+public:
+ /// UsedByIndices - This represents the set of LSRUse indices which reference
+ /// a particular register.
+ SmallBitVector UsedByIndices;
+
+ RegSortData() {}
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
-static cl::opt<bool> EnableFullLSRMode("enable-full-lsr",
- cl::init(false),
- cl::Hidden);
+}
+
+void RegSortData::print(raw_ostream &OS) const {
+ OS << "[NumUses=" << UsedByIndices.count() << ']';
+}
+
+void RegSortData::dump() const {
+ print(errs()); errs() << '\n';
+}
namespace {
- struct BasedUser;
+/// RegUseTracker - Map register candidates to information about how they are
+/// used.
+class RegUseTracker {
+ typedef DenseMap<const SCEV *, RegSortData> RegUsesTy;
- /// IVInfo - This structure keeps track of one IV expression inserted during
- /// StrengthReduceStridedIVUsers. It contains the stride, the common base, as
- /// well as the PHI node and increment value created for rewrite.
- struct IVExpr {
- const SCEV *Stride;
- const SCEV *Base;
- PHINode *PHI;
+ RegUsesTy RegUses;
+ SmallVector<const SCEV *, 16> RegSequence;
- IVExpr(const SCEV *const stride, const SCEV *const base, PHINode *phi)
- : Stride(stride), Base(base), PHI(phi) {}
- };
+public:
+ void CountRegister(const SCEV *Reg, size_t LUIdx);
+
+ bool isRegUsedByUsesOtherThan(const SCEV *Reg, size_t LUIdx) const;
+
+ const SmallBitVector &getUsedByIndices(const SCEV *Reg) const;
+
+ void clear();
+
+ typedef SmallVectorImpl<const SCEV *>::iterator iterator;
+ typedef SmallVectorImpl<const SCEV *>::const_iterator const_iterator;
+ iterator begin() { return RegSequence.begin(); }
+ iterator end() { return RegSequence.end(); }
+ const_iterator begin() const { return RegSequence.begin(); }
+ const_iterator end() const { return RegSequence.end(); }
+};
+
+}
- /// IVsOfOneStride - This structure keeps track of all IV expression inserted
- /// during StrengthReduceStridedIVUsers for a particular stride of the IV.
- struct IVsOfOneStride {
- std::vector<IVExpr> IVs;
+void
+RegUseTracker::CountRegister(const SCEV *Reg, size_t LUIdx) {
+ std::pair<RegUsesTy::iterator, bool> Pair =
+ RegUses.insert(std::make_pair(Reg, RegSortData()));
+ RegSortData &RSD = Pair.first->second;
+ if (Pair.second)
+ RegSequence.push_back(Reg);
+ RSD.UsedByIndices.resize(std::max(RSD.UsedByIndices.size(), LUIdx + 1));
+ RSD.UsedByIndices.set(LUIdx);
+}
+
+bool
+RegUseTracker::isRegUsedByUsesOtherThan(const SCEV *Reg, size_t LUIdx) const {
+ if (!RegUses.count(Reg)) return false;
+ const SmallBitVector &UsedByIndices =
+ RegUses.find(Reg)->second.UsedByIndices;
+ int i = UsedByIndices.find_first();
+ if (i == -1) return false;
+ if ((size_t)i != LUIdx) return true;
+ return UsedByIndices.find_next(i) != -1;
+}
+
+const SmallBitVector &RegUseTracker::getUsedByIndices(const SCEV *Reg) const {
+ RegUsesTy::const_iterator I = RegUses.find(Reg);
+ assert(I != RegUses.end() && "Unknown register!");
+ return I->second.UsedByIndices;
+}
+
+void RegUseTracker::clear() {
+ RegUses.clear();
+ RegSequence.clear();
+}
+
+namespace {
+
+/// Formula - This class holds information that describes a formula for
+/// computing satisfying a use. It may include broken-out immediates and scaled
+/// registers.
+struct Formula {
+ /// AM - This is used to represent complex addressing, as well as other kinds
+ /// of interesting uses.
+ TargetLowering::AddrMode AM;
+
+ /// BaseRegs - The list of "base" registers for this use. When this is
+ /// non-empty, AM.HasBaseReg should be set to true.
+ SmallVector<const SCEV *, 2> BaseRegs;
- void addIV(const SCEV *const Stride, const SCEV *const Base, PHINode *PHI) {
- IVs.push_back(IVExpr(Stride, Base, PHI));
+ /// ScaledReg - The 'scaled' register for this use. This should be non-null
+ /// when AM.Scale is not zero.
+ const SCEV *ScaledReg;
+
+ Formula() : ScaledReg(0) {}
+
+ void InitialMatch(const SCEV *S, Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT);
+
+ unsigned getNumRegs() const;
+ const Type *getType() const;
+
+ bool referencesReg(const SCEV *S) const;
+ bool hasRegsUsedByUsesOtherThan(size_t LUIdx,
+ const RegUseTracker &RegUses) const;
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
+
+}
+
+/// DoInitialMatch - Recursion helper for InitialMatch.
+static void DoInitialMatch(const SCEV *S, Loop *L,
+ SmallVectorImpl<const SCEV *> &Good,
+ SmallVectorImpl<const SCEV *> &Bad,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ // Collect expressions which properly dominate the loop header.
+ if (S->properlyDominates(L->getHeader(), &DT)) {
+ Good.push_back(S);
+ return;
+ }
+
+ // Look at add operands.
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I)
+ DoInitialMatch(*I, L, Good, Bad, SE, DT);
+ return;
+ }
+
+ // Look at addrec operands.
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S))
+ if (!AR->getStart()->isZero()) {
+ DoInitialMatch(AR->getStart(), L, Good, Bad, SE, DT);
+ DoInitialMatch(SE.getAddRecExpr(SE.getIntegerSCEV(0, AR->getType()),
+ AR->getStepRecurrence(SE),
+ AR->getLoop()),
+ L, Good, Bad, SE, DT);
+ return;
}
- };
- class LoopStrengthReduce : public LoopPass {
- IVUsers *IU;
- ScalarEvolution *SE;
- bool Changed;
-
- /// IVsByStride - Keep track of all IVs that have been inserted for a
- /// particular stride.
- std::map<const SCEV *, IVsOfOneStride> IVsByStride;
-
- /// DeadInsts - Keep track of instructions we may have made dead, so that
- /// we can remove them after we are done working.
- SmallVector<WeakVH, 16> DeadInsts;
-
- /// TLI - Keep a pointer of a TargetLowering to consult for determining
- /// transformation profitability.
- const TargetLowering *TLI;
-
- public:
- static char ID; // Pass ID, replacement for typeid
- explicit LoopStrengthReduce(const TargetLowering *tli = NULL) :
- LoopPass(&ID), TLI(tli) {}
-
- bool runOnLoop(Loop *L, LPPassManager &LPM);
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- // We split critical edges, so we change the CFG. However, we do update
- // many analyses if they are around.
- AU.addPreservedID(LoopSimplifyID);
- AU.addPreserved("loops");
- AU.addPreserved("domfrontier");
- AU.addPreserved("domtree");
-
- AU.addRequiredID(LoopSimplifyID);
- AU.addRequired<ScalarEvolution>();
- AU.addPreserved<ScalarEvolution>();
- AU.addRequired<IVUsers>();
- AU.addPreserved<IVUsers>();
+ // Handle a multiplication by -1 (negation) if it didn't fold.
+ if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S))
+ if (Mul->getOperand(0)->isAllOnesValue()) {
+ SmallVector<const SCEV *, 4> Ops(Mul->op_begin()+1, Mul->op_end());
+ const SCEV *NewMul = SE.getMulExpr(Ops);
+
+ SmallVector<const SCEV *, 4> MyGood;
+ SmallVector<const SCEV *, 4> MyBad;
+ DoInitialMatch(NewMul, L, MyGood, MyBad, SE, DT);
+ const SCEV *NegOne = SE.getSCEV(ConstantInt::getAllOnesValue(
+ SE.getEffectiveSCEVType(NewMul->getType())));
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = MyGood.begin(),
+ E = MyGood.end(); I != E; ++I)
+ Good.push_back(SE.getMulExpr(NegOne, *I));
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = MyBad.begin(),
+ E = MyBad.end(); I != E; ++I)
+ Bad.push_back(SE.getMulExpr(NegOne, *I));
+ return;
}
- private:
- void OptimizeIndvars(Loop *L);
-
- /// OptimizeLoopTermCond - Change loop terminating condition to use the
- /// postinc iv when possible.
- void OptimizeLoopTermCond(Loop *L);
-
- /// OptimizeShadowIV - If IV is used in a int-to-float cast
- /// inside the loop then try to eliminate the cast opeation.
- void OptimizeShadowIV(Loop *L);
-
- /// OptimizeMax - Rewrite the loop's terminating condition
- /// if it uses a max computation.
- ICmpInst *OptimizeMax(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse);
-
- /// OptimizeLoopCountIV - If, after all sharing of IVs, the IV used for
- /// deciding when to exit the loop is used only for that purpose, try to
- /// rearrange things so it counts down to a test against zero.
- bool OptimizeLoopCountIV(Loop *L);
- bool OptimizeLoopCountIVOfStride(const SCEV* &Stride,
- IVStrideUse* &CondUse, Loop *L);
-
- /// StrengthReduceIVUsersOfStride - Strength reduce all of the users of a
- /// single stride of IV. All of the users may have different starting
- /// values, and this may not be the only stride.
- void StrengthReduceIVUsersOfStride(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L);
- void StrengthReduceIVUsers(Loop *L);
-
- ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse,
- const SCEV* &CondStride,
- bool PostPass = false);
-
- bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
- const SCEV* &CondStride);
- bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
- const SCEV *CheckForIVReuse(bool, bool, bool, const SCEV *,
- IVExpr&, const Type*,
- const std::vector<BasedUser>& UsersToProcess);
- bool ValidScale(bool, int64_t,
- const std::vector<BasedUser>& UsersToProcess);
- bool ValidOffset(bool, int64_t, int64_t,
- const std::vector<BasedUser>& UsersToProcess);
- const SCEV *CollectIVUsers(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L,
- bool &AllUsesAreAddresses,
- bool &AllUsesAreOutsideLoop,
- std::vector<BasedUser> &UsersToProcess);
- bool StrideMightBeShared(const SCEV *Stride, Loop *L, bool CheckPreInc);
- bool ShouldUseFullStrengthReductionMode(
- const std::vector<BasedUser> &UsersToProcess,
- const Loop *L,
- bool AllUsesAreAddresses,
- const SCEV *Stride);
- void PrepareToStrengthReduceFully(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- const Loop *L,
- SCEVExpander &PreheaderRewriter);
- void PrepareToStrengthReduceFromSmallerStride(
- std::vector<BasedUser> &UsersToProcess,
- Value *CommonBaseV,
- const IVExpr &ReuseIV,
- Instruction *PreInsertPt);
- void PrepareToStrengthReduceWithNewPhi(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- Value *CommonBaseV,
- Instruction *IVIncInsertPt,
- const Loop *L,
- SCEVExpander &PreheaderRewriter);
-
- void DeleteTriviallyDeadInstructions();
- };
+ // Ok, we can't do anything interesting. Just stuff the whole thing into a
+ // register and hope for the best.
+ Bad.push_back(S);
}
-char LoopStrengthReduce::ID = 0;
-static RegisterPass<LoopStrengthReduce>
-X("loop-reduce", "Loop Strength Reduction");
+/// InitialMatch - Incorporate loop-variant parts of S into this Formula,
+/// attempting to keep all loop-invariant and loop-computable values in a
+/// single base register.
+void Formula::InitialMatch(const SCEV *S, Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ SmallVector<const SCEV *, 4> Good;
+ SmallVector<const SCEV *, 4> Bad;
+ DoInitialMatch(S, L, Good, Bad, SE, DT);
+ if (!Good.empty()) {
+ BaseRegs.push_back(SE.getAddExpr(Good));
+ AM.HasBaseReg = true;
+ }
+ if (!Bad.empty()) {
+ BaseRegs.push_back(SE.getAddExpr(Bad));
+ AM.HasBaseReg = true;
+ }
+}
-Pass *llvm::createLoopStrengthReducePass(const TargetLowering *TLI) {
- return new LoopStrengthReduce(TLI);
+/// getNumRegs - Return the total number of register operands used by this
+/// formula. This does not include register uses implied by non-constant
+/// addrec strides.
+unsigned Formula::getNumRegs() const {
+ return !!ScaledReg + BaseRegs.size();
}
-/// DeleteTriviallyDeadInstructions - If any of the instructions is the
-/// specified set are trivially dead, delete them and see if this makes any of
-/// their operands subsequently dead.
-void LoopStrengthReduce::DeleteTriviallyDeadInstructions() {
- while (!DeadInsts.empty()) {
- Instruction *I = dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val());
+/// getType - Return the type of this formula, if it has one, or null
+/// otherwise. This type is meaningless except for the bit size.
+const Type *Formula::getType() const {
+ return !BaseRegs.empty() ? BaseRegs.front()->getType() :
+ ScaledReg ? ScaledReg->getType() :
+ AM.BaseGV ? AM.BaseGV->getType() :
+ 0;
+}
- if (I == 0 || !isInstructionTriviallyDead(I))
- continue;
+/// referencesReg - Test if this formula references the given register.
+bool Formula::referencesReg(const SCEV *S) const {
+ return S == ScaledReg ||
+ std::find(BaseRegs.begin(), BaseRegs.end(), S) != BaseRegs.end();
+}
- for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI)
- if (Instruction *U = dyn_cast<Instruction>(*OI)) {
- *OI = 0;
- if (U->use_empty())
- DeadInsts.push_back(U);
+/// hasRegsUsedByUsesOtherThan - Test whether this formula uses registers
+/// which are used by uses other than the use with the given index.
+bool Formula::hasRegsUsedByUsesOtherThan(size_t LUIdx,
+ const RegUseTracker &RegUses) const {
+ if (ScaledReg)
+ if (RegUses.isRegUsedByUsesOtherThan(ScaledReg, LUIdx))
+ return true;
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
+ E = BaseRegs.end(); I != E; ++I)
+ if (RegUses.isRegUsedByUsesOtherThan(*I, LUIdx))
+ return true;
+ return false;
+}
+
+void Formula::print(raw_ostream &OS) const {
+ bool First = true;
+ if (AM.BaseGV) {
+ if (!First) OS << " + "; else First = false;
+ WriteAsOperand(OS, AM.BaseGV, /*PrintType=*/false);
+ }
+ if (AM.BaseOffs != 0) {
+ if (!First) OS << " + "; else First = false;
+ OS << AM.BaseOffs;
+ }
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
+ E = BaseRegs.end(); I != E; ++I) {
+ if (!First) OS << " + "; else First = false;
+ OS << "reg(" << **I << ')';
+ }
+ if (AM.Scale != 0) {
+ if (!First) OS << " + "; else First = false;
+ OS << AM.Scale << "*reg(";
+ if (ScaledReg)
+ OS << *ScaledReg;
+ else
+ OS << "<unknown>";
+ OS << ')';
+ }
+}
+
+void Formula::dump() const {
+ print(errs()); errs() << '\n';
+}
+
+/// isAddRecSExtable - Return true if the given addrec can be sign-extended
+/// without changing its value.
+static bool isAddRecSExtable(const SCEVAddRecExpr *AR, ScalarEvolution &SE) {
+ const Type *WideTy =
+ IntegerType::get(SE.getContext(),
+ SE.getTypeSizeInBits(AR->getType()) + 1);
+ return isa<SCEVAddRecExpr>(SE.getSignExtendExpr(AR, WideTy));
+}
+
+/// isAddSExtable - Return true if the given add can be sign-extended
+/// without changing its value.
+static bool isAddSExtable(const SCEVAddExpr *A, ScalarEvolution &SE) {
+ const Type *WideTy =
+ IntegerType::get(SE.getContext(),
+ SE.getTypeSizeInBits(A->getType()) + 1);
+ return isa<SCEVAddExpr>(SE.getSignExtendExpr(A, WideTy));
+}
+
+/// isMulSExtable - Return true if the given add can be sign-extended
+/// without changing its value.
+static bool isMulSExtable(const SCEVMulExpr *A, ScalarEvolution &SE) {
+ const Type *WideTy =
+ IntegerType::get(SE.getContext(),
+ SE.getTypeSizeInBits(A->getType()) + 1);
+ return isa<SCEVMulExpr>(SE.getSignExtendExpr(A, WideTy));
+}
+
+/// getExactSDiv - Return an expression for LHS /s RHS, if it can be determined
+/// and if the remainder is known to be zero, or null otherwise. If
+/// IgnoreSignificantBits is true, expressions like (X * Y) /s Y are simplified
+/// to Y, ignoring that the multiplication may overflow, which is useful when
+/// the result will be used in a context where the most significant bits are
+/// ignored.
+static const SCEV *getExactSDiv(const SCEV *LHS, const SCEV *RHS,
+ ScalarEvolution &SE,
+ bool IgnoreSignificantBits = false) {
+ // Handle the trivial case, which works for any SCEV type.
+ if (LHS == RHS)
+ return SE.getIntegerSCEV(1, LHS->getType());
+
+ // Handle x /s -1 as x * -1, to give ScalarEvolution a chance to do some
+ // folding.
+ if (RHS->isAllOnesValue())
+ return SE.getMulExpr(LHS, RHS);
+
+ // Check for a division of a constant by a constant.
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(LHS)) {
+ const SCEVConstant *RC = dyn_cast<SCEVConstant>(RHS);
+ if (!RC)
+ return 0;
+ if (C->getValue()->getValue().srem(RC->getValue()->getValue()) != 0)
+ return 0;
+ return SE.getConstant(C->getValue()->getValue()
+ .sdiv(RC->getValue()->getValue()));
+ }
+
+ // Distribute the sdiv over addrec operands, if the addrec doesn't overflow.
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS)) {
+ if (IgnoreSignificantBits || isAddRecSExtable(AR, SE)) {
+ const SCEV *Start = getExactSDiv(AR->getStart(), RHS, SE,
+ IgnoreSignificantBits);
+ if (!Start) return 0;
+ const SCEV *Step = getExactSDiv(AR->getStepRecurrence(SE), RHS, SE,
+ IgnoreSignificantBits);
+ if (!Step) return 0;
+ return SE.getAddRecExpr(Start, Step, AR->getLoop());
+ }
+ }
+
+ // Distribute the sdiv over add operands, if the add doesn't overflow.
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(LHS)) {
+ if (IgnoreSignificantBits || isAddSExtable(Add, SE)) {
+ SmallVector<const SCEV *, 8> Ops;
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I) {
+ const SCEV *Op = getExactSDiv(*I, RHS, SE,
+ IgnoreSignificantBits);
+ if (!Op) return 0;
+ Ops.push_back(Op);
}
+ return SE.getAddExpr(Ops);
+ }
+ }
- I->eraseFromParent();
- Changed = true;
+ // Check for a multiply operand that we can pull RHS out of.
+ if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(LHS))
+ if (IgnoreSignificantBits || isMulSExtable(Mul, SE)) {
+ SmallVector<const SCEV *, 4> Ops;
+ bool Found = false;
+ for (SCEVMulExpr::op_iterator I = Mul->op_begin(), E = Mul->op_end();
+ I != E; ++I) {
+ if (!Found)
+ if (const SCEV *Q = getExactSDiv(*I, RHS, SE,
+ IgnoreSignificantBits)) {
+ Ops.push_back(Q);
+ Found = true;
+ continue;
+ }
+ Ops.push_back(*I);
+ }
+ return Found ? SE.getMulExpr(Ops) : 0;
+ }
+
+ // Otherwise we don't know.
+ return 0;
+}
+
+/// ExtractImmediate - If S involves the addition of a constant integer value,
+/// return that integer value, and mutate S to point to a new SCEV with that
+/// value excluded.
+static int64_t ExtractImmediate(const SCEV *&S, ScalarEvolution &SE) {
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {
+ if (C->getValue()->getValue().getMinSignedBits() <= 64) {
+ S = SE.getIntegerSCEV(0, C->getType());
+ return C->getValue()->getSExtValue();
+ }
+ } else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(Add->op_begin(), Add->op_end());
+ int64_t Result = ExtractImmediate(NewOps.front(), SE);
+ S = SE.getAddExpr(NewOps);
+ return Result;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
+ int64_t Result = ExtractImmediate(NewOps.front(), SE);
+ S = SE.getAddRecExpr(NewOps, AR->getLoop());
+ return Result;
+ }
+ return 0;
+}
+
+/// ExtractSymbol - If S involves the addition of a GlobalValue address,
+/// return that symbol, and mutate S to point to a new SCEV with that
+/// value excluded.
+static GlobalValue *ExtractSymbol(const SCEV *&S, ScalarEvolution &SE) {
+ if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue())) {
+ S = SE.getIntegerSCEV(0, GV->getType());
+ return GV;
+ }
+ } else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(Add->op_begin(), Add->op_end());
+ GlobalValue *Result = ExtractSymbol(NewOps.back(), SE);
+ S = SE.getAddExpr(NewOps);
+ return Result;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
+ GlobalValue *Result = ExtractSymbol(NewOps.front(), SE);
+ S = SE.getAddRecExpr(NewOps, AR->getLoop());
+ return Result;
}
+ return 0;
}
/// isAddressUse - Returns true if the specified instruction is using the
@@ -276,1776 +536,833 @@ static const Type *getAccessType(const Instruction *Inst) {
break;
}
}
- return AccessTy;
-}
-namespace {
- /// BasedUser - For a particular base value, keep information about how we've
- /// partitioned the expression so far.
- struct BasedUser {
- /// Base - The Base value for the PHI node that needs to be inserted for
- /// this use. As the use is processed, information gets moved from this
- /// field to the Imm field (below). BasedUser values are sorted by this
- /// field.
- const SCEV *Base;
-
- /// Inst - The instruction using the induction variable.
- Instruction *Inst;
-
- /// OperandValToReplace - The operand value of Inst to replace with the
- /// EmittedBase.
- Value *OperandValToReplace;
-
- /// Imm - The immediate value that should be added to the base immediately
- /// before Inst, because it will be folded into the imm field of the
- /// instruction. This is also sometimes used for loop-variant values that
- /// must be added inside the loop.
- const SCEV *Imm;
-
- /// Phi - The induction variable that performs the striding that
- /// should be used for this user.
- PHINode *Phi;
-
- // isUseOfPostIncrementedValue - True if this should use the
- // post-incremented version of this IV, not the preincremented version.
- // This can only be set in special cases, such as the terminating setcc
- // instruction for a loop and uses outside the loop that are dominated by
- // the loop.
- bool isUseOfPostIncrementedValue;
-
- BasedUser(IVStrideUse &IVSU, ScalarEvolution *se)
- : Base(IVSU.getOffset()), Inst(IVSU.getUser()),
- OperandValToReplace(IVSU.getOperandValToReplace()),
- Imm(se->getIntegerSCEV(0, Base->getType())),
- isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue()) {}
-
- // Once we rewrite the code to insert the new IVs we want, update the
- // operands of Inst to use the new expression 'NewBase', with 'Imm' added
- // to it.
- void RewriteInstructionToUseNewBase(const SCEV *NewBase,
- Instruction *InsertPt,
- SCEVExpander &Rewriter, Loop *L, Pass *P,
- SmallVectorImpl<WeakVH> &DeadInsts,
- ScalarEvolution *SE);
-
- Value *InsertCodeForBaseAtPosition(const SCEV *NewBase,
- const Type *Ty,
- SCEVExpander &Rewriter,
- Instruction *IP,
- ScalarEvolution *SE);
- void dump() const;
- };
-}
+ // All pointers have the same requirements, so canonicalize them to an
+ // arbitrary pointer type to minimize variation.
+ if (const PointerType *PTy = dyn_cast<PointerType>(AccessTy))
+ AccessTy = PointerType::get(IntegerType::get(PTy->getContext(), 1),
+ PTy->getAddressSpace());
-void BasedUser::dump() const {
- dbgs() << " Base=" << *Base;
- dbgs() << " Imm=" << *Imm;
- dbgs() << " Inst: " << *Inst;
+ return AccessTy;
}
-Value *BasedUser::InsertCodeForBaseAtPosition(const SCEV *NewBase,
- const Type *Ty,
- SCEVExpander &Rewriter,
- Instruction *IP,
- ScalarEvolution *SE) {
- Value *Base = Rewriter.expandCodeFor(NewBase, 0, IP);
-
- // Wrap the base in a SCEVUnknown so that ScalarEvolution doesn't try to
- // re-analyze it.
- const SCEV *NewValSCEV = SE->getUnknown(Base);
-
- // Always emit the immediate into the same block as the user.
- NewValSCEV = SE->getAddExpr(NewValSCEV, Imm);
-
- return Rewriter.expandCodeFor(NewValSCEV, Ty, IP);
-}
+/// DeleteTriviallyDeadInstructions - If any of the instructions is the
+/// specified set are trivially dead, delete them and see if this makes any of
+/// their operands subsequently dead.
+static bool
+DeleteTriviallyDeadInstructions(SmallVectorImpl<WeakVH> &DeadInsts) {
+ bool Changed = false;
+ while (!DeadInsts.empty()) {
+ Instruction *I = dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val());
-// Once we rewrite the code to insert the new IVs we want, update the
-// operands of Inst to use the new expression 'NewBase', with 'Imm' added
-// to it. NewBasePt is the last instruction which contributes to the
-// value of NewBase in the case that it's a diffferent instruction from
-// the PHI that NewBase is computed from, or null otherwise.
-//
-void BasedUser::RewriteInstructionToUseNewBase(const SCEV *NewBase,
- Instruction *NewBasePt,
- SCEVExpander &Rewriter, Loop *L, Pass *P,
- SmallVectorImpl<WeakVH> &DeadInsts,
- ScalarEvolution *SE) {
- if (!isa<PHINode>(Inst)) {
- // By default, insert code at the user instruction.
- BasicBlock::iterator InsertPt = Inst;
-
- // However, if the Operand is itself an instruction, the (potentially
- // complex) inserted code may be shared by many users. Because of this, we
- // want to emit code for the computation of the operand right before its old
- // computation. This is usually safe, because we obviously used to use the
- // computation when it was computed in its current block. However, in some
- // cases (e.g. use of a post-incremented induction variable) the NewBase
- // value will be pinned to live somewhere after the original computation.
- // In this case, we have to back off.
- //
- // If this is a use outside the loop (which means after, since it is based
- // on a loop indvar) we use the post-incremented value, so that we don't
- // artificially make the preinc value live out the bottom of the loop.
- if (!isUseOfPostIncrementedValue && L->contains(Inst)) {
- if (NewBasePt && isa<PHINode>(OperandValToReplace)) {
- InsertPt = NewBasePt;
- ++InsertPt;
- } else if (Instruction *OpInst
- = dyn_cast<Instruction>(OperandValToReplace)) {
- InsertPt = OpInst;
- while (isa<PHINode>(InsertPt)) ++InsertPt;
- }
- }
- Value *NewVal = InsertCodeForBaseAtPosition(NewBase,
- OperandValToReplace->getType(),
- Rewriter, InsertPt, SE);
- // Replace the use of the operand Value with the new Phi we just created.
- Inst->replaceUsesOfWith(OperandValToReplace, NewVal);
-
- DEBUG(dbgs() << " Replacing with ");
- DEBUG(WriteAsOperand(dbgs(), NewVal, /*PrintType=*/false));
- DEBUG(dbgs() << ", which has value " << *NewBase << " plus IMM "
- << *Imm << "\n");
- return;
- }
+ if (I == 0 || !isInstructionTriviallyDead(I))
+ continue;
- // PHI nodes are more complex. We have to insert one copy of the NewBase+Imm
- // expression into each operand block that uses it. Note that PHI nodes can
- // have multiple entries for the same predecessor. We use a map to make sure
- // that a PHI node only has a single Value* for each predecessor (which also
- // prevents us from inserting duplicate code in some blocks).
- DenseMap<BasicBlock*, Value*> InsertedCode;
- PHINode *PN = cast<PHINode>(Inst);
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- if (PN->getIncomingValue(i) == OperandValToReplace) {
- // If the original expression is outside the loop, put the replacement
- // code in the same place as the original expression,
- // which need not be an immediate predecessor of this PHI. This way we
- // need only one copy of it even if it is referenced multiple times in
- // the PHI. We don't do this when the original expression is inside the
- // loop because multiple copies sometimes do useful sinking of code in
- // that case(?).
- Instruction *OldLoc = dyn_cast<Instruction>(OperandValToReplace);
- BasicBlock *PHIPred = PN->getIncomingBlock(i);
- if (L->contains(OldLoc)) {
- // If this is a critical edge, split the edge so that we do not insert
- // the code on all predecessor/successor paths. We do this unless this
- // is the canonical backedge for this loop, as this can make some
- // inserted code be in an illegal position.
- if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 &&
- !isa<IndirectBrInst>(PHIPred->getTerminator()) &&
- (PN->getParent() != L->getHeader() || !L->contains(PHIPred))) {
-
- // First step, split the critical edge.
- BasicBlock *NewBB = SplitCriticalEdge(PHIPred, PN->getParent(),
- P, false);
-
- // Next step: move the basic block. In particular, if the PHI node
- // is outside of the loop, and PredTI is in the loop, we want to
- // move the block to be immediately before the PHI block, not
- // immediately after PredTI.
- if (L->contains(PHIPred) && !L->contains(PN))
- NewBB->moveBefore(PN->getParent());
-
- // Splitting the edge can reduce the number of PHI entries we have.
- e = PN->getNumIncomingValues();
- PHIPred = NewBB;
- i = PN->getBasicBlockIndex(PHIPred);
- }
- }
- Value *&Code = InsertedCode[PHIPred];
- if (!Code) {
- // Insert the code into the end of the predecessor block.
- Instruction *InsertPt = (L->contains(OldLoc)) ?
- PHIPred->getTerminator() :
- OldLoc->getParent()->getTerminator();
- Code = InsertCodeForBaseAtPosition(NewBase, PN->getType(),
- Rewriter, InsertPt, SE);
-
- DEBUG(dbgs() << " Changing PHI use to ");
- DEBUG(WriteAsOperand(dbgs(), Code, /*PrintType=*/false));
- DEBUG(dbgs() << ", which has value " << *NewBase << " plus IMM "
- << *Imm << "\n");
+ for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI)
+ if (Instruction *U = dyn_cast<Instruction>(*OI)) {
+ *OI = 0;
+ if (U->use_empty())
+ DeadInsts.push_back(U);
}
- // Replace the use of the operand Value with the new Phi we just created.
- PN->setIncomingValue(i, Code);
- Rewriter.clear();
- }
+ I->eraseFromParent();
+ Changed = true;
}
- // PHI node might have become a constant value after SplitCriticalEdge.
- DeadInsts.push_back(Inst);
+ return Changed;
}
+namespace {
-/// fitsInAddressMode - Return true if V can be subsumed within an addressing
-/// mode, and does not need to be put in a register first.
-static bool fitsInAddressMode(const SCEV *V, const Type *AccessTy,
- const TargetLowering *TLI, bool HasBaseReg) {
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(V)) {
- int64_t VC = SC->getValue()->getSExtValue();
- if (TLI) {
- TargetLowering::AddrMode AM;
- AM.BaseOffs = VC;
- AM.HasBaseReg = HasBaseReg;
- return TLI->isLegalAddressingMode(AM, AccessTy);
- } else {
- // Defaults to PPC. PPC allows a sign-extended 16-bit immediate field.
- return (VC > -(1 << 16) && VC < (1 << 16)-1);
- }
- }
-
- if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V))
- if (GlobalValue *GV = dyn_cast<GlobalValue>(SU->getValue())) {
- if (TLI) {
- TargetLowering::AddrMode AM;
- AM.BaseGV = GV;
- AM.HasBaseReg = HasBaseReg;
- return TLI->isLegalAddressingMode(AM, AccessTy);
- } else {
- // Default: assume global addresses are not legal.
- }
- }
+/// Cost - This class is used to measure and compare candidate formulae.
+class Cost {
+ /// TODO: Some of these could be merged. Also, a lexical ordering
+ /// isn't always optimal.
+ unsigned NumRegs;
+ unsigned AddRecCost;
+ unsigned NumIVMuls;
+ unsigned NumBaseAdds;
+ unsigned ImmCost;
+ unsigned SetupCost;
+
+public:
+ Cost()
+ : NumRegs(0), AddRecCost(0), NumIVMuls(0), NumBaseAdds(0), ImmCost(0),
+ SetupCost(0) {}
+
+ unsigned getNumRegs() const { return NumRegs; }
+
+ bool operator<(const Cost &Other) const;
+
+ void Loose();
+
+ void RateFormula(const Formula &F,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const DenseSet<const SCEV *> &VisitedRegs,
+ const Loop *L,
+ const SmallVectorImpl<int64_t> &Offsets,
+ ScalarEvolution &SE, DominatorTree &DT);
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+private:
+ void RateRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT);
+ void RatePrimaryRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT);
+};
- return false;
}
-/// MoveLoopVariantsToImmediateField - Move any subexpressions from Val that are
-/// loop varying to the Imm operand.
-static void MoveLoopVariantsToImmediateField(const SCEV *&Val, const SCEV *&Imm,
- Loop *L, ScalarEvolution *SE) {
- if (Val->isLoopInvariant(L)) return; // Nothing to do.
-
- if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
- SmallVector<const SCEV *, 4> NewOps;
- NewOps.reserve(SAE->getNumOperands());
+/// RateRegister - Tally up interesting quantities from the given register.
+void Cost::RateRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Reg)) {
+ if (AR->getLoop() == L)
+ AddRecCost += 1; /// TODO: This should be a function of the stride.
+
+ // If this is an addrec for a loop that's already been visited by LSR,
+ // don't second-guess its addrec phi nodes. LSR isn't currently smart
+ // enough to reason about more than one loop at a time. Consider these
+ // registers free and leave them alone.
+ else if (L->contains(AR->getLoop()) ||
+ (!AR->getLoop()->contains(L) &&
+ DT.dominates(L->getHeader(), AR->getLoop()->getHeader()))) {
+ for (BasicBlock::iterator I = AR->getLoop()->getHeader()->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I)
+ if (SE.isSCEVable(PN->getType()) &&
+ (SE.getEffectiveSCEVType(PN->getType()) ==
+ SE.getEffectiveSCEVType(AR->getType())) &&
+ SE.getSCEV(PN) == AR)
+ return;
- for (unsigned i = 0; i != SAE->getNumOperands(); ++i)
- if (!SAE->getOperand(i)->isLoopInvariant(L)) {
- // If this is a loop-variant expression, it must stay in the immediate
- // field of the expression.
- Imm = SE->getAddExpr(Imm, SAE->getOperand(i));
- } else {
- NewOps.push_back(SAE->getOperand(i));
- }
+ // If this isn't one of the addrecs that the loop already has, it
+ // would require a costly new phi and add. TODO: This isn't
+ // precisely modeled right now.
+ ++NumBaseAdds;
+ if (!Regs.count(AR->getStart()))
+ RateRegister(AR->getStart(), Regs, L, SE, DT);
+ }
- if (NewOps.empty())
- Val = SE->getIntegerSCEV(0, Val->getType());
- else
- Val = SE->getAddExpr(NewOps);
- } else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
- // Try to pull immediates out of the start value of nested addrec's.
- const SCEV *Start = SARE->getStart();
- MoveLoopVariantsToImmediateField(Start, Imm, L, SE);
-
- SmallVector<const SCEV *, 4> Ops(SARE->op_begin(), SARE->op_end());
- Ops[0] = Start;
- Val = SE->getAddRecExpr(Ops, SARE->getLoop());
- } else {
- // Otherwise, all of Val is variant, move the whole thing over.
- Imm = SE->getAddExpr(Imm, Val);
- Val = SE->getIntegerSCEV(0, Val->getType());
+ // Add the step value register, if it needs one.
+ // TODO: The non-affine case isn't precisely modeled here.
+ if (!AR->isAffine() || !isa<SCEVConstant>(AR->getOperand(1)))
+ if (!Regs.count(AR->getStart()))
+ RateRegister(AR->getOperand(1), Regs, L, SE, DT);
}
+ ++NumRegs;
+
+ // Rough heuristic; favor registers which don't require extra setup
+ // instructions in the preheader.
+ if (!isa<SCEVUnknown>(Reg) &&
+ !isa<SCEVConstant>(Reg) &&
+ !(isa<SCEVAddRecExpr>(Reg) &&
+ (isa<SCEVUnknown>(cast<SCEVAddRecExpr>(Reg)->getStart()) ||
+ isa<SCEVConstant>(cast<SCEVAddRecExpr>(Reg)->getStart()))))
+ ++SetupCost;
}
+/// RatePrimaryRegister - Record this register in the set. If we haven't seen it
+/// before, rate it.
+void Cost::RatePrimaryRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ if (Regs.insert(Reg))
+ RateRegister(Reg, Regs, L, SE, DT);
+}
-/// MoveImmediateValues - Look at Val, and pull out any additions of constants
-/// that can fit into the immediate field of instructions in the target.
-/// Accumulate these immediate values into the Imm value.
-static void MoveImmediateValues(const TargetLowering *TLI,
- const Type *AccessTy,
- const SCEV *&Val, const SCEV *&Imm,
- bool isAddress, Loop *L,
- ScalarEvolution *SE) {
- if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
- SmallVector<const SCEV *, 4> NewOps;
- NewOps.reserve(SAE->getNumOperands());
-
- for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
- const SCEV *NewOp = SAE->getOperand(i);
- MoveImmediateValues(TLI, AccessTy, NewOp, Imm, isAddress, L, SE);
-
- if (!NewOp->isLoopInvariant(L)) {
- // If this is a loop-variant expression, it must stay in the immediate
- // field of the expression.
- Imm = SE->getAddExpr(Imm, NewOp);
- } else {
- NewOps.push_back(NewOp);
- }
- }
-
- if (NewOps.empty())
- Val = SE->getIntegerSCEV(0, Val->getType());
- else
- Val = SE->getAddExpr(NewOps);
- return;
- } else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
- // Try to pull immediates out of the start value of nested addrec's.
- const SCEV *Start = SARE->getStart();
- MoveImmediateValues(TLI, AccessTy, Start, Imm, isAddress, L, SE);
-
- if (Start != SARE->getStart()) {
- SmallVector<const SCEV *, 4> Ops(SARE->op_begin(), SARE->op_end());
- Ops[0] = Start;
- Val = SE->getAddRecExpr(Ops, SARE->getLoop());
+void Cost::RateFormula(const Formula &F,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const DenseSet<const SCEV *> &VisitedRegs,
+ const Loop *L,
+ const SmallVectorImpl<int64_t> &Offsets,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ // Tally up the registers.
+ if (const SCEV *ScaledReg = F.ScaledReg) {
+ if (VisitedRegs.count(ScaledReg)) {
+ Loose();
+ return;
}
- return;
- } else if (const SCEVMulExpr *SME = dyn_cast<SCEVMulExpr>(Val)) {
- // Transform "8 * (4 + v)" -> "32 + 8*V" if "32" fits in the immed field.
- if (isAddress &&
- fitsInAddressMode(SME->getOperand(0), AccessTy, TLI, false) &&
- SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
-
- const SCEV *SubImm = SE->getIntegerSCEV(0, Val->getType());
- const SCEV *NewOp = SME->getOperand(1);
- MoveImmediateValues(TLI, AccessTy, NewOp, SubImm, isAddress, L, SE);
-
- // If we extracted something out of the subexpressions, see if we can
- // simplify this!
- if (NewOp != SME->getOperand(1)) {
- // Scale SubImm up by "8". If the result is a target constant, we are
- // good.
- SubImm = SE->getMulExpr(SubImm, SME->getOperand(0));
- if (fitsInAddressMode(SubImm, AccessTy, TLI, false)) {
- // Accumulate the immediate.
- Imm = SE->getAddExpr(Imm, SubImm);
-
- // Update what is left of 'Val'.
- Val = SE->getMulExpr(SME->getOperand(0), NewOp);
- return;
- }
- }
+ RatePrimaryRegister(ScaledReg, Regs, L, SE, DT);
+ }
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
+ E = F.BaseRegs.end(); I != E; ++I) {
+ const SCEV *BaseReg = *I;
+ if (VisitedRegs.count(BaseReg)) {
+ Loose();
+ return;
}
+ RatePrimaryRegister(BaseReg, Regs, L, SE, DT);
+
+ NumIVMuls += isa<SCEVMulExpr>(BaseReg) &&
+ BaseReg->hasComputableLoopEvolution(L);
}
- // Loop-variant expressions must stay in the immediate field of the
- // expression.
- if ((isAddress && fitsInAddressMode(Val, AccessTy, TLI, false)) ||
- !Val->isLoopInvariant(L)) {
- Imm = SE->getAddExpr(Imm, Val);
- Val = SE->getIntegerSCEV(0, Val->getType());
- return;
+ if (F.BaseRegs.size() > 1)
+ NumBaseAdds += F.BaseRegs.size() - 1;
+
+ // Tally up the non-zero immediates.
+ for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
+ E = Offsets.end(); I != E; ++I) {
+ int64_t Offset = (uint64_t)*I + F.AM.BaseOffs;
+ if (F.AM.BaseGV)
+ ImmCost += 64; // Handle symbolic values conservatively.
+ // TODO: This should probably be the pointer size.
+ else if (Offset != 0)
+ ImmCost += APInt(64, Offset, true).getMinSignedBits();
}
+}
- // Otherwise, no immediates to move.
+/// Loose - Set this cost to a loosing value.
+void Cost::Loose() {
+ NumRegs = ~0u;
+ AddRecCost = ~0u;
+ NumIVMuls = ~0u;
+ NumBaseAdds = ~0u;
+ ImmCost = ~0u;
+ SetupCost = ~0u;
}
-static void MoveImmediateValues(const TargetLowering *TLI,
- Instruction *User,
- const SCEV *&Val, const SCEV *&Imm,
- bool isAddress, Loop *L,
- ScalarEvolution *SE) {
- const Type *AccessTy = getAccessType(User);
- MoveImmediateValues(TLI, AccessTy, Val, Imm, isAddress, L, SE);
+/// operator< - Choose the lower cost.
+bool Cost::operator<(const Cost &Other) const {
+ if (NumRegs != Other.NumRegs)
+ return NumRegs < Other.NumRegs;
+ if (AddRecCost != Other.AddRecCost)
+ return AddRecCost < Other.AddRecCost;
+ if (NumIVMuls != Other.NumIVMuls)
+ return NumIVMuls < Other.NumIVMuls;
+ if (NumBaseAdds != Other.NumBaseAdds)
+ return NumBaseAdds < Other.NumBaseAdds;
+ if (ImmCost != Other.ImmCost)
+ return ImmCost < Other.ImmCost;
+ if (SetupCost != Other.SetupCost)
+ return SetupCost < Other.SetupCost;
+ return false;
}
-/// SeparateSubExprs - Decompose Expr into all of the subexpressions that are
-/// added together. This is used to reassociate common addition subexprs
-/// together for maximal sharing when rewriting bases.
-static void SeparateSubExprs(SmallVector<const SCEV *, 16> &SubExprs,
- const SCEV *Expr,
- ScalarEvolution *SE) {
- if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Expr)) {
- for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
- SeparateSubExprs(SubExprs, AE->getOperand(j), SE);
- } else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Expr)) {
- const SCEV *Zero = SE->getIntegerSCEV(0, Expr->getType());
- if (SARE->getOperand(0) == Zero) {
- SubExprs.push_back(Expr);
- } else {
- // Compute the addrec with zero as its base.
- SmallVector<const SCEV *, 4> Ops(SARE->op_begin(), SARE->op_end());
- Ops[0] = Zero; // Start with zero base.
- SubExprs.push_back(SE->getAddRecExpr(Ops, SARE->getLoop()));
+void Cost::print(raw_ostream &OS) const {
+ OS << NumRegs << " reg" << (NumRegs == 1 ? "" : "s");
+ if (AddRecCost != 0)
+ OS << ", with addrec cost " << AddRecCost;
+ if (NumIVMuls != 0)
+ OS << ", plus " << NumIVMuls << " IV mul" << (NumIVMuls == 1 ? "" : "s");
+ if (NumBaseAdds != 0)
+ OS << ", plus " << NumBaseAdds << " base add"
+ << (NumBaseAdds == 1 ? "" : "s");
+ if (ImmCost != 0)
+ OS << ", plus " << ImmCost << " imm cost";
+ if (SetupCost != 0)
+ OS << ", plus " << SetupCost << " setup cost";
+}
+void Cost::dump() const {
+ print(errs()); errs() << '\n';
+}
- SeparateSubExprs(SubExprs, SARE->getOperand(0), SE);
- }
- } else if (!Expr->isZero()) {
- // Do not add zero.
- SubExprs.push_back(Expr);
- }
-}
-
-// This is logically local to the following function, but C++ says we have
-// to make it file scope.
-struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
-
-/// RemoveCommonExpressionsFromUseBases - Look through all of the Bases of all
-/// the Uses, removing any common subexpressions, except that if all such
-/// subexpressions can be folded into an addressing mode for all uses inside
-/// the loop (this case is referred to as "free" in comments herein) we do
-/// not remove anything. This looks for things like (a+b+c) and
-/// (a+c+d) and computes the common (a+c) subexpression. The common expression
-/// is *removed* from the Bases and returned.
-static const SCEV *
-RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
- ScalarEvolution *SE, Loop *L,
- const TargetLowering *TLI) {
- unsigned NumUses = Uses.size();
-
- // Only one use? This is a very common case, so we handle it specially and
- // cheaply.
- const SCEV *Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
- const SCEV *Result = Zero;
- const SCEV *FreeResult = Zero;
- if (NumUses == 1) {
- // If the use is inside the loop, use its base, regardless of what it is:
- // it is clearly shared across all the IV's. If the use is outside the loop
- // (which means after it) we don't want to factor anything *into* the loop,
- // so just use 0 as the base.
- if (L->contains(Uses[0].Inst))
- std::swap(Result, Uses[0].Base);
- return Result;
- }
+namespace {
- // To find common subexpressions, count how many of Uses use each expression.
- // If any subexpressions are used Uses.size() times, they are common.
- // Also track whether all uses of each expression can be moved into an
- // an addressing mode "for free"; such expressions are left within the loop.
- // struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
- std::map<const SCEV *, SubExprUseData> SubExpressionUseData;
-
- // UniqueSubExprs - Keep track of all of the subexpressions we see in the
- // order we see them.
- SmallVector<const SCEV *, 16> UniqueSubExprs;
-
- SmallVector<const SCEV *, 16> SubExprs;
- unsigned NumUsesInsideLoop = 0;
- for (unsigned i = 0; i != NumUses; ++i) {
- // If the user is outside the loop, just ignore it for base computation.
- // Since the user is outside the loop, it must be *after* the loop (if it
- // were before, it could not be based on the loop IV). We don't want users
- // after the loop to affect base computation of values *inside* the loop,
- // because we can always add their offsets to the result IV after the loop
- // is done, ensuring we get good code inside the loop.
- if (!L->contains(Uses[i].Inst))
- continue;
- NumUsesInsideLoop++;
+/// LSRFixup - An operand value in an instruction which is to be replaced
+/// with some equivalent, possibly strength-reduced, replacement.
+struct LSRFixup {
+ /// UserInst - The instruction which will be updated.
+ Instruction *UserInst;
- // If the base is zero (which is common), return zero now, there are no
- // CSEs we can find.
- if (Uses[i].Base == Zero) return Zero;
+ /// OperandValToReplace - The operand of the instruction which will
+ /// be replaced. The operand may be used more than once; every instance
+ /// will be replaced.
+ Value *OperandValToReplace;
- // If this use is as an address we may be able to put CSEs in the addressing
- // mode rather than hoisting them.
- bool isAddrUse = isAddressUse(Uses[i].Inst, Uses[i].OperandValToReplace);
- // We may need the AccessTy below, but only when isAddrUse, so compute it
- // only in that case.
- const Type *AccessTy = 0;
- if (isAddrUse)
- AccessTy = getAccessType(Uses[i].Inst);
-
- // Split the expression into subexprs.
- SeparateSubExprs(SubExprs, Uses[i].Base, SE);
- // Add one to SubExpressionUseData.Count for each subexpr present, and
- // if the subexpr is not a valid immediate within an addressing mode use,
- // set SubExpressionUseData.notAllUsesAreFree. We definitely want to
- // hoist these out of the loop (if they are common to all uses).
- for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
- if (++SubExpressionUseData[SubExprs[j]].Count == 1)
- UniqueSubExprs.push_back(SubExprs[j]);
- if (!isAddrUse || !fitsInAddressMode(SubExprs[j], AccessTy, TLI, false))
- SubExpressionUseData[SubExprs[j]].notAllUsesAreFree = true;
- }
- SubExprs.clear();
- }
-
- // Now that we know how many times each is used, build Result. Iterate over
- // UniqueSubexprs so that we have a stable ordering.
- for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) {
- std::map<const SCEV *, SubExprUseData>::iterator I =
- SubExpressionUseData.find(UniqueSubExprs[i]);
- assert(I != SubExpressionUseData.end() && "Entry not found?");
- if (I->second.Count == NumUsesInsideLoop) { // Found CSE!
- if (I->second.notAllUsesAreFree)
- Result = SE->getAddExpr(Result, I->first);
- else
- FreeResult = SE->getAddExpr(FreeResult, I->first);
- } else
- // Remove non-cse's from SubExpressionUseData.
- SubExpressionUseData.erase(I);
- }
-
- if (FreeResult != Zero) {
- // We have some subexpressions that can be subsumed into addressing
- // modes in every use inside the loop. However, it's possible that
- // there are so many of them that the combined FreeResult cannot
- // be subsumed, or that the target cannot handle both a FreeResult
- // and a Result in the same instruction (for example because it would
- // require too many registers). Check this.
- for (unsigned i=0; i<NumUses; ++i) {
- if (!L->contains(Uses[i].Inst))
- continue;
- // We know this is an addressing mode use; if there are any uses that
- // are not, FreeResult would be Zero.
- const Type *AccessTy = getAccessType(Uses[i].Inst);
- if (!fitsInAddressMode(FreeResult, AccessTy, TLI, Result!=Zero)) {
- // FIXME: could split up FreeResult into pieces here, some hoisted
- // and some not. There is no obvious advantage to this.
- Result = SE->getAddExpr(Result, FreeResult);
- FreeResult = Zero;
- break;
- }
- }
- }
+ /// PostIncLoop - If this user is to use the post-incremented value of an
+ /// induction variable, this variable is non-null and holds the loop
+ /// associated with the induction variable.
+ const Loop *PostIncLoop;
- // If we found no CSE's, return now.
- if (Result == Zero) return Result;
+ /// LUIdx - The index of the LSRUse describing the expression which
+ /// this fixup needs, minus an offset (below).
+ size_t LUIdx;
- // If we still have a FreeResult, remove its subexpressions from
- // SubExpressionUseData. This means they will remain in the use Bases.
- if (FreeResult != Zero) {
- SeparateSubExprs(SubExprs, FreeResult, SE);
- for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
- std::map<const SCEV *, SubExprUseData>::iterator I =
- SubExpressionUseData.find(SubExprs[j]);
- SubExpressionUseData.erase(I);
- }
- SubExprs.clear();
- }
+ /// Offset - A constant offset to be added to the LSRUse expression.
+ /// This allows multiple fixups to share the same LSRUse with different
+ /// offsets, for example in an unrolled loop.
+ int64_t Offset;
- // Otherwise, remove all of the CSE's we found from each of the base values.
- for (unsigned i = 0; i != NumUses; ++i) {
- // Uses outside the loop don't necessarily include the common base, but
- // the final IV value coming into those uses does. Instead of trying to
- // remove the pieces of the common base, which might not be there,
- // subtract off the base to compensate for this.
- if (!L->contains(Uses[i].Inst)) {
- Uses[i].Base = SE->getMinusSCEV(Uses[i].Base, Result);
- continue;
- }
+ LSRFixup();
- // Split the expression into subexprs.
- SeparateSubExprs(SubExprs, Uses[i].Base, SE);
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
- // Remove any common subexpressions.
- for (unsigned j = 0, e = SubExprs.size(); j != e; ++j)
- if (SubExpressionUseData.count(SubExprs[j])) {
- SubExprs.erase(SubExprs.begin()+j);
- --j; --e;
- }
+}
- // Finally, add the non-shared expressions together.
- if (SubExprs.empty())
- Uses[i].Base = Zero;
- else
- Uses[i].Base = SE->getAddExpr(SubExprs);
- SubExprs.clear();
+LSRFixup::LSRFixup()
+ : UserInst(0), OperandValToReplace(0), PostIncLoop(0),
+ LUIdx(~size_t(0)), Offset(0) {}
+
+void LSRFixup::print(raw_ostream &OS) const {
+ OS << "UserInst=";
+ // Store is common and interesting enough to be worth special-casing.
+ if (StoreInst *Store = dyn_cast<StoreInst>(UserInst)) {
+ OS << "store ";
+ WriteAsOperand(OS, Store->getOperand(0), /*PrintType=*/false);
+ } else if (UserInst->getType()->isVoidTy())
+ OS << UserInst->getOpcodeName();
+ else
+ WriteAsOperand(OS, UserInst, /*PrintType=*/false);
+
+ OS << ", OperandValToReplace=";
+ WriteAsOperand(OS, OperandValToReplace, /*PrintType=*/false);
+
+ if (PostIncLoop) {
+ OS << ", PostIncLoop=";
+ WriteAsOperand(OS, PostIncLoop->getHeader(), /*PrintType=*/false);
}
- return Result;
-}
+ if (LUIdx != ~size_t(0))
+ OS << ", LUIdx=" << LUIdx;
-/// ValidScale - Check whether the given Scale is valid for all loads and
-/// stores in UsersToProcess.
-///
-bool LoopStrengthReduce::ValidScale(bool HasBaseReg, int64_t Scale,
- const std::vector<BasedUser>& UsersToProcess) {
- if (!TLI)
- return true;
+ if (Offset != 0)
+ OS << ", Offset=" << Offset;
+}
- for (unsigned i = 0, e = UsersToProcess.size(); i!=e; ++i) {
- // If this is a load or other access, pass the type of the access in.
- const Type *AccessTy =
- Type::getVoidTy(UsersToProcess[i].Inst->getContext());
- if (isAddressUse(UsersToProcess[i].Inst,
- UsersToProcess[i].OperandValToReplace))
- AccessTy = getAccessType(UsersToProcess[i].Inst);
- else if (isa<PHINode>(UsersToProcess[i].Inst))
- continue;
+void LSRFixup::dump() const {
+ print(errs()); errs() << '\n';
+}
- TargetLowering::AddrMode AM;
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
- AM.BaseOffs = SC->getValue()->getSExtValue();
- AM.HasBaseReg = HasBaseReg || !UsersToProcess[i].Base->isZero();
- AM.Scale = Scale;
+namespace {
- // If load[imm+r*scale] is illegal, bail out.
- if (!TLI->isLegalAddressingMode(AM, AccessTy))
- return false;
+/// UniquifierDenseMapInfo - A DenseMapInfo implementation for holding
+/// DenseMaps and DenseSets of sorted SmallVectors of const SCEV*.
+struct UniquifierDenseMapInfo {
+ static SmallVector<const SCEV *, 2> getEmptyKey() {
+ SmallVector<const SCEV *, 2> V;
+ V.push_back(reinterpret_cast<const SCEV *>(-1));
+ return V;
}
- return true;
-}
-
-/// ValidOffset - Check whether the given Offset is valid for all loads and
-/// stores in UsersToProcess.
-///
-bool LoopStrengthReduce::ValidOffset(bool HasBaseReg,
- int64_t Offset,
- int64_t Scale,
- const std::vector<BasedUser>& UsersToProcess) {
- if (!TLI)
- return true;
- for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i) {
- // If this is a load or other access, pass the type of the access in.
- const Type *AccessTy =
- Type::getVoidTy(UsersToProcess[i].Inst->getContext());
- if (isAddressUse(UsersToProcess[i].Inst,
- UsersToProcess[i].OperandValToReplace))
- AccessTy = getAccessType(UsersToProcess[i].Inst);
- else if (isa<PHINode>(UsersToProcess[i].Inst))
- continue;
+ static SmallVector<const SCEV *, 2> getTombstoneKey() {
+ SmallVector<const SCEV *, 2> V;
+ V.push_back(reinterpret_cast<const SCEV *>(-2));
+ return V;
+ }
- TargetLowering::AddrMode AM;
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
- AM.BaseOffs = SC->getValue()->getSExtValue();
- AM.BaseOffs = (uint64_t)AM.BaseOffs + (uint64_t)Offset;
- AM.HasBaseReg = HasBaseReg || !UsersToProcess[i].Base->isZero();
- AM.Scale = Scale;
+ static unsigned getHashValue(const SmallVector<const SCEV *, 2> &V) {
+ unsigned Result = 0;
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = V.begin(),
+ E = V.end(); I != E; ++I)
+ Result ^= DenseMapInfo<const SCEV *>::getHashValue(*I);
+ return Result;
+ }
- // If load[imm+r*scale] is illegal, bail out.
- if (!TLI->isLegalAddressingMode(AM, AccessTy))
- return false;
+ static bool isEqual(const SmallVector<const SCEV *, 2> &LHS,
+ const SmallVector<const SCEV *, 2> &RHS) {
+ return LHS == RHS;
}
- return true;
-}
+};
+
+/// LSRUse - This class holds the state that LSR keeps for each use in
+/// IVUsers, as well as uses invented by LSR itself. It includes information
+/// about what kinds of things can be folded into the user, information about
+/// the user itself, and information about how the use may be satisfied.
+/// TODO: Represent multiple users of the same expression in common?
+class LSRUse {
+ DenseSet<SmallVector<const SCEV *, 2>, UniquifierDenseMapInfo> Uniquifier;
+
+public:
+ /// KindType - An enum for a kind of use, indicating what types of
+ /// scaled and immediate operands it might support.
+ enum KindType {
+ Basic, ///< A normal use, with no folding.
+ Special, ///< A special case of basic, allowing -1 scales.
+ Address, ///< An address use; folding according to TargetLowering
+ ICmpZero ///< An equality icmp with both operands folded into one.
+ // TODO: Add a generic icmp too?
+ };
-/// RequiresTypeConversion - Returns true if converting Ty1 to Ty2 is not
-/// a nop.
-bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1,
- const Type *Ty2) {
- if (Ty1 == Ty2)
- return false;
- Ty1 = SE->getEffectiveSCEVType(Ty1);
- Ty2 = SE->getEffectiveSCEVType(Ty2);
- if (Ty1 == Ty2)
- return false;
- if (Ty1->canLosslesslyBitCastTo(Ty2))
- return false;
- if (TLI && TLI->isTruncateFree(Ty1, Ty2))
- return false;
- return true;
-}
+ KindType Kind;
+ const Type *AccessTy;
-/// CheckForIVReuse - Returns the multiple if the stride is the multiple
-/// of a previous stride and it is a legal value for the target addressing
-/// mode scale component and optional base reg. This allows the users of
-/// this stride to be rewritten as prev iv * factor. It returns 0 if no
-/// reuse is possible. Factors can be negative on same targets, e.g. ARM.
-///
-/// If all uses are outside the loop, we don't require that all multiplies
-/// be folded into the addressing mode, nor even that the factor be constant;
-/// a multiply (executed once) outside the loop is better than another IV
-/// within. Well, usually.
-const SCEV *LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
- bool AllUsesAreAddresses,
- bool AllUsesAreOutsideLoop,
- const SCEV *Stride,
- IVExpr &IV, const Type *Ty,
- const std::vector<BasedUser>& UsersToProcess) {
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Stride)) {
- int64_t SInt = SC->getValue()->getSExtValue();
- for (unsigned NewStride = 0, e = IU->StrideOrder.size();
- NewStride != e; ++NewStride) {
- std::map<const SCEV *, IVsOfOneStride>::iterator SI =
- IVsByStride.find(IU->StrideOrder[NewStride]);
- if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
- continue;
- // The other stride has no uses, don't reuse it.
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator UI =
- IU->IVUsesByStride.find(IU->StrideOrder[NewStride]);
- if (UI->second->Users.empty())
- continue;
- int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
- if (SI->first != Stride &&
- (unsigned(abs64(SInt)) < SSInt || (SInt % SSInt) != 0))
- continue;
- int64_t Scale = SInt / SSInt;
- // Check that this stride is valid for all the types used for loads and
- // stores; if it can be used for some and not others, we might as well use
- // the original stride everywhere, since we have to create the IV for it
- // anyway. If the scale is 1, then we don't need to worry about folding
- // multiplications.
- if (Scale == 1 ||
- (AllUsesAreAddresses &&
- ValidScale(HasBaseReg, Scale, UsersToProcess))) {
- // Prefer to reuse an IV with a base of zero.
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Only reuse previous IV if it would not require a type conversion
- // and if the base difference can be folded.
- if (II->Base->isZero() &&
- !RequiresTypeConversion(II->Base->getType(), Ty)) {
- IV = *II;
- return SE->getIntegerSCEV(Scale, Stride->getType());
- }
- // Otherwise, settle for an IV with a foldable base.
- if (AllUsesAreAddresses)
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Only reuse previous IV if it would not require a type conversion
- // and if the base difference can be folded.
- if (SE->getEffectiveSCEVType(II->Base->getType()) ==
- SE->getEffectiveSCEVType(Ty) &&
- isa<SCEVConstant>(II->Base)) {
- int64_t Base =
- cast<SCEVConstant>(II->Base)->getValue()->getSExtValue();
- if (Base > INT32_MIN && Base <= INT32_MAX &&
- ValidOffset(HasBaseReg, -Base * Scale,
- Scale, UsersToProcess)) {
- IV = *II;
- return SE->getIntegerSCEV(Scale, Stride->getType());
- }
- }
- }
- }
- } else if (AllUsesAreOutsideLoop) {
- // Accept nonconstant strides here; it is really really right to substitute
- // an existing IV if we can.
- for (unsigned NewStride = 0, e = IU->StrideOrder.size();
- NewStride != e; ++NewStride) {
- std::map<const SCEV *, IVsOfOneStride>::iterator SI =
- IVsByStride.find(IU->StrideOrder[NewStride]);
- if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
- continue;
- int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
- if (SI->first != Stride && SSInt != 1)
- continue;
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Accept nonzero base here.
- // Only reuse previous IV if it would not require a type conversion.
- if (!RequiresTypeConversion(II->Base->getType(), Ty)) {
- IV = *II;
- return Stride;
- }
- }
- // Special case, old IV is -1*x and this one is x. Can treat this one as
- // -1*old.
- for (unsigned NewStride = 0, e = IU->StrideOrder.size();
- NewStride != e; ++NewStride) {
- std::map<const SCEV *, IVsOfOneStride>::iterator SI =
- IVsByStride.find(IU->StrideOrder[NewStride]);
- if (SI == IVsByStride.end())
- continue;
- if (const SCEVMulExpr *ME = dyn_cast<SCEVMulExpr>(SI->first))
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(ME->getOperand(0)))
- if (Stride == ME->getOperand(1) &&
- SC->getValue()->getSExtValue() == -1LL)
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Accept nonzero base here.
- // Only reuse previous IV if it would not require type conversion.
- if (!RequiresTypeConversion(II->Base->getType(), Ty)) {
- IV = *II;
- return SE->getIntegerSCEV(-1LL, Stride->getType());
- }
- }
- }
- return SE->getIntegerSCEV(0, Stride->getType());
-}
-
-/// PartitionByIsUseOfPostIncrementedValue - Simple boolean predicate that
-/// returns true if Val's isUseOfPostIncrementedValue is true.
-static bool PartitionByIsUseOfPostIncrementedValue(const BasedUser &Val) {
- return Val.isUseOfPostIncrementedValue;
-}
-
-/// isNonConstantNegative - Return true if the specified scev is negated, but
-/// not a constant.
-static bool isNonConstantNegative(const SCEV *Expr) {
- const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Expr);
- 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();
-}
-
-/// CollectIVUsers - Transform our list of users and offsets to a bit more
-/// complex table. In this new vector, each 'BasedUser' contains 'Base', the
-/// base of the strided accesses, as well as the old information from Uses. We
-/// progressively move information from the Base field to the Imm field, until
-/// we eventually have the full access expression to rewrite the use.
-const SCEV *LoopStrengthReduce::CollectIVUsers(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L,
- bool &AllUsesAreAddresses,
- bool &AllUsesAreOutsideLoop,
- std::vector<BasedUser> &UsersToProcess) {
- // FIXME: Generalize to non-affine IV's.
- if (!Stride->isLoopInvariant(L))
- return SE->getIntegerSCEV(0, Stride->getType());
-
- UsersToProcess.reserve(Uses.Users.size());
- for (ilist<IVStrideUse>::iterator I = Uses.Users.begin(),
- E = Uses.Users.end(); I != E; ++I) {
- UsersToProcess.push_back(BasedUser(*I, SE));
-
- // Move any loop variant operands from the offset field to the immediate
- // field of the use, so that we don't try to use something before it is
- // computed.
- MoveLoopVariantsToImmediateField(UsersToProcess.back().Base,
- UsersToProcess.back().Imm, L, SE);
- assert(UsersToProcess.back().Base->isLoopInvariant(L) &&
- "Base value is not loop invariant!");
- }
-
- // We now have a whole bunch of uses of like-strided induction variables, but
- // they might all have different bases. We want to emit one PHI node for this
- // stride which we fold as many common expressions (between the IVs) into as
- // possible. Start by identifying the common expressions in the base values
- // for the strides (e.g. if we have "A+C+B" and "A+B+D" as our bases, find
- // "A+B"), emit it to the preheader, then remove the expression from the
- // UsersToProcess base values.
- const SCEV *CommonExprs =
- RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L, TLI);
-
- // Next, figure out what we can represent in the immediate fields of
- // instructions. If we can represent anything there, move it to the imm
- // fields of the BasedUsers. We do this so that it increases the commonality
- // of the remaining uses.
- unsigned NumPHI = 0;
- bool HasAddress = false;
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
- // If the user is not in the current loop, this means it is using the exit
- // value of the IV. Do not put anything in the base, make sure it's all in
- // the immediate field to allow as much factoring as possible.
- if (!L->contains(UsersToProcess[i].Inst)) {
- UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm,
- UsersToProcess[i].Base);
- UsersToProcess[i].Base =
- SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType());
- } else {
- // Not all uses are outside the loop.
- AllUsesAreOutsideLoop = false;
-
- // Addressing modes can be folded into loads and stores. Be careful that
- // the store is through the expression, not of the expression though.
- bool isPHI = false;
- bool isAddress = isAddressUse(UsersToProcess[i].Inst,
- UsersToProcess[i].OperandValToReplace);
- if (isa<PHINode>(UsersToProcess[i].Inst)) {
- isPHI = true;
- ++NumPHI;
- }
+ SmallVector<int64_t, 8> Offsets;
+ int64_t MinOffset;
+ int64_t MaxOffset;
- if (isAddress)
- HasAddress = true;
+ /// AllFixupsOutsideLoop - This records whether all of the fixups using this
+ /// LSRUse are outside of the loop, in which case some special-case heuristics
+ /// may be used.
+ bool AllFixupsOutsideLoop;
- // If this use isn't an address, then not all uses are addresses.
- if (!isAddress && !isPHI)
- AllUsesAreAddresses = false;
+ /// Formulae - A list of ways to build a value that can satisfy this user.
+ /// After the list is populated, one of these is selected heuristically and
+ /// used to formulate a replacement for OperandValToReplace in UserInst.
+ SmallVector<Formula, 12> Formulae;
- MoveImmediateValues(TLI, UsersToProcess[i].Inst, UsersToProcess[i].Base,
- UsersToProcess[i].Imm, isAddress, L, SE);
- }
- }
+ /// Regs - The set of register candidates used by all formulae in this LSRUse.
+ SmallPtrSet<const SCEV *, 4> Regs;
- // If one of the use is a PHI node and all other uses are addresses, still
- // allow iv reuse. Essentially we are trading one constant multiplication
- // for one fewer iv.
- if (NumPHI > 1)
- AllUsesAreAddresses = false;
+ LSRUse(KindType K, const Type *T) : Kind(K), AccessTy(T),
+ MinOffset(INT64_MAX),
+ MaxOffset(INT64_MIN),
+ AllFixupsOutsideLoop(true) {}
- // There are no in-loop address uses.
- if (AllUsesAreAddresses && (!HasAddress && !AllUsesAreOutsideLoop))
- AllUsesAreAddresses = false;
+ bool InsertFormula(const Formula &F);
- return CommonExprs;
-}
+ void check() const;
-/// ShouldUseFullStrengthReductionMode - Test whether full strength-reduction
-/// is valid and profitable for the given set of users of a stride. In
-/// full strength-reduction mode, all addresses at the current stride are
-/// strength-reduced all the way down to pointer arithmetic.
-///
-bool LoopStrengthReduce::ShouldUseFullStrengthReductionMode(
- const std::vector<BasedUser> &UsersToProcess,
- const Loop *L,
- bool AllUsesAreAddresses,
- const SCEV *Stride) {
- if (!EnableFullLSRMode)
- return false;
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
- // The heuristics below aim to avoid increasing register pressure, but
- // fully strength-reducing all the addresses increases the number of
- // add instructions, so don't do this when optimizing for size.
- // TODO: If the loop is large, the savings due to simpler addresses
- // may oughtweight the costs of the extra increment instructions.
- if (L->getHeader()->getParent()->hasFnAttr(Attribute::OptimizeForSize))
- return false;
+/// InsertFormula - If the given formula has not yet been inserted, add it to
+/// the list, and return true. Return false otherwise.
+bool LSRUse::InsertFormula(const Formula &F) {
+ SmallVector<const SCEV *, 2> Key = F.BaseRegs;
+ if (F.ScaledReg) Key.push_back(F.ScaledReg);
+ // Unstable sort by host order ok, because this is only used for uniquifying.
+ std::sort(Key.begin(), Key.end());
- // TODO: For now, don't do full strength reduction if there could
- // potentially be greater-stride multiples of the current stride
- // which could reuse the current stride IV.
- if (IU->StrideOrder.back() != Stride)
+ if (!Uniquifier.insert(Key).second)
return false;
- // Iterate through the uses to find conditions that automatically rule out
- // full-lsr mode.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ) {
- const SCEV *Base = UsersToProcess[i].Base;
- const SCEV *Imm = UsersToProcess[i].Imm;
- // If any users have a loop-variant component, they can't be fully
- // strength-reduced.
- if (Imm && !Imm->isLoopInvariant(L))
- return false;
- // If there are to users with the same base and the difference between
- // the two Imm values can't be folded into the address, full
- // strength reduction would increase register pressure.
- do {
- const SCEV *CurImm = UsersToProcess[i].Imm;
- if ((CurImm || Imm) && CurImm != Imm) {
- if (!CurImm) CurImm = SE->getIntegerSCEV(0, Stride->getType());
- if (!Imm) Imm = SE->getIntegerSCEV(0, Stride->getType());
- const Instruction *Inst = UsersToProcess[i].Inst;
- const Type *AccessTy = getAccessType(Inst);
- const SCEV *Diff = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
- if (!Diff->isZero() &&
- (!AllUsesAreAddresses ||
- !fitsInAddressMode(Diff, AccessTy, TLI, /*HasBaseReg=*/true)))
- return false;
- }
- } while (++i != e && Base == UsersToProcess[i].Base);
- }
+ // Using a register to hold the value of 0 is not profitable.
+ assert((!F.ScaledReg || !F.ScaledReg->isZero()) &&
+ "Zero allocated in a scaled register!");
+#ifndef NDEBUG
+ for (SmallVectorImpl<const SCEV *>::const_iterator I =
+ F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++I)
+ assert(!(*I)->isZero() && "Zero allocated in a base register!");
+#endif
- // If there's exactly one user in this stride, fully strength-reducing it
- // won't increase register pressure. If it's starting from a non-zero base,
- // it'll be simpler this way.
- if (UsersToProcess.size() == 1 && !UsersToProcess[0].Base->isZero())
- return true;
+ // Add the formula to the list.
+ Formulae.push_back(F);
- // Otherwise, if there are any users in this stride that don't require
- // a register for their base, full strength-reduction will increase
- // register pressure.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- if (UsersToProcess[i].Base->isZero())
- return false;
+ // Record registers now being used by this use.
+ if (F.ScaledReg) Regs.insert(F.ScaledReg);
+ Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
- // Otherwise, go for it.
return true;
}
-/// InsertAffinePhi Create and insert a PHI node for an induction variable
-/// with the specified start and step values in the specified loop.
-///
-/// If NegateStride is true, the stride should be negated by using a
-/// subtract instead of an add.
-///
-/// Return the created phi node.
-///
-static PHINode *InsertAffinePhi(const SCEV *Start, const SCEV *Step,
- Instruction *IVIncInsertPt,
- const Loop *L,
- SCEVExpander &Rewriter) {
- assert(Start->isLoopInvariant(L) && "New PHI start is not loop invariant!");
- assert(Step->isLoopInvariant(L) && "New PHI stride is not loop invariant!");
-
- BasicBlock *Header = L->getHeader();
- BasicBlock *Preheader = L->getLoopPreheader();
- BasicBlock *LatchBlock = L->getLoopLatch();
- const Type *Ty = Start->getType();
- Ty = Rewriter.SE.getEffectiveSCEVType(Ty);
-
- PHINode *PN = PHINode::Create(Ty, "lsr.iv", Header->begin());
- PN->addIncoming(Rewriter.expandCodeFor(Start, Ty, Preheader->getTerminator()),
- Preheader);
-
- // If the stride is negative, insert a sub instead of an add for the
- // increment.
- bool isNegative = isNonConstantNegative(Step);
- const SCEV *IncAmount = Step;
- if (isNegative)
- IncAmount = Rewriter.SE.getNegativeSCEV(Step);
-
- // Insert an add instruction right before the terminator corresponding
- // to the back-edge or just before the only use. The location is determined
- // by the caller and passed in as IVIncInsertPt.
- Value *StepV = Rewriter.expandCodeFor(IncAmount, Ty,
- Preheader->getTerminator());
- Instruction *IncV;
- if (isNegative) {
- IncV = BinaryOperator::CreateSub(PN, StepV, "lsr.iv.next",
- IVIncInsertPt);
- } else {
- IncV = BinaryOperator::CreateAdd(PN, StepV, "lsr.iv.next",
- IVIncInsertPt);
- }
- if (!isa<ConstantInt>(StepV)) ++NumVariable;
-
- PN->addIncoming(IncV, LatchBlock);
-
- ++NumInserted;
- return PN;
-}
-
-static void SortUsersToProcess(std::vector<BasedUser> &UsersToProcess) {
- // We want to emit code for users inside the loop first. To do this, we
- // rearrange BasedUser so that the entries at the end have
- // isUseOfPostIncrementedValue = false, because we pop off the end of the
- // vector (so we handle them first).
- std::partition(UsersToProcess.begin(), UsersToProcess.end(),
- PartitionByIsUseOfPostIncrementedValue);
-
- // Sort this by base, so that things with the same base are handled
- // together. By partitioning first and stable-sorting later, we are
- // guaranteed that within each base we will pop off users from within the
- // loop before users outside of the loop with a particular base.
- //
- // We would like to use stable_sort here, but we can't. The problem is that
- // const SCEV *'s don't have a deterministic ordering w.r.t to each other, so
- // we don't have anything to do a '<' comparison on. Because we think the
- // number of uses is small, do a horrible bubble sort which just relies on
- // ==.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
- // Get a base value.
- const SCEV *Base = UsersToProcess[i].Base;
-
- // Compact everything with this base to be consecutive with this one.
- for (unsigned j = i+1; j != e; ++j) {
- if (UsersToProcess[j].Base == Base) {
- std::swap(UsersToProcess[i+1], UsersToProcess[j]);
- ++i;
- }
- }
+void LSRUse::print(raw_ostream &OS) const {
+ OS << "LSR Use: Kind=";
+ switch (Kind) {
+ case Basic: OS << "Basic"; break;
+ case Special: OS << "Special"; break;
+ case ICmpZero: OS << "ICmpZero"; break;
+ case Address:
+ OS << "Address of ";
+ if (AccessTy->isPointerTy())
+ OS << "pointer"; // the full pointer type could be really verbose
+ else
+ OS << *AccessTy;
}
-}
-/// PrepareToStrengthReduceFully - Prepare to fully strength-reduce
-/// UsersToProcess, meaning lowering addresses all the way down to direct
-/// pointer arithmetic.
-///
-void
-LoopStrengthReduce::PrepareToStrengthReduceFully(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- const Loop *L,
- SCEVExpander &PreheaderRewriter) {
- DEBUG(dbgs() << " Fully reducing all users\n");
-
- // Rewrite the UsersToProcess records, creating a separate PHI for each
- // unique Base value.
- Instruction *IVIncInsertPt = L->getLoopLatch()->getTerminator();
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ) {
- // TODO: The uses are grouped by base, but not sorted. We arbitrarily
- // pick the first Imm value here to start with, and adjust it for the
- // other uses.
- const SCEV *Imm = UsersToProcess[i].Imm;
- const SCEV *Base = UsersToProcess[i].Base;
- const SCEV *Start = SE->getAddExpr(CommonExprs, Base, Imm);
- PHINode *Phi = InsertAffinePhi(Start, Stride, IVIncInsertPt, L,
- PreheaderRewriter);
- // Loop over all the users with the same base.
- do {
- UsersToProcess[i].Base = SE->getIntegerSCEV(0, Stride->getType());
- UsersToProcess[i].Imm = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
- UsersToProcess[i].Phi = Phi;
- assert(UsersToProcess[i].Imm->isLoopInvariant(L) &&
- "ShouldUseFullStrengthReductionMode should reject this!");
- } while (++i != e && Base == UsersToProcess[i].Base);
- }
-}
-
-/// FindIVIncInsertPt - Return the location to insert the increment instruction.
-/// If the only use if a use of postinc value, (must be the loop termination
-/// condition), then insert it just before the use.
-static Instruction *FindIVIncInsertPt(std::vector<BasedUser> &UsersToProcess,
- const Loop *L) {
- if (UsersToProcess.size() == 1 &&
- UsersToProcess[0].isUseOfPostIncrementedValue &&
- L->contains(UsersToProcess[0].Inst))
- return UsersToProcess[0].Inst;
- return L->getLoopLatch()->getTerminator();
-}
-
-/// PrepareToStrengthReduceWithNewPhi - Insert a new induction variable for the
-/// given users to share.
-///
-void
-LoopStrengthReduce::PrepareToStrengthReduceWithNewPhi(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- Value *CommonBaseV,
- Instruction *IVIncInsertPt,
- const Loop *L,
- SCEVExpander &PreheaderRewriter) {
- DEBUG(dbgs() << " Inserting new PHI:\n");
-
- PHINode *Phi = InsertAffinePhi(SE->getUnknown(CommonBaseV),
- Stride, IVIncInsertPt, L,
- PreheaderRewriter);
-
- // Remember this in case a later stride is multiple of this.
- IVsByStride[Stride].addIV(Stride, CommonExprs, Phi);
-
- // All the users will share this new IV.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- UsersToProcess[i].Phi = Phi;
-
- DEBUG(dbgs() << " IV=");
- DEBUG(WriteAsOperand(dbgs(), Phi, /*PrintType=*/false));
- DEBUG(dbgs() << "\n");
-}
-
-/// PrepareToStrengthReduceFromSmallerStride - Prepare for the given users to
-/// reuse an induction variable with a stride that is a factor of the current
-/// induction variable.
-///
-void
-LoopStrengthReduce::PrepareToStrengthReduceFromSmallerStride(
- std::vector<BasedUser> &UsersToProcess,
- Value *CommonBaseV,
- const IVExpr &ReuseIV,
- Instruction *PreInsertPt) {
- DEBUG(dbgs() << " Rewriting in terms of existing IV of STRIDE "
- << *ReuseIV.Stride << " and BASE " << *ReuseIV.Base << "\n");
-
- // All the users will share the reused IV.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- UsersToProcess[i].Phi = ReuseIV.PHI;
-
- Constant *C = dyn_cast<Constant>(CommonBaseV);
- if (C &&
- (!C->isNullValue() &&
- !fitsInAddressMode(SE->getUnknown(CommonBaseV), CommonBaseV->getType(),
- TLI, false)))
- // We want the common base emitted into the preheader! This is just
- // using cast as a copy so BitCast (no-op cast) is appropriate
- CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV->getType(),
- "commonbase", PreInsertPt);
-}
-
-static bool IsImmFoldedIntoAddrMode(GlobalValue *GV, int64_t Offset,
- const Type *AccessTy,
- std::vector<BasedUser> &UsersToProcess,
- const TargetLowering *TLI) {
- SmallVector<Instruction*, 16> AddrModeInsts;
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
- if (UsersToProcess[i].isUseOfPostIncrementedValue)
- continue;
- ExtAddrMode AddrMode =
- AddressingModeMatcher::Match(UsersToProcess[i].OperandValToReplace,
- AccessTy, UsersToProcess[i].Inst,
- AddrModeInsts, *TLI);
- if (GV && GV != AddrMode.BaseGV)
- return false;
- if (Offset && !AddrMode.BaseOffs)
- // FIXME: How to accurate check it's immediate offset is folded.
- return false;
- AddrModeInsts.clear();
+ OS << ", Offsets={";
+ for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
+ E = Offsets.end(); I != E; ++I) {
+ OS << *I;
+ if (next(I) != E)
+ OS << ',';
}
- return true;
-}
+ OS << '}';
-/// StrengthReduceIVUsersOfStride - Strength reduce all of the users of a single
-/// stride of IV. All of the users may have different starting values, and this
-/// may not be the only stride.
-void
-LoopStrengthReduce::StrengthReduceIVUsersOfStride(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L) {
- // If all the users are moved to another stride, then there is nothing to do.
- if (Uses.Users.empty())
- return;
+ if (AllFixupsOutsideLoop)
+ OS << ", all-fixups-outside-loop";
+}
- // Keep track if every use in UsersToProcess is an address. If they all are,
- // we may be able to rewrite the entire collection of them in terms of a
- // smaller-stride IV.
- bool AllUsesAreAddresses = true;
-
- // Keep track if every use of a single stride is outside the loop. If so,
- // we want to be more aggressive about reusing a smaller-stride IV; a
- // multiply outside the loop is better than another IV inside. Well, usually.
- bool AllUsesAreOutsideLoop = true;
-
- // Transform our list of users and offsets to a bit more complex table. In
- // this new vector, each 'BasedUser' contains 'Base' the base of the strided
- // access as well as the old information from Uses. We progressively move
- // information from the Base field to the Imm field until we eventually have
- // the full access expression to rewrite the use.
- std::vector<BasedUser> UsersToProcess;
- const SCEV *CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- UsersToProcess);
-
- // Sort the UsersToProcess array so that users with common bases are
- // next to each other.
- SortUsersToProcess(UsersToProcess);
-
- // If we managed to find some expressions in common, we'll need to carry
- // their value in a register and add it in for each use. This will take up
- // a register operand, which potentially restricts what stride values are
- // valid.
- bool HaveCommonExprs = !CommonExprs->isZero();
- const Type *ReplacedTy = CommonExprs->getType();
-
- // If all uses are addresses, consider sinking the immediate part of the
- // common expression back into uses if they can fit in the immediate fields.
- if (TLI && HaveCommonExprs && AllUsesAreAddresses) {
- const SCEV *NewCommon = CommonExprs;
- const SCEV *Imm = SE->getIntegerSCEV(0, ReplacedTy);
- MoveImmediateValues(TLI, Type::getVoidTy(
- L->getLoopPreheader()->getContext()),
- NewCommon, Imm, true, L, SE);
- if (!Imm->isZero()) {
- bool DoSink = true;
-
- // If the immediate part of the common expression is a GV, check if it's
- // possible to fold it into the target addressing mode.
- GlobalValue *GV = 0;
- if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(Imm))
- GV = dyn_cast<GlobalValue>(SU->getValue());
- int64_t Offset = 0;
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Imm))
- Offset = SC->getValue()->getSExtValue();
- if (GV || Offset)
- // Pass VoidTy as the AccessTy to be conservative, because
- // there could be multiple access types among all the uses.
- DoSink = IsImmFoldedIntoAddrMode(GV, Offset,
- Type::getVoidTy(L->getLoopPreheader()->getContext()),
- UsersToProcess, TLI);
-
- if (DoSink) {
- DEBUG(dbgs() << " Sinking " << *Imm << " back down into uses\n");
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm, Imm);
- CommonExprs = NewCommon;
- HaveCommonExprs = !CommonExprs->isZero();
- ++NumImmSunk;
- }
- }
- }
+void LSRUse::dump() const {
+ print(errs()); errs() << '\n';
+}
- // Now that we know what we need to do, insert the PHI node itself.
- //
- DEBUG(dbgs() << "LSR: Examining IVs of TYPE " << *ReplacedTy << " of STRIDE "
- << *Stride << ":\n"
- << " Common base: " << *CommonExprs << '\n');
+/// isLegalUse - Test whether the use described by AM is "legal", meaning it can
+/// be completely folded into the user instruction at isel time. This includes
+/// address-mode folding and special icmp tricks.
+static bool isLegalUse(const TargetLowering::AddrMode &AM,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI) {
+ switch (Kind) {
+ case LSRUse::Address:
+ // If we have low-level target information, ask the target if it can
+ // completely fold this address.
+ if (TLI) return TLI->isLegalAddressingMode(AM, AccessTy);
+
+ // Otherwise, just guess that reg+reg addressing is legal.
+ return !AM.BaseGV && AM.BaseOffs == 0 && AM.Scale <= 1;
+
+ case LSRUse::ICmpZero:
+ // There's not even a target hook for querying whether it would be legal to
+ // fold a GV into an ICmp.
+ if (AM.BaseGV)
+ return false;
- SCEVExpander Rewriter(*SE);
- SCEVExpander PreheaderRewriter(*SE);
+ // ICmp only has two operands; don't allow more than two non-trivial parts.
+ if (AM.Scale != 0 && AM.HasBaseReg && AM.BaseOffs != 0)
+ return false;
- BasicBlock *Preheader = L->getLoopPreheader();
- Instruction *PreInsertPt = Preheader->getTerminator();
- BasicBlock *LatchBlock = L->getLoopLatch();
- Instruction *IVIncInsertPt = LatchBlock->getTerminator();
-
- Value *CommonBaseV = Constant::getNullValue(ReplacedTy);
-
- const SCEV *RewriteFactor = SE->getIntegerSCEV(0, ReplacedTy);
- IVExpr ReuseIV(SE->getIntegerSCEV(0,
- Type::getInt32Ty(Preheader->getContext())),
- SE->getIntegerSCEV(0,
- Type::getInt32Ty(Preheader->getContext())),
- 0);
-
- // Choose a strength-reduction strategy and prepare for it by creating
- // the necessary PHIs and adjusting the bookkeeping.
- if (ShouldUseFullStrengthReductionMode(UsersToProcess, L,
- AllUsesAreAddresses, Stride)) {
- PrepareToStrengthReduceFully(UsersToProcess, Stride, CommonExprs, L,
- PreheaderRewriter);
- } else {
- // Emit the initial base value into the loop preheader.
- CommonBaseV = PreheaderRewriter.expandCodeFor(CommonExprs, ReplacedTy,
- PreInsertPt);
-
- // If all uses are addresses, check if it is possible to reuse an IV. The
- // new IV must have a stride that is a multiple of the old stride; the
- // multiple must be a number that can be encoded in the scale field of the
- // target addressing mode; and we must have a valid instruction after this
- // substitution, including the immediate field, if any.
- RewriteFactor = CheckForIVReuse(HaveCommonExprs, AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- Stride, ReuseIV, ReplacedTy,
- UsersToProcess);
- if (!RewriteFactor->isZero())
- PrepareToStrengthReduceFromSmallerStride(UsersToProcess, CommonBaseV,
- ReuseIV, PreInsertPt);
- else {
- IVIncInsertPt = FindIVIncInsertPt(UsersToProcess, L);
- PrepareToStrengthReduceWithNewPhi(UsersToProcess, Stride, CommonExprs,
- CommonBaseV, IVIncInsertPt,
- L, PreheaderRewriter);
- }
- }
+ // ICmp only supports no scale or a -1 scale, as we can "fold" a -1 scale by
+ // putting the scaled register in the other operand of the icmp.
+ if (AM.Scale != 0 && AM.Scale != -1)
+ return false;
- // Process all the users now, replacing their strided uses with
- // strength-reduced forms. This outer loop handles all bases, the inner
- // loop handles all users of a particular base.
- while (!UsersToProcess.empty()) {
- const SCEV *Base = UsersToProcess.back().Base;
- Instruction *Inst = UsersToProcess.back().Inst;
-
- // Emit the code for Base into the preheader.
- Value *BaseV = 0;
- if (!Base->isZero()) {
- BaseV = PreheaderRewriter.expandCodeFor(Base, 0, PreInsertPt);
-
- DEBUG(dbgs() << " INSERTING code for BASE = " << *Base << ":");
- if (BaseV->hasName())
- DEBUG(dbgs() << " Result value name = %" << BaseV->getName());
- DEBUG(dbgs() << "\n");
-
- // If BaseV is a non-zero constant, make sure that it gets inserted into
- // the preheader, instead of being forward substituted into the uses. We
- // do this by forcing a BitCast (noop cast) to be inserted into the
- // preheader in this case.
- if (!fitsInAddressMode(Base, getAccessType(Inst), TLI, false) &&
- isa<Constant>(BaseV)) {
- // We want this constant emitted into the preheader! This is just
- // using cast as a copy so BitCast (no-op cast) is appropriate
- BaseV = new BitCastInst(BaseV, BaseV->getType(), "preheaderinsert",
- PreInsertPt);
- }
+ // If we have low-level target information, ask the target if it can fold an
+ // integer immediate on an icmp.
+ if (AM.BaseOffs != 0) {
+ if (TLI) return TLI->isLegalICmpImmediate(-AM.BaseOffs);
+ return false;
}
- // Emit the code to add the immediate offset to the Phi value, just before
- // the instructions that we identified as using this stride and base.
- do {
- // FIXME: Use emitted users to emit other users.
- BasedUser &User = UsersToProcess.back();
-
- DEBUG(dbgs() << " Examining ");
- if (User.isUseOfPostIncrementedValue)
- DEBUG(dbgs() << "postinc");
- else
- DEBUG(dbgs() << "preinc");
- DEBUG(dbgs() << " use ");
- DEBUG(WriteAsOperand(dbgs(), UsersToProcess.back().OperandValToReplace,
- /*PrintType=*/false));
- DEBUG(dbgs() << " in Inst: " << *User.Inst << '\n');
-
- // If this instruction wants to use the post-incremented value, move it
- // after the post-inc and use its value instead of the PHI.
- Value *RewriteOp = User.Phi;
- if (User.isUseOfPostIncrementedValue) {
- RewriteOp = User.Phi->getIncomingValueForBlock(LatchBlock);
- // If this user is in the loop, make sure it is the last thing in the
- // loop to ensure it is dominated by the increment. In case it's the
- // only use of the iv, the increment instruction is already before the
- // use.
- if (L->contains(User.Inst) && User.Inst != IVIncInsertPt)
- User.Inst->moveBefore(IVIncInsertPt);
- }
-
- const SCEV *RewriteExpr = SE->getUnknown(RewriteOp);
-
- if (SE->getEffectiveSCEVType(RewriteOp->getType()) !=
- SE->getEffectiveSCEVType(ReplacedTy)) {
- assert(SE->getTypeSizeInBits(RewriteOp->getType()) >
- SE->getTypeSizeInBits(ReplacedTy) &&
- "Unexpected widening cast!");
- RewriteExpr = SE->getTruncateExpr(RewriteExpr, ReplacedTy);
- }
-
- // If we had to insert new instructions for RewriteOp, we have to
- // consider that they may not have been able to end up immediately
- // next to RewriteOp, because non-PHI instructions may never precede
- // PHI instructions in a block. In this case, remember where the last
- // instruction was inserted so that if we're replacing a different
- // PHI node, we can use the later point to expand the final
- // RewriteExpr.
- Instruction *NewBasePt = dyn_cast<Instruction>(RewriteOp);
- if (RewriteOp == User.Phi) NewBasePt = 0;
-
- // Clear the SCEVExpander's expression map so that we are guaranteed
- // to have the code emitted where we expect it.
- Rewriter.clear();
-
- // If we are reusing the iv, then it must be multiplied by a constant
- // factor to take advantage of the addressing mode scale component.
- if (!RewriteFactor->isZero()) {
- // If we're reusing an IV with a nonzero base (currently this happens
- // only when all reuses are outside the loop) subtract that base here.
- // The base has been used to initialize the PHI node but we don't want
- // it here.
- if (!ReuseIV.Base->isZero()) {
- const SCEV *typedBase = ReuseIV.Base;
- if (SE->getEffectiveSCEVType(RewriteExpr->getType()) !=
- SE->getEffectiveSCEVType(ReuseIV.Base->getType())) {
- // It's possible the original IV is a larger type than the new IV,
- // in which case we have to truncate the Base. We checked in
- // RequiresTypeConversion that this is valid.
- assert(SE->getTypeSizeInBits(RewriteExpr->getType()) <
- SE->getTypeSizeInBits(ReuseIV.Base->getType()) &&
- "Unexpected lengthening conversion!");
- typedBase = SE->getTruncateExpr(ReuseIV.Base,
- RewriteExpr->getType());
- }
- RewriteExpr = SE->getMinusSCEV(RewriteExpr, typedBase);
- }
+ return true;
- // Multiply old variable, with base removed, by new scale factor.
- RewriteExpr = SE->getMulExpr(RewriteFactor,
- RewriteExpr);
-
- // The common base is emitted in the loop preheader. But since we
- // are reusing an IV, it has not been used to initialize the PHI node.
- // Add it to the expression used to rewrite the uses.
- // When this use is outside the loop, we earlier subtracted the
- // common base, and are adding it back here. Use the same expression
- // as before, rather than CommonBaseV, so DAGCombiner will zap it.
- if (!CommonExprs->isZero()) {
- if (L->contains(User.Inst))
- RewriteExpr = SE->getAddExpr(RewriteExpr,
- SE->getUnknown(CommonBaseV));
- else
- RewriteExpr = SE->getAddExpr(RewriteExpr, CommonExprs);
- }
- }
+ case LSRUse::Basic:
+ // Only handle single-register values.
+ return !AM.BaseGV && AM.Scale == 0 && AM.BaseOffs == 0;
- // Now that we know what we need to do, insert code before User for the
- // immediate and any loop-variant expressions.
- if (BaseV)
- // Add BaseV to the PHI value if needed.
- RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
-
- User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt,
- Rewriter, L, this,
- DeadInsts, SE);
-
- // Mark old value we replaced as possibly dead, so that it is eliminated
- // if we just replaced the last use of that value.
- DeadInsts.push_back(User.OperandValToReplace);
-
- UsersToProcess.pop_back();
- ++NumReduced;
-
- // If there are any more users to process with the same base, process them
- // now. We sorted by base above, so we just have to check the last elt.
- } while (!UsersToProcess.empty() && UsersToProcess.back().Base == Base);
- // TODO: Next, find out which base index is the most common, pull it out.
- }
-
- // IMPORTANT TODO: Figure out how to partition the IV's with this stride, but
- // different starting values, into different PHIs.
-}
-
-void LoopStrengthReduce::StrengthReduceIVUsers(Loop *L) {
- // Note: this processes each stride/type pair individually. All users
- // passed into StrengthReduceIVUsersOfStride have the same type AND stride.
- // Also, note that we iterate over IVUsesByStride indirectly by using
- // StrideOrder. This extra layer of indirection makes the ordering of
- // strides deterministic - not dependent on map order.
- for (unsigned Stride = 0, e = IU->StrideOrder.size(); Stride != e; ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- // FIXME: Generalize to non-affine IV's.
- if (!SI->first->isLoopInvariant(L))
- continue;
- StrengthReduceIVUsersOfStride(SI->first, *SI->second, L);
+ case LSRUse::Special:
+ // Only handle -1 scales, or no scale.
+ return AM.Scale == 0 || AM.Scale == -1;
}
+
+ return false;
}
-/// FindIVUserForCond - If Cond has an operand that is an expression of an IV,
-/// set the IV user and stride information and return true, otherwise return
-/// false.
-bool LoopStrengthReduce::FindIVUserForCond(ICmpInst *Cond,
- IVStrideUse *&CondUse,
- const SCEV* &CondStride) {
- for (unsigned Stride = 0, e = IU->StrideOrder.size();
- Stride != e && !CondUse; ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
-
- for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; ++UI)
- if (UI->getUser() == Cond) {
- // NOTE: we could handle setcc instructions with multiple uses here, but
- // InstCombine does it as well for simple uses, it's not clear that it
- // occurs enough in real life to handle.
- CondUse = UI;
- CondStride = SI->first;
- return true;
- }
+static bool isLegalUse(TargetLowering::AddrMode AM,
+ int64_t MinOffset, int64_t MaxOffset,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI) {
+ // Check for overflow.
+ if (((int64_t)((uint64_t)AM.BaseOffs + MinOffset) > AM.BaseOffs) !=
+ (MinOffset > 0))
+ return false;
+ AM.BaseOffs = (uint64_t)AM.BaseOffs + MinOffset;
+ if (isLegalUse(AM, Kind, AccessTy, TLI)) {
+ AM.BaseOffs = (uint64_t)AM.BaseOffs - MinOffset;
+ // Check for overflow.
+ if (((int64_t)((uint64_t)AM.BaseOffs + MaxOffset) > AM.BaseOffs) !=
+ (MaxOffset > 0))
+ return false;
+ AM.BaseOffs = (uint64_t)AM.BaseOffs + MaxOffset;
+ return isLegalUse(AM, Kind, AccessTy, TLI);
}
return false;
}
-namespace {
- // Constant strides come first which in turns are sorted by their absolute
- // values. If absolute values are the same, then positive strides comes first.
- // e.g.
- // 4, -1, X, 1, 2 ==> 1, -1, 2, 4, X
- struct StrideCompare {
- const ScalarEvolution *SE;
- explicit StrideCompare(const ScalarEvolution *se) : SE(se) {}
-
- bool operator()(const SCEV *LHS, const SCEV *RHS) {
- const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS);
- const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS);
- if (LHSC && RHSC) {
- int64_t LV = LHSC->getValue()->getSExtValue();
- int64_t RV = RHSC->getValue()->getSExtValue();
- uint64_t ALV = (LV < 0) ? -LV : LV;
- uint64_t ARV = (RV < 0) ? -RV : RV;
- if (ALV == ARV) {
- if (LV != RV)
- return LV > RV;
- } else {
- return ALV < ARV;
- }
+static bool isAlwaysFoldable(int64_t BaseOffs,
+ GlobalValue *BaseGV,
+ bool HasBaseReg,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI) {
+ // Fast-path: zero is always foldable.
+ if (BaseOffs == 0 && !BaseGV) return true;
+
+ // Conservatively, create an address with an immediate and a
+ // base and a scale.
+ TargetLowering::AddrMode AM;
+ AM.BaseOffs = BaseOffs;
+ AM.BaseGV = BaseGV;
+ AM.HasBaseReg = HasBaseReg;
+ AM.Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
+
+ return isLegalUse(AM, Kind, AccessTy, TLI);
+}
- // If it's the same value but different type, sort by bit width so
- // that we emit larger induction variables before smaller
- // ones, letting the smaller be re-written in terms of larger ones.
- return SE->getTypeSizeInBits(RHS->getType()) <
- SE->getTypeSizeInBits(LHS->getType());
- }
- return LHSC && !RHSC;
- }
- };
+static bool isAlwaysFoldable(const SCEV *S,
+ int64_t MinOffset, int64_t MaxOffset,
+ bool HasBaseReg,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI,
+ ScalarEvolution &SE) {
+ // Fast-path: zero is always foldable.
+ if (S->isZero()) return true;
+
+ // Conservatively, create an address with an immediate and a
+ // base and a scale.
+ int64_t BaseOffs = ExtractImmediate(S, SE);
+ GlobalValue *BaseGV = ExtractSymbol(S, SE);
+
+ // If there's anything else involved, it's not foldable.
+ if (!S->isZero()) return false;
+
+ // Fast-path: zero is always foldable.
+ if (BaseOffs == 0 && !BaseGV) return true;
+
+ // Conservatively, create an address with an immediate and a
+ // base and a scale.
+ TargetLowering::AddrMode AM;
+ AM.BaseOffs = BaseOffs;
+ AM.BaseGV = BaseGV;
+ AM.HasBaseReg = HasBaseReg;
+ AM.Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
+
+ return isLegalUse(AM, MinOffset, MaxOffset, Kind, AccessTy, TLI);
}
-/// ChangeCompareStride - If a loop termination compare instruction is the only
-/// use of its stride, and the comparison is against a constant value, try to
-/// eliminate the stride by moving the compare instruction to another stride and
-/// changing its constant operand accordingly. E.g.
-///
-/// loop:
-/// ...
-/// v1 = v1 + 3
-/// v2 = v2 + 1
-/// if (v2 < 10) goto loop
-/// =>
-/// loop:
-/// ...
-/// v1 = v1 + 3
-/// if (v1 < 30) goto loop
-ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse,
- const SCEV* &CondStride,
- bool PostPass) {
- // If there's only one stride in the loop, there's nothing to do here.
- if (IU->StrideOrder.size() < 2)
- return Cond;
+/// FormulaSorter - This class implements an ordering for formulae which sorts
+/// the by their standalone cost.
+class FormulaSorter {
+ /// These two sets are kept empty, so that we compute standalone costs.
+ DenseSet<const SCEV *> VisitedRegs;
+ SmallPtrSet<const SCEV *, 16> Regs;
+ Loop *L;
+ LSRUse *LU;
+ ScalarEvolution &SE;
+ DominatorTree &DT;
+
+public:
+ FormulaSorter(Loop *l, LSRUse &lu, ScalarEvolution &se, DominatorTree &dt)
+ : L(l), LU(&lu), SE(se), DT(dt) {}
+
+ bool operator()(const Formula &A, const Formula &B) {
+ Cost CostA;
+ CostA.RateFormula(A, Regs, VisitedRegs, L, LU->Offsets, SE, DT);
+ Regs.clear();
+ Cost CostB;
+ CostB.RateFormula(B, Regs, VisitedRegs, L, LU->Offsets, SE, DT);
+ Regs.clear();
+ return CostA < CostB;
+ }
+};
+
+/// LSRInstance - This class holds state for the main loop strength reduction
+/// logic.
+class LSRInstance {
+ IVUsers &IU;
+ ScalarEvolution &SE;
+ DominatorTree &DT;
+ const TargetLowering *const TLI;
+ Loop *const L;
+ bool Changed;
+
+ /// IVIncInsertPos - This is the insert position that the current loop's
+ /// induction variable increment should be placed. In simple loops, this is
+ /// the latch block's terminator. But in more complicated cases, this is a
+ /// position which will dominate all the in-loop post-increment users.
+ Instruction *IVIncInsertPos;
+
+ /// Factors - Interesting factors between use strides.
+ SmallSetVector<int64_t, 8> Factors;
+
+ /// Types - Interesting use types, to facilitate truncation reuse.
+ SmallSetVector<const Type *, 4> Types;
+
+ /// Fixups - The list of operands which are to be replaced.
+ SmallVector<LSRFixup, 16> Fixups;
+
+ /// Uses - The list of interesting uses.
+ SmallVector<LSRUse, 16> Uses;
+
+ /// RegUses - Track which uses use which register candidates.
+ RegUseTracker RegUses;
+
+ void OptimizeShadowIV();
+ bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse);
+ ICmpInst *OptimizeMax(ICmpInst *Cond, IVStrideUse* &CondUse);
+ bool OptimizeLoopTermCond();
+
+ void CollectInterestingTypesAndFactors();
+ void CollectFixupsAndInitialFormulae();
+
+ LSRFixup &getNewFixup() {
+ Fixups.push_back(LSRFixup());
+ return Fixups.back();
+ }
- // If there are other users of the condition's stride, don't bother trying to
- // change the condition because the stride will still remain.
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator I =
- IU->IVUsesByStride.find(CondStride);
- if (I == IU->IVUsesByStride.end())
- return Cond;
+ // Support for sharing of LSRUses between LSRFixups.
+ typedef DenseMap<const SCEV *, size_t> UseMapTy;
+ UseMapTy UseMap;
+
+ bool reconcileNewOffset(LSRUse &LU, int64_t NewOffset,
+ LSRUse::KindType Kind, const Type *AccessTy);
+
+ std::pair<size_t, int64_t> getUse(const SCEV *&Expr,
+ LSRUse::KindType Kind,
+ const Type *AccessTy);
+
+public:
+ void InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx);
+ void InsertSupplementalFormula(const SCEV *S, LSRUse &LU, size_t LUIdx);
+ void CountRegisters(const Formula &F, size_t LUIdx);
+ bool InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F);
+
+ void CollectLoopInvariantFixupsAndFormulae();
+
+ void GenerateReassociations(LSRUse &LU, unsigned LUIdx, Formula Base,
+ unsigned Depth = 0);
+ void GenerateCombinations(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateTruncates(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateCrossUseConstantOffsets();
+ void GenerateAllReuseFormulae();
+
+ void FilterOutUndesirableDedicatedRegisters();
+ void NarrowSearchSpaceUsingHeuristics();
+
+ void SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
+ Cost &SolutionCost,
+ SmallVectorImpl<const Formula *> &Workspace,
+ const Cost &CurCost,
+ const SmallPtrSet<const SCEV *, 16> &CurRegs,
+ DenseSet<const SCEV *> &VisitedRegs) const;
+ void Solve(SmallVectorImpl<const Formula *> &Solution) const;
+
+ Value *Expand(const LSRFixup &LF,
+ const Formula &F,
+ BasicBlock::iterator IP,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts) const;
+ void RewriteForPHI(PHINode *PN, const LSRFixup &LF,
+ const Formula &F,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ Pass *P) const;
+ void Rewrite(const LSRFixup &LF,
+ const Formula &F,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ Pass *P) const;
+ void ImplementSolution(const SmallVectorImpl<const Formula *> &Solution,
+ Pass *P);
+
+ LSRInstance(const TargetLowering *tli, Loop *l, Pass *P);
+
+ bool getChanged() const { return Changed; }
+
+ void print_factors_and_types(raw_ostream &OS) const;
+ void print_fixups(raw_ostream &OS) const;
+ void print_uses(raw_ostream &OS) const;
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
- if (I->second->Users.size() > 1) {
- for (ilist<IVStrideUse>::iterator II = I->second->Users.begin(),
- EE = I->second->Users.end(); II != EE; ++II) {
- if (II->getUser() == Cond)
- continue;
- if (!isInstructionTriviallyDead(II->getUser()))
- return Cond;
- }
- }
+}
- // Only handle constant strides for now.
- const SCEVConstant *SC = dyn_cast<SCEVConstant>(CondStride);
- if (!SC) return Cond;
-
- ICmpInst::Predicate Predicate = Cond->getPredicate();
- int64_t CmpSSInt = SC->getValue()->getSExtValue();
- unsigned BitWidth = SE->getTypeSizeInBits(CondStride->getType());
- uint64_t SignBit = 1ULL << (BitWidth-1);
- const Type *CmpTy = Cond->getOperand(0)->getType();
- const Type *NewCmpTy = NULL;
- unsigned TyBits = SE->getTypeSizeInBits(CmpTy);
- unsigned NewTyBits = 0;
- const SCEV *NewStride = NULL;
- Value *NewCmpLHS = NULL;
- Value *NewCmpRHS = NULL;
- int64_t Scale = 1;
- const SCEV *NewOffset = SE->getIntegerSCEV(0, CmpTy);
-
- if (ConstantInt *C = dyn_cast<ConstantInt>(Cond->getOperand(1))) {
- int64_t CmpVal = C->getValue().getSExtValue();
-
- // Check the relevant induction variable for conformance to the pattern.
- const SCEV *IV = SE->getSCEV(Cond->getOperand(0));
- const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
- if (!AR || !AR->isAffine())
- return Cond;
-
- const SCEVConstant *StartC = dyn_cast<SCEVConstant>(AR->getStart());
- // Check stride constant and the comparision constant signs to detect
- // overflow.
- if (StartC) {
- if ((StartC->getValue()->getSExtValue() < CmpVal && CmpSSInt < 0) ||
- (StartC->getValue()->getSExtValue() > CmpVal && CmpSSInt > 0))
- return Cond;
- } else {
- // More restrictive check for the other cases.
- if ((CmpVal & SignBit) != (CmpSSInt & SignBit))
- return Cond;
- }
+/// OptimizeShadowIV - If IV is used in a int-to-float cast
+/// inside the loop then try to eliminate the cast operation.
+void LSRInstance::OptimizeShadowIV() {
+ const SCEV *BackedgeTakenCount = SE.getBackedgeTakenCount(L);
+ if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
+ return;
- // Look for a suitable stride / iv as replacement.
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- if (!isa<SCEVConstant>(SI->first) || SI->second->Users.empty())
- continue;
- int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
- if (SSInt == CmpSSInt ||
- abs64(SSInt) < abs64(CmpSSInt) ||
- (SSInt % CmpSSInt) != 0)
- continue;
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end();
+ UI != E; /* empty */) {
+ IVUsers::const_iterator CandidateUI = UI;
+ ++UI;
+ Instruction *ShadowUse = CandidateUI->getUser();
+ const Type *DestTy = NULL;
- Scale = SSInt / CmpSSInt;
- int64_t NewCmpVal = CmpVal * Scale;
+ /* If shadow use is a int->float cast then insert a second IV
+ to eliminate this cast.
- // If old icmp value fits in icmp immediate field, but the new one doesn't
- // try something else.
- if (TLI &&
- TLI->isLegalICmpImmediate(CmpVal) &&
- !TLI->isLegalICmpImmediate(NewCmpVal))
- continue;
+ for (unsigned i = 0; i < n; ++i)
+ foo((double)i);
- APInt Mul = APInt(BitWidth*2, CmpVal, true);
- Mul = Mul * APInt(BitWidth*2, Scale, true);
- // Check for overflow.
- if (!Mul.isSignedIntN(BitWidth))
- continue;
- // Check for overflow in the stride's type too.
- if (!Mul.isSignedIntN(SE->getTypeSizeInBits(SI->first->getType())))
- continue;
+ is transformed into
- // Watch out for overflow.
- if (ICmpInst::isSigned(Predicate) &&
- (CmpVal & SignBit) != (NewCmpVal & SignBit))
- continue;
+ double d = 0.0;
+ for (unsigned i = 0; i < n; ++i, ++d)
+ foo(d);
+ */
+ if (UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->getUser()))
+ DestTy = UCast->getDestTy();
+ else if (SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->getUser()))
+ DestTy = SCast->getDestTy();
+ if (!DestTy) continue;
- // Pick the best iv to use trying to avoid a cast.
- NewCmpLHS = NULL;
- for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; ++UI) {
- Value *Op = UI->getOperandValToReplace();
-
- // If the IVStrideUse implies a cast, check for an actual cast which
- // can be used to find the original IV expression.
- if (SE->getEffectiveSCEVType(Op->getType()) !=
- SE->getEffectiveSCEVType(SI->first->getType())) {
- CastInst *CI = dyn_cast<CastInst>(Op);
- // If it's not a simple cast, it's complicated.
- if (!CI)
- continue;
- // If it's a cast from a type other than the stride type,
- // it's complicated.
- if (CI->getOperand(0)->getType() != SI->first->getType())
- continue;
- // Ok, we found the IV expression in the stride's type.
- Op = CI->getOperand(0);
- }
+ if (TLI) {
+ // If target does not support DestTy natively then do not apply
+ // this transformation.
+ EVT DVT = TLI->getValueType(DestTy);
+ if (!TLI->isTypeLegal(DVT)) continue;
+ }
- NewCmpLHS = Op;
- if (NewCmpLHS->getType() == CmpTy)
- break;
- }
- if (!NewCmpLHS)
- continue;
+ PHINode *PH = dyn_cast<PHINode>(ShadowUse->getOperand(0));
+ if (!PH) continue;
+ if (PH->getNumIncomingValues() != 2) continue;
- NewCmpTy = NewCmpLHS->getType();
- NewTyBits = SE->getTypeSizeInBits(NewCmpTy);
- const Type *NewCmpIntTy = IntegerType::get(Cond->getContext(), NewTyBits);
- if (RequiresTypeConversion(NewCmpTy, CmpTy)) {
- // Check if it is possible to rewrite it using
- // an iv / stride of a smaller integer type.
- unsigned Bits = NewTyBits;
- if (ICmpInst::isSigned(Predicate))
- --Bits;
- uint64_t Mask = (1ULL << Bits) - 1;
- if (((uint64_t)NewCmpVal & Mask) != (uint64_t)NewCmpVal)
- continue;
- }
+ const Type *SrcTy = PH->getType();
+ int Mantissa = DestTy->getFPMantissaWidth();
+ if (Mantissa == -1) continue;
+ if ((int)SE.getTypeSizeInBits(SrcTy) > Mantissa)
+ continue;
- // Don't rewrite if use offset is non-constant and the new type is
- // of a different type.
- // FIXME: too conservative?
- if (NewTyBits != TyBits && !isa<SCEVConstant>(CondUse->getOffset()))
- continue;
+ unsigned Entry, Latch;
+ if (PH->getIncomingBlock(0) == L->getLoopPreheader()) {
+ Entry = 0;
+ Latch = 1;
+ } else {
+ Entry = 1;
+ Latch = 0;
+ }
- if (!PostPass) {
- bool AllUsesAreAddresses = true;
- bool AllUsesAreOutsideLoop = true;
- std::vector<BasedUser> UsersToProcess;
- const SCEV *CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
- AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- UsersToProcess);
- // Avoid rewriting the compare instruction with an iv of new stride
- // if it's likely the new stride uses will be rewritten using the
- // stride of the compare instruction.
- if (AllUsesAreAddresses &&
- ValidScale(!CommonExprs->isZero(), Scale, UsersToProcess))
- continue;
- }
+ ConstantInt *Init = dyn_cast<ConstantInt>(PH->getIncomingValue(Entry));
+ if (!Init) continue;
+ Constant *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
- // Avoid rewriting the compare instruction with an iv which has
- // implicit extension or truncation built into it.
- // TODO: This is over-conservative.
- if (SE->getTypeSizeInBits(CondUse->getOffset()->getType()) != TyBits)
- continue;
+ BinaryOperator *Incr =
+ dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
+ if (!Incr) continue;
+ if (Incr->getOpcode() != Instruction::Add
+ && Incr->getOpcode() != Instruction::Sub)
+ continue;
- // If scale is negative, use swapped predicate unless it's testing
- // for equality.
- if (Scale < 0 && !Cond->isEquality())
- Predicate = ICmpInst::getSwappedPredicate(Predicate);
+ /* Initialize new IV, double d = 0.0 in above example. */
+ ConstantInt *C = NULL;
+ if (Incr->getOperand(0) == PH)
+ C = dyn_cast<ConstantInt>(Incr->getOperand(1));
+ else if (Incr->getOperand(1) == PH)
+ C = dyn_cast<ConstantInt>(Incr->getOperand(0));
+ else
+ continue;
- NewStride = IU->StrideOrder[i];
- if (!isa<PointerType>(NewCmpTy))
- NewCmpRHS = ConstantInt::get(NewCmpTy, NewCmpVal);
- else {
- Constant *CI = ConstantInt::get(NewCmpIntTy, NewCmpVal);
- NewCmpRHS = ConstantExpr::getIntToPtr(CI, NewCmpTy);
- }
- NewOffset = TyBits == NewTyBits
- ? SE->getMulExpr(CondUse->getOffset(),
- SE->getConstant(CmpTy, Scale))
- : SE->getConstant(NewCmpIntTy,
- cast<SCEVConstant>(CondUse->getOffset())->getValue()
- ->getSExtValue()*Scale);
- break;
- }
- }
+ if (!C) continue;
- // Forgo this transformation if it the increment happens to be
- // unfortunately positioned after the condition, and the condition
- // has multiple uses which prevent it from being moved immediately
- // before the branch. See
- // test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-*.ll
- // for an example of this situation.
- if (!Cond->hasOneUse()) {
- for (BasicBlock::iterator I = Cond, E = Cond->getParent()->end();
- I != E; ++I)
- if (I == NewCmpLHS)
- return Cond;
- }
+ // Ignore negative constants, as the code below doesn't handle them
+ // correctly. TODO: Remove this restriction.
+ if (!C->getValue().isStrictlyPositive()) continue;
- if (NewCmpRHS) {
- // Create a new compare instruction using new stride / iv.
- ICmpInst *OldCond = Cond;
- // Insert new compare instruction.
- Cond = new ICmpInst(OldCond, Predicate, NewCmpLHS, NewCmpRHS,
- L->getHeader()->getName() + ".termcond");
+ /* Add new PHINode. */
+ PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
- DEBUG(dbgs() << " Change compare stride in Inst " << *OldCond);
- DEBUG(dbgs() << " to " << *Cond << '\n');
+ /* create new increment. '++d' in above example. */
+ Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
+ BinaryOperator *NewIncr =
+ BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
+ Instruction::FAdd : Instruction::FSub,
+ NewPH, CFP, "IV.S.next.", Incr);
- // Remove the old compare instruction. The old indvar is probably dead too.
- DeadInsts.push_back(CondUse->getOperandValToReplace());
- OldCond->replaceAllUsesWith(Cond);
- OldCond->eraseFromParent();
+ NewPH->addIncoming(NewInit, PH->getIncomingBlock(Entry));
+ NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
- IU->IVUsesByStride[NewStride]->addUser(NewOffset, Cond, NewCmpLHS);
- CondUse = &IU->IVUsesByStride[NewStride]->Users.back();
- CondStride = NewStride;
- ++NumEliminated;
- Changed = true;
+ /* Remove cast operation */
+ ShadowUse->replaceAllUsesWith(NewPH);
+ ShadowUse->eraseFromParent();
+ break;
}
+}
- return Cond;
+/// FindIVUserForCond - If Cond has an operand that is an expression of an IV,
+/// set the IV user and stride information and return true, otherwise return
+/// false.
+bool LSRInstance::FindIVUserForCond(ICmpInst *Cond,
+ IVStrideUse *&CondUse) {
+ for (IVUsers::iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI)
+ if (UI->getUser() == Cond) {
+ // NOTE: we could handle setcc instructions with multiple uses here, but
+ // InstCombine does it as well for simple uses, it's not clear that it
+ // occurs enough in real life to handle.
+ CondUse = UI;
+ return true;
+ }
+ return false;
}
/// OptimizeMax - Rewrite the loop's terminating condition if it uses
@@ -2088,7 +1405,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
/// are designed around them. The most obvious example of this is the
/// LoopInfo analysis, which doesn't remember trip count values. It
/// expects to be able to rediscover the trip count each time it is
-/// needed, and it does this using a simple analyis that only succeeds if
+/// needed, and it does this using a simple analysis that only succeeds if
/// the loop has a canonical induction variable.
///
/// However, when it comes time to generate code, the maximum operation
@@ -2098,8 +1415,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
/// rewriting their conditions from ICMP_NE back to ICMP_SLT, and deleting
/// the instructions for the maximum computation.
///
-ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse) {
+ICmpInst *LSRInstance::OptimizeMax(ICmpInst *Cond, IVStrideUse* &CondUse) {
// Check that the loop matches the pattern we're looking for.
if (Cond->getPredicate() != CmpInst::ICMP_EQ &&
Cond->getPredicate() != CmpInst::ICMP_NE)
@@ -2108,19 +1424,19 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
SelectInst *Sel = dyn_cast<SelectInst>(Cond->getOperand(1));
if (!Sel || !Sel->hasOneUse()) return Cond;
- const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
+ const SCEV *BackedgeTakenCount = SE.getBackedgeTakenCount(L);
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
return Cond;
- const SCEV *One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
+ const SCEV *One = SE.getIntegerSCEV(1, BackedgeTakenCount->getType());
// Add one to the backedge-taken count to get the trip count.
- const SCEV *IterationCount = SE->getAddExpr(BackedgeTakenCount, One);
+ const SCEV *IterationCount = SE.getAddExpr(BackedgeTakenCount, One);
// Check for a max calculation that matches the pattern.
if (!isa<SCEVSMaxExpr>(IterationCount) && !isa<SCEVUMaxExpr>(IterationCount))
return Cond;
const SCEVNAryExpr *Max = cast<SCEVNAryExpr>(IterationCount);
- if (Max != SE->getSCEV(Sel)) return Cond;
+ if (Max != SE.getSCEV(Sel)) return Cond;
// To handle a max with more than two operands, this optimization would
// require additional checking and setup.
@@ -2130,14 +1446,13 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
const SCEV *MaxLHS = Max->getOperand(0);
const SCEV *MaxRHS = Max->getOperand(1);
if (!MaxLHS || MaxLHS != One) return Cond;
-
// Check the relevant induction variable for conformance to
// the pattern.
- const SCEV *IV = SE->getSCEV(Cond->getOperand(0));
+ const SCEV *IV = SE.getSCEV(Cond->getOperand(0));
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
if (!AR || !AR->isAffine() ||
AR->getStart() != One ||
- AR->getStepRecurrence(*SE) != One)
+ AR->getStepRecurrence(SE) != One)
return Cond;
assert(AR->getLoop() == L &&
@@ -2146,9 +1461,9 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
// Check the right operand of the select, and remember it, as it will
// be used in the new comparison instruction.
Value *NewRHS = 0;
- if (SE->getSCEV(Sel->getOperand(1)) == MaxRHS)
+ if (SE.getSCEV(Sel->getOperand(1)) == MaxRHS)
NewRHS = Sel->getOperand(1);
- else if (SE->getSCEV(Sel->getOperand(2)) == MaxRHS)
+ else if (SE.getSCEV(Sel->getOperand(2)) == MaxRHS)
NewRHS = Sel->getOperand(2);
if (!NewRHS) return Cond;
@@ -2175,552 +1490,1804 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
return NewCond;
}
-/// OptimizeShadowIV - If IV is used in a int-to-float cast
-/// inside the loop then try to eliminate the cast opeation.
-void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
+/// OptimizeLoopTermCond - Change loop terminating condition to use the
+/// postinc iv when possible.
+bool
+LSRInstance::OptimizeLoopTermCond() {
+ SmallPtrSet<Instruction *, 4> PostIncs;
- const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
- if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
- return;
+ BasicBlock *LatchBlock = L->getLoopLatch();
+ SmallVector<BasicBlock*, 8> ExitingBlocks;
+ L->getExitingBlocks(ExitingBlocks);
+
+ for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
+ BasicBlock *ExitingBlock = ExitingBlocks[i];
- for (unsigned Stride = 0, e = IU->StrideOrder.size(); Stride != e;
- ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- if (!isa<SCEVConstant>(SI->first))
+ // Get the terminating condition for the loop if possible. If we
+ // can, we want to change it to use a post-incremented version of its
+ // induction variable, to allow coalescing the live ranges for the IV into
+ // one register value.
+
+ BranchInst *TermBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
+ if (!TermBr)
+ continue;
+ // FIXME: Overly conservative, termination condition could be an 'or' etc..
+ if (TermBr->isUnconditional() || !isa<ICmpInst>(TermBr->getCondition()))
continue;
- for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; /* empty */) {
- ilist<IVStrideUse>::iterator CandidateUI = UI;
- ++UI;
- Instruction *ShadowUse = CandidateUI->getUser();
- const Type *DestTy = NULL;
-
- /* If shadow use is a int->float cast then insert a second IV
- to eliminate this cast.
-
- for (unsigned i = 0; i < n; ++i)
- foo((double)i);
-
- is transformed into
-
- double d = 0.0;
- for (unsigned i = 0; i < n; ++i, ++d)
- foo(d);
- */
- if (UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->getUser()))
- DestTy = UCast->getDestTy();
- else if (SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->getUser()))
- DestTy = SCast->getDestTy();
- if (!DestTy) continue;
-
- if (TLI) {
- // If target does not support DestTy natively then do not apply
- // this transformation.
- EVT DVT = TLI->getValueType(DestTy);
- if (!TLI->isTypeLegal(DVT)) continue;
- }
+ // Search IVUsesByStride to find Cond's IVUse if there is one.
+ IVStrideUse *CondUse = 0;
+ ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
+ if (!FindIVUserForCond(Cond, CondUse))
+ continue;
+
+ // If the trip count is computed in terms of a max (due to ScalarEvolution
+ // being unable to find a sufficient guard, for example), change the loop
+ // comparison to use SLT or ULT instead of NE.
+ // One consequence of doing this now is that it disrupts the count-down
+ // optimization. That's not always a bad thing though, because in such
+ // cases it may still be worthwhile to avoid a max.
+ Cond = OptimizeMax(Cond, CondUse);
+
+ // If this exiting block dominates the latch block, it may also use
+ // the post-inc value if it won't be shared with other uses.
+ // Check for dominance.
+ if (!DT.dominates(ExitingBlock, LatchBlock))
+ continue;
- PHINode *PH = dyn_cast<PHINode>(ShadowUse->getOperand(0));
- if (!PH) continue;
- if (PH->getNumIncomingValues() != 2) continue;
+ // Conservatively avoid trying to use the post-inc value in non-latch
+ // exits if there may be pre-inc users in intervening blocks.
+ if (LatchBlock != ExitingBlock)
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI)
+ // Test if the use is reachable from the exiting block. This dominator
+ // query is a conservative approximation of reachability.
+ if (&*UI != CondUse &&
+ !DT.properlyDominates(UI->getUser()->getParent(), ExitingBlock)) {
+ // Conservatively assume there may be reuse if the quotient of their
+ // strides could be a legal scale.
+ const SCEV *A = CondUse->getStride();
+ const SCEV *B = UI->getStride();
+ if (SE.getTypeSizeInBits(A->getType()) !=
+ SE.getTypeSizeInBits(B->getType())) {
+ if (SE.getTypeSizeInBits(A->getType()) >
+ SE.getTypeSizeInBits(B->getType()))
+ B = SE.getSignExtendExpr(B, A->getType());
+ else
+ A = SE.getSignExtendExpr(A, B->getType());
+ }
+ if (const SCEVConstant *D =
+ dyn_cast_or_null<SCEVConstant>(getExactSDiv(B, A, SE))) {
+ // Stride of one or negative one can have reuse with non-addresses.
+ if (D->getValue()->isOne() ||
+ D->getValue()->isAllOnesValue())
+ goto decline_post_inc;
+ // Avoid weird situations.
+ if (D->getValue()->getValue().getMinSignedBits() >= 64 ||
+ D->getValue()->getValue().isMinSignedValue())
+ goto decline_post_inc;
+ // Without TLI, assume that any stride might be valid, and so any
+ // use might be shared.
+ if (!TLI)
+ goto decline_post_inc;
+ // Check for possible scaled-address reuse.
+ const Type *AccessTy = getAccessType(UI->getUser());
+ TargetLowering::AddrMode AM;
+ AM.Scale = D->getValue()->getSExtValue();
+ if (TLI->isLegalAddressingMode(AM, AccessTy))
+ goto decline_post_inc;
+ AM.Scale = -AM.Scale;
+ if (TLI->isLegalAddressingMode(AM, AccessTy))
+ goto decline_post_inc;
+ }
+ }
- const Type *SrcTy = PH->getType();
- int Mantissa = DestTy->getFPMantissaWidth();
- if (Mantissa == -1) continue;
- if ((int)SE->getTypeSizeInBits(SrcTy) > Mantissa)
- continue;
+ DEBUG(dbgs() << " Change loop exiting icmp to use postinc iv: "
+ << *Cond << '\n');
- unsigned Entry, Latch;
- if (PH->getIncomingBlock(0) == L->getLoopPreheader()) {
- Entry = 0;
- Latch = 1;
+ // It's possible for the setcc instruction to be anywhere in the loop, and
+ // possible for it to have multiple users. If it is not immediately before
+ // the exiting block branch, move it.
+ if (&*++BasicBlock::iterator(Cond) != TermBr) {
+ if (Cond->hasOneUse()) {
+ Cond->moveBefore(TermBr);
} else {
- Entry = 1;
- Latch = 0;
+ // Clone the terminating condition and insert into the loopend.
+ ICmpInst *OldCond = Cond;
+ Cond = cast<ICmpInst>(Cond->clone());
+ Cond->setName(L->getHeader()->getName() + ".termcond");
+ ExitingBlock->getInstList().insert(TermBr, Cond);
+
+ // Clone the IVUse, as the old use still exists!
+ CondUse = &IU.AddUser(CondUse->getStride(), CondUse->getOffset(),
+ Cond, CondUse->getOperandValToReplace());
+ TermBr->replaceUsesOfWith(OldCond, Cond);
}
+ }
- ConstantInt *Init = dyn_cast<ConstantInt>(PH->getIncomingValue(Entry));
- if (!Init) continue;
- Constant *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
+ // If we get to here, we know that we can transform the setcc instruction to
+ // use the post-incremented version of the IV, allowing us to coalesce the
+ // live ranges for the IV correctly.
+ CondUse->setOffset(SE.getMinusSCEV(CondUse->getOffset(),
+ CondUse->getStride()));
+ CondUse->setIsUseOfPostIncrementedValue(true);
+ Changed = true;
- BinaryOperator *Incr =
- dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
- if (!Incr) continue;
- if (Incr->getOpcode() != Instruction::Add
- && Incr->getOpcode() != Instruction::Sub)
- continue;
+ PostIncs.insert(Cond);
+ decline_post_inc:;
+ }
- /* Initialize new IV, double d = 0.0 in above example. */
- ConstantInt *C = NULL;
- if (Incr->getOperand(0) == PH)
- C = dyn_cast<ConstantInt>(Incr->getOperand(1));
- else if (Incr->getOperand(1) == PH)
- C = dyn_cast<ConstantInt>(Incr->getOperand(0));
- else
- continue;
+ // Determine an insertion point for the loop induction variable increment. It
+ // must dominate all the post-inc comparisons we just set up, and it must
+ // dominate the loop latch edge.
+ IVIncInsertPos = L->getLoopLatch()->getTerminator();
+ for (SmallPtrSet<Instruction *, 4>::const_iterator I = PostIncs.begin(),
+ E = PostIncs.end(); I != E; ++I) {
+ BasicBlock *BB =
+ DT.findNearestCommonDominator(IVIncInsertPos->getParent(),
+ (*I)->getParent());
+ if (BB == (*I)->getParent())
+ IVIncInsertPos = *I;
+ else if (BB != IVIncInsertPos->getParent())
+ IVIncInsertPos = BB->getTerminator();
+ }
+
+ return Changed;
+}
- if (!C) continue;
+bool
+LSRInstance::reconcileNewOffset(LSRUse &LU, int64_t NewOffset,
+ LSRUse::KindType Kind, const Type *AccessTy) {
+ int64_t NewMinOffset = LU.MinOffset;
+ int64_t NewMaxOffset = LU.MaxOffset;
+ const Type *NewAccessTy = AccessTy;
+
+ // Check for a mismatched kind. It's tempting to collapse mismatched kinds to
+ // something conservative, however this can pessimize in the case that one of
+ // the uses will have all its uses outside the loop, for example.
+ if (LU.Kind != Kind)
+ return false;
+ // Conservatively assume HasBaseReg is true for now.
+ if (NewOffset < LU.MinOffset) {
+ if (!isAlwaysFoldable(LU.MaxOffset - NewOffset, 0, /*HasBaseReg=*/true,
+ Kind, AccessTy, TLI))
+ return false;
+ NewMinOffset = NewOffset;
+ } else if (NewOffset > LU.MaxOffset) {
+ if (!isAlwaysFoldable(NewOffset - LU.MinOffset, 0, /*HasBaseReg=*/true,
+ Kind, AccessTy, TLI))
+ return false;
+ NewMaxOffset = NewOffset;
+ }
+ // Check for a mismatched access type, and fall back conservatively as needed.
+ if (Kind == LSRUse::Address && AccessTy != LU.AccessTy)
+ NewAccessTy = Type::getVoidTy(AccessTy->getContext());
+
+ // Update the use.
+ LU.MinOffset = NewMinOffset;
+ LU.MaxOffset = NewMaxOffset;
+ LU.AccessTy = NewAccessTy;
+ if (NewOffset != LU.Offsets.back())
+ LU.Offsets.push_back(NewOffset);
+ return true;
+}
- // Ignore negative constants, as the code below doesn't handle them
- // correctly. TODO: Remove this restriction.
- if (!C->getValue().isStrictlyPositive()) continue;
+/// getUse - Return an LSRUse index and an offset value for a fixup which
+/// needs the given expression, with the given kind and optional access type.
+/// Either reuse an existing use or create a new one, as needed.
+std::pair<size_t, int64_t>
+LSRInstance::getUse(const SCEV *&Expr,
+ LSRUse::KindType Kind, const Type *AccessTy) {
+ const SCEV *Copy = Expr;
+ int64_t Offset = ExtractImmediate(Expr, SE);
+
+ // Basic uses can't accept any offset, for example.
+ if (!isAlwaysFoldable(Offset, 0, /*HasBaseReg=*/true, Kind, AccessTy, TLI)) {
+ Expr = Copy;
+ Offset = 0;
+ }
- /* Add new PHINode. */
- PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
+ std::pair<UseMapTy::iterator, bool> P =
+ UseMap.insert(std::make_pair(Expr, 0));
+ if (!P.second) {
+ // A use already existed with this base.
+ size_t LUIdx = P.first->second;
+ LSRUse &LU = Uses[LUIdx];
+ if (reconcileNewOffset(LU, Offset, Kind, AccessTy))
+ // Reuse this use.
+ return std::make_pair(LUIdx, Offset);
+ }
- /* create new increment. '++d' in above example. */
- Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
- BinaryOperator *NewIncr =
- BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
- Instruction::FAdd : Instruction::FSub,
- NewPH, CFP, "IV.S.next.", Incr);
+ // Create a new use.
+ size_t LUIdx = Uses.size();
+ P.first->second = LUIdx;
+ Uses.push_back(LSRUse(Kind, AccessTy));
+ LSRUse &LU = Uses[LUIdx];
- NewPH->addIncoming(NewInit, PH->getIncomingBlock(Entry));
- NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
+ // We don't need to track redundant offsets, but we don't need to go out
+ // of our way here to avoid them.
+ if (LU.Offsets.empty() || Offset != LU.Offsets.back())
+ LU.Offsets.push_back(Offset);
- /* Remove cast operation */
- ShadowUse->replaceAllUsesWith(NewPH);
- ShadowUse->eraseFromParent();
- NumShadow++;
- break;
- }
- }
+ LU.MinOffset = Offset;
+ LU.MaxOffset = Offset;
+ return std::make_pair(LUIdx, Offset);
}
-/// OptimizeIndvars - Now that IVUsesByStride is set up with all of the indvar
-/// uses in the loop, look to see if we can eliminate some, in favor of using
-/// common indvars for the different uses.
-void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
- // TODO: implement optzns here.
+void LSRInstance::CollectInterestingTypesAndFactors() {
+ SmallSetVector<const SCEV *, 4> Strides;
+
+ // Collect interesting types and strides.
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) {
+ const SCEV *Stride = UI->getStride();
+
+ // Collect interesting types.
+ Types.insert(SE.getEffectiveSCEVType(Stride->getType()));
- OptimizeShadowIV(L);
+ // Add the stride for this loop.
+ Strides.insert(Stride);
+
+ // Add strides for other mentioned loops.
+ for (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(UI->getOffset());
+ AR; AR = dyn_cast<SCEVAddRecExpr>(AR->getStart()))
+ Strides.insert(AR->getStepRecurrence(SE));
+ }
+
+ // Compute interesting factors from the set of interesting strides.
+ for (SmallSetVector<const SCEV *, 4>::const_iterator
+ I = Strides.begin(), E = Strides.end(); I != E; ++I)
+ for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter =
+ next(I); NewStrideIter != E; ++NewStrideIter) {
+ const SCEV *OldStride = *I;
+ const SCEV *NewStride = *NewStrideIter;
+
+ if (SE.getTypeSizeInBits(OldStride->getType()) !=
+ SE.getTypeSizeInBits(NewStride->getType())) {
+ if (SE.getTypeSizeInBits(OldStride->getType()) >
+ SE.getTypeSizeInBits(NewStride->getType()))
+ NewStride = SE.getSignExtendExpr(NewStride, OldStride->getType());
+ else
+ OldStride = SE.getSignExtendExpr(OldStride, NewStride->getType());
+ }
+ if (const SCEVConstant *Factor =
+ dyn_cast_or_null<SCEVConstant>(getExactSDiv(NewStride, OldStride,
+ SE, true))) {
+ if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
+ Factors.insert(Factor->getValue()->getValue().getSExtValue());
+ } else if (const SCEVConstant *Factor =
+ dyn_cast_or_null<SCEVConstant>(getExactSDiv(OldStride,
+ NewStride,
+ SE, true))) {
+ if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
+ Factors.insert(Factor->getValue()->getValue().getSExtValue());
+ }
+ }
+
+ // If all uses use the same type, don't bother looking for truncation-based
+ // reuse.
+ if (Types.size() == 1)
+ Types.clear();
+
+ DEBUG(print_factors_and_types(dbgs()));
}
-bool LoopStrengthReduce::StrideMightBeShared(const SCEV* Stride, Loop *L,
- bool CheckPreInc) {
- int64_t SInt = cast<SCEVConstant>(Stride)->getValue()->getSExtValue();
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- const SCEV *Share = SI->first;
- if (!isa<SCEVConstant>(SI->first) || Share == Stride)
- continue;
- int64_t SSInt = cast<SCEVConstant>(Share)->getValue()->getSExtValue();
- if (SSInt == SInt)
- return true; // This can definitely be reused.
- if (unsigned(abs64(SSInt)) < SInt || (SSInt % SInt) != 0)
- continue;
- int64_t Scale = SSInt / SInt;
- bool AllUsesAreAddresses = true;
- bool AllUsesAreOutsideLoop = true;
- std::vector<BasedUser> UsersToProcess;
- const SCEV *CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
- AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- UsersToProcess);
- if (AllUsesAreAddresses &&
- ValidScale(!CommonExprs->isZero(), Scale, UsersToProcess)) {
- if (!CheckPreInc)
- return true;
- // Any pre-inc iv use?
- IVUsersOfOneStride &StrideUses = *IU->IVUsesByStride[Share];
- for (ilist<IVStrideUse>::iterator I = StrideUses.Users.begin(),
- E = StrideUses.Users.end(); I != E; ++I) {
- if (!I->isUseOfPostIncrementedValue())
- return true;
+void LSRInstance::CollectFixupsAndInitialFormulae() {
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) {
+ // Record the uses.
+ LSRFixup &LF = getNewFixup();
+ LF.UserInst = UI->getUser();
+ LF.OperandValToReplace = UI->getOperandValToReplace();
+ if (UI->isUseOfPostIncrementedValue())
+ LF.PostIncLoop = L;
+
+ LSRUse::KindType Kind = LSRUse::Basic;
+ const Type *AccessTy = 0;
+ if (isAddressUse(LF.UserInst, LF.OperandValToReplace)) {
+ Kind = LSRUse::Address;
+ AccessTy = getAccessType(LF.UserInst);
+ }
+
+ const SCEV *S = IU.getCanonicalExpr(*UI);
+
+ // Equality (== and !=) ICmps are special. We can rewrite (i == N) as
+ // (N - i == 0), and this allows (N - i) to be the expression that we work
+ // with rather than just N or i, so we can consider the register
+ // requirements for both N and i at the same time. Limiting this code to
+ // equality icmps is not a problem because all interesting loops use
+ // equality icmps, thanks to IndVarSimplify.
+ if (ICmpInst *CI = dyn_cast<ICmpInst>(LF.UserInst))
+ if (CI->isEquality()) {
+ // Swap the operands if needed to put the OperandValToReplace on the
+ // left, for consistency.
+ Value *NV = CI->getOperand(1);
+ if (NV == LF.OperandValToReplace) {
+ CI->setOperand(1, CI->getOperand(0));
+ CI->setOperand(0, NV);
+ }
+
+ // x == y --> x - y == 0
+ const SCEV *N = SE.getSCEV(NV);
+ if (N->isLoopInvariant(L)) {
+ Kind = LSRUse::ICmpZero;
+ S = SE.getMinusSCEV(N, S);
+ }
+
+ // -1 and the negations of all interesting strides (except the negation
+ // of -1) are now also interesting.
+ for (size_t i = 0, e = Factors.size(); i != e; ++i)
+ if (Factors[i] != -1)
+ Factors.insert(-(uint64_t)Factors[i]);
+ Factors.insert(-1);
}
+
+ // Set up the initial formula for this use.
+ std::pair<size_t, int64_t> P = getUse(S, Kind, AccessTy);
+ LF.LUIdx = P.first;
+ LF.Offset = P.second;
+ LSRUse &LU = Uses[LF.LUIdx];
+ LU.AllFixupsOutsideLoop &= !L->contains(LF.UserInst);
+
+ // If this is the first use of this LSRUse, give it a formula.
+ if (LU.Formulae.empty()) {
+ InsertInitialFormula(S, LU, LF.LUIdx);
+ CountRegisters(LU.Formulae.back(), LF.LUIdx);
}
}
- return false;
+
+ DEBUG(print_fixups(dbgs()));
}
-/// isUsedByExitBranch - Return true if icmp is used by a loop terminating
-/// conditional branch or it's and / or with other conditions before being used
-/// as the condition.
-static bool isUsedByExitBranch(ICmpInst *Cond, Loop *L) {
- BasicBlock *CondBB = Cond->getParent();
- if (!L->isLoopExiting(CondBB))
- return false;
- BranchInst *TermBr = dyn_cast<BranchInst>(CondBB->getTerminator());
- if (!TermBr || !TermBr->isConditional())
+void
+LSRInstance::InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx) {
+ Formula F;
+ F.InitialMatch(S, L, SE, DT);
+ bool Inserted = InsertFormula(LU, LUIdx, F);
+ assert(Inserted && "Initial formula already exists!"); (void)Inserted;
+}
+
+void
+LSRInstance::InsertSupplementalFormula(const SCEV *S,
+ LSRUse &LU, size_t LUIdx) {
+ Formula F;
+ F.BaseRegs.push_back(S);
+ F.AM.HasBaseReg = true;
+ bool Inserted = InsertFormula(LU, LUIdx, F);
+ assert(Inserted && "Supplemental formula already exists!"); (void)Inserted;
+}
+
+/// CountRegisters - Note which registers are used by the given formula,
+/// updating RegUses.
+void LSRInstance::CountRegisters(const Formula &F, size_t LUIdx) {
+ if (F.ScaledReg)
+ RegUses.CountRegister(F.ScaledReg, LUIdx);
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
+ E = F.BaseRegs.end(); I != E; ++I)
+ RegUses.CountRegister(*I, LUIdx);
+}
+
+/// InsertFormula - If the given formula has not yet been inserted, add it to
+/// the list, and return true. Return false otherwise.
+bool LSRInstance::InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F) {
+ if (!LU.InsertFormula(F))
return false;
- Value *User = *Cond->use_begin();
- Instruction *UserInst = dyn_cast<Instruction>(User);
- while (UserInst &&
- (UserInst->getOpcode() == Instruction::And ||
- UserInst->getOpcode() == Instruction::Or)) {
- if (!UserInst->hasOneUse() || UserInst->getParent() != CondBB)
- return false;
- User = *User->use_begin();
- UserInst = dyn_cast<Instruction>(User);
+ CountRegisters(F, LUIdx);
+ return true;
+}
+
+/// CollectLoopInvariantFixupsAndFormulae - Check for other uses of
+/// loop-invariant values which we're tracking. These other uses will pin these
+/// values in registers, making them less profitable for elimination.
+/// TODO: This currently misses non-constant addrec step registers.
+/// TODO: Should this give more weight to users inside the loop?
+void
+LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
+ SmallVector<const SCEV *, 8> Worklist(RegUses.begin(), RegUses.end());
+ SmallPtrSet<const SCEV *, 8> Inserted;
+
+ while (!Worklist.empty()) {
+ const SCEV *S = Worklist.pop_back_val();
+
+ if (const SCEVNAryExpr *N = dyn_cast<SCEVNAryExpr>(S))
+ Worklist.insert(Worklist.end(), N->op_begin(), N->op_end());
+ else if (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(S))
+ Worklist.push_back(C->getOperand());
+ else if (const SCEVUDivExpr *D = dyn_cast<SCEVUDivExpr>(S)) {
+ Worklist.push_back(D->getLHS());
+ Worklist.push_back(D->getRHS());
+ } else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
+ if (!Inserted.insert(U)) continue;
+ const Value *V = U->getValue();
+ if (const Instruction *Inst = dyn_cast<Instruction>(V))
+ if (L->contains(Inst)) continue;
+ for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end();
+ UI != UE; ++UI) {
+ const Instruction *UserInst = dyn_cast<Instruction>(*UI);
+ // Ignore non-instructions.
+ if (!UserInst)
+ continue;
+ // Ignore instructions in other functions (as can happen with
+ // Constants).
+ if (UserInst->getParent()->getParent() != L->getHeader()->getParent())
+ continue;
+ // Ignore instructions not dominated by the loop.
+ const BasicBlock *UseBB = !isa<PHINode>(UserInst) ?
+ UserInst->getParent() :
+ cast<PHINode>(UserInst)->getIncomingBlock(
+ PHINode::getIncomingValueNumForOperand(UI.getOperandNo()));
+ if (!DT.dominates(L->getHeader(), UseBB))
+ continue;
+ // Ignore uses which are part of other SCEV expressions, to avoid
+ // analyzing them multiple times.
+ if (SE.isSCEVable(UserInst->getType()) &&
+ !isa<SCEVUnknown>(SE.getSCEV(const_cast<Instruction *>(UserInst))))
+ continue;
+ // Ignore icmp instructions which are already being analyzed.
+ if (const ICmpInst *ICI = dyn_cast<ICmpInst>(UserInst)) {
+ unsigned OtherIdx = !UI.getOperandNo();
+ Value *OtherOp = const_cast<Value *>(ICI->getOperand(OtherIdx));
+ if (SE.getSCEV(OtherOp)->hasComputableLoopEvolution(L))
+ continue;
+ }
+
+ LSRFixup &LF = getNewFixup();
+ LF.UserInst = const_cast<Instruction *>(UserInst);
+ LF.OperandValToReplace = UI.getUse();
+ std::pair<size_t, int64_t> P = getUse(S, LSRUse::Basic, 0);
+ LF.LUIdx = P.first;
+ LF.Offset = P.second;
+ LSRUse &LU = Uses[LF.LUIdx];
+ LU.AllFixupsOutsideLoop &= L->contains(LF.UserInst);
+ InsertSupplementalFormula(U, LU, LF.LUIdx);
+ CountRegisters(LU.Formulae.back(), Uses.size() - 1);
+ break;
+ }
+ }
}
- return User == TermBr;
}
-static bool ShouldCountToZero(ICmpInst *Cond, IVStrideUse* &CondUse,
- ScalarEvolution *SE, Loop *L,
- const TargetLowering *TLI = 0) {
- if (!L->contains(Cond))
- return false;
+/// CollectSubexprs - Split S into subexpressions which can be pulled out into
+/// separate registers. If C is non-null, multiply each subexpression by C.
+static void CollectSubexprs(const SCEV *S, const SCEVConstant *C,
+ SmallVectorImpl<const SCEV *> &Ops,
+ ScalarEvolution &SE) {
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ // Break out add operands.
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I)
+ CollectSubexprs(*I, C, Ops, SE);
+ return;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ // Split a non-zero base out of an addrec.
+ if (!AR->getStart()->isZero()) {
+ CollectSubexprs(SE.getAddRecExpr(SE.getIntegerSCEV(0, AR->getType()),
+ AR->getStepRecurrence(SE),
+ AR->getLoop()), C, Ops, SE);
+ CollectSubexprs(AR->getStart(), C, Ops, SE);
+ return;
+ }
+ } else if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
+ // Break (C * (a + b + c)) into C*a + C*b + C*c.
+ if (Mul->getNumOperands() == 2)
+ if (const SCEVConstant *Op0 =
+ dyn_cast<SCEVConstant>(Mul->getOperand(0))) {
+ CollectSubexprs(Mul->getOperand(1),
+ C ? cast<SCEVConstant>(SE.getMulExpr(C, Op0)) : Op0,
+ Ops, SE);
+ return;
+ }
+ }
- if (!isa<SCEVConstant>(CondUse->getOffset()))
- return false;
+ // Otherwise use the value itself.
+ Ops.push_back(C ? SE.getMulExpr(C, S) : S);
+}
- // Handle only tests for equality for the moment.
- if (!Cond->isEquality() || !Cond->hasOneUse())
- return false;
- if (!isUsedByExitBranch(Cond, L))
- return false;
+/// GenerateReassociations - Split out subexpressions from adds and the bases of
+/// addrecs.
+void LSRInstance::GenerateReassociations(LSRUse &LU, unsigned LUIdx,
+ Formula Base,
+ unsigned Depth) {
+ // Arbitrarily cap recursion to protect compile time.
+ if (Depth >= 3) return;
+
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
+ const SCEV *BaseReg = Base.BaseRegs[i];
+
+ SmallVector<const SCEV *, 8> AddOps;
+ CollectSubexprs(BaseReg, 0, AddOps, SE);
+ if (AddOps.size() == 1) continue;
+
+ for (SmallVectorImpl<const SCEV *>::const_iterator J = AddOps.begin(),
+ JE = AddOps.end(); J != JE; ++J) {
+ // Don't pull a constant into a register if the constant could be folded
+ // into an immediate field.
+ if (isAlwaysFoldable(*J, LU.MinOffset, LU.MaxOffset,
+ Base.getNumRegs() > 1,
+ LU.Kind, LU.AccessTy, TLI, SE))
+ continue;
- Value *CondOp0 = Cond->getOperand(0);
- const SCEV *IV = SE->getSCEV(CondOp0);
- const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
- if (!AR || !AR->isAffine())
- return false;
+ // Collect all operands except *J.
+ SmallVector<const SCEV *, 8> InnerAddOps;
+ for (SmallVectorImpl<const SCEV *>::const_iterator K = AddOps.begin(),
+ KE = AddOps.end(); K != KE; ++K)
+ if (K != J)
+ InnerAddOps.push_back(*K);
+
+ // Don't leave just a constant behind in a register if the constant could
+ // be folded into an immediate field.
+ if (InnerAddOps.size() == 1 &&
+ isAlwaysFoldable(InnerAddOps[0], LU.MinOffset, LU.MaxOffset,
+ Base.getNumRegs() > 1,
+ LU.Kind, LU.AccessTy, TLI, SE))
+ continue;
- const SCEVConstant *SC = dyn_cast<SCEVConstant>(AR->getStepRecurrence(*SE));
- if (!SC || SC->getValue()->getSExtValue() < 0)
- // If it's already counting down, don't do anything.
- return false;
+ Formula F = Base;
+ F.BaseRegs[i] = SE.getAddExpr(InnerAddOps);
+ F.BaseRegs.push_back(*J);
+ if (InsertFormula(LU, LUIdx, F))
+ // If that formula hadn't been seen before, recurse to find more like
+ // it.
+ GenerateReassociations(LU, LUIdx, LU.Formulae.back(), Depth+1);
+ }
+ }
+}
- // If the RHS of the comparison is not an loop invariant, the rewrite
- // cannot be done. Also bail out if it's already comparing against a zero.
- // If we are checking this before cmp stride optimization, check if it's
- // comparing against a already legal immediate.
- Value *RHS = Cond->getOperand(1);
- ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS);
- if (!L->isLoopInvariant(RHS) ||
- (RHSC && RHSC->isZero()) ||
- (RHSC && TLI && TLI->isLegalICmpImmediate(RHSC->getSExtValue())))
- return false;
+/// GenerateCombinations - Generate a formula consisting of all of the
+/// loop-dominating registers added into a single register.
+void LSRInstance::GenerateCombinations(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // This method is only interesting on a plurality of registers.
+ if (Base.BaseRegs.size() <= 1) return;
+
+ Formula F = Base;
+ F.BaseRegs.clear();
+ SmallVector<const SCEV *, 4> Ops;
+ for (SmallVectorImpl<const SCEV *>::const_iterator
+ I = Base.BaseRegs.begin(), E = Base.BaseRegs.end(); I != E; ++I) {
+ const SCEV *BaseReg = *I;
+ if (BaseReg->properlyDominates(L->getHeader(), &DT) &&
+ !BaseReg->hasComputableLoopEvolution(L))
+ Ops.push_back(BaseReg);
+ else
+ F.BaseRegs.push_back(BaseReg);
+ }
+ if (Ops.size() > 1) {
+ const SCEV *Sum = SE.getAddExpr(Ops);
+ // TODO: If Sum is zero, it probably means ScalarEvolution missed an
+ // opportunity to fold something. For now, just ignore such cases
+ // rather than proceed with zero in a register.
+ if (!Sum->isZero()) {
+ F.BaseRegs.push_back(Sum);
+ (void)InsertFormula(LU, LUIdx, F);
+ }
+ }
+}
- // Make sure the IV is only used for counting. Value may be preinc or
- // postinc; 2 uses in either case.
- if (!CondOp0->hasNUses(2))
- return false;
+/// GenerateSymbolicOffsets - Generate reuse formulae using symbolic offsets.
+void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // We can't add a symbolic offset if the address already contains one.
+ if (Base.AM.BaseGV) return;
- return true;
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
+ const SCEV *G = Base.BaseRegs[i];
+ GlobalValue *GV = ExtractSymbol(G, SE);
+ if (G->isZero() || !GV)
+ continue;
+ Formula F = Base;
+ F.AM.BaseGV = GV;
+ if (!isLegalUse(F.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ F.BaseRegs[i] = G;
+ (void)InsertFormula(LU, LUIdx, F);
+ }
}
-/// OptimizeLoopTermCond - Change loop terminating condition to use the
-/// postinc iv when possible.
-void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
- BasicBlock *LatchBlock = L->getLoopLatch();
- bool LatchExit = L->isLoopExiting(LatchBlock);
- SmallVector<BasicBlock*, 8> ExitingBlocks;
- L->getExitingBlocks(ExitingBlocks);
+/// GenerateConstantOffsets - Generate reuse formulae using symbolic offsets.
+void LSRInstance::GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // TODO: For now, just add the min and max offset, because it usually isn't
+ // worthwhile looking at everything inbetween.
+ SmallVector<int64_t, 4> Worklist;
+ Worklist.push_back(LU.MinOffset);
+ if (LU.MaxOffset != LU.MinOffset)
+ Worklist.push_back(LU.MaxOffset);
+
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
+ const SCEV *G = Base.BaseRegs[i];
+
+ for (SmallVectorImpl<int64_t>::const_iterator I = Worklist.begin(),
+ E = Worklist.end(); I != E; ++I) {
+ Formula F = Base;
+ F.AM.BaseOffs = (uint64_t)Base.AM.BaseOffs - *I;
+ if (isLegalUse(F.AM, LU.MinOffset - *I, LU.MaxOffset - *I,
+ LU.Kind, LU.AccessTy, TLI)) {
+ F.BaseRegs[i] = SE.getAddExpr(G, SE.getIntegerSCEV(*I, G->getType()));
+
+ (void)InsertFormula(LU, LUIdx, F);
+ }
+ }
- for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
- BasicBlock *ExitingBlock = ExitingBlocks[i];
+ int64_t Imm = ExtractImmediate(G, SE);
+ if (G->isZero() || Imm == 0)
+ continue;
+ Formula F = Base;
+ F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Imm;
+ if (!isLegalUse(F.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ F.BaseRegs[i] = G;
+ (void)InsertFormula(LU, LUIdx, F);
+ }
+}
- // Finally, get the terminating condition for the loop if possible. If we
- // can, we want to change it to use a post-incremented version of its
- // induction variable, to allow coalescing the live ranges for the IV into
- // one register value.
+/// GenerateICmpZeroScales - For ICmpZero, check to see if we can scale up
+/// the comparison. For example, x == y -> x*c == y*c.
+void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ if (LU.Kind != LSRUse::ICmpZero) return;
- BranchInst *TermBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
- if (!TermBr)
+ // Determine the integer type for the base formula.
+ const Type *IntTy = Base.getType();
+ if (!IntTy) return;
+ if (SE.getTypeSizeInBits(IntTy) > 64) return;
+
+ // Don't do this if there is more than one offset.
+ if (LU.MinOffset != LU.MaxOffset) return;
+
+ assert(!Base.AM.BaseGV && "ICmpZero use is not legal!");
+
+ // Check each interesting stride.
+ for (SmallSetVector<int64_t, 8>::const_iterator
+ I = Factors.begin(), E = Factors.end(); I != E; ++I) {
+ int64_t Factor = *I;
+ Formula F = Base;
+
+ // Check that the multiplication doesn't overflow.
+ if (F.AM.BaseOffs == INT64_MIN && Factor == -1)
continue;
- // FIXME: Overly conservative, termination condition could be an 'or' etc..
- if (TermBr->isUnconditional() || !isa<ICmpInst>(TermBr->getCondition()))
+ F.AM.BaseOffs = (uint64_t)Base.AM.BaseOffs * Factor;
+ if (F.AM.BaseOffs / Factor != Base.AM.BaseOffs)
continue;
- // Search IVUsesByStride to find Cond's IVUse if there is one.
- IVStrideUse *CondUse = 0;
- const SCEV *CondStride = 0;
- ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
- if (!FindIVUserForCond(Cond, CondUse, CondStride))
+ // Check that multiplying with the use offset doesn't overflow.
+ int64_t Offset = LU.MinOffset;
+ if (Offset == INT64_MIN && Factor == -1)
+ continue;
+ Offset = (uint64_t)Offset * Factor;
+ if (Offset / Factor != LU.MinOffset)
continue;
- // If the latch block is exiting and it's not a single block loop, it's
- // not safe to use postinc iv in other exiting blocks. FIXME: overly
- // conservative? How about icmp stride optimization?
- bool UsePostInc = !(e > 1 && LatchExit && ExitingBlock != LatchBlock);
- if (UsePostInc && ExitingBlock != LatchBlock) {
- if (!Cond->hasOneUse())
- // See below, we don't want the condition to be cloned.
- UsePostInc = false;
- else {
- // If exiting block is the latch block, we know it's safe and profitable
- // to transform the icmp to use post-inc iv. Otherwise do so only if it
- // would not reuse another iv and its iv would be reused by other uses.
- // We are optimizing for the case where the icmp is the only use of the
- // iv.
- IVUsersOfOneStride &StrideUses = *IU->IVUsesByStride[CondStride];
- for (ilist<IVStrideUse>::iterator I = StrideUses.Users.begin(),
- E = StrideUses.Users.end(); I != E; ++I) {
- if (I->getUser() == Cond)
- continue;
- if (!I->isUseOfPostIncrementedValue()) {
- UsePostInc = false;
- break;
- }
+ // Check that this scale is legal.
+ if (!isLegalUse(F.AM, Offset, Offset, LU.Kind, LU.AccessTy, TLI))
+ continue;
+
+ // Compensate for the use having MinOffset built into it.
+ F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Offset - LU.MinOffset;
+
+ const SCEV *FactorS = SE.getIntegerSCEV(Factor, IntTy);
+
+ // Check that multiplying with each base register doesn't overflow.
+ for (size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) {
+ F.BaseRegs[i] = SE.getMulExpr(F.BaseRegs[i], FactorS);
+ if (getExactSDiv(F.BaseRegs[i], FactorS, SE) != Base.BaseRegs[i])
+ goto next;
+ }
+
+ // Check that multiplying with the scaled register doesn't overflow.
+ if (F.ScaledReg) {
+ F.ScaledReg = SE.getMulExpr(F.ScaledReg, FactorS);
+ if (getExactSDiv(F.ScaledReg, FactorS, SE) != Base.ScaledReg)
+ continue;
+ }
+
+ // If we make it here and it's legal, add it.
+ (void)InsertFormula(LU, LUIdx, F);
+ next:;
+ }
+}
+
+/// GenerateScales - Generate stride factor reuse formulae by making use of
+/// scaled-offset address modes, for example.
+void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // Determine the integer type for the base formula.
+ const Type *IntTy = Base.getType();
+ if (!IntTy) return;
+
+ // If this Formula already has a scaled register, we can't add another one.
+ if (Base.AM.Scale != 0) return;
+
+ // Check each interesting stride.
+ for (SmallSetVector<int64_t, 8>::const_iterator
+ I = Factors.begin(), E = Factors.end(); I != E; ++I) {
+ int64_t Factor = *I;
+
+ Base.AM.Scale = Factor;
+ Base.AM.HasBaseReg = Base.BaseRegs.size() > 1;
+ // Check whether this scale is going to be legal.
+ if (!isLegalUse(Base.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI)) {
+ // As a special-case, handle special out-of-loop Basic users specially.
+ // TODO: Reconsider this special case.
+ if (LU.Kind == LSRUse::Basic &&
+ isLegalUse(Base.AM, LU.MinOffset, LU.MaxOffset,
+ LSRUse::Special, LU.AccessTy, TLI) &&
+ LU.AllFixupsOutsideLoop)
+ LU.Kind = LSRUse::Special;
+ else
+ continue;
+ }
+ // For an ICmpZero, negating a solitary base register won't lead to
+ // new solutions.
+ if (LU.Kind == LSRUse::ICmpZero &&
+ !Base.AM.HasBaseReg && Base.AM.BaseOffs == 0 && !Base.AM.BaseGV)
+ continue;
+ // For each addrec base reg, apply the scale, if possible.
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i)
+ if (const SCEVAddRecExpr *AR =
+ dyn_cast<SCEVAddRecExpr>(Base.BaseRegs[i])) {
+ const SCEV *FactorS = SE.getIntegerSCEV(Factor, IntTy);
+ if (FactorS->isZero())
+ continue;
+ // Divide out the factor, ignoring high bits, since we'll be
+ // scaling the value back up in the end.
+ if (const SCEV *Quotient = getExactSDiv(AR, FactorS, SE, true)) {
+ // TODO: This could be optimized to avoid all the copying.
+ Formula F = Base;
+ F.ScaledReg = Quotient;
+ std::swap(F.BaseRegs[i], F.BaseRegs.back());
+ F.BaseRegs.pop_back();
+ (void)InsertFormula(LU, LUIdx, F);
}
}
+ }
+}
- // If iv for the stride might be shared and any of the users use pre-inc
- // iv might be used, then it's not safe to use post-inc iv.
- if (UsePostInc &&
- isa<SCEVConstant>(CondStride) &&
- StrideMightBeShared(CondStride, L, true))
- UsePostInc = false;
- }
+/// GenerateTruncates - Generate reuse formulae from different IV types.
+void LSRInstance::GenerateTruncates(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // This requires TargetLowering to tell us which truncates are free.
+ if (!TLI) return;
+
+ // Don't bother truncating symbolic values.
+ if (Base.AM.BaseGV) return;
+
+ // Determine the integer type for the base formula.
+ const Type *DstTy = Base.getType();
+ if (!DstTy) return;
+ DstTy = SE.getEffectiveSCEVType(DstTy);
+
+ for (SmallSetVector<const Type *, 4>::const_iterator
+ I = Types.begin(), E = Types.end(); I != E; ++I) {
+ const Type *SrcTy = *I;
+ if (SrcTy != DstTy && TLI->isTruncateFree(SrcTy, DstTy)) {
+ Formula F = Base;
+
+ if (F.ScaledReg) F.ScaledReg = SE.getAnyExtendExpr(F.ScaledReg, *I);
+ for (SmallVectorImpl<const SCEV *>::iterator J = F.BaseRegs.begin(),
+ JE = F.BaseRegs.end(); J != JE; ++J)
+ *J = SE.getAnyExtendExpr(*J, SrcTy);
+
+ // TODO: This assumes we've done basic processing on all uses and
+ // have an idea what the register usage is.
+ if (!F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
+ continue;
- // If the trip count is computed in terms of a max (due to ScalarEvolution
- // being unable to find a sufficient guard, for example), change the loop
- // comparison to use SLT or ULT instead of NE.
- Cond = OptimizeMax(L, Cond, CondUse);
-
- // If possible, change stride and operands of the compare instruction to
- // eliminate one stride. However, avoid rewriting the compare instruction
- // with an iv of new stride if it's likely the new stride uses will be
- // rewritten using the stride of the compare instruction.
- if (ExitingBlock == LatchBlock && isa<SCEVConstant>(CondStride)) {
- // If the condition stride is a constant and it's the only use, we might
- // want to optimize it first by turning it to count toward zero.
- if (!StrideMightBeShared(CondStride, L, false) &&
- !ShouldCountToZero(Cond, CondUse, SE, L, TLI))
- Cond = ChangeCompareStride(L, Cond, CondUse, CondStride);
+ (void)InsertFormula(LU, LUIdx, F);
}
+ }
+}
+
+namespace {
+
+/// WorkItem - Helper class for GenerateCrossUseConstantOffsets. It's used to
+/// defer modifications so that the search phase doesn't have to worry about
+/// the data structures moving underneath it.
+struct WorkItem {
+ size_t LUIdx;
+ int64_t Imm;
+ const SCEV *OrigReg;
+
+ WorkItem(size_t LI, int64_t I, const SCEV *R)
+ : LUIdx(LI), Imm(I), OrigReg(R) {}
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
+
+}
+
+void WorkItem::print(raw_ostream &OS) const {
+ OS << "in formulae referencing " << *OrigReg << " in use " << LUIdx
+ << " , add offset " << Imm;
+}
+
+void WorkItem::dump() const {
+ print(errs()); errs() << '\n';
+}
- if (!UsePostInc)
+/// GenerateCrossUseConstantOffsets - Look for registers which are a constant
+/// distance apart and try to form reuse opportunities between them.
+void LSRInstance::GenerateCrossUseConstantOffsets() {
+ // Group the registers by their value without any added constant offset.
+ typedef std::map<int64_t, const SCEV *> ImmMapTy;
+ typedef DenseMap<const SCEV *, ImmMapTy> RegMapTy;
+ RegMapTy Map;
+ DenseMap<const SCEV *, SmallBitVector> UsedByIndicesMap;
+ SmallVector<const SCEV *, 8> Sequence;
+ for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
+ I != E; ++I) {
+ const SCEV *Reg = *I;
+ int64_t Imm = ExtractImmediate(Reg, SE);
+ std::pair<RegMapTy::iterator, bool> Pair =
+ Map.insert(std::make_pair(Reg, ImmMapTy()));
+ if (Pair.second)
+ Sequence.push_back(Reg);
+ Pair.first->second.insert(std::make_pair(Imm, *I));
+ UsedByIndicesMap[Reg] |= RegUses.getUsedByIndices(*I);
+ }
+
+ // Now examine each set of registers with the same base value. Build up
+ // a list of work to do and do the work in a separate step so that we're
+ // not adding formulae and register counts while we're searching.
+ SmallVector<WorkItem, 32> WorkItems;
+ SmallSet<std::pair<size_t, int64_t>, 32> UniqueItems;
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = Sequence.begin(),
+ E = Sequence.end(); I != E; ++I) {
+ const SCEV *Reg = *I;
+ const ImmMapTy &Imms = Map.find(Reg)->second;
+
+ // It's not worthwhile looking for reuse if there's only one offset.
+ if (Imms.size() == 1)
continue;
- DEBUG(dbgs() << " Change loop exiting icmp to use postinc iv: "
- << *Cond << '\n');
+ DEBUG(dbgs() << "Generating cross-use offsets for " << *Reg << ':';
+ for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
+ J != JE; ++J)
+ dbgs() << ' ' << J->first;
+ dbgs() << '\n');
- // It's possible for the setcc instruction to be anywhere in the loop, and
- // possible for it to have multiple users. If it is not immediately before
- // the exiting block branch, move it.
- if (&*++BasicBlock::iterator(Cond) != (Instruction*)TermBr) {
- if (Cond->hasOneUse()) { // Condition has a single use, just move it.
- Cond->moveBefore(TermBr);
+ // Examine each offset.
+ for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
+ J != JE; ++J) {
+ const SCEV *OrigReg = J->second;
+
+ int64_t JImm = J->first;
+ const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
+
+ if (!isa<SCEVConstant>(OrigReg) &&
+ UsedByIndicesMap[Reg].count() == 1) {
+ DEBUG(dbgs() << "Skipping cross-use reuse for " << *OrigReg << '\n');
+ continue;
+ }
+
+ // Conservatively examine offsets between this orig reg a few selected
+ // other orig regs.
+ ImmMapTy::const_iterator OtherImms[] = {
+ Imms.begin(), prior(Imms.end()),
+ Imms.upper_bound((Imms.begin()->first + prior(Imms.end())->first) / 2)
+ };
+ for (size_t i = 0, e = array_lengthof(OtherImms); i != e; ++i) {
+ ImmMapTy::const_iterator M = OtherImms[i];
+ if (M == J || M == JE) continue;
+
+ // Compute the difference between the two.
+ int64_t Imm = (uint64_t)JImm - M->first;
+ for (int LUIdx = UsedByIndices.find_first(); LUIdx != -1;
+ LUIdx = UsedByIndices.find_next(LUIdx))
+ // Make a memo of this use, offset, and register tuple.
+ if (UniqueItems.insert(std::make_pair(LUIdx, Imm)))
+ WorkItems.push_back(WorkItem(LUIdx, Imm, OrigReg));
+ }
+ }
+ }
+
+ Map.clear();
+ Sequence.clear();
+ UsedByIndicesMap.clear();
+ UniqueItems.clear();
+
+ // Now iterate through the worklist and add new formulae.
+ for (SmallVectorImpl<WorkItem>::const_iterator I = WorkItems.begin(),
+ E = WorkItems.end(); I != E; ++I) {
+ const WorkItem &WI = *I;
+ size_t LUIdx = WI.LUIdx;
+ LSRUse &LU = Uses[LUIdx];
+ int64_t Imm = WI.Imm;
+ const SCEV *OrigReg = WI.OrigReg;
+
+ const Type *IntTy = SE.getEffectiveSCEVType(OrigReg->getType());
+ const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm));
+ unsigned BitWidth = SE.getTypeSizeInBits(IntTy);
+
+ // TODO: Use a more targeted data structure.
+ for (size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) {
+ Formula F = LU.Formulae[L];
+ // Use the immediate in the scaled register.
+ if (F.ScaledReg == OrigReg) {
+ int64_t Offs = (uint64_t)F.AM.BaseOffs +
+ Imm * (uint64_t)F.AM.Scale;
+ // Don't create 50 + reg(-50).
+ if (F.referencesReg(SE.getSCEV(
+ ConstantInt::get(IntTy, -(uint64_t)Offs))))
+ continue;
+ Formula NewF = F;
+ NewF.AM.BaseOffs = Offs;
+ if (!isLegalUse(NewF.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ NewF.ScaledReg = SE.getAddExpr(NegImmS, NewF.ScaledReg);
+
+ // If the new scale is a constant in a register, and adding the constant
+ // value to the immediate would produce a value closer to zero than the
+ // immediate itself, then the formula isn't worthwhile.
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(NewF.ScaledReg))
+ if (C->getValue()->getValue().isNegative() !=
+ (NewF.AM.BaseOffs < 0) &&
+ (C->getValue()->getValue().abs() * APInt(BitWidth, F.AM.Scale))
+ .ule(APInt(BitWidth, NewF.AM.BaseOffs).abs()))
+ continue;
+
+ // OK, looks good.
+ (void)InsertFormula(LU, LUIdx, NewF);
} else {
- // Otherwise, clone the terminating condition and insert into the
- // loopend.
- Cond = cast<ICmpInst>(Cond->clone());
- Cond->setName(L->getHeader()->getName() + ".termcond");
- ExitingBlock->getInstList().insert(TermBr, Cond);
+ // Use the immediate in a base register.
+ for (size_t N = 0, NE = F.BaseRegs.size(); N != NE; ++N) {
+ const SCEV *BaseReg = F.BaseRegs[N];
+ if (BaseReg != OrigReg)
+ continue;
+ Formula NewF = F;
+ NewF.AM.BaseOffs = (uint64_t)NewF.AM.BaseOffs + Imm;
+ if (!isLegalUse(NewF.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ NewF.BaseRegs[N] = SE.getAddExpr(NegImmS, BaseReg);
+
+ // If the new formula has a constant in a register, and adding the
+ // constant value to the immediate would produce a value closer to
+ // zero than the immediate itself, then the formula isn't worthwhile.
+ for (SmallVectorImpl<const SCEV *>::const_iterator
+ J = NewF.BaseRegs.begin(), JE = NewF.BaseRegs.end();
+ J != JE; ++J)
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*J))
+ if (C->getValue()->getValue().isNegative() !=
+ (NewF.AM.BaseOffs < 0) &&
+ C->getValue()->getValue().abs()
+ .ule(APInt(BitWidth, NewF.AM.BaseOffs).abs()))
+ goto skip_formula;
+
+ // Ok, looks good.
+ (void)InsertFormula(LU, LUIdx, NewF);
+ break;
+ skip_formula:;
+ }
+ }
+ }
+ }
+}
- // Clone the IVUse, as the old use still exists!
- IU->IVUsesByStride[CondStride]->addUser(CondUse->getOffset(), Cond,
- CondUse->getOperandValToReplace());
- CondUse = &IU->IVUsesByStride[CondStride]->Users.back();
+/// GenerateAllReuseFormulae - Generate formulae for each use.
+void
+LSRInstance::GenerateAllReuseFormulae() {
+ // This is split into multiple loops so that hasRegsUsedByUsesOtherThan
+ // queries are more precise.
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
+ }
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateScales(LU, LUIdx, LU.Formulae[i]);
+ }
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
+ }
+
+ GenerateCrossUseConstantOffsets();
+}
+
+/// If their are multiple formulae with the same set of registers used
+/// by other uses, pick the best one and delete the others.
+void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
+#ifndef NDEBUG
+ bool Changed = false;
+#endif
+
+ // Collect the best formula for each unique set of shared registers. This
+ // is reset for each use.
+ typedef DenseMap<SmallVector<const SCEV *, 2>, size_t, UniquifierDenseMapInfo>
+ BestFormulaeTy;
+ BestFormulaeTy BestFormulae;
+
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ FormulaSorter Sorter(L, LU, SE, DT);
+
+ // Clear out the set of used regs; it will be recomputed.
+ LU.Regs.clear();
+
+ for (size_t FIdx = 0, NumForms = LU.Formulae.size();
+ FIdx != NumForms; ++FIdx) {
+ Formula &F = LU.Formulae[FIdx];
+
+ SmallVector<const SCEV *, 2> Key;
+ for (SmallVectorImpl<const SCEV *>::const_iterator J = F.BaseRegs.begin(),
+ JE = F.BaseRegs.end(); J != JE; ++J) {
+ const SCEV *Reg = *J;
+ if (RegUses.isRegUsedByUsesOtherThan(Reg, LUIdx))
+ Key.push_back(Reg);
}
+ if (F.ScaledReg &&
+ RegUses.isRegUsedByUsesOtherThan(F.ScaledReg, LUIdx))
+ Key.push_back(F.ScaledReg);
+ // Unstable sort by host order ok, because this is only used for
+ // uniquifying.
+ std::sort(Key.begin(), Key.end());
+
+ std::pair<BestFormulaeTy::const_iterator, bool> P =
+ BestFormulae.insert(std::make_pair(Key, FIdx));
+ if (!P.second) {
+ Formula &Best = LU.Formulae[P.first->second];
+ if (Sorter.operator()(F, Best))
+ std::swap(F, Best);
+ DEBUG(dbgs() << "Filtering out "; F.print(dbgs());
+ dbgs() << "\n"
+ " in favor of "; Best.print(dbgs());
+ dbgs() << '\n');
+#ifndef NDEBUG
+ Changed = true;
+#endif
+ std::swap(F, LU.Formulae.back());
+ LU.Formulae.pop_back();
+ --FIdx;
+ --NumForms;
+ continue;
+ }
+ if (F.ScaledReg) LU.Regs.insert(F.ScaledReg);
+ LU.Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
}
+ BestFormulae.clear();
+ }
- // If we get to here, we know that we can transform the setcc instruction to
- // use the post-incremented version of the IV, allowing us to coalesce the
- // live ranges for the IV correctly.
- CondUse->setOffset(SE->getMinusSCEV(CondUse->getOffset(), CondStride));
- CondUse->setIsUseOfPostIncrementedValue(true);
- Changed = true;
+ DEBUG(if (Changed) {
+ dbgs() << "\n"
+ "After filtering out undesirable candidates:\n";
+ print_uses(dbgs());
+ });
+}
- ++NumLoopCond;
+/// NarrowSearchSpaceUsingHeuristics - If there are an extraordinary number of
+/// formulae to choose from, use some rough heuristics to prune down the number
+/// of formulae. This keeps the main solver from taking an extraordinary amount
+/// of time in some worst-case scenarios.
+void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
+ // This is a rough guess that seems to work fairly well.
+ const size_t Limit = UINT16_MAX;
+
+ SmallPtrSet<const SCEV *, 4> Taken;
+ for (;;) {
+ // Estimate the worst-case number of solutions we might consider. We almost
+ // never consider this many solutions because we prune the search space,
+ // but the pruning isn't always sufficient.
+ uint32_t Power = 1;
+ for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ size_t FSize = I->Formulae.size();
+ if (FSize >= Limit) {
+ Power = Limit;
+ break;
+ }
+ Power *= FSize;
+ if (Power >= Limit)
+ break;
+ }
+ if (Power < Limit)
+ break;
+
+ // Ok, we have too many of formulae on our hands to conveniently handle.
+ // Use a rough heuristic to thin out the list.
+
+ // Pick the register which is used by the most LSRUses, which is likely
+ // to be a good reuse register candidate.
+ const SCEV *Best = 0;
+ unsigned BestNum = 0;
+ for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
+ I != E; ++I) {
+ const SCEV *Reg = *I;
+ if (Taken.count(Reg))
+ continue;
+ if (!Best)
+ Best = Reg;
+ else {
+ unsigned Count = RegUses.getUsedByIndices(Reg).count();
+ if (Count > BestNum) {
+ Best = Reg;
+ BestNum = Count;
+ }
+ }
+ }
+
+ DEBUG(dbgs() << "Narrowing the search space by assuming " << *Best
+ << " will yield profitable reuse.\n");
+ Taken.insert(Best);
+
+ // In any use with formulae which references this register, delete formulae
+ // which don't reference it.
+ for (SmallVectorImpl<LSRUse>::iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ LSRUse &LU = *I;
+ if (!LU.Regs.count(Best)) continue;
+
+ // Clear out the set of used regs; it will be recomputed.
+ LU.Regs.clear();
+
+ for (size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
+ Formula &F = LU.Formulae[i];
+ if (!F.referencesReg(Best)) {
+ DEBUG(dbgs() << " Deleting "; F.print(dbgs()); dbgs() << '\n');
+ std::swap(LU.Formulae.back(), F);
+ LU.Formulae.pop_back();
+ --e;
+ --i;
+ continue;
+ }
+
+ if (F.ScaledReg) LU.Regs.insert(F.ScaledReg);
+ LU.Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
+ }
+ }
+
+ DEBUG(dbgs() << "After pre-selection:\n";
+ print_uses(dbgs()));
}
}
-bool LoopStrengthReduce::OptimizeLoopCountIVOfStride(const SCEV* &Stride,
- IVStrideUse* &CondUse,
- Loop *L) {
- // If the only use is an icmp of a loop exiting conditional branch, then
- // attempt the optimization.
- BasedUser User = BasedUser(*CondUse, SE);
- assert(isa<ICmpInst>(User.Inst) && "Expecting an ICMPInst!");
- ICmpInst *Cond = cast<ICmpInst>(User.Inst);
+/// SolveRecurse - This is the recursive solver.
+void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
+ Cost &SolutionCost,
+ SmallVectorImpl<const Formula *> &Workspace,
+ const Cost &CurCost,
+ const SmallPtrSet<const SCEV *, 16> &CurRegs,
+ DenseSet<const SCEV *> &VisitedRegs) const {
+ // Some ideas:
+ // - prune more:
+ // - use more aggressive filtering
+ // - sort the formula so that the most profitable solutions are found first
+ // - sort the uses too
+ // - search faster:
+ // - don't compute a cost, and then compare. compare while computing a cost
+ // and bail early.
+ // - track register sets with SmallBitVector
+
+ const LSRUse &LU = Uses[Workspace.size()];
+
+ // If this use references any register that's already a part of the
+ // in-progress solution, consider it a requirement that a formula must
+ // reference that register in order to be considered. This prunes out
+ // unprofitable searching.
+ SmallSetVector<const SCEV *, 4> ReqRegs;
+ for (SmallPtrSet<const SCEV *, 16>::const_iterator I = CurRegs.begin(),
+ E = CurRegs.end(); I != E; ++I)
+ if (LU.Regs.count(*I))
+ ReqRegs.insert(*I);
+
+ bool AnySatisfiedReqRegs = false;
+ SmallPtrSet<const SCEV *, 16> NewRegs;
+ Cost NewCost;
+retry:
+ for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
+ E = LU.Formulae.end(); I != E; ++I) {
+ const Formula &F = *I;
+
+ // Ignore formulae which do not use any of the required registers.
+ for (SmallSetVector<const SCEV *, 4>::const_iterator J = ReqRegs.begin(),
+ JE = ReqRegs.end(); J != JE; ++J) {
+ const SCEV *Reg = *J;
+ if ((!F.ScaledReg || F.ScaledReg != Reg) &&
+ std::find(F.BaseRegs.begin(), F.BaseRegs.end(), Reg) ==
+ F.BaseRegs.end())
+ goto skip;
+ }
+ AnySatisfiedReqRegs = true;
+
+ // Evaluate the cost of the current formula. If it's already worse than
+ // the current best, prune the search at that point.
+ NewCost = CurCost;
+ NewRegs = CurRegs;
+ NewCost.RateFormula(F, NewRegs, VisitedRegs, L, LU.Offsets, SE, DT);
+ if (NewCost < SolutionCost) {
+ Workspace.push_back(&F);
+ if (Workspace.size() != Uses.size()) {
+ SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
+ NewRegs, VisitedRegs);
+ if (F.getNumRegs() == 1 && Workspace.size() == 1)
+ VisitedRegs.insert(F.ScaledReg ? F.ScaledReg : F.BaseRegs[0]);
+ } else {
+ DEBUG(dbgs() << "New best at "; NewCost.print(dbgs());
+ dbgs() << ". Regs:";
+ for (SmallPtrSet<const SCEV *, 16>::const_iterator
+ I = NewRegs.begin(), E = NewRegs.end(); I != E; ++I)
+ dbgs() << ' ' << **I;
+ dbgs() << '\n');
+
+ SolutionCost = NewCost;
+ Solution = Workspace;
+ }
+ Workspace.pop_back();
+ }
+ skip:;
+ }
- // Less strict check now that compare stride optimization is done.
- if (!ShouldCountToZero(Cond, CondUse, SE, L))
- return false;
+ // If none of the formulae had all of the required registers, relax the
+ // constraint so that we don't exclude all formulae.
+ if (!AnySatisfiedReqRegs) {
+ ReqRegs.clear();
+ goto retry;
+ }
+}
- Value *CondOp0 = Cond->getOperand(0);
- PHINode *PHIExpr = dyn_cast<PHINode>(CondOp0);
- Instruction *Incr;
- if (!PHIExpr) {
- // Value tested is postinc. Find the phi node.
- Incr = dyn_cast<BinaryOperator>(CondOp0);
- // FIXME: Just use User.OperandValToReplace here?
- if (!Incr || Incr->getOpcode() != Instruction::Add)
- return false;
+void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution) const {
+ SmallVector<const Formula *, 8> Workspace;
+ Cost SolutionCost;
+ SolutionCost.Loose();
+ Cost CurCost;
+ SmallPtrSet<const SCEV *, 16> CurRegs;
+ DenseSet<const SCEV *> VisitedRegs;
+ Workspace.reserve(Uses.size());
+
+ SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
+ CurRegs, VisitedRegs);
+
+ // Ok, we've now made all our decisions.
+ DEBUG(dbgs() << "\n"
+ "The chosen solution requires "; SolutionCost.print(dbgs());
+ dbgs() << ":\n";
+ for (size_t i = 0, e = Uses.size(); i != e; ++i) {
+ dbgs() << " ";
+ Uses[i].print(dbgs());
+ dbgs() << "\n"
+ " ";
+ Solution[i]->print(dbgs());
+ dbgs() << '\n';
+ });
+}
- PHIExpr = dyn_cast<PHINode>(Incr->getOperand(0));
- if (!PHIExpr)
- return false;
- // 1 use for preinc value, the increment.
- if (!PHIExpr->hasOneUse())
- return false;
- } else {
- assert(isa<PHINode>(CondOp0) &&
- "Unexpected loop exiting counting instruction sequence!");
- PHIExpr = cast<PHINode>(CondOp0);
- // Value tested is preinc. Find the increment.
- // A CmpInst is not a BinaryOperator; we depend on this.
- Instruction::use_iterator UI = PHIExpr->use_begin();
- Incr = dyn_cast<BinaryOperator>(UI);
- if (!Incr)
- Incr = dyn_cast<BinaryOperator>(++UI);
- // One use for postinc value, the phi. Unnecessarily conservative?
- if (!Incr || !Incr->hasOneUse() || Incr->getOpcode() != Instruction::Add)
- return false;
+/// getImmediateDominator - A handy utility for the specific DominatorTree
+/// query that we need here.
+///
+static BasicBlock *getImmediateDominator(BasicBlock *BB, DominatorTree &DT) {
+ DomTreeNode *Node = DT.getNode(BB);
+ if (!Node) return 0;
+ Node = Node->getIDom();
+ if (!Node) return 0;
+ return Node->getBlock();
+}
+
+Value *LSRInstance::Expand(const LSRFixup &LF,
+ const Formula &F,
+ BasicBlock::iterator IP,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts) const {
+ const LSRUse &LU = Uses[LF.LUIdx];
+
+ // Then, collect some instructions which we will remain dominated by when
+ // expanding the replacement. These must be dominated by any operands that
+ // will be required in the expansion.
+ SmallVector<Instruction *, 4> Inputs;
+ if (Instruction *I = dyn_cast<Instruction>(LF.OperandValToReplace))
+ Inputs.push_back(I);
+ if (LU.Kind == LSRUse::ICmpZero)
+ if (Instruction *I =
+ dyn_cast<Instruction>(cast<ICmpInst>(LF.UserInst)->getOperand(1)))
+ Inputs.push_back(I);
+ if (LF.PostIncLoop) {
+ if (!L->contains(LF.UserInst))
+ Inputs.push_back(L->getLoopLatch()->getTerminator());
+ else
+ Inputs.push_back(IVIncInsertPos);
}
- // Replace the increment with a decrement.
- DEBUG(dbgs() << "LSR: Examining use ");
- DEBUG(WriteAsOperand(dbgs(), CondOp0, /*PrintType=*/false));
- DEBUG(dbgs() << " in Inst: " << *Cond << '\n');
- BinaryOperator *Decr = BinaryOperator::Create(Instruction::Sub,
- Incr->getOperand(0), Incr->getOperand(1), "tmp", Incr);
- Incr->replaceAllUsesWith(Decr);
- Incr->eraseFromParent();
-
- // Substitute endval-startval for the original startval, and 0 for the
- // original endval. Since we're only testing for equality this is OK even
- // if the computation wraps around.
- BasicBlock *Preheader = L->getLoopPreheader();
- Instruction *PreInsertPt = Preheader->getTerminator();
- unsigned InBlock = L->contains(PHIExpr->getIncomingBlock(0)) ? 1 : 0;
- Value *StartVal = PHIExpr->getIncomingValue(InBlock);
- Value *EndVal = Cond->getOperand(1);
- DEBUG(dbgs() << " Optimize loop counting iv to count down ["
- << *EndVal << " .. " << *StartVal << "]\n");
-
- // FIXME: check for case where both are constant.
- Constant* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0);
- BinaryOperator *NewStartVal = BinaryOperator::Create(Instruction::Sub,
- EndVal, StartVal, "tmp", PreInsertPt);
- PHIExpr->setIncomingValue(InBlock, NewStartVal);
- Cond->setOperand(1, Zero);
- DEBUG(dbgs() << " New icmp: " << *Cond << "\n");
-
- int64_t SInt = cast<SCEVConstant>(Stride)->getValue()->getSExtValue();
- const SCEV *NewStride = 0;
- bool Found = false;
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *OldStride = IU->StrideOrder[i];
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(OldStride))
- if (SC->getValue()->getSExtValue() == -SInt) {
- Found = true;
- NewStride = OldStride;
+ // Then, climb up the immediate dominator tree as far as we can go while
+ // still being dominated by the input positions.
+ for (;;) {
+ bool AllDominate = true;
+ Instruction *BetterPos = 0;
+ BasicBlock *IDom = getImmediateDominator(IP->getParent(), DT);
+ if (!IDom) break;
+ Instruction *Tentative = IDom->getTerminator();
+ for (SmallVectorImpl<Instruction *>::const_iterator I = Inputs.begin(),
+ E = Inputs.end(); I != E; ++I) {
+ Instruction *Inst = *I;
+ if (Inst == Tentative || !DT.dominates(Inst, Tentative)) {
+ AllDominate = false;
break;
}
+ if (IDom == Inst->getParent() &&
+ (!BetterPos || DT.dominates(BetterPos, Inst)))
+ BetterPos = next(BasicBlock::iterator(Inst));
+ }
+ if (!AllDominate)
+ break;
+ if (BetterPos)
+ IP = BetterPos;
+ else
+ IP = Tentative;
}
+ while (isa<PHINode>(IP)) ++IP;
+
+ // Inform the Rewriter if we have a post-increment use, so that it can
+ // perform an advantageous expansion.
+ Rewriter.setPostInc(LF.PostIncLoop);
+
+ // This is the type that the user actually needs.
+ const Type *OpTy = LF.OperandValToReplace->getType();
+ // This will be the type that we'll initially expand to.
+ const Type *Ty = F.getType();
+ if (!Ty)
+ // No type known; just expand directly to the ultimate type.
+ Ty = OpTy;
+ else if (SE.getEffectiveSCEVType(Ty) == SE.getEffectiveSCEVType(OpTy))
+ // Expand directly to the ultimate type if it's the right size.
+ Ty = OpTy;
+ // This is the type to do integer arithmetic in.
+ const Type *IntTy = SE.getEffectiveSCEVType(Ty);
+
+ // Build up a list of operands to add together to form the full base.
+ SmallVector<const SCEV *, 8> Ops;
+
+ // Expand the BaseRegs portion.
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
+ E = F.BaseRegs.end(); I != E; ++I) {
+ const SCEV *Reg = *I;
+ assert(!Reg->isZero() && "Zero allocated in a base register!");
+
+ // If we're expanding for a post-inc user for the add-rec's loop, make the
+ // post-inc adjustment.
+ const SCEV *Start = Reg;
+ while (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Start)) {
+ if (AR->getLoop() == LF.PostIncLoop) {
+ Reg = SE.getAddExpr(Reg, AR->getStepRecurrence(SE));
+ // If the user is inside the loop, insert the code after the increment
+ // so that it is dominated by its operand. If the original insert point
+ // was already dominated by the increment, keep it, because there may
+ // be loop-variant operands that need to be respected also.
+ if (L->contains(LF.UserInst) && !DT.dominates(IVIncInsertPos, IP))
+ IP = IVIncInsertPos;
+ break;
+ }
+ Start = AR->getStart();
+ }
- if (!Found)
- NewStride = SE->getIntegerSCEV(-SInt, Stride->getType());
- IU->AddUser(NewStride, CondUse->getOffset(), Cond, Cond->getOperand(0));
- IU->IVUsesByStride[Stride]->removeUser(CondUse);
+ Ops.push_back(SE.getUnknown(Rewriter.expandCodeFor(Reg, 0, IP)));
+ }
- CondUse = &IU->IVUsesByStride[NewStride]->Users.back();
- Stride = NewStride;
+ // Flush the operand list to suppress SCEVExpander hoisting.
+ if (!Ops.empty()) {
+ Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
+ Ops.clear();
+ Ops.push_back(SE.getUnknown(FullV));
+ }
- ++NumCountZero;
+ // Expand the ScaledReg portion.
+ Value *ICmpScaledV = 0;
+ if (F.AM.Scale != 0) {
+ const SCEV *ScaledS = F.ScaledReg;
+
+ // If we're expanding for a post-inc user for the add-rec's loop, make the
+ // post-inc adjustment.
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(ScaledS))
+ if (AR->getLoop() == LF.PostIncLoop)
+ ScaledS = SE.getAddExpr(ScaledS, AR->getStepRecurrence(SE));
+
+ if (LU.Kind == LSRUse::ICmpZero) {
+ // An interesting way of "folding" with an icmp is to use a negated
+ // scale, which we'll implement by inserting it into the other operand
+ // of the icmp.
+ assert(F.AM.Scale == -1 &&
+ "The only scale supported by ICmpZero uses is -1!");
+ ICmpScaledV = Rewriter.expandCodeFor(ScaledS, 0, IP);
+ } else {
+ // Otherwise just expand the scaled register and an explicit scale,
+ // which is expected to be matched as part of the address.
+ ScaledS = SE.getUnknown(Rewriter.expandCodeFor(ScaledS, 0, IP));
+ ScaledS = SE.getMulExpr(ScaledS,
+ SE.getIntegerSCEV(F.AM.Scale,
+ ScaledS->getType()));
+ Ops.push_back(ScaledS);
+
+ // Flush the operand list to suppress SCEVExpander hoisting.
+ Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
+ Ops.clear();
+ Ops.push_back(SE.getUnknown(FullV));
+ }
+ }
- return true;
+ // Expand the GV portion.
+ if (F.AM.BaseGV) {
+ Ops.push_back(SE.getUnknown(F.AM.BaseGV));
+
+ // Flush the operand list to suppress SCEVExpander hoisting.
+ Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
+ Ops.clear();
+ Ops.push_back(SE.getUnknown(FullV));
+ }
+
+ // Expand the immediate portion.
+ int64_t Offset = (uint64_t)F.AM.BaseOffs + LF.Offset;
+ if (Offset != 0) {
+ if (LU.Kind == LSRUse::ICmpZero) {
+ // The other interesting way of "folding" with an ICmpZero is to use a
+ // negated immediate.
+ if (!ICmpScaledV)
+ ICmpScaledV = ConstantInt::get(IntTy, -Offset);
+ else {
+ Ops.push_back(SE.getUnknown(ICmpScaledV));
+ ICmpScaledV = ConstantInt::get(IntTy, Offset);
+ }
+ } else {
+ // Just add the immediate values. These again are expected to be matched
+ // as part of the address.
+ Ops.push_back(SE.getUnknown(ConstantInt::getSigned(IntTy, Offset)));
+ }
+ }
+
+ // Emit instructions summing all the operands.
+ const SCEV *FullS = Ops.empty() ?
+ SE.getIntegerSCEV(0, IntTy) :
+ SE.getAddExpr(Ops);
+ Value *FullV = Rewriter.expandCodeFor(FullS, Ty, IP);
+
+ // We're done expanding now, so reset the rewriter.
+ Rewriter.setPostInc(0);
+
+ // An ICmpZero Formula represents an ICmp which we're handling as a
+ // comparison against zero. Now that we've expanded an expression for that
+ // form, update the ICmp's other operand.
+ if (LU.Kind == LSRUse::ICmpZero) {
+ ICmpInst *CI = cast<ICmpInst>(LF.UserInst);
+ DeadInsts.push_back(CI->getOperand(1));
+ assert(!F.AM.BaseGV && "ICmp does not support folding a global value and "
+ "a scale at the same time!");
+ if (F.AM.Scale == -1) {
+ if (ICmpScaledV->getType() != OpTy) {
+ Instruction *Cast =
+ CastInst::Create(CastInst::getCastOpcode(ICmpScaledV, false,
+ OpTy, false),
+ ICmpScaledV, OpTy, "tmp", CI);
+ ICmpScaledV = Cast;
+ }
+ CI->setOperand(1, ICmpScaledV);
+ } else {
+ assert(F.AM.Scale == 0 &&
+ "ICmp does not support folding a global value and "
+ "a scale at the same time!");
+ Constant *C = ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy),
+ -(uint64_t)Offset);
+ if (C->getType() != OpTy)
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ OpTy, false),
+ C, OpTy);
+
+ CI->setOperand(1, C);
+ }
+ }
+
+ return FullV;
}
-/// OptimizeLoopCountIV - If, after all sharing of IVs, the IV used for deciding
-/// when to exit the loop is used only for that purpose, try to rearrange things
-/// so it counts down to a test against zero.
-bool LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) {
- bool ThisChanged = false;
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *Stride = IU->StrideOrder[i];
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(Stride);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- // FIXME: Generalize to non-affine IV's.
- if (!SI->first->isLoopInvariant(L))
- continue;
- // If stride is a constant and it has an icmpinst use, check if we can
- // optimize the loop to count down.
- if (isa<SCEVConstant>(Stride) && SI->second->Users.size() == 1) {
- Instruction *User = SI->second->Users.begin()->getUser();
- if (!isa<ICmpInst>(User))
- continue;
- const SCEV *CondStride = Stride;
- IVStrideUse *Use = &*SI->second->Users.begin();
- if (!OptimizeLoopCountIVOfStride(CondStride, Use, L))
- continue;
- ThisChanged = true;
+/// RewriteForPHI - Helper for Rewrite. PHI nodes are special because the use
+/// of their operands effectively happens in their predecessor blocks, so the
+/// expression may need to be expanded in multiple places.
+void LSRInstance::RewriteForPHI(PHINode *PN,
+ const LSRFixup &LF,
+ const Formula &F,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ Pass *P) const {
+ DenseMap<BasicBlock *, Value *> Inserted;
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingValue(i) == LF.OperandValToReplace) {
+ BasicBlock *BB = PN->getIncomingBlock(i);
+
+ // If this is a critical edge, split the edge so that we do not insert
+ // the code on all predecessor/successor paths. We do this unless this
+ // is the canonical backedge for this loop, which complicates post-inc
+ // users.
+ if (e != 1 && BB->getTerminator()->getNumSuccessors() > 1 &&
+ !isa<IndirectBrInst>(BB->getTerminator()) &&
+ (PN->getParent() != L->getHeader() || !L->contains(BB))) {
+ // Split the critical edge.
+ BasicBlock *NewBB = SplitCriticalEdge(BB, PN->getParent(), P);
+
+ // If PN is outside of the loop and BB is in the loop, we want to
+ // move the block to be immediately before the PHI block, not
+ // immediately after BB.
+ if (L->contains(BB) && !L->contains(PN))
+ NewBB->moveBefore(PN->getParent());
+
+ // Splitting the edge can reduce the number of PHI entries we have.
+ e = PN->getNumIncomingValues();
+ BB = NewBB;
+ i = PN->getBasicBlockIndex(BB);
+ }
- // Now check if it's possible to reuse this iv for other stride uses.
- for (unsigned j = 0, ee = IU->StrideOrder.size(); j != ee; ++j) {
- const SCEV *SStride = IU->StrideOrder[j];
- if (SStride == CondStride)
- continue;
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SII =
- IU->IVUsesByStride.find(SStride);
- assert(SII != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- // FIXME: Generalize to non-affine IV's.
- if (!SII->first->isLoopInvariant(L))
- continue;
- // FIXME: Rewrite other stride using CondStride.
+ std::pair<DenseMap<BasicBlock *, Value *>::iterator, bool> Pair =
+ Inserted.insert(std::make_pair(BB, static_cast<Value *>(0)));
+ if (!Pair.second)
+ PN->setIncomingValue(i, Pair.first->second);
+ else {
+ Value *FullV = Expand(LF, F, BB->getTerminator(), Rewriter, DeadInsts);
+
+ // If this is reuse-by-noop-cast, insert the noop cast.
+ const Type *OpTy = LF.OperandValToReplace->getType();
+ if (FullV->getType() != OpTy)
+ FullV =
+ CastInst::Create(CastInst::getCastOpcode(FullV, false,
+ OpTy, false),
+ FullV, LF.OperandValToReplace->getType(),
+ "tmp", BB->getTerminator());
+
+ PN->setIncomingValue(i, FullV);
+ Pair.first->second = FullV;
}
}
+}
+
+/// Rewrite - Emit instructions for the leading candidate expression for this
+/// LSRUse (this is called "expanding"), and update the UserInst to reference
+/// the newly expanded value.
+void LSRInstance::Rewrite(const LSRFixup &LF,
+ const Formula &F,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ Pass *P) const {
+ // First, find an insertion point that dominates UserInst. For PHI nodes,
+ // find the nearest block which dominates all the relevant uses.
+ if (PHINode *PN = dyn_cast<PHINode>(LF.UserInst)) {
+ RewriteForPHI(PN, LF, F, Rewriter, DeadInsts, P);
+ } else {
+ Value *FullV = Expand(LF, F, LF.UserInst, Rewriter, DeadInsts);
+
+ // If this is reuse-by-noop-cast, insert the noop cast.
+ const Type *OpTy = LF.OperandValToReplace->getType();
+ if (FullV->getType() != OpTy) {
+ Instruction *Cast =
+ CastInst::Create(CastInst::getCastOpcode(FullV, false, OpTy, false),
+ FullV, OpTy, "tmp", LF.UserInst);
+ FullV = Cast;
+ }
+
+ // Update the user. ICmpZero is handled specially here (for now) because
+ // Expand may have updated one of the operands of the icmp already, and
+ // its new value may happen to be equal to LF.OperandValToReplace, in
+ // which case doing replaceUsesOfWith leads to replacing both operands
+ // with the same value. TODO: Reorganize this.
+ if (Uses[LF.LUIdx].Kind == LSRUse::ICmpZero)
+ LF.UserInst->setOperand(0, FullV);
+ else
+ LF.UserInst->replaceUsesOfWith(LF.OperandValToReplace, FullV);
}
- Changed |= ThisChanged;
- return ThisChanged;
+ DeadInsts.push_back(LF.OperandValToReplace);
}
-bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
- IU = &getAnalysis<IVUsers>();
- SE = &getAnalysis<ScalarEvolution>();
- Changed = false;
+void
+LSRInstance::ImplementSolution(const SmallVectorImpl<const Formula *> &Solution,
+ Pass *P) {
+ // Keep track of instructions we may have made dead, so that
+ // we can remove them after we are done working.
+ SmallVector<WeakVH, 16> DeadInsts;
+
+ SCEVExpander Rewriter(SE);
+ Rewriter.disableCanonicalMode();
+ Rewriter.setIVIncInsertPos(L, IVIncInsertPos);
- // If LoopSimplify form is not available, stay out of trouble.
- if (!L->getLoopPreheader() || !L->getLoopLatch())
- return false;
+ // Expand the new value definitions and update the users.
+ for (size_t i = 0, e = Fixups.size(); i != e; ++i) {
+ size_t LUIdx = Fixups[i].LUIdx;
+
+ Rewrite(Fixups[i], *Solution[LUIdx], Rewriter, DeadInsts, P);
+
+ Changed = true;
+ }
- if (!IU->IVUsesByStride.empty()) {
- DEBUG(dbgs() << "\nLSR on \"" << L->getHeader()->getParent()->getName()
- << "\" ";
- L->print(dbgs()));
+ // Clean up after ourselves. This must be done before deleting any
+ // instructions.
+ Rewriter.clear();
- // Sort the StrideOrder so we process larger strides first.
- std::stable_sort(IU->StrideOrder.begin(), IU->StrideOrder.end(),
- StrideCompare(SE));
+ Changed |= DeleteTriviallyDeadInstructions(DeadInsts);
+}
- // Optimize induction variables. Some indvar uses can be transformed to use
- // strides that will be needed for other purposes. A common example of this
- // is the exit test for the loop, which can often be rewritten to use the
- // computation of some other indvar to decide when to terminate the loop.
- OptimizeIndvars(L);
+LSRInstance::LSRInstance(const TargetLowering *tli, Loop *l, Pass *P)
+ : IU(P->getAnalysis<IVUsers>()),
+ SE(P->getAnalysis<ScalarEvolution>()),
+ DT(P->getAnalysis<DominatorTree>()),
+ TLI(tli), L(l), Changed(false), IVIncInsertPos(0) {
- // Change loop terminating condition to use the postinc iv when possible
- // and optimize loop terminating compare. FIXME: Move this after
- // StrengthReduceIVUsersOfStride?
- OptimizeLoopTermCond(L);
+ // If LoopSimplify form is not available, stay out of trouble.
+ if (!L->isLoopSimplifyForm()) return;
+
+ // If there's no interesting work to be done, bail early.
+ if (IU.empty()) return;
+
+ DEBUG(dbgs() << "\nLSR on loop ";
+ WriteAsOperand(dbgs(), L->getHeader(), /*PrintType=*/false);
+ dbgs() << ":\n");
+
+ /// OptimizeShadowIV - If IV is used in a int-to-float cast
+ /// inside the loop then try to eliminate the cast operation.
+ OptimizeShadowIV();
+
+ // Change loop terminating condition to use the postinc iv when possible.
+ Changed |= OptimizeLoopTermCond();
+
+ CollectInterestingTypesAndFactors();
+ CollectFixupsAndInitialFormulae();
+ CollectLoopInvariantFixupsAndFormulae();
+
+ DEBUG(dbgs() << "LSR found " << Uses.size() << " uses:\n";
+ print_uses(dbgs()));
+
+ // Now use the reuse data to generate a bunch of interesting ways
+ // to formulate the values needed for the uses.
+ GenerateAllReuseFormulae();
+
+ DEBUG(dbgs() << "\n"
+ "After generating reuse formulae:\n";
+ print_uses(dbgs()));
+
+ FilterOutUndesirableDedicatedRegisters();
+ NarrowSearchSpaceUsingHeuristics();
+
+ SmallVector<const Formula *, 8> Solution;
+ Solve(Solution);
+ assert(Solution.size() == Uses.size() && "Malformed solution!");
+
+ // Release memory that is no longer needed.
+ Factors.clear();
+ Types.clear();
+ RegUses.clear();
+
+#ifndef NDEBUG
+ // Formulae should be legal.
+ for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ const LSRUse &LU = *I;
+ for (SmallVectorImpl<Formula>::const_iterator J = LU.Formulae.begin(),
+ JE = LU.Formulae.end(); J != JE; ++J)
+ assert(isLegalUse(J->AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI) &&
+ "Illegal formula generated!");
+ };
+#endif
- // FIXME: We can shrink overlarge IV's here. e.g. if the code has
- // computation in i64 values and the target doesn't support i64, demote
- // the computation to 32-bit if safe.
+ // Now that we've decided what we want, make it so.
+ ImplementSolution(Solution, P);
+}
- // FIXME: Attempt to reuse values across multiple IV's. In particular, we
- // could have something like "for(i) { foo(i*8); bar(i*16) }", which should
- // be codegened as "for (j = 0;; j+=8) { foo(j); bar(j+j); }" on X86/PPC.
- // Need to be careful that IV's are all the same type. Only works for
- // intptr_t indvars.
+void LSRInstance::print_factors_and_types(raw_ostream &OS) const {
+ if (Factors.empty() && Types.empty()) return;
- // IVsByStride keeps IVs for one particular loop.
- assert(IVsByStride.empty() && "Stale entries in IVsByStride?");
+ OS << "LSR has identified the following interesting factors and types: ";
+ bool First = true;
- StrengthReduceIVUsers(L);
+ for (SmallSetVector<int64_t, 8>::const_iterator
+ I = Factors.begin(), E = Factors.end(); I != E; ++I) {
+ if (!First) OS << ", ";
+ First = false;
+ OS << '*' << *I;
+ }
- // After all sharing is done, see if we can adjust the loop to test against
- // zero instead of counting up to a maximum. This is usually faster.
- OptimizeLoopCountIV(L);
+ for (SmallSetVector<const Type *, 4>::const_iterator
+ I = Types.begin(), E = Types.end(); I != E; ++I) {
+ if (!First) OS << ", ";
+ First = false;
+ OS << '(' << **I << ')';
+ }
+ OS << '\n';
+}
- // We're done analyzing this loop; release all the state we built up for it.
- IVsByStride.clear();
+void LSRInstance::print_fixups(raw_ostream &OS) const {
+ OS << "LSR is examining the following fixup sites:\n";
+ for (SmallVectorImpl<LSRFixup>::const_iterator I = Fixups.begin(),
+ E = Fixups.end(); I != E; ++I) {
+ const LSRFixup &LF = *I;
+ dbgs() << " ";
+ LF.print(OS);
+ OS << '\n';
+ }
+}
- // Clean up after ourselves
- DeleteTriviallyDeadInstructions();
+void LSRInstance::print_uses(raw_ostream &OS) const {
+ OS << "LSR is examining the following uses:\n";
+ for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ const LSRUse &LU = *I;
+ dbgs() << " ";
+ LU.print(OS);
+ OS << '\n';
+ for (SmallVectorImpl<Formula>::const_iterator J = LU.Formulae.begin(),
+ JE = LU.Formulae.end(); J != JE; ++J) {
+ OS << " ";
+ J->print(OS);
+ OS << '\n';
+ }
}
+}
+
+void LSRInstance::print(raw_ostream &OS) const {
+ print_factors_and_types(OS);
+ print_fixups(OS);
+ print_uses(OS);
+}
+
+void LSRInstance::dump() const {
+ print(errs()); errs() << '\n';
+}
+
+namespace {
+
+class LoopStrengthReduce : public LoopPass {
+ /// TLI - Keep a pointer of a TargetLowering to consult for determining
+ /// transformation profitability.
+ const TargetLowering *const TLI;
+
+public:
+ static char ID; // Pass ID, replacement for typeid
+ explicit LoopStrengthReduce(const TargetLowering *tli = 0);
+
+private:
+ bool runOnLoop(Loop *L, LPPassManager &LPM);
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+
+}
+
+char LoopStrengthReduce::ID = 0;
+static RegisterPass<LoopStrengthReduce>
+X("loop-reduce", "Loop Strength Reduction");
+
+Pass *llvm::createLoopStrengthReducePass(const TargetLowering *TLI) {
+ return new LoopStrengthReduce(TLI);
+}
+
+LoopStrengthReduce::LoopStrengthReduce(const TargetLowering *tli)
+ : LoopPass(&ID), TLI(tli) {}
+
+void LoopStrengthReduce::getAnalysisUsage(AnalysisUsage &AU) const {
+ // We split critical edges, so we change the CFG. However, we do update
+ // many analyses if they are around.
+ AU.addPreservedID(LoopSimplifyID);
+ AU.addPreserved<LoopInfo>();
+ AU.addPreserved("domfrontier");
+
+ AU.addRequiredID(LoopSimplifyID);
+ AU.addRequired<DominatorTree>();
+ AU.addPreserved<DominatorTree>();
+ AU.addRequired<ScalarEvolution>();
+ AU.addPreserved<ScalarEvolution>();
+ AU.addRequired<IVUsers>();
+ AU.addPreserved<IVUsers>();
+}
+
+bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager & /*LPM*/) {
+ bool Changed = false;
+
+ // Run the main LSR transformation.
+ Changed |= LSRInstance(TLI, L, this).getChanged();
// At this point, it is worth checking to see if any recurrence PHIs are also
// dead, so that we can remove them as well.
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index e5fba28..071e9b7 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -170,7 +170,7 @@ Pass *llvm::createLoopUnswitchPass(bool Os) {
/// Otherwise, return null.
static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) {
// We can never unswitch on vector conditions.
- if (isa<VectorType>(Cond->getType()))
+ if (Cond->getType()->isVectorTy())
return 0;
// Constants should be folded, not unswitched on!
@@ -871,7 +871,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
// If we know that LIC == Val, or that LIC == NotVal, just replace uses of LIC
// in the loop with the appropriate one directly.
if (IsEqual || (isa<ConstantInt>(Val) &&
- Val->getType()->isInteger(1))) {
+ Val->getType()->isIntegerTy(1))) {
Value *Replacement;
if (IsEqual)
Replacement = Val;
@@ -997,10 +997,10 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
case Instruction::And:
if (isa<ConstantInt>(I->getOperand(0)) &&
// constant -> RHS
- I->getOperand(0)->getType()->isInteger(1))
+ I->getOperand(0)->getType()->isIntegerTy(1))
cast<BinaryOperator>(I)->swapOperands();
if (ConstantInt *CB = dyn_cast<ConstantInt>(I->getOperand(1)))
- if (CB->getType()->isInteger(1)) {
+ if (CB->getType()->isIntegerTy(1)) {
if (CB->isOne()) // X & 1 -> X
ReplaceUsesOfWith(I, I->getOperand(0), Worklist, L, LPM);
else // X & 0 -> 0
@@ -1011,10 +1011,10 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
case Instruction::Or:
if (isa<ConstantInt>(I->getOperand(0)) &&
// constant -> RHS
- I->getOperand(0)->getType()->isInteger(1))
+ I->getOperand(0)->getType()->isIntegerTy(1))
cast<BinaryOperator>(I)->swapOperands();
if (ConstantInt *CB = dyn_cast<ConstantInt>(I->getOperand(1)))
- if (CB->getType()->isInteger(1)) {
+ if (CB->getType()->isIntegerTy(1)) {
if (CB->isOne()) // X | 1 -> 1
ReplaceUsesOfWith(I, I->getOperand(1), Worklist, L, LPM);
else // X | 0 -> X
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index e0aa491..62e2977 100644
--- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -42,7 +42,7 @@ static Value *isBytewiseValue(Value *V) {
LLVMContext &Context = V->getContext();
// All byte-wide stores are splatable, even of arbitrary variables.
- if (V->getType()->isInteger(8)) return V;
+ if (V->getType()->isIntegerTy(8)) return V;
// Constant float and double values can be handled as integer values if the
// corresponding integer value is "byteable". An important case is 0.0.
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index bbd4b45..5aca9cd 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -182,7 +182,7 @@ unsigned Reassociate::getRank(Value *V) {
// If this is a not or neg instruction, do not count it for rank. This
// assures us that X and ~X will have the same rank.
- if (!I->getType()->isInteger() ||
+ if (!I->getType()->isIntegerTy() ||
(!BinaryOperator::isNot(I) && !BinaryOperator::isNeg(I)))
++Rank;
@@ -597,19 +597,35 @@ Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) {
/// FindSingleUseMultiplyFactors - If V is a single-use multiply, recursively
/// add its operands as factors, otherwise add V to the list of factors.
+///
+/// Ops is the top-level list of add operands we're trying to factor.
static void FindSingleUseMultiplyFactors(Value *V,
- SmallVectorImpl<Value*> &Factors) {
+ SmallVectorImpl<Value*> &Factors,
+ const SmallVectorImpl<ValueEntry> &Ops,
+ bool IsRoot) {
BinaryOperator *BO;
- if ((!V->hasOneUse() && !V->use_empty()) ||
+ if (!(V->hasOneUse() || V->use_empty()) || // More than one use.
!(BO = dyn_cast<BinaryOperator>(V)) ||
BO->getOpcode() != Instruction::Mul) {
Factors.push_back(V);
return;
}
+ // If this value has a single use because it is another input to the add
+ // tree we're reassociating and we dropped its use, it actually has two
+ // uses and we can't factor it.
+ if (!IsRoot) {
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ if (Ops[i].Op == V) {
+ Factors.push_back(V);
+ return;
+ }
+ }
+
+
// Otherwise, add the LHS and RHS to the list of factors.
- FindSingleUseMultiplyFactors(BO->getOperand(1), Factors);
- FindSingleUseMultiplyFactors(BO->getOperand(0), Factors);
+ FindSingleUseMultiplyFactors(BO->getOperand(1), Factors, Ops, false);
+ FindSingleUseMultiplyFactors(BO->getOperand(0), Factors, Ops, false);
}
/// OptimizeAndOrXor - Optimize a series of operands to an 'and', 'or', or 'xor'
@@ -753,7 +769,7 @@ Value *Reassociate::OptimizeAdd(Instruction *I,
// Compute all of the factors of this added value.
SmallVector<Value*, 8> Factors;
- FindSingleUseMultiplyFactors(BOp, Factors);
+ FindSingleUseMultiplyFactors(BOp, Factors, Ops, true);
assert(Factors.size() > 1 && "Bad linearize!");
// Add one to FactorOccurrences for each unique factor in this op.
@@ -929,8 +945,8 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {
}
// Reject cases where it is pointless to do this.
- if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
- isa<VectorType>(BI->getType()))
+ if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPointTy() ||
+ BI->getType()->isVectorTy())
continue; // Floating point ops are not associative.
// Do not reassociate boolean (i1) expressions. We want to preserve the
@@ -939,7 +955,7 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {
// is not further optimized, it is likely to be transformed back to a
// short-circuited form for code gen, and the source order may have been
// optimized for the most likely conditions.
- if (BI->getType()->isInteger(1))
+ if (BI->getType()->isIntegerTy(1))
continue;
// If this is a subtract instruction which is not already in negate form,
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index 02b45a1..7e37938 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -295,7 +295,7 @@ public:
}
void markOverdefined(Value *V) {
- assert(!isa<StructType>(V->getType()) && "Should use other method");
+ assert(!V->getType()->isStructTy() && "Should use other method");
markOverdefined(ValueState[V], V);
}
@@ -321,12 +321,12 @@ private:
}
void markConstant(Value *V, Constant *C) {
- assert(!isa<StructType>(V->getType()) && "Should use other method");
+ assert(!V->getType()->isStructTy() && "Should use other method");
markConstant(ValueState[V], V, C);
}
void markForcedConstant(Value *V, Constant *C) {
- assert(!isa<StructType>(V->getType()) && "Should use other method");
+ assert(!V->getType()->isStructTy() && "Should use other method");
ValueState[V].markForcedConstant(C);
DEBUG(dbgs() << "markForcedConstant: " << *C << ": " << *V << '\n');
InstWorkList.push_back(V);
@@ -360,7 +360,7 @@ private:
}
void mergeInValue(Value *V, LatticeVal MergeWithV) {
- assert(!isa<StructType>(V->getType()) && "Should use other method");
+ assert(!V->getType()->isStructTy() && "Should use other method");
mergeInValue(ValueState[V], V, MergeWithV);
}
@@ -369,7 +369,7 @@ private:
/// value. This function handles the case when the value hasn't been seen yet
/// by properly seeding constants etc.
LatticeVal &getValueState(Value *V) {
- assert(!isa<StructType>(V->getType()) && "Should use getStructValueState");
+ assert(!V->getType()->isStructTy() && "Should use getStructValueState");
std::pair<DenseMap<Value*, LatticeVal>::iterator, bool> I =
ValueState.insert(std::make_pair(V, LatticeVal()));
@@ -392,7 +392,7 @@ private:
/// value/field pair. This function handles the case when the value hasn't
/// been seen yet by properly seeding constants etc.
LatticeVal &getStructValueState(Value *V, unsigned i) {
- assert(isa<StructType>(V->getType()) && "Should use getValueState");
+ assert(V->getType()->isStructTy() && "Should use getValueState");
assert(i < cast<StructType>(V->getType())->getNumElements() &&
"Invalid element #");
@@ -666,7 +666,7 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
void SCCPSolver::visitPHINode(PHINode &PN) {
// If this PN returns a struct, just mark the result overdefined.
// TODO: We could do a lot better than this if code actually uses this.
- if (isa<StructType>(PN.getType()))
+ if (PN.getType()->isStructTy())
return markAnythingOverdefined(&PN);
if (getValueState(&PN).isOverdefined()) {
@@ -742,7 +742,7 @@ void SCCPSolver::visitReturnInst(ReturnInst &I) {
Value *ResultOp = I.getOperand(0);
// If we are tracking the return value of this function, merge it in.
- if (!TrackedRetVals.empty() && !isa<StructType>(ResultOp->getType())) {
+ if (!TrackedRetVals.empty() && !ResultOp->getType()->isStructTy()) {
DenseMap<Function*, LatticeVal>::iterator TFRVI =
TrackedRetVals.find(F);
if (TFRVI != TrackedRetVals.end()) {
@@ -787,7 +787,7 @@ void SCCPSolver::visitCastInst(CastInst &I) {
void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) {
// If this returns a struct, mark all elements over defined, we don't track
// structs in structs.
- if (isa<StructType>(EVI.getType()))
+ if (EVI.getType()->isStructTy())
return markAnythingOverdefined(&EVI);
// If this is extracting from more than one level of struct, we don't know.
@@ -795,7 +795,7 @@ void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) {
return markOverdefined(&EVI);
Value *AggVal = EVI.getAggregateOperand();
- if (isa<StructType>(AggVal->getType())) {
+ if (AggVal->getType()->isStructTy()) {
unsigned i = *EVI.idx_begin();
LatticeVal EltVal = getStructValueState(AggVal, i);
mergeInValue(getValueState(&EVI), &EVI, EltVal);
@@ -828,7 +828,7 @@ void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) {
}
Value *Val = IVI.getInsertedValueOperand();
- if (isa<StructType>(Val->getType()))
+ if (Val->getType()->isStructTy())
// We don't track structs in structs.
markOverdefined(getStructValueState(&IVI, i), &IVI);
else {
@@ -841,7 +841,7 @@ void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) {
void SCCPSolver::visitSelectInst(SelectInst &I) {
// If this select returns a struct, just mark the result overdefined.
// TODO: We could do a lot better than this if code actually uses this.
- if (isa<StructType>(I.getType()))
+ if (I.getType()->isStructTy())
return markAnythingOverdefined(&I);
LatticeVal CondValue = getValueState(I.getCondition());
@@ -1166,7 +1166,7 @@ void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) {
void SCCPSolver::visitStoreInst(StoreInst &SI) {
// If this store is of a struct, ignore it.
- if (isa<StructType>(SI.getOperand(0)->getType()))
+ if (SI.getOperand(0)->getType()->isStructTy())
return;
if (TrackedGlobals.empty() || !isa<GlobalVariable>(SI.getOperand(1)))
@@ -1187,7 +1187,7 @@ void SCCPSolver::visitStoreInst(StoreInst &SI) {
// global, we can replace the load with the loaded constant value!
void SCCPSolver::visitLoadInst(LoadInst &I) {
// If this load is of a struct, just mark the result overdefined.
- if (isa<StructType>(I.getType()))
+ if (I.getType()->isStructTy())
return markAnythingOverdefined(&I);
LatticeVal PtrVal = getValueState(I.getOperand(0));
@@ -1241,7 +1241,7 @@ CallOverdefined:
// Otherwise, if we have a single return value case, and if the function is
// a declaration, maybe we can constant fold it.
- if (F && F->isDeclaration() && !isa<StructType>(I->getType()) &&
+ if (F && F->isDeclaration() && !I->getType()->isStructTy() &&
canConstantFoldCallTo(F)) {
SmallVector<Constant*, 8> Operands;
@@ -1352,7 +1352,7 @@ void SCCPSolver::Solve() {
// since all of its users will have already been marked as overdefined.
// Update all of the users of this instruction's value.
//
- if (isa<StructType>(I->getType()) || !getValueState(I).isOverdefined())
+ if (I->getType()->isStructTy() || !getValueState(I).isOverdefined())
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI)
if (Instruction *I = dyn_cast<Instruction>(*UI))
@@ -1418,7 +1418,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
if (!LV.isUndefined()) continue;
// No instructions using structs need disambiguation.
- if (isa<StructType>(I->getOperand(0)->getType()))
+ if (I->getOperand(0)->getType()->isStructTy())
continue;
// Get the lattice values of the first two operands for use below.
@@ -1426,7 +1426,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
LatticeVal Op1LV;
if (I->getNumOperands() == 2) {
// No instructions using structs need disambiguation.
- if (isa<StructType>(I->getOperand(1)->getType()))
+ if (I->getOperand(1)->getType()->isStructTy())
continue;
// If this is a two-operand instruction, and if both operands are
@@ -1656,7 +1656,7 @@ bool SCCP::runOnFunction(Function &F) {
continue;
// TODO: Reconstruct structs from their elements.
- if (isa<StructType>(Inst->getType()))
+ if (Inst->getType()->isStructTy())
continue;
LatticeVal IV = Solver.getLatticeValueFor(Inst);
@@ -1792,7 +1792,7 @@ bool IPSCCP::runOnModule(Module &M) {
if (Solver.isBlockExecutable(F->begin())) {
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI) {
- if (AI->use_empty() || isa<StructType>(AI->getType())) continue;
+ if (AI->use_empty() || AI->getType()->isStructTy()) continue;
// TODO: Could use getStructLatticeValueFor to find out if the entire
// result is a constant and replace it entirely if so.
@@ -1835,7 +1835,7 @@ bool IPSCCP::runOnModule(Module &M) {
for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) {
Instruction *Inst = BI++;
- if (Inst->getType()->isVoidTy() || isa<StructType>(Inst->getType()))
+ if (Inst->getType()->isVoidTy() || Inst->getType()->isStructTy())
continue;
// TODO: Could use getStructLatticeValueFor to find out if the entire
@@ -1918,6 +1918,14 @@ bool IPSCCP::runOnModule(Module &M) {
// all call uses with the inferred value. This means we don't need to bother
// actually returning anything from the function. Replace all return
// instructions with return undef.
+ //
+ // Do this in two stages: first identify the functions we should process, then
+ // actually zap their returns. This is important because we can only do this
+ // if the address of the function isn't taken. In cases where a return is the
+ // last use of a function, the order of processing functions would affect
+ // whether other functions are optimizable.
+ SmallVector<ReturnInst*, 8> ReturnsToZap;
+
// TODO: Process multiple value ret instructions also.
const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals();
for (DenseMap<Function*, LatticeVal>::const_iterator I = RV.begin(),
@@ -1933,7 +1941,13 @@ bool IPSCCP::runOnModule(Module &M) {
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
if (!isa<UndefValue>(RI->getOperand(0)))
- RI->setOperand(0, UndefValue::get(F->getReturnType()));
+ ReturnsToZap.push_back(RI);
+ }
+
+ // Zap all returns which we've identified as zap to change.
+ for (unsigned i = 0, e = ReturnsToZap.size(); i != e; ++i) {
+ Function *F = ReturnsToZap[i]->getParent()->getParent();
+ ReturnsToZap[i]->setOperand(0, UndefValue::get(F->getReturnType()));
}
// If we infered constant or undef values for globals variables, we can delete
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 900d119..bbe6270 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -302,7 +302,7 @@ bool SROA::performScalarRepl(Function &F) {
// random stuff that doesn't use vectors (e.g. <9 x double>) because then
// we just get a lot of insert/extracts. If at least one vector is
// involved, then we probably really do have a union of vector/array.
- if (VectorTy && isa<VectorType>(VectorTy) && HadAVector) {
+ if (VectorTy && VectorTy->isVectorTy() && HadAVector) {
DEBUG(dbgs() << "CONVERT TO VECTOR: " << *AI << "\n TYPE = "
<< *VectorTy << '\n');
@@ -449,7 +449,7 @@ void SROA::isSafeGEP(GetElementPtrInst *GEPI, AllocaInst *AI,
// into.
for (; GEPIt != E; ++GEPIt) {
// Ignore struct elements, no extra checking needed for these.
- if (isa<StructType>(*GEPIt))
+ if ((*GEPIt)->isStructTy())
continue;
ConstantInt *IdxVal = dyn_cast<ConstantInt>(GEPIt.getOperand());
@@ -480,7 +480,7 @@ void SROA::isSafeMemAccess(AllocaInst *AI, uint64_t Offset, uint64_t MemSize,
// (which are essentially the same as the MemIntrinsics, especially with
// regard to copying padding between elements), or references using the
// aggregate type of the alloca.
- if (!MemOpType || isa<IntegerType>(MemOpType) || UsesAggregateType) {
+ if (!MemOpType || MemOpType->isIntegerTy() || UsesAggregateType) {
if (!UsesAggregateType) {
if (isStore)
Info.isMemCpyDst = true;
@@ -565,7 +565,7 @@ void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset,
}
LI->replaceAllUsesWith(Insert);
DeadInsts.push_back(LI);
- } else if (isa<IntegerType>(LIType) &&
+ } else if (LIType->isIntegerTy() &&
TD->getTypeAllocSize(LIType) ==
TD->getTypeAllocSize(AI->getAllocatedType())) {
// If this is a load of the entire alloca to an integer, rewrite it.
@@ -588,7 +588,7 @@ void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset,
new StoreInst(Extract, NewElts[i], SI);
}
DeadInsts.push_back(SI);
- } else if (isa<IntegerType>(SIType) &&
+ } else if (SIType->isIntegerTy() &&
TD->getTypeAllocSize(SIType) ==
TD->getTypeAllocSize(AI->getAllocatedType())) {
// If this is a store of the entire alloca from an integer, rewrite it.
@@ -833,9 +833,9 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
// Convert the integer value to the appropriate type.
StoreVal = ConstantInt::get(Context, TotalVal);
- if (isa<PointerType>(ValTy))
+ if (ValTy->isPointerTy())
StoreVal = ConstantExpr::getIntToPtr(StoreVal, ValTy);
- else if (ValTy->isFloatingPoint())
+ else if (ValTy->isFloatingPointTy())
StoreVal = ConstantExpr::getBitCast(StoreVal, ValTy);
assert(StoreVal->getType() == ValTy && "Type mismatch!");
@@ -939,7 +939,7 @@ void SROA::RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI,
Value *DestField = NewElts[i];
if (EltVal->getType() == FieldTy) {
// Storing to an integer field of this size, just do it.
- } else if (FieldTy->isFloatingPoint() || isa<VectorType>(FieldTy)) {
+ } else if (FieldTy->isFloatingPointTy() || FieldTy->isVectorTy()) {
// Bitcast to the right element type (for fp/vector values).
EltVal = new BitCastInst(EltVal, FieldTy, "", SI);
} else {
@@ -983,7 +983,8 @@ void SROA::RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI,
Value *DestField = NewElts[i];
if (EltVal->getType() == ArrayEltTy) {
// Storing to an integer field of this size, just do it.
- } else if (ArrayEltTy->isFloatingPoint() || isa<VectorType>(ArrayEltTy)) {
+ } else if (ArrayEltTy->isFloatingPointTy() ||
+ ArrayEltTy->isVectorTy()) {
// Bitcast to the right element type (for fp/vector values).
EltVal = new BitCastInst(EltVal, ArrayEltTy, "", SI);
} else {
@@ -1043,8 +1044,8 @@ void SROA::RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI,
const IntegerType *FieldIntTy = IntegerType::get(LI->getContext(),
FieldSizeBits);
- if (!isa<IntegerType>(FieldTy) && !FieldTy->isFloatingPoint() &&
- !isa<VectorType>(FieldTy))
+ if (!FieldTy->isIntegerTy() && !FieldTy->isFloatingPointTy() &&
+ !FieldTy->isVectorTy())
SrcField = new BitCastInst(SrcField,
PointerType::getUnqual(FieldIntTy),
"", LI);
@@ -1182,7 +1183,7 @@ static void MergeInType(const Type *In, uint64_t Offset, const Type *&VecTy,
return;
}
} else if (In->isFloatTy() || In->isDoubleTy() ||
- (isa<IntegerType>(In) && In->getPrimitiveSizeInBits() >= 8 &&
+ (In->isIntegerTy() && In->getPrimitiveSizeInBits() >= 8 &&
isPowerOf2_32(In->getPrimitiveSizeInBits()))) {
// If we're accessing something that could be an element of a vector, see
// if the implied vector agrees with what we already have and if Offset is
@@ -1226,7 +1227,7 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
return false;
MergeInType(LI->getType(), Offset, VecTy,
AllocaSize, *TD, V->getContext());
- SawVec |= isa<VectorType>(LI->getType());
+ SawVec |= LI->getType()->isVectorTy();
continue;
}
@@ -1235,7 +1236,7 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
if (SI->getOperand(0) == V || SI->isVolatile()) return 0;
MergeInType(SI->getOperand(0)->getType(), Offset,
VecTy, AllocaSize, *TD, V->getContext());
- SawVec |= isa<VectorType>(SI->getOperand(0)->getType());
+ SawVec |= SI->getOperand(0)->getType()->isVectorTy();
continue;
}
@@ -1437,7 +1438,7 @@ Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType,
// If the result alloca is a vector type, this is either an element
// access or a bitcast to another vector type of the same size.
if (const VectorType *VTy = dyn_cast<VectorType>(FromVal->getType())) {
- if (isa<VectorType>(ToType))
+ if (ToType->isVectorTy())
return Builder.CreateBitCast(FromVal, ToType, "tmp");
// Otherwise it must be an element access.
@@ -1520,9 +1521,9 @@ Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType,
LIBitWidth), "tmp");
// If the result is an integer, this is a trunc or bitcast.
- if (isa<IntegerType>(ToType)) {
+ if (ToType->isIntegerTy()) {
// Should be done.
- } else if (ToType->isFloatingPoint() || isa<VectorType>(ToType)) {
+ } else if (ToType->isFloatingPointTy() || ToType->isVectorTy()) {
// Just do a bitcast, we know the sizes match up.
FromVal = Builder.CreateBitCast(FromVal, ToType, "tmp");
} else {
@@ -1600,10 +1601,10 @@ Value *SROA::ConvertScalar_InsertValue(Value *SV, Value *Old,
unsigned DestWidth = TD->getTypeSizeInBits(AllocaType);
unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType());
unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType);
- if (SV->getType()->isFloatingPoint() || isa<VectorType>(SV->getType()))
+ if (SV->getType()->isFloatingPointTy() || SV->getType()->isVectorTy())
SV = Builder.CreateBitCast(SV,
IntegerType::get(SV->getContext(),SrcWidth), "tmp");
- else if (isa<PointerType>(SV->getType()))
+ else if (SV->getType()->isPointerTy())
SV = Builder.CreatePtrToInt(SV, TD->getIntPtrType(SV->getContext()), "tmp");
// Zero extend or truncate the value if needed.
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index 4216e8f..05027ae 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -17,6 +17,7 @@
#define DEBUG_TYPE "simplify-libcalls"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -67,496 +68,14 @@ public:
Context = &CI->getCalledFunction()->getContext();
return CallOptimizer(CI->getCalledFunction(), CI, B);
}
-
- /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
- Value *CastToCStr(Value *V, IRBuilder<> &B);
-
- /// EmitStrLen - Emit a call to the strlen function to the builder, for the
- /// specified pointer. Ptr is required to be some pointer type, and the
- /// return value has 'intptr_t' type.
- Value *EmitStrLen(Value *Ptr, IRBuilder<> &B);
-
- /// EmitStrChr - Emit a call to the strchr function to the builder, for the
- /// specified pointer and character. Ptr is required to be some pointer type,
- /// and the return value has 'i8*' type.
- Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B);
-
- /// 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,
- unsigned Align, IRBuilder<> &B);
-
- /// EmitMemMove - Emit a call to the memmove function to the builder. This
- /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
- Value *EmitMemMove(Value *Dst, Value *Src, Value *Len,
- unsigned Align, IRBuilder<> &B);
-
- /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
- /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
- Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B);
-
- /// EmitMemCmp - Emit a call to the memcmp function.
- Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B);
-
- /// EmitMemSet - Emit a call to the memset function
- Value *EmitMemSet(Value *Dst, Value *Val, Value *Len, IRBuilder<> &B);
-
- /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
- /// (e.g. 'floor'). This function is known to take a single of type matching
- /// 'Op' and returns one value with the same type. If 'Op' is a long double,
- /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f'
- /// suffix.
- Value *EmitUnaryFloatFnCall(Value *Op, const char *Name, IRBuilder<> &B,
- const AttrListPtr &Attrs);
-
- /// EmitPutChar - Emit a call to the putchar function. This assumes that Char
- /// is an integer.
- Value *EmitPutChar(Value *Char, IRBuilder<> &B);
-
- /// EmitPutS - Emit a call to the puts function. This assumes that Str is
- /// some pointer.
- void EmitPutS(Value *Str, IRBuilder<> &B);
-
- /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
- /// an i32, and File is a pointer to FILE.
- void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B);
-
- /// EmitFPutS - Emit a call to the puts function. Str is required to be a
- /// pointer and File is a pointer to FILE.
- void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B);
-
- /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
- /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
- void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B);
-
};
} // End anonymous namespace.
-/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
-Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) {
- return B.CreateBitCast(V, Type::getInt8PtrTy(*Context), "cstr");
-}
-
-/// EmitStrLen - Emit a call to the strlen function to the builder, for the
-/// specified pointer. This always returns an integer value of size intptr_t.
-Value *LibCallOptimization::EmitStrLen(Value *Ptr, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI[2];
- AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
- AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
- Attribute::NoUnwind);
-
- Constant *StrLen =M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2),
- TD->getIntPtrType(*Context),
- Type::getInt8PtrTy(*Context),
- NULL);
- CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
- if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
-
- return CI;
-}
-
-/// EmitStrChr - Emit a call to the strchr function to the builder, for the
-/// specified pointer and character. Ptr is required to be some pointer type,
-/// and the return value has 'i8*' type.
-Value *LibCallOptimization::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI =
- AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
-
- const Type *I8Ptr = Type::getInt8PtrTy(*Context);
- const Type *I32Ty = Type::getInt32Ty(*Context);
- Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(&AWI, 1),
- I8Ptr, I8Ptr, I32Ty, NULL);
- CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
- ConstantInt::get(I32Ty, C), "strchr");
- if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
- 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.
-Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
- unsigned Align, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- const Type *Ty = Len->getType();
- Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, &Ty, 1);
- Dst = CastToCStr(Dst, B);
- Src = CastToCStr(Src, B);
- return B.CreateCall4(MemCpy, Dst, Src, Len,
- ConstantInt::get(Type::getInt32Ty(*Context), Align));
-}
-
-/// EmitMemMove - Emit a call to the memmove function to the builder. This
-/// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
-Value *LibCallOptimization::EmitMemMove(Value *Dst, Value *Src, Value *Len,
- unsigned Align, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- const Type *Ty = TD->getIntPtrType(*Context);
- Value *MemMove = Intrinsic::getDeclaration(M, Intrinsic::memmove, &Ty, 1);
- Dst = CastToCStr(Dst, B);
- Src = CastToCStr(Src, B);
- Value *A = ConstantInt::get(Type::getInt32Ty(*Context), Align);
- return B.CreateCall4(MemMove, Dst, Src, Len, A);
-}
-
-/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
-/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
-Value *LibCallOptimization::EmitMemChr(Value *Ptr, Value *Val,
- Value *Len, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI;
- AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
-
- Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1),
- Type::getInt8PtrTy(*Context),
- Type::getInt8PtrTy(*Context),
- Type::getInt32Ty(*Context),
- TD->getIntPtrType(*Context),
- NULL);
- CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
-
- if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
-
- return CI;
-}
-
-/// EmitMemCmp - Emit a call to the memcmp function.
-Value *LibCallOptimization::EmitMemCmp(Value *Ptr1, Value *Ptr2,
- Value *Len, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI[3];
- AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
- AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
- AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
- Attribute::NoUnwind);
-
- Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3),
- Type::getInt32Ty(*Context),
- Type::getInt8PtrTy(*Context),
- Type::getInt8PtrTy(*Context),
- TD->getIntPtrType(*Context), NULL);
- CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
- Len, "memcmp");
-
- if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
-
- return CI;
-}
-
-/// EmitMemSet - Emit a call to the memset function
-Value *LibCallOptimization::EmitMemSet(Value *Dst, Value *Val,
- Value *Len, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- Intrinsic::ID IID = Intrinsic::memset;
- const Type *Tys[1];
- Tys[0] = Len->getType();
- Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1);
- Value *Align = ConstantInt::get(Type::getInt32Ty(*Context), 1);
- return B.CreateCall4(MemSet, CastToCStr(Dst, B), Val, Len, Align);
-}
-
-/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
-/// 'floor'). This function is known to take a single of type matching 'Op' and
-/// returns one value with the same type. If 'Op' is a long double, 'l' is
-/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
-Value *LibCallOptimization::EmitUnaryFloatFnCall(Value *Op, const char *Name,
- IRBuilder<> &B,
- const AttrListPtr &Attrs) {
- char NameBuffer[20];
- if (!Op->getType()->isDoubleTy()) {
- // If we need to add a suffix, copy into NameBuffer.
- unsigned NameLen = strlen(Name);
- assert(NameLen < sizeof(NameBuffer)-2);
- memcpy(NameBuffer, Name, NameLen);
- if (Op->getType()->isFloatTy())
- NameBuffer[NameLen] = 'f'; // floorf
- else
- NameBuffer[NameLen] = 'l'; // floorl
- NameBuffer[NameLen+1] = 0;
- Name = NameBuffer;
- }
-
- Module *M = Caller->getParent();
- Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
- Op->getType(), NULL);
- CallInst *CI = B.CreateCall(Callee, Op, Name);
- CI->setAttributes(Attrs);
- if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
-
- return CI;
-}
-
-/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
-/// is an integer.
-Value *LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- Value *PutChar = M->getOrInsertFunction("putchar", Type::getInt32Ty(*Context),
- Type::getInt32Ty(*Context), NULL);
- CallInst *CI = B.CreateCall(PutChar,
- B.CreateIntCast(Char,
- Type::getInt32Ty(*Context),
- /*isSigned*/true,
- "chari"),
- "putchar");
-
- if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
- return CI;
-}
-
-/// EmitPutS - Emit a call to the puts function. This assumes that Str is
-/// some pointer.
-void LibCallOptimization::EmitPutS(Value *Str, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI[2];
- AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
- AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
-
- Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2),
- Type::getInt32Ty(*Context),
- Type::getInt8PtrTy(*Context),
- NULL);
- CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
- if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
-
-}
-
-/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
-/// an integer and File is a pointer to FILE.
-void LibCallOptimization::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI[2];
- AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
- AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
- Constant *F;
- if (isa<PointerType>(File->getType()))
- F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2),
- Type::getInt32Ty(*Context),
- Type::getInt32Ty(*Context), File->getType(),
- NULL);
- else
- F = M->getOrInsertFunction("fputc",
- Type::getInt32Ty(*Context),
- Type::getInt32Ty(*Context),
- File->getType(), NULL);
- Char = B.CreateIntCast(Char, Type::getInt32Ty(*Context), /*isSigned*/true,
- "chari");
- CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
-
- if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
- CI->setCallingConv(Fn->getCallingConv());
-}
-
-/// EmitFPutS - Emit a call to the puts function. Str is required to be a
-/// pointer and File is a pointer to FILE.
-void LibCallOptimization::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI[3];
- AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
- AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
- AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
- Constant *F;
- if (isa<PointerType>(File->getType()))
- F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3),
- Type::getInt32Ty(*Context),
- Type::getInt8PtrTy(*Context),
- File->getType(), NULL);
- else
- F = M->getOrInsertFunction("fputs", Type::getInt32Ty(*Context),
- Type::getInt8PtrTy(*Context),
- File->getType(), NULL);
- CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
-
- if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
- CI->setCallingConv(Fn->getCallingConv());
-}
-
-/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
-/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
-void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File,
- IRBuilder<> &B) {
- Module *M = Caller->getParent();
- AttributeWithIndex AWI[3];
- AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
- AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
- AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
- Constant *F;
- if (isa<PointerType>(File->getType()))
- F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3),
- TD->getIntPtrType(*Context),
- Type::getInt8PtrTy(*Context),
- TD->getIntPtrType(*Context),
- TD->getIntPtrType(*Context),
- File->getType(), NULL);
- else
- F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(*Context),
- Type::getInt8PtrTy(*Context),
- TD->getIntPtrType(*Context),
- TD->getIntPtrType(*Context),
- File->getType(), NULL);
- CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
- ConstantInt::get(TD->getIntPtrType(*Context), 1), File);
-
- if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
- CI->setCallingConv(Fn->getCallingConv());
-}
//===----------------------------------------------------------------------===//
// Helper Functions
//===----------------------------------------------------------------------===//
-/// GetStringLengthH - If we can compute the length of the string pointed to by
-/// the specified pointer, return 'len+1'. If we can't, return 0.
-static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) {
- // Look through noop bitcast instructions.
- if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
- return GetStringLengthH(BCI->getOperand(0), PHIs);
-
- // If this is a PHI node, there are two cases: either we have already seen it
- // or we haven't.
- if (PHINode *PN = dyn_cast<PHINode>(V)) {
- if (!PHIs.insert(PN))
- return ~0ULL; // already in the set.
-
- // If it was new, see if all the input strings are the same length.
- uint64_t LenSoFar = ~0ULL;
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- uint64_t Len = GetStringLengthH(PN->getIncomingValue(i), PHIs);
- if (Len == 0) return 0; // Unknown length -> unknown.
-
- if (Len == ~0ULL) continue;
-
- if (Len != LenSoFar && LenSoFar != ~0ULL)
- return 0; // Disagree -> unknown.
- LenSoFar = Len;
- }
-
- // Success, all agree.
- return LenSoFar;
- }
-
- // strlen(select(c,x,y)) -> strlen(x) ^ strlen(y)
- if (SelectInst *SI = dyn_cast<SelectInst>(V)) {
- uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs);
- if (Len1 == 0) return 0;
- uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs);
- if (Len2 == 0) return 0;
- if (Len1 == ~0ULL) return Len2;
- if (Len2 == ~0ULL) return Len1;
- if (Len1 != Len2) return 0;
- return Len1;
- }
-
- // If the value is not a GEP instruction nor a constant expression with a
- // GEP instruction, then return unknown.
- User *GEP = 0;
- if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
- GEP = GEPI;
- } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
- if (CE->getOpcode() != Instruction::GetElementPtr)
- return 0;
- GEP = CE;
- } else {
- return 0;
- }
-
- // Make sure the GEP has exactly three arguments.
- if (GEP->getNumOperands() != 3)
- return 0;
-
- // Check to make sure that the first operand of the GEP is an integer and
- // has value 0 so that we are sure we're indexing into the initializer.
- if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
- if (!Idx->isZero())
- return 0;
- } else
- return 0;
-
- // If the second index isn't a ConstantInt, then this is a variable index
- // into the array. If this occurs, we can't say anything meaningful about
- // the string.
- uint64_t StartIdx = 0;
- if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
- StartIdx = CI->getZExtValue();
- else
- return 0;
-
- // The GEP instruction, constant or instruction, must reference a global
- // variable that is a constant and is initialized. The referenced constant
- // initializer is the array that we'll use for optimization.
- GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
- if (!GV || !GV->isConstant() || !GV->hasInitializer() ||
- GV->mayBeOverridden())
- return 0;
- Constant *GlobalInit = GV->getInitializer();
-
- // Handle the ConstantAggregateZero case, which is a degenerate case. The
- // initializer is constant zero so the length of the string must be zero.
- if (isa<ConstantAggregateZero>(GlobalInit))
- return 1; // Len = 0 offset by 1.
-
- // Must be a Constant Array
- ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
- if (!Array || !Array->getType()->getElementType()->isInteger(8))
- return false;
-
- // Get the number of elements in the array
- uint64_t NumElts = Array->getType()->getNumElements();
-
- // Traverse the constant array from StartIdx (derived above) which is
- // the place the GEP refers to in the array.
- for (unsigned i = StartIdx; i != NumElts; ++i) {
- Constant *Elt = Array->getOperand(i);
- ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
- if (!CI) // This array isn't suitable, non-int initializer.
- return 0;
- if (CI->isZero())
- return i-StartIdx+1; // We found end of string, success!
- }
-
- return 0; // The array isn't null terminated, conservatively return 'unknown'.
-}
-
-/// GetStringLength - If we can compute the length of the string pointed to by
-/// the specified pointer, return 'len+1'. If we can't, return 0.
-static uint64_t GetStringLength(Value *V) {
- if (!isa<PointerType>(V->getType())) return 0;
-
- SmallPtrSet<PHINode*, 32> PHIs;
- uint64_t Len = GetStringLengthH(V, PHIs);
- // If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return
- // an empty string as a length.
- return Len == ~0ULL ? 1 : Len;
-}
-
/// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the
/// value is equal or not-equal to zero.
static bool IsOnlyUsedInZeroEqualityComparison(Value *V) {
@@ -613,7 +132,7 @@ struct StrCatOpt : public LibCallOptimization {
void EmitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, IRBuilder<> &B) {
// We need to find the end of the destination string. That's where the
// memory is to be moved to. We just generate a call to strlen.
- Value *DstLen = EmitStrLen(Dst, B);
+ Value *DstLen = EmitStrLen(Dst, B, TD);
// Now that we have the destination's length, we must index into the
// destination's pointer to get the actual memcpy destination (end of
@@ -623,7 +142,7 @@ struct StrCatOpt : public LibCallOptimization {
// We have enough information to now generate the memcpy call to do the
// concatenation for us. Make a memcpy to copy the nul byte with align = 1.
EmitMemCpy(CpyDst, Src,
- ConstantInt::get(TD->getIntPtrType(*Context), Len+1), 1, B);
+ ConstantInt::get(TD->getIntPtrType(*Context), Len+1), 1, B, TD);
}
};
@@ -638,7 +157,7 @@ struct StrNCatOpt : public StrCatOpt {
FT->getReturnType() != Type::getInt8PtrTy(*Context) ||
FT->getParamType(0) != FT->getReturnType() ||
FT->getParamType(1) != FT->getReturnType() ||
- !isa<IntegerType>(FT->getParamType(2)))
+ !FT->getParamType(2)->isIntegerTy())
return 0;
// Extract some information from the instruction
@@ -697,11 +216,12 @@ struct StrChrOpt : public LibCallOptimization {
if (!TD) return 0;
uint64_t Len = GetStringLength(SrcStr);
- if (Len == 0 || !FT->getParamType(1)->isInteger(32)) // memchr needs i32.
+ if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32.
return 0;
return EmitMemChr(SrcStr, CI->getOperand(2), // include nul.
- ConstantInt::get(TD->getIntPtrType(*Context), Len), B);
+ ConstantInt::get(TD->getIntPtrType(*Context), Len),
+ B, TD);
}
// Otherwise, the character is a constant, see if the first argument is
@@ -739,7 +259,7 @@ struct StrCmpOpt : public LibCallOptimization {
// Verify the "strcmp" function prototype.
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 2 ||
- !FT->getReturnType()->isInteger(32) ||
+ !FT->getReturnType()->isIntegerTy(32) ||
FT->getParamType(0) != FT->getParamType(1) ||
FT->getParamType(0) != Type::getInt8PtrTy(*Context))
return 0;
@@ -772,7 +292,7 @@ struct StrCmpOpt : public LibCallOptimization {
return EmitMemCmp(Str1P, Str2P,
ConstantInt::get(TD->getIntPtrType(*Context),
- std::min(Len1, Len2)), B);
+ std::min(Len1, Len2)), B, TD);
}
return 0;
@@ -787,10 +307,10 @@ struct StrNCmpOpt : public LibCallOptimization {
// Verify the "strncmp" function prototype.
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 3 ||
- !FT->getReturnType()->isInteger(32) ||
+ !FT->getReturnType()->isIntegerTy(32) ||
FT->getParamType(0) != FT->getParamType(1) ||
FT->getParamType(0) != Type::getInt8PtrTy(*Context) ||
- !isa<IntegerType>(FT->getParamType(2)))
+ !FT->getParamType(2)->isIntegerTy())
return 0;
Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2);
@@ -852,7 +372,7 @@ struct StrCpyOpt : public LibCallOptimization {
// We have enough information to now generate the memcpy call to do the
// concatenation for us. Make a memcpy to copy the nul byte with align = 1.
EmitMemCpy(Dst, Src,
- ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B);
+ ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD);
return Dst;
}
};
@@ -866,7 +386,7 @@ struct StrNCpyOpt : public LibCallOptimization {
if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
FT->getParamType(0) != FT->getParamType(1) ||
FT->getParamType(0) != Type::getInt8PtrTy(*Context) ||
- !isa<IntegerType>(FT->getParamType(2)))
+ !FT->getParamType(2)->isIntegerTy())
return 0;
Value *Dst = CI->getOperand(1);
@@ -881,7 +401,7 @@ struct StrNCpyOpt : public LibCallOptimization {
if (SrcLen == 0) {
// strncpy(x, "", y) -> memset(x, '\0', y, 1)
EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'), LenOp,
- B);
+ B, TD);
return Dst;
}
@@ -901,7 +421,7 @@ struct StrNCpyOpt : public LibCallOptimization {
// strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]
EmitMemCpy(Dst, Src,
- ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B);
+ ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD);
return Dst;
}
@@ -915,7 +435,7 @@ struct StrLenOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 1 ||
FT->getParamType(0) != Type::getInt8PtrTy(*Context) ||
- !isa<IntegerType>(FT->getReturnType()))
+ !FT->getReturnType()->isIntegerTy())
return 0;
Value *Src = CI->getOperand(1);
@@ -939,8 +459,8 @@ struct StrToOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
const FunctionType *FT = Callee->getFunctionType();
if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)))
+ !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy())
return 0;
Value *EndPtr = CI->getOperand(2);
@@ -960,9 +480,9 @@ struct StrStrOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 2 ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
- !isa<PointerType>(FT->getReturnType()))
+ !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy() ||
+ !FT->getReturnType()->isPointerTy())
return 0;
// fold strstr(x, x) -> x.
@@ -993,7 +513,7 @@ struct StrStrOpt : public LibCallOptimization {
// fold strstr(x, "y") -> strchr(x, 'y').
if (HasStr2 && ToFindStr.size() == 1)
- return B.CreateBitCast(EmitStrChr(CI->getOperand(1), ToFindStr[0], B),
+ return B.CreateBitCast(EmitStrChr(CI->getOperand(1), ToFindStr[0], B, TD),
CI->getType());
return 0;
}
@@ -1006,9 +526,9 @@ struct StrStrOpt : public LibCallOptimization {
struct MemCmpOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
const FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() != 3 || !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
- !FT->getReturnType()->isInteger(32))
+ if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy() ||
+ !FT->getReturnType()->isIntegerTy(32))
return 0;
Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
@@ -1055,13 +575,14 @@ struct MemCpyOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
+ !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy() ||
FT->getParamType(2) != TD->getIntPtrType(*Context))
return 0;
// memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
- EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B);
+ EmitMemCpy(CI->getOperand(1), CI->getOperand(2),
+ CI->getOperand(3), 1, B, TD);
return CI->getOperand(1);
}
};
@@ -1076,13 +597,14 @@ struct MemMoveOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
+ !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy() ||
FT->getParamType(2) != TD->getIntPtrType(*Context))
return 0;
// memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
- EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B);
+ EmitMemMove(CI->getOperand(1), CI->getOperand(2),
+ CI->getOperand(3), 1, B, TD);
return CI->getOperand(1);
}
};
@@ -1097,137 +619,20 @@ struct MemSetOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<IntegerType>(FT->getParamType(1)) ||
+ !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isIntegerTy() ||
FT->getParamType(2) != TD->getIntPtrType(*Context))
return 0;
// memset(p, v, n) -> llvm.memset(p, v, n, 1)
Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context),
false);
- EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B);
+ EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B, TD);
return CI->getOperand(1);
}
};
//===----------------------------------------------------------------------===//
-// Object Size Checking Optimizations
-//===----------------------------------------------------------------------===//
-
-//===---------------------------------------===//
-// 'memcpy_chk' Optimizations
-
-struct MemCpyChkOpt : 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() != 4 || FT->getReturnType() != FT->getParamType(0) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
- !isa<IntegerType>(FT->getParamType(3)) ||
- FT->getParamType(2) != TD->getIntPtrType(*Context))
- return 0;
-
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
- if (!SizeCI)
- return 0;
- if (SizeCI->isAllOnesValue()) {
- EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B);
- return CI->getOperand(1);
- }
-
- return 0;
- }
-};
-
-//===---------------------------------------===//
-// 'memset_chk' Optimizations
-
-struct MemSetChkOpt : 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() != 4 || FT->getReturnType() != FT->getParamType(0) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<IntegerType>(FT->getParamType(1)) ||
- !isa<IntegerType>(FT->getParamType(3)) ||
- FT->getParamType(2) != TD->getIntPtrType(*Context))
- return 0;
-
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
- if (!SizeCI)
- return 0;
- if (SizeCI->isAllOnesValue()) {
- Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context),
- false);
- EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B);
- return CI->getOperand(1);
- }
-
- return 0;
- }
-};
-
-//===---------------------------------------===//
-// 'memmove_chk' Optimizations
-
-struct MemMoveChkOpt : 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() != 4 || FT->getReturnType() != FT->getParamType(0) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
- !isa<IntegerType>(FT->getParamType(3)) ||
- FT->getParamType(2) != TD->getIntPtrType(*Context))
- return 0;
-
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
- if (!SizeCI)
- return 0;
- if (SizeCI->isAllOnesValue()) {
- EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
- 1, B);
- return CI->getOperand(1);
- }
-
- return 0;
- }
-};
-
-struct StrCpyChkOpt : public LibCallOptimization {
- virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
- const FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
- !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)))
- return 0;
-
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
- if (!SizeCI)
- return 0;
-
- // If a) we don't have any length information, or b) we know this will
- // fit then just lower to a plain strcpy. Otherwise we'll keep our
- // strcpy_chk call which may fail at runtime if the size is too long.
- // TODO: It might be nice to get a maximum length out of the possible
- // string lengths for varying.
- if (SizeCI->isAllOnesValue() ||
- SizeCI->getZExtValue() >= GetStringLength(CI->getOperand(2)))
- return EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B);
-
- return 0;
- }
-};
-
-
-//===----------------------------------------------------------------------===//
// Math Library Optimizations
//===----------------------------------------------------------------------===//
@@ -1241,7 +646,7 @@ struct PowOpt : public LibCallOptimization {
// result type.
if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
FT->getParamType(0) != FT->getParamType(1) ||
- !FT->getParamType(0)->isFloatingPoint())
+ !FT->getParamType(0)->isFloatingPointTy())
return 0;
Value *Op1 = CI->getOperand(1), *Op2 = CI->getOperand(2);
@@ -1295,7 +700,7 @@ struct Exp2Opt : public LibCallOptimization {
// Just make sure this has 1 argument of FP type, which matches the
// result type.
if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
- !FT->getParamType(0)->isFloatingPoint())
+ !FT->getParamType(0)->isFloatingPointTy())
return 0;
Value *Op = CI->getOperand(1);
@@ -1375,8 +780,8 @@ struct FFSOpt : public LibCallOptimization {
// Just make sure this has 2 arguments of the same FP type, which match the
// result type.
if (FT->getNumParams() != 1 ||
- !FT->getReturnType()->isInteger(32) ||
- !isa<IntegerType>(FT->getParamType(0)))
+ !FT->getReturnType()->isIntegerTy(32) ||
+ !FT->getParamType(0)->isIntegerTy())
return 0;
Value *Op = CI->getOperand(1);
@@ -1410,8 +815,8 @@ struct IsDigitOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
const FunctionType *FT = Callee->getFunctionType();
// We require integer(i32)
- if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
- !FT->getParamType(0)->isInteger(32))
+ if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
+ !FT->getParamType(0)->isIntegerTy(32))
return 0;
// isdigit(c) -> (c-'0') <u 10
@@ -1431,8 +836,8 @@ struct IsAsciiOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
const FunctionType *FT = Callee->getFunctionType();
// We require integer(i32)
- if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
- !FT->getParamType(0)->isInteger(32))
+ if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
+ !FT->getParamType(0)->isIntegerTy(32))
return 0;
// isascii(c) -> c <u 128
@@ -1450,7 +855,7 @@ struct AbsOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
const FunctionType *FT = Callee->getFunctionType();
// We require integer(integer) where the types agree.
- if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
+ if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
FT->getParamType(0) != FT->getReturnType())
return 0;
@@ -1473,7 +878,7 @@ struct ToAsciiOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
// We require i32(i32)
if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
- !FT->getParamType(0)->isInteger(32))
+ !FT->getParamType(0)->isIntegerTy(32))
return 0;
// isascii(c) -> c & 0x7f
@@ -1493,8 +898,8 @@ struct PrintFOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
// Require one fixed pointer argument and an integer/void result.
const FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() < 1 || !isa<PointerType>(FT->getParamType(0)) ||
- !(isa<IntegerType>(FT->getReturnType()) ||
+ if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
+ !(FT->getReturnType()->isIntegerTy() ||
FT->getReturnType()->isVoidTy()))
return 0;
@@ -1512,7 +917,7 @@ struct PrintFOpt : public LibCallOptimization {
// in case there is an error writing to stdout.
if (FormatStr.size() == 1) {
Value *Res = EmitPutChar(ConstantInt::get(Type::getInt32Ty(*Context),
- FormatStr[0]), B);
+ FormatStr[0]), B, TD);
if (CI->use_empty()) return CI;
return B.CreateIntCast(Res, CI->getType(), true);
}
@@ -1526,7 +931,7 @@ struct PrintFOpt : public LibCallOptimization {
Constant *C = ConstantArray::get(*Context, FormatStr, true);
C = new GlobalVariable(*Callee->getParent(), C->getType(), true,
GlobalVariable::InternalLinkage, C, "str");
- EmitPutS(C, B);
+ EmitPutS(C, B, TD);
return CI->use_empty() ? (Value*)CI :
ConstantInt::get(CI->getType(), FormatStr.size()+1);
}
@@ -1534,8 +939,8 @@ struct PrintFOpt : public LibCallOptimization {
// Optimize specific format strings.
// printf("%c", chr) --> putchar(*(i8*)dst)
if (FormatStr == "%c" && CI->getNumOperands() > 2 &&
- isa<IntegerType>(CI->getOperand(2)->getType())) {
- Value *Res = EmitPutChar(CI->getOperand(2), B);
+ CI->getOperand(2)->getType()->isIntegerTy()) {
+ Value *Res = EmitPutChar(CI->getOperand(2), B, TD);
if (CI->use_empty()) return CI;
return B.CreateIntCast(Res, CI->getType(), true);
@@ -1543,9 +948,9 @@ struct PrintFOpt : public LibCallOptimization {
// printf("%s\n", str) --> puts(str)
if (FormatStr == "%s\n" && CI->getNumOperands() > 2 &&
- isa<PointerType>(CI->getOperand(2)->getType()) &&
+ CI->getOperand(2)->getType()->isPointerTy() &&
CI->use_empty()) {
- EmitPutS(CI->getOperand(2), B);
+ EmitPutS(CI->getOperand(2), B, TD);
return CI;
}
return 0;
@@ -1559,9 +964,9 @@ struct SPrintFOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
// Require two fixed pointer arguments and an integer result.
const FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
- !isa<IntegerType>(FT->getReturnType()))
+ if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy() ||
+ !FT->getReturnType()->isIntegerTy())
return 0;
// Check for a fixed format string.
@@ -1582,8 +987,8 @@ struct SPrintFOpt : public LibCallOptimization {
// sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
EmitMemCpy(CI->getOperand(1), CI->getOperand(2), // Copy the nul byte.
- ConstantInt::get
- (TD->getIntPtrType(*Context), FormatStr.size()+1),1,B);
+ ConstantInt::get(TD->getIntPtrType(*Context),
+ FormatStr.size()+1), 1, B, TD);
return ConstantInt::get(CI->getType(), FormatStr.size());
}
@@ -1595,7 +1000,7 @@ struct SPrintFOpt : public LibCallOptimization {
// Decode the second character of the format string.
if (FormatStr[1] == 'c') {
// sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
- if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
+ if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0;
Value *V = B.CreateTrunc(CI->getOperand(3),
Type::getInt8Ty(*Context), "char");
Value *Ptr = CastToCStr(CI->getOperand(1), B);
@@ -1612,13 +1017,13 @@ struct SPrintFOpt : public LibCallOptimization {
if (!TD) return 0;
// sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
- if (!isa<PointerType>(CI->getOperand(3)->getType())) return 0;
+ if (!CI->getOperand(3)->getType()->isPointerTy()) return 0;
- Value *Len = EmitStrLen(CI->getOperand(3), B);
+ Value *Len = EmitStrLen(CI->getOperand(3), B, TD);
Value *IncLen = B.CreateAdd(Len,
ConstantInt::get(Len->getType(), 1),
"leninc");
- EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B);
+ EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B, TD);
// The sprintf result is the unincremented number of bytes in the string.
return B.CreateIntCast(Len, CI->getType(), false);
@@ -1634,11 +1039,11 @@ struct FWriteOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
// Require a pointer, an integer, an integer, a pointer, returning integer.
const FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() != 4 || !isa<PointerType>(FT->getParamType(0)) ||
- !isa<IntegerType>(FT->getParamType(1)) ||
- !isa<IntegerType>(FT->getParamType(2)) ||
- !isa<PointerType>(FT->getParamType(3)) ||
- !isa<IntegerType>(FT->getReturnType()))
+ if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isIntegerTy() ||
+ !FT->getParamType(2)->isIntegerTy() ||
+ !FT->getParamType(3)->isPointerTy() ||
+ !FT->getReturnType()->isIntegerTy())
return 0;
// Get the element size and count.
@@ -1654,7 +1059,7 @@ struct FWriteOpt : public LibCallOptimization {
// If this is writing one byte, turn it into fputc.
if (Bytes == 1) { // fwrite(S,1,1,F) -> fputc(S[0],F)
Value *Char = B.CreateLoad(CastToCStr(CI->getOperand(1), B), "char");
- EmitFPutC(Char, CI->getOperand(4), B);
+ EmitFPutC(Char, CI->getOperand(4), B, TD);
return ConstantInt::get(CI->getType(), 1);
}
@@ -1672,8 +1077,8 @@ struct FPutsOpt : public LibCallOptimization {
// Require two pointers. Also, we can't optimize if return value is used.
const FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
+ if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy() ||
!CI->use_empty())
return 0;
@@ -1682,7 +1087,7 @@ struct FPutsOpt : public LibCallOptimization {
if (!Len) return 0;
EmitFWrite(CI->getOperand(1),
ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
- CI->getOperand(2), B);
+ CI->getOperand(2), B, TD);
return CI; // Known to have no uses (see above).
}
};
@@ -1694,9 +1099,9 @@ struct FPrintFOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
// Require two fixed paramters as pointers and integer result.
const FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
- !isa<IntegerType>(FT->getReturnType()))
+ if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
+ !FT->getParamType(1)->isPointerTy() ||
+ !FT->getReturnType()->isIntegerTy())
return 0;
// All the optimizations depend on the format string.
@@ -1716,7 +1121,7 @@ struct FPrintFOpt : public LibCallOptimization {
EmitFWrite(CI->getOperand(2),
ConstantInt::get(TD->getIntPtrType(*Context),
FormatStr.size()),
- CI->getOperand(1), B);
+ CI->getOperand(1), B, TD);
return ConstantInt::get(CI->getType(), FormatStr.size());
}
@@ -1728,16 +1133,16 @@ struct FPrintFOpt : public LibCallOptimization {
// Decode the second character of the format string.
if (FormatStr[1] == 'c') {
// fprintf(F, "%c", chr) --> *(i8*)dst = chr
- if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
- EmitFPutC(CI->getOperand(3), CI->getOperand(1), B);
+ if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0;
+ EmitFPutC(CI->getOperand(3), CI->getOperand(1), B, TD);
return ConstantInt::get(CI->getType(), 1);
}
if (FormatStr[1] == 's') {
// fprintf(F, "%s", str) -> fputs(str, F)
- if (!isa<PointerType>(CI->getOperand(3)->getType()) || !CI->use_empty())
+ if (!CI->getOperand(3)->getType()->isPointerTy() || !CI->use_empty())
return 0;
- EmitFPutS(CI->getOperand(3), CI->getOperand(1), B);
+ EmitFPutS(CI->getOperand(3), CI->getOperand(1), B, TD);
return CI;
}
return 0;
@@ -1769,10 +1174,6 @@ namespace {
SPrintFOpt SPrintF; PrintFOpt PrintF;
FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF;
- // Object Size Checking
- MemCpyChkOpt MemCpyChk; MemSetChkOpt MemSetChk; MemMoveChkOpt MemMoveChk;
- StrCpyChkOpt StrCpyChk;
-
bool Modified; // This is only used by doInitialization.
public:
static char ID; // Pass identification
@@ -1878,12 +1279,6 @@ void SimplifyLibCalls::InitOptimizations() {
Optimizations["fwrite"] = &FWrite;
Optimizations["fputs"] = &FPuts;
Optimizations["fprintf"] = &FPrintF;
-
- // Object Size Checking
- Optimizations["__memcpy_chk"] = &MemCpyChk;
- Optimizations["__memset_chk"] = &MemSetChk;
- Optimizations["__memmove_chk"] = &MemMoveChk;
- Optimizations["__strcpy_chk"] = &StrCpyChk;
}
@@ -2000,7 +1395,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 's':
if (Name == "strlen") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setOnlyReadsMemory(F);
setDoesNotThrow(F);
@@ -2018,14 +1413,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "strncpy" ||
Name == "strtoull") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
} else if (Name == "strxfrm") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2038,8 +1433,8 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "strcasecmp" ||
Name == "strncasecmp") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setOnlyReadsMemory(F);
setDoesNotThrow(F);
@@ -2048,7 +1443,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
} else if (Name == "strstr" ||
Name == "strpbrk") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setOnlyReadsMemory(F);
setDoesNotThrow(F);
@@ -2056,7 +1451,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
} else if (Name == "strtok" ||
Name == "strtok_r") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
@@ -2064,15 +1459,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "setbuf" ||
Name == "setvbuf") {
if (FTy->getNumParams() < 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "strdup" ||
Name == "strndup") {
if (FTy->getNumParams() < 1 ||
- !isa<PointerType>(FTy->getReturnType()) ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getReturnType()->isPointerTy() ||
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
@@ -2082,31 +1477,31 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "sprintf" ||
Name == "statvfs") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
setDoesNotCapture(F, 2);
} else if (Name == "snprintf") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(2)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(2)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
setDoesNotCapture(F, 3);
} else if (Name == "setitimer") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(1)) ||
- !isa<PointerType>(FTy->getParamType(2)))
+ !FTy->getParamType(1)->isPointerTy() ||
+ !FTy->getParamType(2)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
setDoesNotCapture(F, 3);
} else if (Name == "system") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
// May throw; "system" is a valid pthread cancellation point.
setDoesNotCapture(F, 1);
@@ -2115,14 +1510,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'm':
if (Name == "malloc") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getReturnType()))
+ !FTy->getReturnType()->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
} else if (Name == "memcmp") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setOnlyReadsMemory(F);
setDoesNotThrow(F);
@@ -2141,18 +1536,18 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "memccpy" ||
Name == "memmove") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
} else if (Name == "memalign") {
- if (!isa<PointerType>(FTy->getReturnType()))
+ if (!FTy->getReturnType()->isPointerTy())
continue;
setDoesNotAlias(F, 0);
} else if (Name == "mkdir" ||
Name == "mktime") {
if (FTy->getNumParams() == 0 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2161,15 +1556,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'r':
if (Name == "realloc") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getReturnType()))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getReturnType()->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
setDoesNotCapture(F, 1);
} else if (Name == "read") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
// May throw; "read" is a valid pthread cancellation point.
setDoesNotCapture(F, 2);
@@ -2178,15 +1573,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "remove" ||
Name == "realpath") {
if (FTy->getNumParams() < 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "rename" ||
Name == "readlink") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2196,7 +1591,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'w':
if (Name == "write") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
// May throw; "write" is a valid pthread cancellation point.
setDoesNotCapture(F, 2);
@@ -2205,16 +1600,16 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'b':
if (Name == "bcopy") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
setDoesNotCapture(F, 2);
} else if (Name == "bcmp") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setOnlyReadsMemory(F);
@@ -2222,7 +1617,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
setDoesNotCapture(F, 2);
} else if (Name == "bzero") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2231,7 +1626,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'c':
if (Name == "calloc") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getReturnType()))
+ !FTy->getReturnType()->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
@@ -2241,7 +1636,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "clearerr" ||
Name == "closedir") {
if (FTy->getNumParams() == 0 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2253,14 +1648,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "atof" ||
Name == "atoll") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setOnlyReadsMemory(F);
setDoesNotCapture(F, 1);
} else if (Name == "access") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2269,9 +1664,9 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'f':
if (Name == "fopen") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getReturnType()) ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getReturnType()->isPointerTy() ||
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
@@ -2279,8 +1674,8 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
setDoesNotCapture(F, 2);
} else if (Name == "fdopen") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getReturnType()) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getReturnType()->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
@@ -2300,13 +1695,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "funlockfile" ||
Name == "ftrylockfile") {
if (FTy->getNumParams() == 0 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "ferror") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2318,22 +1713,22 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "frexpl" ||
Name == "fstatvfs") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
} else if (Name == "fgets") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(2)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(2)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 3);
} else if (Name == "fread" ||
Name == "fwrite") {
if (FTy->getNumParams() != 4 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(3)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(3)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2343,8 +1738,8 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "fprintf" ||
Name == "fgetpos") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2356,13 +1751,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "getlogin_r" ||
Name == "getc_unlocked") {
if (FTy->getNumParams() == 0 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "getenv") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setOnlyReadsMemory(F);
@@ -2372,13 +1767,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
setDoesNotThrow(F);
} else if (Name == "getitimer") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
} else if (Name == "getpwnam") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2387,7 +1782,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'u':
if (Name == "ungetc") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
@@ -2395,15 +1790,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "unlink" ||
Name == "unsetenv") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "utime" ||
Name == "utimes") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2413,7 +1808,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'p':
if (Name == "putc") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
@@ -2421,14 +1816,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "printf" ||
Name == "perror") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "pread" ||
Name == "pwrite") {
if (FTy->getNumParams() != 4 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
// May throw; these are valid pthread cancellation points.
setDoesNotCapture(F, 2);
@@ -2436,9 +1831,9 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
setDoesNotThrow(F);
} else if (Name == "popen") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getReturnType()) ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getReturnType()->isPointerTy() ||
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
@@ -2446,7 +1841,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
setDoesNotCapture(F, 2);
} else if (Name == "pclose") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2455,43 +1850,43 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'v':
if (Name == "vscanf") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "vsscanf" ||
Name == "vfscanf") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(1)) ||
- !isa<PointerType>(FTy->getParamType(2)))
+ !FTy->getParamType(1)->isPointerTy() ||
+ !FTy->getParamType(2)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
setDoesNotCapture(F, 2);
} else if (Name == "valloc") {
- if (!isa<PointerType>(FTy->getReturnType()))
+ if (!FTy->getReturnType()->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
} else if (Name == "vprintf") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "vfprintf" ||
Name == "vsprintf") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
setDoesNotCapture(F, 2);
} else if (Name == "vsnprintf") {
if (FTy->getNumParams() != 4 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(2)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(2)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2501,14 +1896,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'o':
if (Name == "open") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
// May throw; "open" is a valid pthread cancellation point.
setDoesNotCapture(F, 1);
} else if (Name == "opendir") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getReturnType()) ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getReturnType()->isPointerTy() ||
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
@@ -2517,13 +1912,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
break;
case 't':
if (Name == "tmpfile") {
- if (!isa<PointerType>(FTy->getReturnType()))
+ if (!FTy->getReturnType()->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
} else if (Name == "times") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2546,15 +1941,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'l':
if (Name == "lstat") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
setDoesNotCapture(F, 2);
} else if (Name == "lchown") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2563,7 +1958,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 'q':
if (Name == "qsort") {
if (FTy->getNumParams() != 4 ||
- !isa<PointerType>(FTy->getParamType(3)))
+ !FTy->getParamType(3)->isPointerTy())
continue;
// May throw; places call through function pointer.
setDoesNotCapture(F, 4);
@@ -2573,27 +1968,27 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
if (Name == "__strdup" ||
Name == "__strndup") {
if (FTy->getNumParams() < 1 ||
- !isa<PointerType>(FTy->getReturnType()) ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getReturnType()->isPointerTy() ||
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
setDoesNotCapture(F, 1);
} else if (Name == "__strtok_r") {
if (FTy->getNumParams() != 3 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
} else if (Name == "_IO_getc") {
if (FTy->getNumParams() != 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "_IO_putc") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
@@ -2602,7 +1997,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
case 1:
if (Name == "\1__isoc99_scanf") {
if (FTy->getNumParams() < 1 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
@@ -2611,17 +2006,17 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
Name == "\1statvfs64" ||
Name == "\1__isoc99_sscanf") {
if (FTy->getNumParams() < 1 ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
setDoesNotCapture(F, 2);
} else if (Name == "\1fopen64") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getReturnType()) ||
- !isa<PointerType>(FTy->getParamType(0)) ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getReturnType()->isPointerTy() ||
+ !FTy->getParamType(0)->isPointerTy() ||
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
@@ -2630,25 +2025,25 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
} else if (Name == "\1fseeko64" ||
Name == "\1ftello64") {
if (FTy->getNumParams() == 0 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 1);
} else if (Name == "\1tmpfile64") {
- if (!isa<PointerType>(FTy->getReturnType()))
+ if (!FTy->getReturnType()->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotAlias(F, 0);
} else if (Name == "\1fstat64" ||
Name == "\1fstatvfs64") {
if (FTy->getNumParams() != 2 ||
- !isa<PointerType>(FTy->getParamType(1)))
+ !FTy->getParamType(1)->isPointerTy())
continue;
setDoesNotThrow(F);
setDoesNotCapture(F, 2);
} else if (Name == "\1open64") {
if (FTy->getNumParams() < 2 ||
- !isa<PointerType>(FTy->getParamType(0)))
+ !FTy->getParamType(0)->isPointerTy())
continue;
// May throw; "open" is a valid pthread cancellation point.
setDoesNotCapture(F, 1);
diff --git a/lib/Transforms/Utils/AddrModeMatcher.cpp b/lib/Transforms/Utils/AddrModeMatcher.cpp
index 8c4aa59..be6b383 100644
--- a/lib/Transforms/Utils/AddrModeMatcher.cpp
+++ b/lib/Transforms/Utils/AddrModeMatcher.cpp
@@ -125,7 +125,7 @@ static bool MightBeFoldableInst(Instruction *I) {
// Don't touch identity bitcasts.
if (I->getType() == I->getOperand(0)->getType())
return false;
- return isa<PointerType>(I->getType()) || isa<IntegerType>(I->getType());
+ return I->getType()->isPointerTy() || I->getType()->isIntegerTy();
case Instruction::PtrToInt:
// PtrToInt is always a noop, as we know that the int type is pointer sized.
return true;
@@ -167,8 +167,8 @@ bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode,
case Instruction::BitCast:
// BitCast is always a noop, and we can handle it as long as it is
// int->int or pointer->pointer (we don't want int<->fp or something).
- if ((isa<PointerType>(AddrInst->getOperand(0)->getType()) ||
- isa<IntegerType>(AddrInst->getOperand(0)->getType())) &&
+ if ((AddrInst->getOperand(0)->getType()->isPointerTy() ||
+ AddrInst->getOperand(0)->getType()->isIntegerTy()) &&
// Don't touch identity bitcasts. These were probably put here by LSR,
// and we don't want to mess around with them. Assume it knows what it
// is doing.
@@ -569,7 +569,7 @@ IsProfitableToFoldIntoAddressingMode(Instruction *I, ExtAddrMode &AMBefore,
// Get the access type of this use. If the use isn't a pointer, we don't
// know what it accesses.
Value *Address = User->getOperand(OpNo);
- if (!isa<PointerType>(Address->getType()))
+ if (!Address->getType()->isPointerTy())
return false;
const Type *AddressAccessTy =
cast<PointerType>(Address->getType())->getElementType();
diff --git a/lib/Transforms/Utils/Android.mk b/lib/Transforms/Utils/Android.mk
new file mode 100644
index 0000000..d9f31d7
--- /dev/null
+++ b/lib/Transforms/Utils/Android.mk
@@ -0,0 +1,49 @@
+LOCAL_PATH:= $(call my-dir)
+
+transforms_utils_SRC_FILES := \
+ AddrModeMatcher.cpp \
+ BasicBlockUtils.cpp \
+ BasicInliner.cpp \
+ BreakCriticalEdges.cpp \
+ CloneFunction.cpp \
+ CloneLoop.cpp \
+ CloneModule.cpp \
+ CodeExtractor.cpp \
+ DemoteRegToStack.cpp \
+ InlineFunction.cpp \
+ InstructionNamer.cpp \
+ LCSSA.cpp \
+ Local.cpp \
+ LoopSimplify.cpp \
+ LoopUnroll.cpp \
+ LowerInvoke.cpp \
+ LowerSwitch.cpp \
+ Mem2Reg.cpp \
+ PromoteMemoryToRegister.cpp \
+ SSAUpdater.cpp \
+ SSI.cpp \
+ SimplifyCFG.cpp \
+ UnifyFunctionExitNodes.cpp \
+ ValueMapper.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(transforms_utils_SRC_FILES)
+LOCAL_MODULE:= libLLVMTransformUtils
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(transforms_utils_SRC_FILES)
+LOCAL_MODULE:= libLLVMTransformUtils
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp
index 7bc4fcd..1f62dab 100644
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -274,24 +274,31 @@ void llvm::RemoveSuccessor(TerminatorInst *TI, unsigned SuccNum) {
ReplaceInstWithInst(TI, NewTI);
}
-/// SplitEdge - Split the edge connecting specified block. Pass P must
-/// not be NULL.
-BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, Pass *P) {
- TerminatorInst *LatchTerm = BB->getTerminator();
- unsigned SuccNum = 0;
+/// GetSuccessorNumber - Search for the specified successor of basic block BB
+/// and return its position in the terminator instruction's list of
+/// successors. It is an error to call this with a block that is not a
+/// successor.
+unsigned llvm::GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ) {
+ TerminatorInst *Term = BB->getTerminator();
#ifndef NDEBUG
- unsigned e = LatchTerm->getNumSuccessors();
+ unsigned e = Term->getNumSuccessors();
#endif
for (unsigned i = 0; ; ++i) {
assert(i != e && "Didn't find edge?");
- if (LatchTerm->getSuccessor(i) == Succ) {
- SuccNum = i;
- break;
- }
+ if (Term->getSuccessor(i) == Succ)
+ return i;
}
+ return 0;
+}
+
+/// SplitEdge - Split the edge connecting specified block. Pass P must
+/// not be NULL.
+BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, Pass *P) {
+ unsigned SuccNum = GetSuccessorNumber(BB, Succ);
// If this is a critical edge, let SplitCriticalEdge do it.
- if (SplitCriticalEdge(BB->getTerminator(), SuccNum, P))
+ TerminatorInst *LatchTerm = BB->getTerminator();
+ if (SplitCriticalEdge(LatchTerm, SuccNum, P))
return LatchTerm->getSuccessor(SuccNum);
// If the edge isn't critical, then BB has a single successor or Succ has a
diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp
index 19c7206..3657390 100644
--- a/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -179,7 +179,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// Create a new basic block, linking it into the CFG.
BasicBlock *NewBB = BasicBlock::Create(TI->getContext(),
TIBB->getName() + "." + DestBB->getName() + "_crit_edge");
- // Create our unconditional branch...
+ // Create our unconditional branch.
BranchInst::Create(DestBB, NewBB);
// Branch to the new block, breaking the edge.
@@ -192,16 +192,47 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// If there are any PHI nodes in DestBB, we need to update them so that they
// merge incoming values from NewBB instead of from TIBB.
- //
- for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
- PHINode *PN = cast<PHINode>(I);
- // We no longer enter through TIBB, now we come in through NewBB. Revector
- // exactly one entry in the PHI node that used to come from TIBB to come
- // from NewBB.
- int BBIdx = PN->getBasicBlockIndex(TIBB);
- PN->setIncomingBlock(BBIdx, NewBB);
+ if (PHINode *APHI = dyn_cast<PHINode>(DestBB->begin())) {
+ // This conceptually does:
+ // foreach (PHINode *PN in DestBB)
+ // PN->setIncomingBlock(PN->getIncomingBlock(TIBB), NewBB);
+ // but is optimized for two cases.
+
+ if (APHI->getNumIncomingValues() <= 8) { // Small # preds case.
+ unsigned BBIdx = 0;
+ for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
+ // We no longer enter through TIBB, now we come in through NewBB.
+ // Revector exactly one entry in the PHI node that used to come from
+ // TIBB to come from NewBB.
+ PHINode *PN = cast<PHINode>(I);
+
+ // Reuse the previous value of BBIdx if it lines up. In cases where we
+ // have multiple phi nodes with *lots* of predecessors, this is a speed
+ // win because we don't have to scan the PHI looking for TIBB. This
+ // happens because the BB list of PHI nodes are usually in the same
+ // order.
+ if (PN->getIncomingBlock(BBIdx) != TIBB)
+ BBIdx = PN->getBasicBlockIndex(TIBB);
+ PN->setIncomingBlock(BBIdx, NewBB);
+ }
+ } else {
+ // However, the foreach loop is slow for blocks with lots of predecessors
+ // because PHINode::getIncomingBlock is O(n) in # preds. Instead, walk
+ // the user list of TIBB to find the PHI nodes.
+ SmallPtrSet<PHINode*, 16> UpdatedPHIs;
+
+ for (Value::use_iterator UI = TIBB->use_begin(), E = TIBB->use_end();
+ UI != E; ) {
+ Value::use_iterator Use = UI++;
+ if (PHINode *PN = dyn_cast<PHINode>(Use)) {
+ // Remove one entry from each PHI.
+ if (PN->getParent() == DestBB && UpdatedPHIs.insert(PN))
+ PN->setOperand(Use.getOperandNo(), NewBB);
+ }
+ }
+ }
}
-
+
// If there are any other edges from TIBB to DestBB, update those to go
// through the split block, making those edges non-critical as well (and
// reducing the number of phi entries in the DestBB if relevant).
@@ -221,6 +252,15 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// If we don't have a pass object, we can't update anything...
if (P == 0) return NewBB;
+
+ DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>();
+ DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>();
+ LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>();
+ ProfileInfo *PI = P->getAnalysisIfAvailable<ProfileInfo>();
+
+ // If we have nothing to update, just return.
+ if (DT == 0 && DF == 0 && LI == 0 && PI == 0)
+ return NewBB;
// Now update analysis information. Since the only predecessor of NewBB is
// the TIBB, TIBB clearly dominates NewBB. TIBB usually doesn't dominate
@@ -229,14 +269,23 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// loop header) then NewBB dominates DestBB.
SmallVector<BasicBlock*, 8> OtherPreds;
- for (pred_iterator I = pred_begin(DestBB), E = pred_end(DestBB); I != E; ++I)
- if (*I != NewBB)
- OtherPreds.push_back(*I);
+ // If there is a PHI in the block, loop over predecessors with it, which is
+ // faster than iterating pred_begin/end.
+ if (PHINode *PN = dyn_cast<PHINode>(DestBB->begin())) {
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingBlock(i) != NewBB)
+ OtherPreds.push_back(PN->getIncomingBlock(i));
+ } else {
+ for (pred_iterator I = pred_begin(DestBB), E = pred_end(DestBB);
+ I != E; ++I)
+ if (*I != NewBB)
+ OtherPreds.push_back(*I);
+ }
bool NewBBDominatesDestBB = true;
// Should we update DominatorTree information?
- if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>()) {
+ if (DT) {
DomTreeNode *TINode = DT->getNode(TIBB);
// The new block is not the immediate dominator for any other nodes, but
@@ -267,7 +316,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
}
// Should we update DominanceFrontier information?
- if (DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>()) {
+ if (DF) {
// If NewBBDominatesDestBB hasn't been computed yet, do so with DF.
if (!OtherPreds.empty()) {
// FIXME: IMPLEMENT THIS!
@@ -301,7 +350,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
}
// Update LoopInfo if it is around.
- if (LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>()) {
+ if (LI) {
if (Loop *TIL = LI->getLoopFor(TIBB)) {
// If one or the other blocks were not in a loop, the new block is not
// either, and thus LI doesn't need to be updated.
@@ -382,9 +431,8 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
}
// Update ProfileInfo if it is around.
- if (ProfileInfo *PI = P->getAnalysisIfAvailable<ProfileInfo>()) {
- PI->splitEdge(TIBB,DestBB,NewBB,MergeIdenticalEdges);
- }
+ if (PI)
+ PI->splitEdge(TIBB, DestBB, NewBB, MergeIdenticalEdges);
return NewBB;
}
diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp
new file mode 100644
index 0000000..2ea4bb6
--- /dev/null
+++ b/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -0,0 +1,324 @@
+//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements some functions that will create standard C libcalls.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/BuildLibCalls.h"
+#include "llvm/Type.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Module.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Intrinsics.h"
+
+using namespace llvm;
+
+/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
+Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
+ return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
+}
+
+/// EmitStrLen - Emit a call to the strlen function to the builder, for the
+/// specified pointer. This always returns an integer value of size intptr_t.
+Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI[2];
+ AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
+ Attribute::NoUnwind);
+
+ LLVMContext &Context = B.GetInsertBlock()->getContext();
+ Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2),
+ TD->getIntPtrType(Context),
+ B.getInt8PtrTy(),
+ NULL);
+ CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
+ if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+
+ return CI;
+}
+
+/// EmitStrChr - Emit a call to the strchr function to the builder, for the
+/// specified pointer and character. Ptr is required to be some pointer type,
+/// and the return value has 'i8*' type.
+Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
+ const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI =
+ AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
+
+ const Type *I8Ptr = B.getInt8PtrTy();
+ const Type *I32Ty = B.getInt32Ty();
+ Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(&AWI, 1),
+ I8Ptr, I8Ptr, I32Ty, NULL);
+ CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
+ ConstantInt::get(I32Ty, C), "strchr");
+ if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+ return CI;
+}
+
+/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
+/// specified pointer arguments.
+Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
+ const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI[2];
+ AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
+ const Type *I8Ptr = B.getInt8PtrTy();
+ 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.
+Value *llvm::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
+ unsigned Align, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ const Type *Ty = Len->getType();
+ Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, &Ty, 1);
+ Dst = CastToCStr(Dst, B);
+ Src = CastToCStr(Src, B);
+ return B.CreateCall4(MemCpy, Dst, Src, Len,
+ ConstantInt::get(B.getInt32Ty(), Align));
+}
+
+/// EmitMemMove - Emit a call to the memmove function to the builder. This
+/// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
+Value *llvm::EmitMemMove(Value *Dst, Value *Src, Value *Len,
+ unsigned Align, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ LLVMContext &Context = B.GetInsertBlock()->getContext();
+ const Type *Ty = TD->getIntPtrType(Context);
+ Value *MemMove = Intrinsic::getDeclaration(M, Intrinsic::memmove, &Ty, 1);
+ Dst = CastToCStr(Dst, B);
+ Src = CastToCStr(Src, B);
+ Value *A = ConstantInt::get(B.getInt32Ty(), Align);
+ return B.CreateCall4(MemMove, Dst, Src, Len, A);
+}
+
+/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
+/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
+Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
+ Value *Len, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI;
+ AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
+ LLVMContext &Context = B.GetInsertBlock()->getContext();
+ Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1),
+ B.getInt8PtrTy(),
+ B.getInt8PtrTy(),
+ B.getInt32Ty(),
+ TD->getIntPtrType(Context),
+ NULL);
+ CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
+
+ if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+
+ return CI;
+}
+
+/// EmitMemCmp - Emit a call to the memcmp function.
+Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
+ Value *Len, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI[3];
+ AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
+ AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
+ Attribute::NoUnwind);
+
+ LLVMContext &Context = B.GetInsertBlock()->getContext();
+ Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3),
+ B.getInt32Ty(),
+ B.getInt8PtrTy(),
+ B.getInt8PtrTy(),
+ TD->getIntPtrType(Context), NULL);
+ CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
+ Len, "memcmp");
+
+ if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+
+ return CI;
+}
+
+/// EmitMemSet - Emit a call to the memset function
+Value *llvm::EmitMemSet(Value *Dst, Value *Val,
+ Value *Len, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Intrinsic::ID IID = Intrinsic::memset;
+ const Type *Tys[1];
+ Tys[0] = Len->getType();
+ Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1);
+ Value *Align = ConstantInt::get(B.getInt32Ty(), 1);
+ return B.CreateCall4(MemSet, CastToCStr(Dst, B), Val, Len, Align);
+}
+
+/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
+/// 'floor'). This function is known to take a single of type matching 'Op' and
+/// returns one value with the same type. If 'Op' is a long double, 'l' is
+/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
+Value *llvm::EmitUnaryFloatFnCall(Value *Op, const char *Name,
+ IRBuilder<> &B, const AttrListPtr &Attrs) {
+ char NameBuffer[20];
+ if (!Op->getType()->isDoubleTy()) {
+ // If we need to add a suffix, copy into NameBuffer.
+ unsigned NameLen = strlen(Name);
+ assert(NameLen < sizeof(NameBuffer)-2);
+ memcpy(NameBuffer, Name, NameLen);
+ if (Op->getType()->isFloatTy())
+ NameBuffer[NameLen] = 'f'; // floorf
+ else
+ NameBuffer[NameLen] = 'l'; // floorl
+ NameBuffer[NameLen+1] = 0;
+ Name = NameBuffer;
+ }
+
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
+ Op->getType(), NULL);
+ CallInst *CI = B.CreateCall(Callee, Op, Name);
+ CI->setAttributes(Attrs);
+ if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+
+ return CI;
+}
+
+/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
+/// is an integer.
+Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
+ B.getInt32Ty(), NULL);
+ CallInst *CI = B.CreateCall(PutChar,
+ B.CreateIntCast(Char,
+ B.getInt32Ty(),
+ /*isSigned*/true,
+ "chari"),
+ "putchar");
+
+ if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+ return CI;
+}
+
+/// EmitPutS - Emit a call to the puts function. This assumes that Str is
+/// some pointer.
+void llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI[2];
+ AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
+
+ Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2),
+ B.getInt32Ty(),
+ B.getInt8PtrTy(),
+ NULL);
+ CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
+ if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+
+}
+
+/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
+/// an integer and File is a pointer to FILE.
+void llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
+ const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI[2];
+ AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
+ Constant *F;
+ if (File->getType()->isPointerTy())
+ F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2),
+ B.getInt32Ty(),
+ B.getInt32Ty(), File->getType(),
+ NULL);
+ else
+ F = M->getOrInsertFunction("fputc",
+ B.getInt32Ty(),
+ B.getInt32Ty(),
+ File->getType(), NULL);
+ Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
+ "chari");
+ CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
+
+ if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
+ CI->setCallingConv(Fn->getCallingConv());
+}
+
+/// EmitFPutS - Emit a call to the puts function. Str is required to be a
+/// pointer and File is a pointer to FILE.
+void llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
+ const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI[3];
+ AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
+ AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
+ Constant *F;
+ if (File->getType()->isPointerTy())
+ F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3),
+ B.getInt32Ty(),
+ B.getInt8PtrTy(),
+ File->getType(), NULL);
+ else
+ F = M->getOrInsertFunction("fputs", B.getInt32Ty(),
+ B.getInt8PtrTy(),
+ File->getType(), NULL);
+ CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
+
+ if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
+ CI->setCallingConv(Fn->getCallingConv());
+}
+
+/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
+/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
+void llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
+ IRBuilder<> &B, const TargetData *TD) {
+ Module *M = B.GetInsertBlock()->getParent()->getParent();
+ AttributeWithIndex AWI[3];
+ AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
+ AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
+ LLVMContext &Context = B.GetInsertBlock()->getContext();
+ Constant *F;
+ if (File->getType()->isPointerTy())
+ F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3),
+ TD->getIntPtrType(Context),
+ B.getInt8PtrTy(),
+ TD->getIntPtrType(Context),
+ TD->getIntPtrType(Context),
+ File->getType(), NULL);
+ else
+ F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(Context),
+ B.getInt8PtrTy(),
+ TD->getIntPtrType(Context),
+ TD->getIntPtrType(Context),
+ File->getType(), NULL);
+ CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
+ ConstantInt::get(TD->getIntPtrType(Context), 1), File);
+
+ if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
+ CI->setCallingConv(Fn->getCallingConv());
+}
diff --git a/lib/Transforms/Utils/CMakeLists.txt b/lib/Transforms/Utils/CMakeLists.txt
index 93577b4..dec227a 100644
--- a/lib/Transforms/Utils/CMakeLists.txt
+++ b/lib/Transforms/Utils/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_library(LLVMTransformUtils
BasicBlockUtils.cpp
BasicInliner.cpp
BreakCriticalEdges.cpp
+ BuildLibCalls.cpp
CloneFunction.cpp
CloneLoop.cpp
CloneModule.cpp
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 7e7973a..d03f7a6 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -46,7 +46,7 @@ using namespace llvm;
static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD,
uint64_t &ByteOffset,
unsigned MaxLookup = 6) {
- if (!isa<PointerType>(V->getType()))
+ if (!V->getType()->isPointerTy())
return V;
for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
@@ -65,7 +65,7 @@ static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD,
} else {
return V;
}
- assert(isa<PointerType>(V->getType()) && "Unexpected operand type!");
+ assert(V->getType()->isPointerTy() && "Unexpected operand type!");
}
return V;
}
@@ -490,6 +490,17 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, Pass *P) {
// Splice all the instructions from PredBB to DestBB.
PredBB->getTerminator()->eraseFromParent();
DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList());
+
+ // Zap anything that took the address of DestBB. Not doing this will give the
+ // address an invalid value.
+ if (DestBB->hasAddressTaken()) {
+ BlockAddress *BA = BlockAddress::get(DestBB);
+ Constant *Replacement =
+ ConstantInt::get(llvm::Type::getInt32Ty(BA->getContext()), 1);
+ BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement,
+ BA->getType()));
+ BA->destroyConstant();
+ }
// Anything that branched to PredBB now branches to DestBB.
PredBB->replaceAllUsesWith(DestBB);
diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp
index 57bab60..924b744 100644
--- a/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/lib/Transforms/Utils/LoopSimplify.cpp
@@ -51,6 +51,7 @@
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/Debug.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
@@ -147,6 +148,11 @@ ReprocessLoop:
// Delete each unique out-of-loop (and thus dead) predecessor.
for (SmallPtrSet<BasicBlock *, 4>::iterator I = BadPreds.begin(),
E = BadPreds.end(); I != E; ++I) {
+
+ DEBUG(dbgs() << "LoopSimplify: Deleting edge from dead predecessor ";
+ WriteAsOperand(dbgs(), *I, false);
+ dbgs() << "\n");
+
// Inform each successor of each dead pred.
for (succ_iterator SI = succ_begin(*I), SE = succ_end(*I); SI != SE; ++SI)
(*SI)->removePredecessor(*I);
@@ -159,6 +165,27 @@ ReprocessLoop:
}
}
+ // If there are exiting blocks with branches on undef, resolve the undef in
+ // the direction which will exit the loop. This will help simplify loop
+ // trip count computations.
+ SmallVector<BasicBlock*, 8> ExitingBlocks;
+ L->getExitingBlocks(ExitingBlocks);
+ for (SmallVectorImpl<BasicBlock *>::iterator I = ExitingBlocks.begin(),
+ E = ExitingBlocks.end(); I != E; ++I)
+ if (BranchInst *BI = dyn_cast<BranchInst>((*I)->getTerminator()))
+ if (BI->isConditional()) {
+ if (UndefValue *Cond = dyn_cast<UndefValue>(BI->getCondition())) {
+
+ DEBUG(dbgs() << "LoopSimplify: Resolving \"br i1 undef\" to exit in ";
+ WriteAsOperand(dbgs(), *I, false);
+ dbgs() << "\n");
+
+ BI->setCondition(ConstantInt::get(Cond->getType(),
+ !L->contains(BI->getSuccessor(0))));
+ Changed = true;
+ }
+ }
+
// Does the loop already have a preheader? If so, don't insert one.
BasicBlock *Preheader = L->getLoopPreheader();
if (!Preheader) {
@@ -250,8 +277,6 @@ ReprocessLoop:
break;
}
if (UniqueExit) {
- SmallVector<BasicBlock*, 8> ExitingBlocks;
- L->getExitingBlocks(ExitingBlocks);
for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
BasicBlock *ExitingBlock = ExitingBlocks[i];
if (!ExitingBlock->getSinglePredecessor()) continue;
@@ -282,6 +307,11 @@ ReprocessLoop:
// Success. The block is now dead, so remove it from the loop,
// update the dominator tree and dominance frontier, and delete it.
+
+ DEBUG(dbgs() << "LoopSimplify: Eliminating exiting block ";
+ WriteAsOperand(dbgs(), ExitingBlock, false);
+ dbgs() << "\n");
+
assert(pred_begin(ExitingBlock) == pred_end(ExitingBlock));
Changed = true;
LI->removeBlock(ExitingBlock);
@@ -335,6 +365,10 @@ BasicBlock *LoopSimplify::InsertPreheaderForLoop(Loop *L) {
SplitBlockPredecessors(Header, &OutsideBlocks[0], OutsideBlocks.size(),
".preheader", this);
+ DEBUG(dbgs() << "LoopSimplify: Creating pre-header ";
+ WriteAsOperand(dbgs(), NewBB, false);
+ dbgs() << "\n");
+
// Make sure that NewBB is put someplace intelligent, which doesn't mess up
// code layout too horribly.
PlaceSplitBlockCarefully(NewBB, OutsideBlocks, L);
@@ -360,6 +394,10 @@ BasicBlock *LoopSimplify::RewriteLoopExitBlock(Loop *L, BasicBlock *Exit) {
LoopBlocks.size(), ".loopexit",
this);
+ DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block ";
+ WriteAsOperand(dbgs(), NewBB, false);
+ dbgs() << "\n");
+
return NewBB;
}
@@ -480,6 +518,8 @@ Loop *LoopSimplify::SeparateNestedLoop(Loop *L, LPPassManager &LPM) {
OuterLoopPreds.push_back(PN->getIncomingBlock(i));
}
+ DEBUG(dbgs() << "LoopSimplify: Splitting out a new outer loop\n");
+
BasicBlock *Header = L->getHeader();
BasicBlock *NewBB = SplitBlockPredecessors(Header, &OuterLoopPreds[0],
OuterLoopPreds.size(),
@@ -574,6 +614,10 @@ LoopSimplify::InsertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader) {
Header->getName()+".backedge", F);
BranchInst *BETerminator = BranchInst::Create(Header, BEBlock);
+ DEBUG(dbgs() << "LoopSimplify: Inserting unique backedge block ";
+ WriteAsOperand(dbgs(), BEBlock, false);
+ dbgs() << "\n");
+
// Move the new backedge block to right after the last backedge block.
Function::iterator InsertPos = BackedgeBlocks.back(); ++InsertPos;
F->getBasicBlockList().splice(InsertPos, F->getBasicBlockList(), BEBlock);
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 544e20b..4f5a70b 100644
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -518,7 +518,7 @@ void PromoteMem2Reg::run() {
// If this PHI node merges one value and/or undefs, get the value.
if (Value *V = PN->hasConstantValue(&DT)) {
- if (AST && isa<PointerType>(PN->getType()))
+ if (AST && PN->getType()->isPointerTy())
AST->deleteValue(PN);
PN->replaceAllUsesWith(V);
PN->eraseFromParent();
@@ -780,7 +780,7 @@ void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
if (ReplVal == LI)
ReplVal = UndefValue::get(LI->getType());
LI->replaceAllUsesWith(ReplVal);
- if (AST && isa<PointerType>(LI->getType()))
+ if (AST && LI->getType()->isPointerTy())
AST->deleteValue(LI);
LI->eraseFromParent();
LBI.deleteValue(LI);
@@ -838,7 +838,7 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;)
if (LoadInst *LI = dyn_cast<LoadInst>(*UI++)) {
LI->replaceAllUsesWith(UndefValue::get(LI->getType()));
- if (AST && isa<PointerType>(LI->getType()))
+ if (AST && LI->getType()->isPointerTy())
AST->deleteValue(LI);
LBI.deleteValue(LI);
LI->eraseFromParent();
@@ -874,7 +874,7 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
// Otherwise, there was a store before this load, the load takes its value.
--I;
LI->replaceAllUsesWith(I->second->getOperand(0));
- if (AST && isa<PointerType>(LI->getType()))
+ if (AST && LI->getType()->isPointerTy())
AST->deleteValue(LI);
LI->eraseFromParent();
LBI.deleteValue(LI);
@@ -922,7 +922,7 @@ bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo,
InsertedPHINodes.insert(PN);
- if (AST && isa<PointerType>(PN->getType()))
+ if (AST && PN->getType()->isPointerTy())
AST->copyValue(PointerAllocaValues[AllocaNo], PN);
return true;
@@ -996,7 +996,7 @@ NextIteration:
// Anything using the load now uses the current value.
LI->replaceAllUsesWith(V);
- if (AST && isa<PointerType>(LI->getType()))
+ if (AST && LI->getType()->isPointerTy())
AST->deleteValue(LI);
BB->getInstList().erase(LI);
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 795b6bf..f343c38 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -271,7 +271,7 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
ConstantInt *SimplifyCFGOpt::GetConstantInt(Value *V) {
// Normal constant int.
ConstantInt *CI = dyn_cast<ConstantInt>(V);
- if (CI || !TD || !isa<Constant>(V) || !isa<PointerType>(V->getType()))
+ if (CI || !TD || !isa<Constant>(V) || !V->getType()->isPointerTy())
return CI;
// This is some kind of pointer constant. Turn it into a pointer-sized
@@ -701,7 +701,7 @@ bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(TerminatorInst *TI) {
AddPredecessorToBlock(NewSuccessors[i], Pred, BB);
// Convert pointer to int before we switch.
- if (isa<PointerType>(CV->getType())) {
+ if (CV->getType()->isPointerTy()) {
assert(TD && "Cannot switch on pointer without TargetData");
CV = new PtrToIntInst(CV, TD->getIntPtrType(CV->getContext()),
"magicptr", PTI);
@@ -915,7 +915,7 @@ static bool SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *BB1) {
case Instruction::Add:
case Instruction::Sub:
// Not worth doing for vector ops.
- if (isa<VectorType>(HInst->getType()))
+ if (HInst->getType()->isVectorTy())
return false;
break;
case Instruction::And:
@@ -925,7 +925,7 @@ static bool SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *BB1) {
case Instruction::LShr:
case Instruction::AShr:
// Don't mess with vector operations.
- if (isa<VectorType>(HInst->getType()))
+ if (HInst->getType()->isVectorTy())
return false;
break; // These are all cheap and non-trapping instructions.
}
@@ -1077,7 +1077,7 @@ static bool FoldCondBranchOnPHI(BranchInst *BI) {
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
ConstantInt *CB;
if ((CB = dyn_cast<ConstantInt>(PN->getIncomingValue(i))) &&
- CB->getType()->isInteger(1)) {
+ CB->getType()->isIntegerTy(1)) {
// Okay, we now know that all edges from PredBB should be revectored to
// branch to RealDest.
BasicBlock *PredBB = PN->getIncomingBlock(i);
@@ -2068,7 +2068,7 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
if (!TrueWhenEqual) std::swap(DefaultBB, EdgeBB);
// Convert pointer to int before we switch.
- if (isa<PointerType>(CompVal->getType())) {
+ if (CompVal->getType()->isPointerTy()) {
assert(TD && "Cannot switch on pointer without TargetData");
CompVal = new PtrToIntInst(CompVal,
TD->getIntPtrType(CompVal->getContext()),
diff --git a/lib/VMCore/Android.mk b/lib/VMCore/Android.mk
new file mode 100644
index 0000000..4784684
--- /dev/null
+++ b/lib/VMCore/Android.mk
@@ -0,0 +1,61 @@
+LOCAL_PATH:= $(call my-dir)
+
+vmcore_SRC_FILES := \
+ AsmWriter.cpp \
+ Attributes.cpp \
+ AutoUpgrade.cpp \
+ BasicBlock.cpp \
+ ConstantFold.cpp \
+ Constants.cpp \
+ Core.cpp \
+ Dominators.cpp \
+ Function.cpp \
+ GVMaterializer.cpp \
+ Globals.cpp \
+ IRBuilder.cpp \
+ InlineAsm.cpp \
+ Instruction.cpp \
+ Instructions.cpp \
+ IntrinsicInst.cpp \
+ LLVMContext.cpp \
+ LeakDetector.cpp \
+ Metadata.cpp \
+ Module.cpp \
+ Pass.cpp \
+ PassManager.cpp \
+ PrintModulePass.cpp \
+ Type.cpp \
+ TypeSymbolTable.cpp \
+ Use.cpp \
+ Value.cpp \
+ ValueSymbolTable.cpp \
+ ValueTypes.cpp \
+ Verifier.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+REQUIRES_RTTI := 1
+
+LOCAL_SRC_FILES := $(vmcore_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMCore
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+REQUIRES_RTTI := 1
+
+LOCAL_SRC_FILES := $(vmcore_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMCore
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index ab5f45a..fd74241 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -17,6 +17,7 @@
#include "llvm/Assembly/Writer.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Assembly/AsmAnnotationWriter.h"
+#include "llvm/LLVMContext.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
@@ -239,6 +240,19 @@ void TypePrinting::CalcTypeName(const Type *Ty,
OS << '>';
break;
}
+ case Type::UnionTyID: {
+ const UnionType *UTy = cast<UnionType>(Ty);
+ OS << "union { ";
+ for (StructType::element_iterator I = UTy->element_begin(),
+ E = UTy->element_end(); I != E; ++I) {
+ CalcTypeName(*I, TypeStack, OS);
+ if (next(I) != UTy->element_end())
+ OS << ',';
+ OS << ' ';
+ }
+ OS << '}';
+ break;
+ }
case Type::PointerTyID: {
const PointerType *PTy = cast<PointerType>(Ty);
CalcTypeName(PTy->getElementType(), TypeStack, OS);
@@ -363,8 +377,8 @@ namespace {
return;
// If this is a structure or opaque type, add a name for the type.
- if (((isa<StructType>(Ty) && cast<StructType>(Ty)->getNumElements())
- || isa<OpaqueType>(Ty)) && !TP.hasTypeName(Ty)) {
+ if (((Ty->isStructTy() && cast<StructType>(Ty)->getNumElements())
+ || Ty->isOpaqueTy()) && !TP.hasTypeName(Ty)) {
TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size())));
NumberedTypes.push_back(Ty);
}
@@ -418,13 +432,13 @@ static void AddModuleTypesToPrinter(TypePrinting &TP,
// they are used too often to have a single useful name.
if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
const Type *PETy = PTy->getElementType();
- if ((PETy->isPrimitiveType() || PETy->isInteger()) &&
- !isa<OpaqueType>(PETy))
+ if ((PETy->isPrimitiveType() || PETy->isIntegerTy()) &&
+ !PETy->isOpaqueTy())
continue;
}
// Likewise don't insert primitives either.
- if (Ty->isInteger() || Ty->isPrimitiveType())
+ if (Ty->isIntegerTy() || Ty->isPrimitiveType())
continue;
// Get the name as a string and insert it into TypeNames.
@@ -836,7 +850,7 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
TypePrinting &TypePrinter, SlotTracker *Machine) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- if (CI->getType()->isInteger(1)) {
+ if (CI->getType()->isIntegerTy(1)) {
Out << (CI->getZExtValue() ? "true" : "false");
return;
}
@@ -1223,7 +1237,6 @@ class AssemblyWriter {
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter;
std::vector<const Type*> NumberedTypes;
- SmallVector<StringRef, 8> MDNames;
public:
inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
@@ -1231,8 +1244,6 @@ public:
AssemblyAnnotationWriter *AAW)
: Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M);
- if (M)
- M->getMDKindNames(MDNames);
}
void printMDNodeBody(const MDNode *MD);
@@ -1252,15 +1263,14 @@ public:
void printArgument(const Argument *FA, Attributes Attrs);
void printBasicBlock(const BasicBlock *BB);
void printInstruction(const Instruction &I);
-private:
+private:
// printInfoComment - Print a little comment after the instruction indicating
// which slot it occupies.
void printInfoComment(const Value &V);
};
} // end of anonymous namespace
-
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (Operand == 0) {
Out << "<null operand!>";
@@ -1689,11 +1699,15 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
}
-
/// printInfoComment - Print a little comment after the instruction indicating
/// which slot it occupies.
///
void AssemblyWriter::printInfoComment(const Value &V) {
+ if (AnnotationWriter) {
+ AnnotationWriter->printInfoComment(V, Out);
+ return;
+ }
+
if (V.getType()->isVoidTy()) return;
Out.PadToColumn(50);
@@ -1834,8 +1848,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
//
Out << ' ';
if (!FTy->isVarArg() &&
- (!isa<PointerType>(RetTy) ||
- !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
+ (!RetTy->isPointerTy() ||
+ !cast<PointerType>(RetTy)->getElementType()->isFunctionTy())) {
TypePrinter.print(RetTy, Out);
Out << ' ';
writeOperand(Operand, false);
@@ -1880,8 +1894,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
//
Out << ' ';
if (!FTy->isVarArg() &&
- (!isa<PointerType>(RetTy) ||
- !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
+ (!RetTy->isPointerTy() ||
+ !cast<PointerType>(RetTy)->getElementType()->isFunctionTy())) {
TypePrinter.print(RetTy, Out);
Out << ' ';
writeOperand(Operand, false);
@@ -1972,12 +1986,20 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
}
// Print Metadata info.
- if (!MDNames.empty()) {
- SmallVector<std::pair<unsigned, MDNode*>, 4> InstMD;
- I.getAllMetadata(InstMD);
- for (unsigned i = 0, e = InstMD.size(); i != e; ++i)
- Out << ", !" << MDNames[InstMD[i].first]
- << " !" << Machine.getMetadataSlot(InstMD[i].second);
+ SmallVector<std::pair<unsigned, MDNode*>, 4> InstMD;
+ I.getAllMetadata(InstMD);
+ if (!InstMD.empty()) {
+ SmallVector<StringRef, 8> MDNames;
+ I.getType()->getContext().getMDKindNames(MDNames);
+ for (unsigned i = 0, e = InstMD.size(); i != e; ++i) {
+ unsigned Kind = InstMD[i].first;
+ if (Kind < MDNames.size()) {
+ Out << ", !" << MDNames[Kind];
+ } else {
+ Out << ", !<unknown kind #" << Kind << ">";
+ }
+ Out << " !" << Machine.getMetadataSlot(InstMD[i].second);
+ }
}
printInfoComment(I);
}
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index a371c6f..a000aee 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -70,6 +70,11 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "noimplicitfloat ";
if (Attrs & Attribute::Naked)
Result += "naked ";
+ if (Attrs & Attribute::StackAlignment) {
+ Result += "alignstack(";
+ Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));
+ Result += ") ";
+ }
if (Attrs & Attribute::Alignment) {
Result += "align ";
Result += utostr(Attribute::getAlignmentFromAttrs(Attrs));
@@ -84,11 +89,11 @@ std::string Attribute::getAsString(Attributes Attrs) {
Attributes Attribute::typeIncompatible(const Type *Ty) {
Attributes Incompatible = None;
- if (!Ty->isInteger())
+ if (!Ty->isIntegerTy())
// Attributes that only apply to integers.
Incompatible |= SExt | ZExt;
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
// Attributes that only apply to pointers.
Incompatible |= ByVal | Nest | NoAlias | StructRet | NoCapture;
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 5c117d8..549977c 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -112,7 +112,7 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) {
IdxList.push_back(Zero);
} else if (const SequentialType *STy =
dyn_cast<SequentialType>(ElTy)) {
- if (isa<PointerType>(ElTy)) break; // Can't index into pointers!
+ if (ElTy->isPointerTy()) break; // Can't index into pointers!
ElTy = STy->getElementType();
IdxList.push_back(Zero);
} else {
@@ -155,12 +155,12 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) {
// Handle integral constant input.
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- if (DestTy->isInteger())
+ if (DestTy->isIntegerTy())
// Integral -> Integral. This is a no-op because the bit widths must
// be the same. Consequently, we just fold to V.
return V;
- if (DestTy->isFloatingPoint())
+ if (DestTy->isFloatingPointTy())
return ConstantFP::get(DestTy->getContext(),
APFloat(CI->getValue(),
!DestTy->isPPC_FP128Ty()));
@@ -189,7 +189,7 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) {
///
static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart,
unsigned ByteSize) {
- assert(isa<IntegerType>(C->getType()) &&
+ assert(C->getType()->isIntegerTy() &&
(cast<IntegerType>(C->getType())->getBitWidth() & 7) == 0 &&
"Non-byte sized integer input");
unsigned CSize = cast<IntegerType>(C->getType())->getBitWidth()/8;
@@ -334,11 +334,7 @@ static Constant *getFoldedSizeOf(const Type *Ty, const Type *DestTy,
Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
return ConstantExpr::getNUWMul(E, N);
}
- if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
- Constant *N = ConstantInt::get(DestTy, VTy->getNumElements());
- Constant *E = getFoldedSizeOf(VTy->getElementType(), DestTy, true);
- return ConstantExpr::getNUWMul(E, N);
- }
+
if (const StructType *STy = dyn_cast<StructType>(Ty))
if (!STy->isPacked()) {
unsigned NumElems = STy->getNumElements();
@@ -361,10 +357,26 @@ static Constant *getFoldedSizeOf(const Type *Ty, const Type *DestTy,
}
}
+ if (const UnionType *UTy = dyn_cast<UnionType>(Ty)) {
+ unsigned NumElems = UTy->getNumElements();
+ // Check for a union with all members having the same size.
+ Constant *MemberSize =
+ getFoldedSizeOf(UTy->getElementType(0), DestTy, true);
+ bool AllSame = true;
+ for (unsigned i = 1; i != NumElems; ++i)
+ if (MemberSize !=
+ getFoldedSizeOf(UTy->getElementType(i), DestTy, true)) {
+ AllSame = false;
+ break;
+ }
+ if (AllSame)
+ return MemberSize;
+ }
+
// Pointer size doesn't depend on the pointee type, so canonicalize them
// to an arbitrary pointee.
if (const PointerType *PTy = dyn_cast<PointerType>(Ty))
- if (!PTy->getElementType()->isInteger(1))
+ if (!PTy->getElementType()->isIntegerTy(1))
return
getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1),
PTy->getAddressSpace()),
@@ -426,10 +438,28 @@ static Constant *getFoldedAlignOf(const Type *Ty, const Type *DestTy,
return MemberAlign;
}
+ if (const UnionType *UTy = dyn_cast<UnionType>(Ty)) {
+ // Union alignment is the maximum alignment of any member.
+ // Without target data, we can't compare much, but we can check to see
+ // if all the members have the same alignment.
+ unsigned NumElems = UTy->getNumElements();
+ // Check for a union with all members having the same alignment.
+ Constant *MemberAlign =
+ getFoldedAlignOf(UTy->getElementType(0), DestTy, true);
+ bool AllSame = true;
+ for (unsigned i = 1; i != NumElems; ++i)
+ if (MemberAlign != getFoldedAlignOf(UTy->getElementType(i), DestTy, true)) {
+ AllSame = false;
+ break;
+ }
+ if (AllSame)
+ return MemberAlign;
+ }
+
// Pointer alignment doesn't depend on the pointee type, so canonicalize them
// to an arbitrary pointee.
if (const PointerType *PTy = dyn_cast<PointerType>(Ty))
- if (!PTy->getElementType()->isInteger(1))
+ if (!PTy->getElementType()->isIntegerTy(1))
return
getFoldedAlignOf(PointerType::get(IntegerType::get(PTy->getContext(),
1),
@@ -464,13 +494,7 @@ static Constant *getFoldedOffsetOf(const Type *Ty, Constant *FieldNo,
Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
return ConstantExpr::getNUWMul(E, N);
}
- if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
- Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo, false,
- DestTy, false),
- FieldNo, DestTy);
- Constant *E = getFoldedSizeOf(VTy->getElementType(), DestTy, true);
- return ConstantExpr::getNUWMul(E, N);
- }
+
if (const StructType *STy = dyn_cast<StructType>(Ty))
if (!STy->isPacked()) {
unsigned NumElems = STy->getNumElements();
@@ -551,7 +575,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
// operating on each element. In the cast of bitcasts, the element
// count may be mismatched; don't attempt to handle that here.
if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (isa<VectorType>(DestTy) &&
+ if (DestTy->isVectorTy() &&
cast<VectorType>(DestTy)->getNumElements() ==
CV->getType()->getNumElements()) {
std::vector<Constant*> res;
@@ -629,12 +653,12 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
ConstantInt *CI = cast<ConstantInt>(CE->getOperand(2));
if (CI->isOne() &&
STy->getNumElements() == 2 &&
- STy->getElementType(0)->isInteger(1)) {
+ STy->getElementType(0)->isIntegerTy(1)) {
return getFoldedAlignOf(STy->getElementType(1), DestTy, false);
}
}
// Handle an offsetof-like expression.
- if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)){
+ if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()){
if (Constant *C = getFoldedOffsetOf(Ty, CE->getOperand(2),
DestTy, false))
return C;
@@ -885,6 +909,8 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
unsigned numOps;
if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy))
numOps = AR->getNumElements();
+ else if (AggTy->isUnionTy())
+ numOps = 1;
else
numOps = cast<StructType>(AggTy)->getNumElements();
@@ -901,6 +927,10 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
if (const StructType* ST = dyn_cast<StructType>(AggTy))
return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
+ if (const UnionType* UT = dyn_cast<UnionType>(AggTy)) {
+ assert(Ops.size() == 1 && "Union can only contain a single value!");
+ return ConstantUnion::get(UT, Ops[0]);
+ }
return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
}
@@ -1099,6 +1129,10 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
return ConstantExpr::getLShr(C1, C2);
break;
}
+ } else if (isa<ConstantInt>(C1)) {
+ // If C1 is a ConstantInt and C2 is not, swap the operands.
+ if (Instruction::isCommutative(Opcode))
+ return ConstantExpr::get(Opcode, C2, C1);
}
// At this point we know neither constant is an UndefValue.
@@ -1358,35 +1392,12 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
} else if (isa<ConstantExpr>(C2)) {
// If C2 is a constant expr and C1 isn't, flop them around and fold the
// other way if possible.
- switch (Opcode) {
- case Instruction::Add:
- case Instruction::FAdd:
- case Instruction::Mul:
- case Instruction::FMul:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- // No change of opcode required.
+ if (Instruction::isCommutative(Opcode))
return ConstantFoldBinaryInstruction(Opcode, C2, C1);
-
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- case Instruction::Sub:
- case Instruction::FSub:
- case Instruction::SDiv:
- case Instruction::UDiv:
- case Instruction::FDiv:
- case Instruction::URem:
- case Instruction::SRem:
- case Instruction::FRem:
- default: // These instructions cannot be flopped around.
- break;
- }
}
// i1 can be simplified in many cases.
- if (C1->getType()->isInteger(1)) {
+ if (C1->getType()->isIntegerTy(1)) {
switch (Opcode) {
case Instruction::Add:
case Instruction::Sub:
@@ -1421,7 +1432,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
/// isZeroSizedType - This type is zero sized if its an array or structure of
/// zero sized types. The only leaf zero sized type is an empty structure.
static bool isMaybeZeroSizedType(const Type *Ty) {
- if (isa<OpaqueType>(Ty)) return true; // Can't say.
+ if (Ty->isOpaqueTy()) return true; // Can't say.
if (const StructType *STy = dyn_cast<StructType>(Ty)) {
// If all of elements have zero size, this does too.
@@ -1452,10 +1463,10 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) {
// Ok, we have two differing integer indices. Sign extend them to be the same
// type. Long is always big enough, so we use it.
- if (!C1->getType()->isInteger(64))
+ if (!C1->getType()->isIntegerTy(64))
C1 = ConstantExpr::getSExt(C1, Type::getInt64Ty(C1->getContext()));
- if (!C2->getType()->isInteger(64))
+ if (!C2->getType()->isIntegerTy(64))
C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(C1->getContext()));
if (C1 == C2) return 0; // They are equal
@@ -1661,7 +1672,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
// If the cast is not actually changing bits, and the second operand is a
// null pointer, do the comparison with the pre-casted value.
if (V2->isNullValue() &&
- (isa<PointerType>(CE1->getType()) || CE1->getType()->isInteger())) {
+ (CE1->getType()->isPointerTy() || CE1->getType()->isIntegerTy())) {
if (CE1->getOpcode() == Instruction::ZExt) isSigned = false;
if (CE1->getOpcode() == Instruction::SExt) isSigned = true;
return evaluateICmpRelation(CE1Op0,
@@ -1807,7 +1818,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
// Handle some degenerate cases first
if (isa<UndefValue>(C1) || isa<UndefValue>(C2))
- return UndefValue::get(ResultTy);
+ return ConstantInt::get(ResultTy, CmpInst::isTrueWhenEqual(pred));
// No compile-time operations on this type yet.
if (C1->getType()->isPPC_FP128Ty())
@@ -1836,7 +1847,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
}
// If the comparison is a comparison between two i1's, simplify it.
- if (C1->getType()->isInteger(1)) {
+ if (C1->getType()->isIntegerTy(1)) {
switch(pred) {
case ICmpInst::ICMP_EQ:
if (isa<ConstantInt>(C2))
@@ -1908,7 +1919,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
return ConstantInt::get(ResultTy, R==APFloat::cmpGreaterThan ||
R==APFloat::cmpEqual);
}
- } else if (isa<VectorType>(C1->getType())) {
+ } else if (C1->getType()->isVectorTy()) {
SmallVector<Constant*, 16> C1Elts, C2Elts;
C1->getVectorElements(C1Elts);
C2->getVectorElements(C2Elts);
@@ -1925,7 +1936,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
return ConstantVector::get(&ResElts[0], ResElts.size());
}
- if (C1->getType()->isFloatingPoint()) {
+ if (C1->getType()->isFloatingPointTy()) {
int Result = -1; // -1 = unknown, 0 = known false, 1 = known true.
switch (evaluateFCmpRelation(C1, C2)) {
default: llvm_unreachable("Unknown relation!");
@@ -2059,7 +2070,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
if (ConstantExpr *CE2 = dyn_cast<ConstantExpr>(C2)) {
Constant *CE2Op0 = CE2->getOperand(0);
if (CE2->getOpcode() == Instruction::BitCast &&
- isa<VectorType>(CE2->getType())==isa<VectorType>(CE2Op0->getType())) {
+ CE2->getType()->isVectorTy() == CE2Op0->getType()->isVectorTy()) {
Constant *Inverse = ConstantExpr::getBitCast(C1, CE2Op0->getType());
return ConstantExpr::getICmp(pred, Inverse, CE2Op0);
}
@@ -2067,8 +2078,8 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
// If the left hand side is an extension, try eliminating it.
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
- if (CE1->getOpcode() == Instruction::SExt ||
- CE1->getOpcode() == Instruction::ZExt) {
+ if ((CE1->getOpcode() == Instruction::SExt && ICmpInst::isSigned(pred)) ||
+ (CE1->getOpcode() == Instruction::ZExt && !ICmpInst::isSigned(pred))){
Constant *CE1Op0 = CE1->getOperand(0);
Constant *CE1Inverse = ConstantExpr::getTrunc(CE1, CE1Op0->getType());
if (CE1Inverse == CE1Op0) {
@@ -2086,27 +2097,8 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
// If C2 is a constant expr and C1 isn't, flip them around and fold the
// other way if possible.
// Also, if C1 is null and C2 isn't, flip them around.
- switch (pred) {
- case ICmpInst::ICMP_EQ:
- case ICmpInst::ICMP_NE:
- // No change of predicate required.
- return ConstantExpr::getICmp(pred, C2, C1);
-
- case ICmpInst::ICMP_ULT:
- case ICmpInst::ICMP_SLT:
- case ICmpInst::ICMP_UGT:
- case ICmpInst::ICMP_SGT:
- case ICmpInst::ICMP_ULE:
- case ICmpInst::ICMP_SLE:
- case ICmpInst::ICMP_UGE:
- case ICmpInst::ICMP_SGE:
- // Change the predicate as necessary to swap the operands.
- pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred);
- return ConstantExpr::getICmp(pred, C2, C1);
-
- default: // These predicates cannot be flopped around.
- break;
- }
+ pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred);
+ return ConstantExpr::getICmp(pred, C2, C1);
}
}
return 0;
@@ -2178,7 +2170,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
I != E; ++I)
LastTy = *I;
- if ((LastTy && isa<ArrayType>(LastTy)) || Idx0->isNullValue()) {
+ if ((LastTy && LastTy->isArrayTy()) || Idx0->isNullValue()) {
SmallVector<Value*, 16> NewIndices;
NewIndices.reserve(NumIdx + CE->getNumOperands());
for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i)
@@ -2260,10 +2252,10 @@ Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
// Before adding, extend both operands to i64 to avoid
// overflow trouble.
- if (!PrevIdx->getType()->isInteger(64))
+ if (!PrevIdx->getType()->isIntegerTy(64))
PrevIdx = ConstantExpr::getSExt(PrevIdx,
Type::getInt64Ty(Div->getContext()));
- if (!Div->getType()->isInteger(64))
+ if (!Div->getType()->isIntegerTy(64))
Div = ConstantExpr::getSExt(Div,
Type::getInt64Ty(Div->getContext()));
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 2250626..10f8879 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -229,7 +229,7 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
/// This handles breaking down a vector undef into undef elements, etc. For
/// constant exprs and other cases we can't handle, we return an empty vector.
void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const {
- assert(isa<VectorType>(getType()) && "Not a vector constant!");
+ assert(getType()->isVectorTy() && "Not a vector constant!");
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) {
for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i)
@@ -404,13 +404,13 @@ ConstantFP* ConstantFP::getNegativeZero(const Type* Ty) {
Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) {
if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
- if (PTy->getElementType()->isFloatingPoint()) {
+ if (PTy->getElementType()->isFloatingPointTy()) {
std::vector<Constant*> zeros(PTy->getNumElements(),
getNegativeZero(PTy->getElementType()));
return ConstantVector::get(PTy, zeros);
}
- if (Ty->isFloatingPoint())
+ if (Ty->isFloatingPointTy())
return getNegativeZero(Ty);
return Constant::getNullValue(Ty);
@@ -585,6 +585,27 @@ Constant* ConstantStruct::get(LLVMContext &Context,
return get(Context, std::vector<Constant*>(Vals, Vals+NumVals), Packed);
}
+ConstantUnion::ConstantUnion(const UnionType *T, Constant* V)
+ : Constant(T, ConstantUnionVal,
+ OperandTraits<ConstantUnion>::op_end(this) - 1, 1) {
+ Use *OL = OperandList;
+ assert(T->getElementTypeIndex(V->getType()) >= 0 &&
+ "Initializer for union element isn't a member of union type!");
+ *OL = V;
+}
+
+// ConstantUnion accessors.
+Constant* ConstantUnion::get(const UnionType* T, Constant* V) {
+ LLVMContextImpl* pImpl = T->getContext().pImpl;
+
+ // Create a ConstantAggregateZero value if all elements are zeros...
+ if (!V->isNullValue())
+ return pImpl->UnionConstants.getOrCreate(T, V);
+
+ return ConstantAggregateZero::get(T);
+}
+
+
ConstantVector::ConstantVector(const VectorType *T,
const std::vector<Constant*> &V)
: Constant(T, ConstantVectorVal,
@@ -640,13 +661,13 @@ Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) {
}
Constant* ConstantExpr::getNSWNeg(Constant* C) {
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
}
Constant* ConstantExpr::getNUWNeg(Constant* C) {
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
}
@@ -923,7 +944,7 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
// Factory Function Implementation
ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) {
- assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) &&
+ assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) &&
"Cannot create an aggregate zero of non-aggregate type!");
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
@@ -948,7 +969,7 @@ void ConstantArray::destroyConstant() {
/// if the elements of the array are all ConstantInt's.
bool ConstantArray::isString() const {
// Check the element type for i8...
- if (!getType()->getElementType()->isInteger(8))
+ if (!getType()->getElementType()->isIntegerTy(8))
return false;
// Check the elements to make sure they are all integers, not constant
// expressions.
@@ -963,7 +984,7 @@ bool ConstantArray::isString() const {
/// null bytes except its terminator.
bool ConstantArray::isCString() const {
// Check the element type for i8...
- if (!getType()->getElementType()->isInteger(8))
+ if (!getType()->getElementType()->isIntegerTy(8))
return false;
// Last element must be a null.
@@ -1010,6 +1031,13 @@ void ConstantStruct::destroyConstant() {
// destroyConstant - Remove the constant from the constant table...
//
+void ConstantUnion::destroyConstant() {
+ getType()->getContext().pImpl->UnionConstants.remove(this);
+ destroyConstantImpl();
+}
+
+// destroyConstant - Remove the constant from the constant table...
+//
void ConstantVector::destroyConstant() {
getType()->getContext().pImpl->VectorConstants.remove(this);
destroyConstantImpl();
@@ -1211,18 +1239,18 @@ Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
}
Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
- assert(isa<PointerType>(S->getType()) && "Invalid cast");
- assert((Ty->isInteger() || isa<PointerType>(Ty)) && "Invalid cast");
+ assert(S->getType()->isPointerTy() && "Invalid cast");
+ assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return getCast(Instruction::PtrToInt, S, Ty);
return getCast(Instruction::BitCast, S, Ty);
}
Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
bool isSigned) {
- assert(C->getType()->isIntOrIntVector() &&
- Ty->isIntOrIntVector() && "Invalid cast");
+ assert(C->getType()->isIntOrIntVectorTy() &&
+ Ty->isIntOrIntVectorTy() && "Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
@@ -1233,7 +1261,7 @@ Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
}
Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -1250,8 +1278,8 @@ Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "Trunc operand must be integer");
- assert(Ty->isIntOrIntVector() && "Trunc produces only integral");
+ assert(C->getType()->isIntOrIntVectorTy() && "Trunc operand must be integer");
+ assert(Ty->isIntOrIntVectorTy() && "Trunc produces only integral");
assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"SrcTy must be larger than DestTy for Trunc!");
@@ -1264,8 +1292,8 @@ Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "SExt operand must be integral");
- assert(Ty->isIntOrIntVector() && "SExt produces only integer");
+ assert(C->getType()->isIntOrIntVectorTy() && "SExt operand must be integral");
+ assert(Ty->isIntOrIntVectorTy() && "SExt produces only integer");
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for SExt!");
@@ -1278,8 +1306,8 @@ Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "ZEXt operand must be integral");
- assert(Ty->isIntOrIntVector() && "ZExt produces only integer");
+ assert(C->getType()->isIntOrIntVectorTy() && "ZEXt operand must be integral");
+ assert(Ty->isIntOrIntVectorTy() && "ZExt produces only integer");
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for ZExt!");
@@ -1292,7 +1320,7 @@ Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"This is an illegal floating point truncation!");
return getFoldedCast(Instruction::FPTrunc, C, Ty);
@@ -1304,7 +1332,7 @@ Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"This is an illegal floating point extension!");
return getFoldedCast(Instruction::FPExt, C, Ty);
@@ -1316,7 +1344,7 @@ Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
"This is an illegal uint to floating point cast!");
return getFoldedCast(Instruction::UIToFP, C, Ty);
}
@@ -1327,7 +1355,7 @@ Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
"This is an illegal sint to floating point cast!");
return getFoldedCast(Instruction::SIToFP, C, Ty);
}
@@ -1338,7 +1366,7 @@ Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
"This is an illegal floating point to uint cast!");
return getFoldedCast(Instruction::FPToUI, C, Ty);
}
@@ -1349,20 +1377,20 @@ Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
"This is an illegal floating point to sint cast!");
return getFoldedCast(Instruction::FPToSI, C, Ty);
}
Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) {
- assert(isa<PointerType>(C->getType()) && "PtrToInt source must be pointer");
- assert(DstTy->isInteger() && "PtrToInt destination must be integral");
+ assert(C->getType()->isPointerTy() && "PtrToInt source must be pointer");
+ assert(DstTy->isIntegerTy() && "PtrToInt destination must be integral");
return getFoldedCast(Instruction::PtrToInt, C, DstTy);
}
Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) {
- assert(C->getType()->isInteger() && "IntToPtr source must be integral");
- assert(isa<PointerType>(DstTy) && "IntToPtr destination must be a pointer");
+ assert(C->getType()->isIntegerTy() && "IntToPtr source must be integral");
+ assert(DstTy->isPointerTy() && "IntToPtr destination must be a pointer");
return getFoldedCast(Instruction::IntToPtr, C, DstTy);
}
@@ -1421,7 +1449,7 @@ Constant *ConstantExpr::getCompareTy(unsigned short predicate,
Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
unsigned Flags) {
// API compatibility: Adjust integer opcodes to floating-point opcodes.
- if (C1->getType()->isFPOrFPVector()) {
+ if (C1->getType()->isFPOrFPVectorTy()) {
if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
else if (Opcode == Instruction::Sub) Opcode = Instruction::FSub;
else if (Opcode == Instruction::Mul) Opcode = Instruction::FMul;
@@ -1432,51 +1460,51 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
case Instruction::Sub:
case Instruction::Mul:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an integer operation on a non-integer type!");
break;
case Instruction::FAdd:
case Instruction::FSub:
case Instruction::FMul:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create a floating-point operation on a "
"non-floating-point type!");
break;
case Instruction::UDiv:
case Instruction::SDiv:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::FDiv:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::URem:
case Instruction::SRem:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::FRem:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create a logical operation on a non-integral type!");
break;
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create a shift operation on a non-integer type!");
break;
default:
@@ -1564,7 +1592,7 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
(Constant**)Idxs, NumIdx))
return FC; // Fold a few common cases...
- assert(isa<PointerType>(C->getType()) &&
+ assert(C->getType()->isPointerTy() &&
"Non-pointer type for constant GetElementPtr expression");
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
@@ -1591,7 +1619,7 @@ Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy,
(Constant**)Idxs, NumIdx))
return FC; // Fold a few common cases...
- assert(isa<PointerType>(C->getType()) &&
+ assert(C->getType()->isPointerTy() &&
"Non-pointer type for constant GetElementPtr expression");
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
@@ -1699,9 +1727,9 @@ Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
}
Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
- assert(isa<VectorType>(Val->getType()) &&
+ assert(Val->getType()->isVectorTy() &&
"Tried to create extractelement operation on non-vector type!");
- assert(Idx->getType()->isInteger(32) &&
+ assert(Idx->getType()->isIntegerTy(32) &&
"Extractelement index must be i32 type!");
return getExtractElementTy(cast<VectorType>(Val->getType())->getElementType(),
Val, Idx);
@@ -1723,11 +1751,11 @@ Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
Constant *Idx) {
- assert(isa<VectorType>(Val->getType()) &&
+ assert(Val->getType()->isVectorTy() &&
"Tried to create insertelement operation on non-vector type!");
assert(Elt->getType() == cast<VectorType>(Val->getType())->getElementType()
&& "Insertelement types must match!");
- assert(Idx->getType()->isInteger(32) &&
+ assert(Idx->getType()->isIntegerTy(32) &&
"Insertelement index must be i32 type!");
return getInsertElementTy(Val->getType(), Val, Elt, Idx);
}
@@ -1811,9 +1839,9 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg,
Constant* ConstantExpr::getNeg(Constant* C) {
// API compatibility: Adjust integer opcodes to floating-point opcodes.
- if (C->getType()->isFPOrFPVector())
+ if (C->getType()->isFPOrFPVectorTy())
return getFNeg(C);
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return get(Instruction::Sub,
ConstantFP::getZeroValueForNegation(C->getType()),
@@ -1821,7 +1849,7 @@ Constant* ConstantExpr::getNeg(Constant* C) {
}
Constant* ConstantExpr::getFNeg(Constant* C) {
- assert(C->getType()->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() &&
"Cannot FNEG a non-floating-point value!");
return get(Instruction::FSub,
ConstantFP::getZeroValueForNegation(C->getType()),
@@ -1829,7 +1857,7 @@ Constant* ConstantExpr::getFNeg(Constant* C) {
}
Constant* ConstantExpr::getNot(Constant* C) {
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NOT a nonintegral value!");
return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()));
}
@@ -2083,6 +2111,56 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
destroyConstant();
}
+void ConstantUnion::replaceUsesOfWithOnConstant(Value *From, Value *To,
+ Use *U) {
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+ Constant *ToC = cast<Constant>(To);
+
+ assert(U == OperandList && "Union constants can only have one use!");
+ assert(getNumOperands() == 1 && "Union constants can only have one use!");
+ assert(getOperand(0) == From && "ReplaceAllUsesWith broken!");
+
+ std::pair<LLVMContextImpl::UnionConstantsTy::MapKey, ConstantUnion*> Lookup;
+ Lookup.first.first = getType();
+ Lookup.second = this;
+ Lookup.first.second = ToC;
+
+ LLVMContext &Context = getType()->getContext();
+ LLVMContextImpl *pImpl = Context.pImpl;
+
+ Constant *Replacement = 0;
+ if (ToC->isNullValue()) {
+ Replacement = ConstantAggregateZero::get(getType());
+ } else {
+ // Check to see if we have this union type already.
+ bool Exists;
+ LLVMContextImpl::UnionConstantsTy::MapTy::iterator I =
+ pImpl->UnionConstants.InsertOrGetItem(Lookup, Exists);
+
+ if (Exists) {
+ Replacement = I->second;
+ } else {
+ // Okay, the new shape doesn't exist in the system yet. Instead of
+ // creating a new constant union, inserting it, replaceallusesof'ing the
+ // old with the new, then deleting the old... just update the current one
+ // in place!
+ pImpl->UnionConstants.MoveConstantToNewSlot(this, I);
+
+ // Update to the new value.
+ setOperand(0, ToC);
+ return;
+ }
+ }
+
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement.
+ uncheckedReplaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}
+
void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h
index 08224e4..c798ba2 100644
--- a/lib/VMCore/ConstantsContext.h
+++ b/lib/VMCore/ConstantsContext.h
@@ -341,6 +341,13 @@ struct ConstantTraits< std::vector<T, Alloc> > {
}
};
+template<>
+struct ConstantTraits<Constant *> {
+ static unsigned uses(Constant * const & v) {
+ return 1;
+ }
+};
+
template<class ConstantClass, class TypeClass, class ValType>
struct ConstantCreator {
static ConstantClass *create(const TypeClass *Ty, const ValType &V) {
@@ -470,6 +477,14 @@ struct ConstantKeyData<ConstantStruct> {
}
};
+template<>
+struct ConstantKeyData<ConstantUnion> {
+ typedef Constant* ValType;
+ static ValType getValType(ConstantUnion *CU) {
+ return cast<Constant>(CU->getOperand(0));
+ }
+};
+
// ConstantPointerNull does not take extra "value" argument...
template<class ValType>
struct ConstantCreator<ConstantPointerNull, PointerType, ValType> {
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index 1755cd2..f4f65c5 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -55,6 +55,15 @@ void LLVMContextDispose(LLVMContextRef C) {
delete unwrap(C);
}
+unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name,
+ unsigned SLen) {
+ return unwrap(C)->getMDKindID(StringRef(Name, SLen));
+}
+
+unsigned LLVMGetMDKindID(const char* Name, unsigned SLen) {
+ return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen);
+}
+
/*===-- Operations on modules ---------------------------------------------===*/
@@ -141,6 +150,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
return LLVMFunctionTypeKind;
case Type::StructTyID:
return LLVMStructTypeKind;
+ case Type::UnionTyID:
+ return LLVMUnionTypeKind;
case Type::ArrayTyID:
return LLVMArrayTypeKind;
case Type::PointerTyID:
@@ -299,6 +310,35 @@ LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy) {
return unwrap<StructType>(StructTy)->isPacked();
}
+/*--.. Operations on union types ..........................................--*/
+
+LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
+ unsigned ElementCount) {
+ SmallVector<const Type*, 8> Tys;
+ for (LLVMTypeRef *I = ElementTypes,
+ *E = ElementTypes + ElementCount; I != E; ++I)
+ Tys.push_back(unwrap(*I));
+
+ return wrap(UnionType::get(&Tys[0], Tys.size()));
+}
+
+LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes,
+ unsigned ElementCount, int Packed) {
+ return LLVMUnionTypeInContext(LLVMGetGlobalContext(), ElementTypes,
+ ElementCount);
+}
+
+unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy) {
+ return unwrap<UnionType>(UnionTy)->getNumElements();
+}
+
+void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest) {
+ UnionType *Ty = unwrap<UnionType>(UnionTy);
+ for (FunctionType::param_iterator I = Ty->element_begin(),
+ E = Ty->element_end(); I != E; ++I)
+ *Dest++ = wrap(*I);
+}
+
/*--.. Operations on array, pointer, and vector types (sequence types) .....--*/
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount) {
@@ -394,6 +434,18 @@ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) {
unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal));
}
+int LLVMHasMetadata(LLVMValueRef Inst) {
+ return unwrap<Instruction>(Inst)->hasMetadata();
+}
+
+LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) {
+ return wrap(unwrap<Instruction>(Inst)->getMetadata(KindID));
+}
+
+void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) {
+ unwrap<Instruction>(Inst)->setMetadata(KindID, MD? unwrap<MDNode>(MD) : NULL);
+}
+
/*--.. Conversion functions ................................................--*/
#define LLVM_DEFINE_VALUE_CAST(name) \
@@ -404,7 +456,7 @@ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) {
LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST)
/*--.. Operations on Uses ..................................................--*/
-LLVMUseIteratorRef LLVMGetFirstUse(LLVMValueRef Val) {
+LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) {
Value *V = unwrap(Val);
Value::use_iterator I = V->use_begin();
if (I == V->use_end())
@@ -412,16 +464,19 @@ LLVMUseIteratorRef LLVMGetFirstUse(LLVMValueRef Val) {
return wrap(&(I.getUse()));
}
-LLVMUseIteratorRef LLVMGetNextUse(LLVMUseIteratorRef UR) {
- return wrap(unwrap(UR)->getNext());
+LLVMUseRef LLVMGetNextUse(LLVMUseRef U) {
+ Use *Next = unwrap(U)->getNext();
+ if (Next)
+ return wrap(Next);
+ return 0;
}
-LLVMValueRef LLVMGetUser(LLVMUseIteratorRef UR) {
- return wrap(unwrap(UR)->getUser());
+LLVMValueRef LLVMGetUser(LLVMUseRef U) {
+ return wrap(unwrap(U)->getUser());
}
-LLVMValueRef LLVMGetUsedValue(LLVMUseIteratorRef UR) {
- return wrap(unwrap(UR)->get());
+LLVMValueRef LLVMGetUsedValue(LLVMUseRef U) {
+ return wrap(unwrap(U)->get());
}
/*--.. Operations on Users .................................................--*/
@@ -462,6 +517,26 @@ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) {
wrap(ConstantPointerNull::get(unwrap<PointerType>(Ty)));
}
+/*--.. Operations on metadata nodes ........................................--*/
+
+LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
+ unsigned SLen) {
+ return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen)));
+}
+
+LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) {
+ return LLVMMDStringInContext(LLVMGetGlobalContext(), Str, SLen);
+}
+
+LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
+ unsigned Count) {
+ return wrap(MDNode::get(*unwrap(C), unwrap<Value>(Vals, Count), Count));
+}
+
+LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) {
+ return LLVMMDNodeInContext(LLVMGetGlobalContext(), Vals, Count);
+}
+
/*--.. Operations on scalar constants ......................................--*/
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
@@ -536,11 +611,13 @@ LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
return LLVMConstStructInContext(LLVMGetGlobalContext(), ConstantVals, Count,
Packed);
}
-
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) {
return wrap(ConstantVector::get(
unwrap<Constant>(ScalarConstantVals, Size), Size));
}
+LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val) {
+ return wrap(ConstantUnion::get(unwrap<UnionType>(Ty), unwrap<Constant>(Val)));
+}
/*--.. Constant expressions ................................................--*/
@@ -561,6 +638,17 @@ LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal) {
unwrap<Constant>(ConstantVal)));
}
+LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal) {
+ return wrap(ConstantExpr::getNSWNeg(
+ unwrap<Constant>(ConstantVal)));
+}
+
+LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal) {
+ return wrap(ConstantExpr::getNUWNeg(
+ unwrap<Constant>(ConstantVal)));
+}
+
+
LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal) {
return wrap(ConstantExpr::getFNeg(
unwrap<Constant>(ConstantVal)));
@@ -584,6 +672,13 @@ LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant,
unwrap<Constant>(RHSConstant)));
}
+LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant,
+ LLVMValueRef RHSConstant) {
+ return wrap(ConstantExpr::getNUWAdd(
+ unwrap<Constant>(LHSConstant),
+ unwrap<Constant>(RHSConstant)));
+}
+
LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getFAdd(
unwrap<Constant>(LHSConstant),
@@ -596,6 +691,20 @@ LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
unwrap<Constant>(RHSConstant)));
}
+LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant,
+ LLVMValueRef RHSConstant) {
+ return wrap(ConstantExpr::getNSWSub(
+ unwrap<Constant>(LHSConstant),
+ unwrap<Constant>(RHSConstant)));
+}
+
+LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant,
+ LLVMValueRef RHSConstant) {
+ return wrap(ConstantExpr::getNUWSub(
+ unwrap<Constant>(LHSConstant),
+ unwrap<Constant>(RHSConstant)));
+}
+
LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getFSub(unwrap<Constant>(LHSConstant),
unwrap<Constant>(RHSConstant)));
@@ -607,6 +716,20 @@ LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
unwrap<Constant>(RHSConstant)));
}
+LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant,
+ LLVMValueRef RHSConstant) {
+ return wrap(ConstantExpr::getNSWMul(
+ unwrap<Constant>(LHSConstant),
+ unwrap<Constant>(RHSConstant)));
+}
+
+LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant,
+ LLVMValueRef RHSConstant) {
+ return wrap(ConstantExpr::getNUWMul(
+ unwrap<Constant>(LHSConstant),
+ unwrap<Constant>(RHSConstant)));
+}
+
LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getFMul(
unwrap<Constant>(LHSConstant),
@@ -893,6 +1016,10 @@ LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString,
Constraints, HasSideEffects, IsAlignStack));
}
+LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB) {
+ return wrap(BlockAddress::get(unwrap<Function>(F), unwrap(BB)));
+}
+
/*--.. Operations on global variables, functions, and aliases (globals) ....--*/
LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global) {
@@ -1029,6 +1156,14 @@ LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) {
GlobalValue::ExternalLinkage, 0, Name));
}
+LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
+ const char *Name,
+ unsigned AddressSpace) {
+ return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false,
+ GlobalValue::ExternalLinkage, 0, Name, 0,
+ false, AddressSpace));
+}
+
LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) {
return wrap(unwrap(M)->getNamedGlobal(Name));
}
@@ -1184,14 +1319,14 @@ void LLVMSetGC(LLVMValueRef Fn, const char *GC) {
void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
Function *Func = unwrap<Function>(Fn);
const AttrListPtr PAL = Func->getAttributes();
- const AttrListPtr PALnew = PAL.addAttr(0, PA);
+ const AttrListPtr PALnew = PAL.addAttr(~0U, PA);
Func->setAttributes(PALnew);
}
void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
Function *Func = unwrap<Function>(Fn);
const AttrListPtr PAL = Func->getAttributes();
- const AttrListPtr PALnew = PAL.removeAttr(0, PA);
+ const AttrListPtr PALnew = PAL.removeAttr(~0U, PA);
Func->setAttributes(PALnew);
}
@@ -1532,6 +1667,21 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) {
delete unwrap(Builder);
}
+/*--.. Metadata builders ...................................................--*/
+
+void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) {
+ unwrap(Builder)->SetCurrentDebugLocation(L? unwrap<MDNode>(L) : NULL);
+}
+
+LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) {
+ return wrap(unwrap(Builder)->getCurrentDebugLocation());
+}
+
+void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) {
+ unwrap(Builder)->SetInstDebugLocation(unwrap<Instruction>(Inst));
+}
+
+
/*--.. Instruction builders ................................................--*/
LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef B) {
@@ -1561,6 +1711,11 @@ LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef B, LLVMValueRef V,
return wrap(unwrap(B)->CreateSwitch(unwrap(V), unwrap(Else), NumCases));
}
+LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
+ unsigned NumDests) {
+ return wrap(unwrap(B)->CreateIndirectBr(unwrap(Addr), NumDests));
+}
+
LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
@@ -1583,6 +1738,10 @@ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
unwrap<SwitchInst>(Switch)->addCase(unwrap<ConstantInt>(OnVal), unwrap(Dest));
}
+void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) {
+ unwrap<IndirectBrInst>(IndirectBr)->addDestination(unwrap(Dest));
+}
+
/*--.. Arithmetic ..........................................................--*/
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
@@ -1595,6 +1754,11 @@ LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RH
return wrap(unwrap(B)->CreateNSWAdd(unwrap(LHS), unwrap(RHS), Name));
}
+LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateNUWAdd(unwrap(LHS), unwrap(RHS), Name));
+}
+
LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name) {
return wrap(unwrap(B)->CreateFAdd(unwrap(LHS), unwrap(RHS), Name));
@@ -1605,6 +1769,16 @@ LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name));
}
+LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateNSWSub(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateNUWSub(unwrap(LHS), unwrap(RHS), Name));
+}
+
LLVMValueRef LLVMBuildFSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name) {
return wrap(unwrap(B)->CreateFSub(unwrap(LHS), unwrap(RHS), Name));
@@ -1615,6 +1789,16 @@ LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name));
}
+LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateNSWMul(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateNUWMul(unwrap(LHS), unwrap(RHS), Name));
+}
+
LLVMValueRef LLVMBuildFMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name) {
return wrap(unwrap(B)->CreateFMul(unwrap(LHS), unwrap(RHS), Name));
@@ -1685,10 +1869,27 @@ LLVMValueRef LLVMBuildXor(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
return wrap(unwrap(B)->CreateXor(unwrap(LHS), unwrap(RHS), Name));
}
+LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op,
+ LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateBinOp(Instruction::BinaryOps(Op), unwrap(LHS),
+ unwrap(RHS), Name));
+}
+
LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
return wrap(unwrap(B)->CreateNeg(unwrap(V), Name));
}
+LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateNSWNeg(unwrap(V), Name));
+}
+
+LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
+ const char *Name) {
+ return wrap(unwrap(B)->CreateNUWNeg(unwrap(V), Name));
+}
+
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
return wrap(unwrap(B)->CreateFNeg(unwrap(V), Name));
}
@@ -1856,6 +2057,12 @@ LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef B, LLVMValueRef Val,
Name));
}
+LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name) {
+ return wrap(unwrap(B)->CreateCast(Instruction::CastOps(Op), unwrap(Val),
+ unwrap(DestTy), Name));
+}
+
LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef B, LLVMValueRef Val,
LLVMTypeRef DestTy, const char *Name) {
return wrap(unwrap(B)->CreatePointerCast(unwrap(Val), unwrap(DestTy), Name));
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index f00f6ee..dbc283e 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -73,35 +73,35 @@ unsigned Argument::getArgNo() const {
/// hasByValAttr - Return true if this argument has the byval attribute on it
/// in its containing function.
bool Argument::hasByValAttr() const {
- if (!isa<PointerType>(getType())) return false;
+ if (!getType()->isPointerTy()) return false;
return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal);
}
/// hasNestAttr - Return true if this argument has the nest attribute on
/// it in its containing function.
bool Argument::hasNestAttr() const {
- if (!isa<PointerType>(getType())) return false;
+ if (!getType()->isPointerTy()) return false;
return getParent()->paramHasAttr(getArgNo()+1, Attribute::Nest);
}
/// hasNoAliasAttr - Return true if this argument has the noalias attribute on
/// it in its containing function.
bool Argument::hasNoAliasAttr() const {
- if (!isa<PointerType>(getType())) return false;
+ if (!getType()->isPointerTy()) return false;
return getParent()->paramHasAttr(getArgNo()+1, Attribute::NoAlias);
}
/// hasNoCaptureAttr - Return true if this argument has the nocapture attribute
/// on it in its containing function.
bool Argument::hasNoCaptureAttr() const {
- if (!isa<PointerType>(getType())) return false;
+ if (!getType()->isPointerTy()) return false;
return getParent()->paramHasAttr(getArgNo()+1, Attribute::NoCapture);
}
/// hasSRetAttr - Return true if this argument has the sret attribute on
/// it in its containing function.
bool Argument::hasStructRetAttr() const {
- if (!isa<PointerType>(getType())) return false;
+ if (!getType()->isPointerTy()) return false;
if (this != getParent()->arg_begin())
return false; // StructRet param must be first param
return getParent()->paramHasAttr(1, Attribute::StructRet);
@@ -155,7 +155,7 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
: GlobalValue(PointerType::getUnqual(Ty),
Value::FunctionVal, 0, 0, Linkage, name) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
- !isa<OpaqueType>(getReturnType()) && "invalid return type");
+ !getReturnType()->isOpaqueTy() && "invalid return type");
SymTab = new ValueSymbolTable();
// If the function has arguments, mark them as lazily built.
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index f149c44..489ec65 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -44,10 +44,10 @@ static bool removeDeadUsersOfConstant(const Constant *C) {
}
bool GlobalValue::isMaterializable() const {
- return getParent()->isMaterializable(this);
+ return getParent() && getParent()->isMaterializable(this);
}
bool GlobalValue::isDematerializable() const {
- return getParent()->isDematerializable(this);
+ return getParent() && getParent()->isDematerializable(this);
}
bool GlobalValue::Materialize(std::string *ErrInfo) {
return getParent()->Materialize(this, ErrInfo);
diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp
index 4bc3cbb..9f2786e 100644
--- a/lib/VMCore/IRBuilder.cpp
+++ b/lib/VMCore/IRBuilder.cpp
@@ -19,7 +19,7 @@
using namespace llvm;
/// CreateGlobalString - Make a new global variable with an initializer that
-/// has array of i8 type filled in the nul terminated string value
+/// has array of i8 type filled in with the nul terminated string value
/// specified. If Name is specified, it is the name of the global variable
/// created.
Value *IRBuilderBase::CreateGlobalString(const char *Str, const Twine &Name) {
diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp
index ec21773..6355834 100644
--- a/lib/VMCore/InlineAsm.cpp
+++ b/lib/VMCore/InlineAsm.cpp
@@ -220,7 +220,7 @@ bool InlineAsm::Verify(const FunctionType *Ty, StringRef ConstStr) {
if (!Ty->getReturnType()->isVoidTy()) return false;
break;
case 1:
- if (isa<StructType>(Ty->getReturnType())) return false;
+ if (Ty->getReturnType()->isStructTy()) return false;
break;
default:
const StructType *STy = dyn_cast<StructType>(Ty->getReturnType());
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 4ec8295..8f4763f 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -562,7 +562,7 @@ static Instruction* createFree(Value* Source, Instruction *InsertBefore,
BasicBlock *InsertAtEnd) {
assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) &&
"createFree needs either InsertBefore or InsertAtEnd");
- assert(isa<PointerType>(Source->getType()) &&
+ assert(Source->getType()->isPointerTy() &&
"Can not free something of nonpointer type!");
BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
@@ -787,7 +787,7 @@ BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const {
void BranchInst::AssertOK() {
if (isConditional())
- assert(getCondition()->getType()->isInteger(1) &&
+ assert(getCondition()->getType()->isIntegerTy(1) &&
"May only branch on boolean predicates!");
}
@@ -892,7 +892,7 @@ static Value *getAISize(LLVMContext &Context, Value *Amt) {
else {
assert(!isa<BasicBlock>(Amt) &&
"Passed basic block into allocation size parameter! Use other ctor");
- assert(Amt->getType()->isInteger(32) &&
+ assert(Amt->getType()->isIntegerTy(32) &&
"Allocation array size is not a 32-bit integer!");
}
return Amt;
@@ -989,7 +989,7 @@ bool AllocaInst::isStaticAlloca() const {
//===----------------------------------------------------------------------===//
void LoadInst::AssertOK() {
- assert(isa<PointerType>(getOperand(0)->getType()) &&
+ assert(getOperand(0)->getType()->isPointerTy() &&
"Ptr must have pointer type.");
}
@@ -1103,7 +1103,7 @@ void LoadInst::setAlignment(unsigned Align) {
void StoreInst::AssertOK() {
assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
- assert(isa<PointerType>(getOperand(1)->getType()) &&
+ assert(getOperand(1)->getType()->isPointerTy() &&
"Ptr must have pointer type!");
assert(getOperand(0)->getType() ==
cast<PointerType>(getOperand(1)->getType())->getElementType()
@@ -1285,7 +1285,7 @@ static const Type* getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs,
unsigned CurIdx = 1;
for (; CurIdx != NumIdx; ++CurIdx) {
const CompositeType *CT = dyn_cast<CompositeType>(Agg);
- if (!CT || isa<PointerType>(CT)) return 0;
+ if (!CT || CT->isPointerTy()) return 0;
IndexTy Index = Idxs[CurIdx];
if (!CT->indexValid(Index)) return 0;
Agg = CT->getTypeAtIndex(Index);
@@ -1391,7 +1391,7 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
- if (!isa<VectorType>(Val->getType()) || !Index->getType()->isInteger(32))
+ if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy(32))
return false;
return true;
}
@@ -1432,13 +1432,13 @@ InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt,
const Value *Index) {
- if (!isa<VectorType>(Vec->getType()))
+ if (!Vec->getType()->isVectorTy())
return false; // First operand of insertelement must be vector type.
if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType())
return false;// Second operand of insertelement must be vector element type.
- if (!Index->getType()->isInteger(32))
+ if (!Index->getType()->isIntegerTy(32))
return false; // Third operand of insertelement must be i32.
return true;
}
@@ -1485,12 +1485,12 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
const Value *Mask) {
- if (!isa<VectorType>(V1->getType()) || V1->getType() != V2->getType())
+ if (!V1->getType()->isVectorTy() || V1->getType() != V2->getType())
return false;
const VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType());
if (!isa<Constant>(Mask) || MaskTy == 0 ||
- !MaskTy->getElementType()->isInteger(32))
+ !MaskTy->getElementType()->isIntegerTy(32))
return false;
return true;
}
@@ -1602,7 +1602,7 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg,
unsigned CurIdx = 0;
for (; CurIdx != NumIdx; ++CurIdx) {
const CompositeType *CT = dyn_cast<CompositeType>(Agg);
- if (!CT || isa<PointerType>(CT) || isa<VectorType>(CT)) return 0;
+ if (!CT || CT->isPointerTy() || CT->isVectorTy()) return 0;
unsigned Index = Idxs[CurIdx];
if (!CT->indexValid(Index)) return 0;
Agg = CT->getTypeAtIndex(Index);
@@ -1632,7 +1632,7 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg,
static BinaryOperator::BinaryOps AdjustIType(BinaryOperator::BinaryOps iType,
const Type *Ty) {
// API compatibility: Adjust integer opcodes to floating-point opcodes.
- if (Ty->isFPOrFPVector()) {
+ if (Ty->isFPOrFPVectorTy()) {
if (iType == BinaryOperator::Add) iType = BinaryOperator::FAdd;
else if (iType == BinaryOperator::Sub) iType = BinaryOperator::FSub;
else if (iType == BinaryOperator::Mul) iType = BinaryOperator::FMul;
@@ -1678,14 +1678,14 @@ void BinaryOperator::init(BinaryOps iType) {
case Mul:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isIntOrIntVector() &&
+ assert(getType()->isIntOrIntVectorTy() &&
"Tried to create an integer operation on a non-integer type!");
break;
case FAdd: case FSub:
case FMul:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isFPOrFPVector() &&
+ assert(getType()->isFPOrFPVectorTy() &&
"Tried to create a floating-point operation on a "
"non-floating-point type!");
break;
@@ -1693,28 +1693,28 @@ void BinaryOperator::init(BinaryOps iType) {
case SDiv:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ assert((getType()->isIntegerTy() || (getType()->isVectorTy() &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Incorrect operand type (not integer) for S/UDIV");
break;
case FDiv:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isFPOrFPVector() &&
+ assert(getType()->isFPOrFPVectorTy() &&
"Incorrect operand type (not floating point) for FDIV");
break;
case URem:
case SRem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ assert((getType()->isIntegerTy() || (getType()->isVectorTy() &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Incorrect operand type (not integer) for S/UREM");
break;
case FRem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isFPOrFPVector() &&
+ assert(getType()->isFPOrFPVectorTy() &&
"Incorrect operand type (not floating point) for FREM");
break;
case Shl:
@@ -1722,18 +1722,18 @@ void BinaryOperator::init(BinaryOps iType) {
case AShr:
assert(getType() == LHS->getType() &&
"Shift operation should return same type as operands!");
- assert((getType()->isInteger() ||
- (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ assert((getType()->isIntegerTy() ||
+ (getType()->isVectorTy() &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Tried to create a shift operation on a non-integral type!");
break;
case And: case Or:
case Xor:
assert(getType() == LHS->getType() &&
"Logical operation should return same type as operands!");
- assert((getType()->isInteger() ||
- (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ assert((getType()->isIntegerTy() ||
+ (getType()->isVectorTy() &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Tried to create a logical operation on a non-integral type!");
break;
default:
@@ -1960,7 +1960,8 @@ bool CastInst::isIntegerCast() const {
case Instruction::Trunc:
return true;
case Instruction::BitCast:
- return getOperand(0)->getType()->isInteger() && getType()->isInteger();
+ return getOperand(0)->getType()->isIntegerTy() &&
+ getType()->isIntegerTy();
}
}
@@ -1976,8 +1977,8 @@ bool CastInst::isLosslessCast() const {
return true;
// Pointer to pointer is always lossless.
- if (isa<PointerType>(SrcTy))
- return isa<PointerType>(DstTy);
+ if (SrcTy->isPointerTy())
+ return DstTy->isPointerTy();
return false; // Other types have no identity values
}
@@ -2093,25 +2094,25 @@ unsigned CastInst::isEliminableCastPair(
// no-op cast in second op implies firstOp as long as the DestTy
// is integer and we are not converting between a vector and a
// non vector type.
- if (!isa<VectorType>(SrcTy) && DstTy->isInteger())
+ if (!SrcTy->isVectorTy() && DstTy->isIntegerTy())
return firstOp;
return 0;
case 4:
// no-op cast in second op implies firstOp as long as the DestTy
// is floating point.
- if (DstTy->isFloatingPoint())
+ if (DstTy->isFloatingPointTy())
return firstOp;
return 0;
case 5:
// no-op cast in first op implies secondOp as long as the SrcTy
// is an integer.
- if (SrcTy->isInteger())
+ if (SrcTy->isIntegerTy())
return secondOp;
return 0;
case 6:
// no-op cast in first op implies secondOp as long as the SrcTy
// is a floating point.
- if (SrcTy->isFloatingPoint())
+ if (SrcTy->isFloatingPointTy())
return secondOp;
return 0;
case 7: {
@@ -2147,12 +2148,12 @@ unsigned CastInst::isEliminableCastPair(
case 11:
// bitcast followed by ptrtoint is allowed as long as the bitcast
// is a pointer to pointer cast.
- if (isa<PointerType>(SrcTy) && isa<PointerType>(MidTy))
+ if (SrcTy->isPointerTy() && MidTy->isPointerTy())
return secondOp;
return 0;
case 12:
// inttoptr, bitcast -> intptr if bitcast is a ptr to ptr cast
- if (isa<PointerType>(MidTy) && isa<PointerType>(DstTy))
+ if (MidTy->isPointerTy() && DstTy->isPointerTy())
return firstOp;
return 0;
case 13: {
@@ -2273,11 +2274,11 @@ CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
const Twine &Name,
BasicBlock *InsertAtEnd) {
- assert(isa<PointerType>(S->getType()) && "Invalid cast");
- assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert(S->getType()->isPointerTy() && "Invalid cast");
+ assert((Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Invalid cast");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd);
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
}
@@ -2286,11 +2287,11 @@ CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
const Twine &Name,
Instruction *InsertBefore) {
- assert(isa<PointerType>(S->getType()) && "Invalid cast");
- assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert(S->getType()->isPointerTy() && "Invalid cast");
+ assert((Ty->isIntegerTy() || Ty->isPointerTy()) &&
"Invalid cast");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
}
@@ -2298,7 +2299,7 @@ CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
bool isSigned, const Twine &Name,
Instruction *InsertBefore) {
- assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
"Invalid integer cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2312,7 +2313,7 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
bool isSigned, const Twine &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2326,7 +2327,7 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const Twine &Name,
Instruction *InsertBefore) {
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2339,7 +2340,7 @@ CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const Twine &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2363,21 +2364,21 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
// Run through the possibilities ...
- if (DestTy->isInteger()) { // Casting to integral
- if (SrcTy->isInteger()) { // Casting from integral
+ if (DestTy->isIntegerTy()) { // Casting to integral
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
// Casting from vector
return DestBits == PTy->getBitWidth();
} else { // Casting from something else
- return isa<PointerType>(SrcTy);
+ return SrcTy->isPointerTy();
}
- } else if (DestTy->isFloatingPoint()) { // Casting to floating pt
- if (SrcTy->isInteger()) { // Casting from integral
+ } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
// Casting from vector
@@ -2393,10 +2394,10 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
} else { // Casting from something else
return DestPTy->getBitWidth() == SrcBits;
}
- } else if (isa<PointerType>(DestTy)) { // Casting to pointer
- if (isa<PointerType>(SrcTy)) { // Casting from pointer
+ } else if (DestTy->isPointerTy()) { // Casting to pointer
+ if (SrcTy->isPointerTy()) { // Casting from pointer
return true;
- } else if (SrcTy->isInteger()) { // Casting from integral
+ } else if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
} else { // Casting from something else
return false;
@@ -2425,8 +2426,8 @@ CastInst::getCastOpcode(
"Only first class types are castable!");
// Run through the possibilities ...
- if (DestTy->isInteger()) { // Casting to integral
- if (SrcTy->isInteger()) { // Casting from integral
+ if (DestTy->isIntegerTy()) { // Casting to integral
+ if (SrcTy->isIntegerTy()) { // Casting from integral
if (DestBits < SrcBits)
return Trunc; // int -> smaller int
else if (DestBits > SrcBits) { // its an extension
@@ -2437,7 +2438,7 @@ CastInst::getCastOpcode(
} else {
return BitCast; // Same size, No-op cast
}
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
if (DestIsSigned)
return FPToSI; // FP -> sint
else
@@ -2448,17 +2449,17 @@ CastInst::getCastOpcode(
PTy = NULL;
return BitCast; // Same size, no-op cast
} else {
- assert(isa<PointerType>(SrcTy) &&
+ assert(SrcTy->isPointerTy() &&
"Casting from a value that is not first-class type");
return PtrToInt; // ptr -> int
}
- } else if (DestTy->isFloatingPoint()) { // Casting to floating pt
- if (SrcTy->isInteger()) { // Casting from integral
+ } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
+ if (SrcTy->isIntegerTy()) { // Casting from integral
if (SrcIsSigned)
return SIToFP; // sint -> FP
else
return UIToFP; // uint -> FP
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
if (DestBits < SrcBits) {
return FPTrunc; // FP -> smaller FP
} else if (DestBits > SrcBits) {
@@ -2485,10 +2486,10 @@ CastInst::getCastOpcode(
} else {
assert(!"Illegal cast to vector (wrong type or size)");
}
- } else if (isa<PointerType>(DestTy)) {
- if (isa<PointerType>(SrcTy)) {
+ } else if (DestTy->isPointerTy()) {
+ if (SrcTy->isPointerTy()) {
return BitCast; // ptr -> ptr
- } else if (SrcTy->isInteger()) {
+ } else if (SrcTy->isIntegerTy()) {
return IntToPtr; // int -> ptr
} else {
assert(!"Casting pointer to other than pointer or int");
@@ -2528,50 +2529,50 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
switch (op) {
default: return false; // This is an input error
case Instruction::Trunc:
- return SrcTy->isIntOrIntVector() &&
- DstTy->isIntOrIntVector()&& SrcBitSize > DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() &&
+ DstTy->isIntOrIntVectorTy()&& SrcBitSize > DstBitSize;
case Instruction::ZExt:
- return SrcTy->isIntOrIntVector() &&
- DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() &&
+ DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
case Instruction::SExt:
- return SrcTy->isIntOrIntVector() &&
- DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() &&
+ DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
case Instruction::FPTrunc:
- return SrcTy->isFPOrFPVector() &&
- DstTy->isFPOrFPVector() &&
+ return SrcTy->isFPOrFPVectorTy() &&
+ DstTy->isFPOrFPVectorTy() &&
SrcBitSize > DstBitSize;
case Instruction::FPExt:
- return SrcTy->isFPOrFPVector() &&
- DstTy->isFPOrFPVector() &&
+ return SrcTy->isFPOrFPVectorTy() &&
+ DstTy->isFPOrFPVectorTy() &&
SrcBitSize < DstBitSize;
case Instruction::UIToFP:
case Instruction::SIToFP:
if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isIntOrIntVector() &&
- DVTy->getElementType()->isFPOrFPVector() &&
+ return SVTy->getElementType()->isIntOrIntVectorTy() &&
+ DVTy->getElementType()->isFPOrFPVectorTy() &&
SVTy->getNumElements() == DVTy->getNumElements();
}
}
- return SrcTy->isIntOrIntVector() && DstTy->isFPOrFPVector();
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy();
case Instruction::FPToUI:
case Instruction::FPToSI:
if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isFPOrFPVector() &&
- DVTy->getElementType()->isIntOrIntVector() &&
+ return SVTy->getElementType()->isFPOrFPVectorTy() &&
+ DVTy->getElementType()->isIntOrIntVectorTy() &&
SVTy->getNumElements() == DVTy->getNumElements();
}
}
- return SrcTy->isFPOrFPVector() && DstTy->isIntOrIntVector();
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy();
case Instruction::PtrToInt:
- return isa<PointerType>(SrcTy) && DstTy->isInteger();
+ return SrcTy->isPointerTy() && DstTy->isIntegerTy();
case Instruction::IntToPtr:
- return SrcTy->isInteger() && isa<PointerType>(DstTy);
+ return SrcTy->isIntegerTy() && DstTy->isPointerTy();
case Instruction::BitCast:
// BitCast implies a no-op cast of type only. No bits change.
// However, you can't cast pointers to anything but pointers.
- if (isa<PointerType>(SrcTy) != isa<PointerType>(DstTy))
+ if (SrcTy->isPointerTy() != DstTy->isPointerTy())
return false;
// Now we know we're not dealing with a pointer/non-pointer mismatch. In all
@@ -3149,7 +3150,7 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
//===----------------------------------------------------------------------===//
void IndirectBrInst::init(Value *Address, unsigned NumDests) {
- assert(Address && isa<PointerType>(Address->getType()) &&
+ assert(Address && Address->getType()->isPointerTy() &&
"Address of indirectbr must be a pointer");
ReservedSpace = 1+NumDests;
NumOperands = 1;
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index ccca789..9887f28 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -116,6 +116,10 @@ public:
ConstantStruct, true /*largekey*/> StructConstantsTy;
StructConstantsTy StructConstants;
+ typedef ConstantUniqueMap<Constant*, UnionType, ConstantUnion>
+ UnionConstantsTy;
+ UnionConstantsTy UnionConstants;
+
typedef ConstantUniqueMap<std::vector<Constant*>, VectorType,
ConstantVector> VectorConstantsTy;
VectorConstantsTy VectorConstants;
@@ -159,12 +163,16 @@ public:
TypeMap<PointerValType, PointerType> PointerTypes;
TypeMap<FunctionValType, FunctionType> FunctionTypes;
TypeMap<StructValType, StructType> StructTypes;
+ TypeMap<UnionValType, UnionType> UnionTypes;
TypeMap<IntegerValType, IntegerType> IntegerTypes;
// Opaque types are not structurally uniqued, so don't use TypeMap.
typedef SmallPtrSet<const OpaqueType*, 8> OpaqueTypesTy;
OpaqueTypesTy OpaqueTypes;
-
+
+ /// Used as an abstract type that will never be resolved.
+ OpaqueType *const AlwaysOpaqueTy;
+
/// ValueHandles - This map keeps track of all of the value handles that are
/// watching a Value*. The Value::HasValueHandle bit is used to know
@@ -196,7 +204,12 @@ public:
Int8Ty(C, 8),
Int16Ty(C, 16),
Int32Ty(C, 32),
- Int64Ty(C, 64) { }
+ Int64Ty(C, 64),
+ AlwaysOpaqueTy(new OpaqueType(C)) {
+ // Make sure the AlwaysOpaqueTy stays alive as long as the Context.
+ AlwaysOpaqueTy->addRef();
+ OpaqueTypes.insert(AlwaysOpaqueTy);
+ }
~LLVMContextImpl() {
ExprConstants.freeConstants();
@@ -216,12 +229,28 @@ public:
if (I->second->use_empty())
delete I->second;
}
- MDNodeSet.clear();
+ AlwaysOpaqueTy->dropRef();
for (OpaqueTypesTy::iterator I = OpaqueTypes.begin(), E = OpaqueTypes.end();
I != E; ++I) {
(*I)->AbstractTypeUsers.clear();
delete *I;
}
+ // Destroy MDNode operands first.
+ for (FoldingSetIterator<MDNode> I = MDNodeSet.begin(), E = MDNodeSet.end();
+ I != E;) {
+ MDNode *N = &(*I);
+ ++I;
+ N->replaceAllOperandsWithNull();
+ }
+ while (!MDNodeSet.empty()) {
+ MDNode *N = &(*MDNodeSet.begin());
+ N->destroy();
+ }
+ // Destroy MDStrings.
+ for (StringMap<MDString*>::iterator I = MDStringCache.begin(),
+ E = MDStringCache.end(); I != E; ++I) {
+ delete I->second;
+ }
}
};
diff --git a/lib/VMCore/Makefile b/lib/VMCore/Makefile
index bc5e77d..4395ecf 100644
--- a/lib/VMCore/Makefile
+++ b/lib/VMCore/Makefile
@@ -30,5 +30,5 @@ $(GENFILE): $(ObjDir)/Intrinsics.gen.tmp
changed significantly. )
install-local:: $(GENFILE)
- $(Echo) Installing $(PROJ_includedir)/llvm/Intrinsics.gen
- $(Verb) $(DataInstall) $(GENFILE) $(PROJ_includedir)/llvm/Intrinsics.gen
+ $(Echo) Installing $(DESTDIR)$(PROJ_includedir)/llvm/Intrinsics.gen
+ $(Verb) $(DataInstall) $(GENFILE) $(DESTDIR)$(PROJ_includedir)/llvm/Intrinsics.gen
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index 07a5f3c..a08c454 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -257,6 +257,13 @@ void MDNode::Profile(FoldingSetNodeID &ID) const {
ID.AddPointer(getOperand(i));
}
+// replaceAllOperandsWithNull - This is used while destroying llvm context to
+// gracefully delete all nodes. This method replaces all operands with null.
+void MDNode::replaceAllOperandsWithNull() {
+ for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
+ Op != E; ++Op)
+ replaceOperand(Op, 0);
+}
// Replace value from this node's operand list.
void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
index 2b0b235..a782e5a 100644
--- a/lib/VMCore/Pass.cpp
+++ b/lib/VMCore/Pass.cpp
@@ -194,6 +194,9 @@ PassManagerType BasicBlockPass::getPotentialPassManagerType() const {
//
namespace {
class PassRegistrar {
+ /// Guards the contents of this class.
+ mutable sys::SmartMutex<true> Lock;
+
/// PassInfoMap - Keep track of the passinfo object for each registered llvm
/// pass.
typedef std::map<intptr_t, const PassInfo*> MapType;
@@ -213,16 +216,19 @@ class PassRegistrar {
public:
const PassInfo *GetPassInfo(intptr_t TI) const {
+ sys::SmartScopedLock<true> Guard(Lock);
MapType::const_iterator I = PassInfoMap.find(TI);
return I != PassInfoMap.end() ? I->second : 0;
}
const PassInfo *GetPassInfo(StringRef Arg) const {
+ sys::SmartScopedLock<true> Guard(Lock);
StringMapType::const_iterator I = PassInfoStringMap.find(Arg);
return I != PassInfoStringMap.end() ? I->second : 0;
}
void RegisterPass(const PassInfo &PI) {
+ sys::SmartScopedLock<true> Guard(Lock);
bool Inserted =
PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted;
@@ -230,6 +236,7 @@ public:
}
void UnregisterPass(const PassInfo &PI) {
+ sys::SmartScopedLock<true> Guard(Lock);
MapType::iterator I = PassInfoMap.find(PI.getTypeInfo());
assert(I != PassInfoMap.end() && "Pass registered but not in map!");
@@ -239,6 +246,7 @@ public:
}
void EnumerateWith(PassRegistrationListener *L) {
+ sys::SmartScopedLock<true> Guard(Lock);
for (MapType::const_iterator I = PassInfoMap.begin(),
E = PassInfoMap.end(); I != E; ++I)
L->passEnumerate(I->second);
@@ -249,6 +257,7 @@ public:
void RegisterAnalysisGroup(PassInfo *InterfaceInfo,
const PassInfo *ImplementationInfo,
bool isDefault) {
+ sys::SmartScopedLock<true> Guard(Lock);
AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo];
assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
"Cannot add a pass to the same analysis group more than once!");
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index a1d554e..c4dfe14 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -1118,6 +1118,7 @@ bool BBPassManager::runOnFunction(Function &F) {
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
BasicBlockPass *BP = getContainedPass(Index);
+ bool LocalChanged = false;
dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName());
dumpRequiredSet(BP);
@@ -1129,11 +1130,12 @@ bool BBPassManager::runOnFunction(Function &F) {
PassManagerPrettyStackEntry X(BP, *I);
Timer *T = StartPassTimer(BP);
- Changed |= BP->runOnBasicBlock(*I);
+ LocalChanged |= BP->runOnBasicBlock(*I);
StopPassTimer(BP, T);
}
- if (Changed)
+ Changed |= LocalChanged;
+ if (LocalChanged)
dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
I->getName());
dumpPreservedSet(BP);
@@ -1220,9 +1222,11 @@ void FunctionPassManager::add(Pass *P) {
/// so, return true.
///
bool FunctionPassManager::run(Function &F) {
- std::string errstr;
- if (F.Materialize(&errstr)) {
- llvm_report_error("Error reading bitcode file: " + errstr);
+ if (F.isMaterializable()) {
+ std::string errstr;
+ if (F.Materialize(&errstr)) {
+ llvm_report_error("Error reading bitcode file: " + errstr);
+ }
}
return FPM->run(F);
}
@@ -1332,6 +1336,7 @@ bool FPPassManager::runOnFunction(Function &F) {
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
FunctionPass *FP = getContainedPass(Index);
+ bool LocalChanged = false;
dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName());
dumpRequiredSet(FP);
@@ -1342,11 +1347,12 @@ bool FPPassManager::runOnFunction(Function &F) {
PassManagerPrettyStackEntry X(FP, F);
Timer *T = StartPassTimer(FP);
- Changed |= FP->runOnFunction(F);
+ LocalChanged |= FP->runOnFunction(F);
StopPassTimer(FP, T);
}
- if (Changed)
+ Changed |= LocalChanged;
+ if (LocalChanged)
dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
dumpPreservedSet(FP);
@@ -1405,6 +1411,7 @@ MPPassManager::runOnModule(Module &M) {
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
ModulePass *MP = getContainedPass(Index);
+ bool LocalChanged = false;
dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier());
dumpRequiredSet(MP);
@@ -1414,11 +1421,12 @@ MPPassManager::runOnModule(Module &M) {
{
PassManagerPrettyStackEntry X(MP, M);
Timer *T = StartPassTimer(MP);
- Changed |= MP->runOnModule(M);
+ LocalChanged |= MP->runOnModule(M);
StopPassTimer(MP, T);
}
- if (Changed)
+ Changed |= LocalChanged;
+ if (LocalChanged)
dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
M.getModuleIdentifier());
dumpPreservedSet(MP);
@@ -1704,8 +1712,13 @@ LLVMPassManagerRef LLVMCreatePassManager() {
return wrap(new PassManager());
}
+LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M) {
+ return wrap(new FunctionPassManager(unwrap(M)));
+}
+
LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) {
- return wrap(new FunctionPassManager(unwrap(P)));
+ return LLVMCreateFunctionPassManagerForModule(
+ reinterpret_cast<LLVMModuleRef>(P));
}
LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 044de4f..9b2c2ca 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -50,8 +50,8 @@ void AbstractTypeUser::setType(Value *V, const Type *NewTy) {
/// Because of the way Type subclasses are allocated, this function is necessary
/// to use the correct kind of "delete" operator to deallocate the Type object.
-/// Some type objects (FunctionTy, StructTy) allocate additional space after
-/// the space for their derived type to hold the contained types array of
+/// Some type objects (FunctionTy, StructTy, UnionTy) allocate additional space
+/// after the space for their derived type to hold the contained types array of
/// PATypeHandles. Using this allocation scheme means all the PATypeHandles are
/// allocated with the type object, decreasing allocations and eliminating the
/// need for a std::vector to be used in the Type class itself.
@@ -61,7 +61,8 @@ void Type::destroy() const {
// Structures and Functions allocate their contained types past the end of
// the type object itself. These need to be destroyed differently than the
// other types.
- if (isa<FunctionType>(this) || isa<StructType>(this)) {
+ if (this->isFunctionTy() || this->isStructTy() ||
+ this->isUnionTy()) {
// First, make sure we destruct any PATypeHandles allocated by these
// subclasses. They must be manually destructed.
for (unsigned i = 0; i < NumContainedTys; ++i)
@@ -69,10 +70,12 @@ void Type::destroy() const {
// Now call the destructor for the subclass directly because we're going
// to delete this as an array of char.
- if (isa<FunctionType>(this))
+ if (this->isFunctionTy())
static_cast<const FunctionType*>(this)->FunctionType::~FunctionType();
- else
+ else if (this->isStructTy())
static_cast<const StructType*>(this)->StructType::~StructType();
+ else
+ static_cast<const UnionType*>(this)->UnionType::~UnionType();
// Finally, remove the memory as an array deallocation of the chars it was
// constructed from.
@@ -124,32 +127,32 @@ const Type *Type::getScalarType() const {
return this;
}
-/// isInteger - Return true if this is an IntegerType of the specified width.
-bool Type::isInteger(unsigned Bitwidth) const {
- return isInteger() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
+/// isIntegerTy - Return true if this is an IntegerType of the specified width.
+bool Type::isIntegerTy(unsigned Bitwidth) const {
+ return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
}
-/// isIntOrIntVector - Return true if this is an integer type or a vector of
+/// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
/// integer types.
///
-bool Type::isIntOrIntVector() const {
- if (isInteger())
+bool Type::isIntOrIntVectorTy() const {
+ if (isIntegerTy())
return true;
if (ID != Type::VectorTyID) return false;
- return cast<VectorType>(this)->getElementType()->isInteger();
+ return cast<VectorType>(this)->getElementType()->isIntegerTy();
}
-/// isFPOrFPVector - Return true if this is a FP type or a vector of FP types.
+/// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP types.
///
-bool Type::isFPOrFPVector() const {
+bool Type::isFPOrFPVectorTy() const {
if (ID == Type::FloatTyID || ID == Type::DoubleTyID ||
ID == Type::FP128TyID || ID == Type::X86_FP80TyID ||
ID == Type::PPC_FP128TyID)
return true;
if (ID != Type::VectorTyID) return false;
- return cast<VectorType>(this)->getElementType()->isFloatingPoint();
+ return cast<VectorType>(this)->getElementType()->isFloatingPointTy();
}
// canLosslesslyBitCastTo - Return true if this type can be converted to
@@ -173,8 +176,8 @@ bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
// At this point we have only various mismatches of the first class types
// remaining and ptr->ptr. Just select the lossless conversions. Everything
// else is not lossless.
- if (isa<PointerType>(this))
- return isa<PointerType>(Ty);
+ if (this->isPointerTy())
+ return Ty->isPointerTy();
return false; // Other types have no identity values
}
@@ -204,7 +207,7 @@ unsigned Type::getScalarSizeInBits() const {
int Type::getFPMantissaWidth() const {
if (const VectorType *VTy = dyn_cast<VectorType>(this))
return VTy->getElementType()->getFPMantissaWidth();
- assert(isFloatingPoint() && "Not a floating point type!");
+ assert(isFloatingPointTy() && "Not a floating point type!");
if (ID == FloatTyID) return 24;
if (ID == DoubleTyID) return 53;
if (ID == X86_FP80TyID) return 64;
@@ -217,7 +220,7 @@ int Type::getFPMantissaWidth() const {
/// iff all of the members of the type are sized as well. Since asking for
/// their size is relatively uncommon, move this operation out of line.
bool Type::isSizedDerivedType() const {
- if (isa<IntegerType>(this))
+ if (this->isIntegerTy())
return true;
if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
@@ -226,7 +229,7 @@ bool Type::isSizedDerivedType() const {
if (const VectorType *PTy = dyn_cast<VectorType>(this))
return PTy->getElementType()->isSized();
- if (!isa<StructType>(this))
+ if (!this->isStructTy() && !this->isUnionTy())
return false;
// Okay, our struct is sized if all of the elements are...
@@ -285,7 +288,7 @@ std::string Type::getDescription() const {
bool StructType::indexValid(const Value *V) const {
// Structure indexes require 32-bit integer constants.
- if (V->getType()->isInteger(32))
+ if (V->getType()->isIntegerTy(32))
if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
return indexValid(CU->getZExtValue());
return false;
@@ -308,6 +311,32 @@ const Type *StructType::getTypeAtIndex(unsigned Idx) const {
return ContainedTys[Idx];
}
+
+bool UnionType::indexValid(const Value *V) const {
+ // Union indexes require 32-bit integer constants.
+ if (V->getType()->isIntegerTy(32))
+ if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
+ return indexValid(CU->getZExtValue());
+ return false;
+}
+
+bool UnionType::indexValid(unsigned V) const {
+ return V < NumContainedTys;
+}
+
+// getTypeAtIndex - Given an index value into the type, return the type of the
+// element. For a structure type, this must be a constant value...
+//
+const Type *UnionType::getTypeAtIndex(const Value *V) const {
+ unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
+ return getTypeAtIndex(Idx);
+}
+
+const Type *UnionType::getTypeAtIndex(unsigned Idx) const {
+ assert(indexValid(Idx) && "Invalid structure index!");
+ return ContainedTys[Idx];
+}
+
//===----------------------------------------------------------------------===//
// Primitive 'Type' data
//===----------------------------------------------------------------------===//
@@ -418,7 +447,7 @@ bool FunctionType::isValidReturnType(const Type *RetTy) {
/// isValidArgumentType - Return true if the specified type is valid as an
/// argument type.
bool FunctionType::isValidArgumentType(const Type *ArgTy) {
- return ArgTy->isFirstClassType() || isa<OpaqueType>(ArgTy);
+ return ArgTy->isFirstClassType() || ArgTy->isOpaqueTy();
}
FunctionType::FunctionType(const Type *Result,
@@ -463,6 +492,23 @@ StructType::StructType(LLVMContext &C,
setAbstract(isAbstract);
}
+UnionType::UnionType(LLVMContext &C,const Type* const* Types, unsigned NumTypes)
+ : CompositeType(C, UnionTyID) {
+ ContainedTys = reinterpret_cast<PATypeHandle*>(this + 1);
+ NumContainedTys = NumTypes;
+ bool isAbstract = false;
+ for (unsigned i = 0; i < NumTypes; ++i) {
+ assert(Types[i] && "<null> type for union field!");
+ assert(isValidElementType(Types[i]) &&
+ "Invalid type for union element!");
+ new (&ContainedTys[i]) PATypeHandle(Types[i], this);
+ isAbstract |= Types[i]->isAbstract();
+ }
+
+ // Calculate whether or not this type is abstract
+ setAbstract(isAbstract);
+}
+
ArrayType::ArrayType(const Type *ElType, uint64_t NumEl)
: SequentialType(ArrayTyID, ElType) {
NumElements = NumEl;
@@ -507,30 +553,7 @@ void DerivedType::dropAllTypeUses() {
if (NumContainedTys != 0) {
// The type must stay abstract. To do this, we insert a pointer to a type
// that will never get resolved, thus will always be abstract.
- static Type *AlwaysOpaqueTy = 0;
- static PATypeHolder* Holder = 0;
- Type *tmp = AlwaysOpaqueTy;
- if (llvm_is_multithreaded()) {
- sys::MemoryFence();
- if (!tmp) {
- llvm_acquire_global_lock();
- tmp = AlwaysOpaqueTy;
- if (!tmp) {
- tmp = OpaqueType::get(getContext());
- PATypeHolder* tmp2 = new PATypeHolder(tmp);
- sys::MemoryFence();
- AlwaysOpaqueTy = tmp;
- Holder = tmp2;
- }
-
- llvm_release_global_lock();
- }
- } else if (!AlwaysOpaqueTy) {
- AlwaysOpaqueTy = OpaqueType::get(getContext());
- Holder = new PATypeHolder(AlwaysOpaqueTy);
- }
-
- ContainedTys[0] = AlwaysOpaqueTy;
+ ContainedTys[0] = getContext().pImpl->AlwaysOpaqueTy;
// Change the rest of the types to be Int32Ty's. It doesn't matter what we
// pick so long as it doesn't point back to this type. We choose something
@@ -590,7 +613,7 @@ void Type::PromoteAbstractToConcrete() {
// Concrete types are leaves in the tree. Since an SCC will either be all
// abstract or all concrete, we only need to check one type.
if (SCC[0]->isAbstract()) {
- if (isa<OpaqueType>(SCC[0]))
+ if (SCC[0]->isOpaqueTy())
return; // Not going to be concrete, sorry.
// If all of the children of all of the types in this SCC are concrete,
@@ -637,7 +660,7 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
std::map<const Type *, const Type *> &EqTypes) {
if (Ty == Ty2) return true;
if (Ty->getTypeID() != Ty2->getTypeID()) return false;
- if (isa<OpaqueType>(Ty))
+ if (Ty->isOpaqueTy())
return false; // Two unequal opaque types are never equal
std::map<const Type*, const Type*>::iterator It = EqTypes.find(Ty);
@@ -667,6 +690,13 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes))
return false;
return true;
+ } else if (const UnionType *UTy = dyn_cast<UnionType>(Ty)) {
+ const UnionType *UTy2 = cast<UnionType>(Ty2);
+ if (UTy->getNumElements() != UTy2->getNumElements()) return false;
+ for (unsigned i = 0, e = UTy2->getNumElements(); i != e; ++i)
+ if (!TypesEqual(UTy->getElementType(i), UTy2->getElementType(i), EqTypes))
+ return false;
+ return true;
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
const ArrayType *ATy2 = cast<ArrayType>(Ty2);
return ATy->getNumElements() == ATy2->getNumElements() &&
@@ -858,7 +888,7 @@ ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) {
bool ArrayType::isValidElementType(const Type *ElemTy) {
return ElemTy->getTypeID() != VoidTyID && ElemTy->getTypeID() != LabelTyID &&
- ElemTy->getTypeID() != MetadataTyID && !isa<FunctionType>(ElemTy);
+ ElemTy->getTypeID() != MetadataTyID && !ElemTy->isFunctionTy();
}
VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) {
@@ -881,8 +911,8 @@ VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) {
}
bool VectorType::isValidElementType(const Type *ElemTy) {
- return ElemTy->isInteger() || ElemTy->isFloatingPoint() ||
- isa<OpaqueType>(ElemTy);
+ return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
+ ElemTy->isOpaqueTy();
}
//===----------------------------------------------------------------------===//
@@ -924,12 +954,66 @@ StructType *StructType::get(LLVMContext &Context, const Type *type, ...) {
}
bool StructType::isValidElementType(const Type *ElemTy) {
- return ElemTy->getTypeID() != VoidTyID && ElemTy->getTypeID() != LabelTyID &&
- ElemTy->getTypeID() != MetadataTyID && !isa<FunctionType>(ElemTy);
+ return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
+ !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
}
//===----------------------------------------------------------------------===//
+// Union Type Factory...
+//
+
+UnionType *UnionType::get(const Type* const* Types, unsigned NumTypes) {
+ assert(NumTypes > 0 && "union must have at least one member type!");
+ UnionValType UTV(Types, NumTypes);
+ UnionType *UT = 0;
+
+ LLVMContextImpl *pImpl = Types[0]->getContext().pImpl;
+
+ UT = pImpl->UnionTypes.get(UTV);
+
+ if (!UT) {
+ // Value not found. Derive a new type!
+ UT = (UnionType*) operator new(sizeof(UnionType) +
+ sizeof(PATypeHandle) * NumTypes);
+ new (UT) UnionType(Types[0]->getContext(), Types, NumTypes);
+ pImpl->UnionTypes.add(UTV, UT);
+ }
+#ifdef DEBUG_MERGE_TYPES
+ DEBUG(dbgs() << "Derived new type: " << *UT << "\n");
+#endif
+ return UT;
+}
+
+UnionType *UnionType::get(const Type *type, ...) {
+ va_list ap;
+ SmallVector<const llvm::Type*, 8> UnionFields;
+ va_start(ap, type);
+ while (type) {
+ UnionFields.push_back(type);
+ type = va_arg(ap, llvm::Type*);
+ }
+ unsigned NumTypes = UnionFields.size();
+ assert(NumTypes > 0 && "union must have at least one member type!");
+ return llvm::UnionType::get(&UnionFields[0], NumTypes);
+}
+
+bool UnionType::isValidElementType(const Type *ElemTy) {
+ return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
+ !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
+}
+
+int UnionType::getElementTypeIndex(const Type *ElemTy) const {
+ int index = 0;
+ for (UnionType::element_iterator I = element_begin(), E = element_end();
+ I != E; ++I, ++index) {
+ if (ElemTy == *I) return index;
+ }
+
+ return -1;
+}
+
+//===----------------------------------------------------------------------===//
// Pointer Type Factory...
//
@@ -1192,6 +1276,21 @@ void StructType::typeBecameConcrete(const DerivedType *AbsTy) {
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
+void UnionType::refineAbstractType(const DerivedType *OldType,
+ const Type *NewType) {
+ LLVMContextImpl *pImpl = OldType->getContext().pImpl;
+ pImpl->UnionTypes.RefineAbstractType(this, OldType, NewType);
+}
+
+void UnionType::typeBecameConcrete(const DerivedType *AbsTy) {
+ LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
+ pImpl->UnionTypes.TypeBecameConcrete(this, AbsTy);
+}
+
+// refineAbstractType - Called when a contained type is found to be more
+// concrete - this could potentially change us from an abstract type to a
+// concrete type.
+//
void PointerType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
LLVMContextImpl *pImpl = OldType->getContext().pImpl;
@@ -1204,7 +1303,7 @@ void PointerType::typeBecameConcrete(const DerivedType *AbsTy) {
}
bool SequentialType::indexValid(const Value *V) const {
- if (isa<IntegerType>(V->getType()))
+ if (V->getType()->isIntegerTy())
return true;
return false;
}
diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h
index 4842845..02ab113 100644
--- a/lib/VMCore/TypesContext.h
+++ b/lib/VMCore/TypesContext.h
@@ -180,6 +180,32 @@ public:
}
};
+// UnionValType - Define a class to hold the key that goes into the TypeMap
+//
+class UnionValType {
+ std::vector<const Type*> ElTypes;
+public:
+ UnionValType(const Type* const* Types, unsigned NumTypes)
+ : ElTypes(&Types[0], &Types[NumTypes]) {}
+
+ static UnionValType get(const UnionType *UT) {
+ std::vector<const Type *> ElTypes;
+ ElTypes.reserve(UT->getNumElements());
+ for (unsigned i = 0, e = UT->getNumElements(); i != e; ++i)
+ ElTypes.push_back(UT->getElementType(i));
+
+ return UnionValType(&ElTypes[0], ElTypes.size());
+ }
+
+ static unsigned hashTypeStructure(const UnionType *UT) {
+ return UT->getNumElements();
+ }
+
+ inline bool operator<(const UnionValType &UTV) const {
+ return (ElTypes < UTV.ElTypes);
+ }
+};
+
// FunctionValType - Define a class to hold the key that goes into the TypeMap
//
class FunctionValType {
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 3759b8a..a36d262 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -45,11 +45,11 @@ Value::Value(const Type *ty, unsigned scid)
UseList(0), Name(0) {
if (isa<CallInst>(this) || isa<InvokeInst>(this))
assert((VTy->isFirstClassType() || VTy->isVoidTy() ||
- isa<OpaqueType>(ty) || VTy->getTypeID() == Type::StructTyID) &&
+ ty->isOpaqueTy() || VTy->isStructTy()) &&
"invalid CallInst type!");
else if (!isa<Constant>(this) && !isa<BasicBlock>(this))
assert((VTy->isFirstClassType() || VTy->isVoidTy() ||
- isa<OpaqueType>(ty)) &&
+ ty->isOpaqueTy()) &&
"Cannot create non-first-class values except for constants!");
}
@@ -320,7 +320,7 @@ void Value::replaceAllUsesWith(Value *New) {
}
Value *Value::stripPointerCasts() {
- if (!isa<PointerType>(getType()))
+ if (!getType()->isPointerTy())
return this;
Value *V = this;
do {
@@ -337,12 +337,12 @@ Value *Value::stripPointerCasts() {
} else {
return V;
}
- assert(isa<PointerType>(V->getType()) && "Unexpected operand type!");
+ assert(V->getType()->isPointerTy() && "Unexpected operand type!");
} while (1);
}
Value *Value::getUnderlyingObject(unsigned MaxLookup) {
- if (!isa<PointerType>(getType()))
+ if (!getType()->isPointerTy())
return this;
Value *V = this;
for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
@@ -357,7 +357,7 @@ Value *Value::getUnderlyingObject(unsigned MaxLookup) {
} else {
return V;
}
- assert(isa<PointerType>(V->getType()) && "Unexpected operand type!");
+ assert(V->getType()->isPointerTy() && "Unexpected operand type!");
}
return V;
}
diff --git a/lib/VMCore/ValueTypes.cpp b/lib/VMCore/ValueTypes.cpp
index 7f9a6cd..a092cd1 100644
--- a/lib/VMCore/ValueTypes.cpp
+++ b/lib/VMCore/ValueTypes.cpp
@@ -36,17 +36,17 @@ EVT EVT::getExtendedVectorVT(LLVMContext &Context, EVT VT,
bool EVT::isExtendedFloatingPoint() const {
assert(isExtended() && "Type is not extended!");
- return LLVMTy->isFPOrFPVector();
+ return LLVMTy->isFPOrFPVectorTy();
}
bool EVT::isExtendedInteger() const {
assert(isExtended() && "Type is not extended!");
- return LLVMTy->isIntOrIntVector();
+ return LLVMTy->isIntOrIntVectorTy();
}
bool EVT::isExtendedVector() const {
assert(isExtended() && "Type is not extended!");
- return isa<VectorType>(LLVMTy);
+ return LLVMTy->isVectorTy();
}
bool EVT::isExtended64BitVector() const {
@@ -126,6 +126,7 @@ std::string EVT::getEVTString() const {
case MVT::v8f32: return "v8f32";
case MVT::v2f64: return "v2f64";
case MVT::v4f64: return "v4f64";
+ case MVT::Metadata:return "Metadata";
}
}
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index d0e8d30..721e96a 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -161,7 +161,8 @@ namespace {
VerifierFailureAction action;
// What to do if verification fails.
Module *Mod; // Module we are verifying right now
- DominatorTree *DT; // Dominator Tree, caution can be null!
+ LLVMContext *Context; // Context within which we are verifying
+ DominatorTree *DT; // Dominator Tree, caution can be null!
std::string Messages;
raw_string_ostream MessagesStr;
@@ -178,24 +179,25 @@ namespace {
Verifier()
: FunctionPass(&ID),
Broken(false), RealPass(true), action(AbortProcessAction),
- DT(0), MessagesStr(Messages) {}
+ Mod(0), Context(0), DT(0), MessagesStr(Messages) {}
explicit Verifier(VerifierFailureAction ctn)
: FunctionPass(&ID),
- Broken(false), RealPass(true), action(ctn), DT(0),
+ Broken(false), RealPass(true), action(ctn), Mod(0), Context(0), DT(0),
MessagesStr(Messages) {}
explicit Verifier(bool AB)
: FunctionPass(&ID),
Broken(false), RealPass(true),
- action( AB ? AbortProcessAction : PrintMessageAction), DT(0),
- MessagesStr(Messages) {}
+ action( AB ? AbortProcessAction : PrintMessageAction), Mod(0),
+ Context(0), DT(0), MessagesStr(Messages) {}
explicit Verifier(DominatorTree &dt)
: FunctionPass(&ID),
- Broken(false), RealPass(false), action(PrintMessageAction),
- DT(&dt), MessagesStr(Messages) {}
+ Broken(false), RealPass(false), action(PrintMessageAction), Mod(0),
+ Context(0), DT(&dt), MessagesStr(Messages) {}
bool doInitialization(Module &M) {
Mod = &M;
+ Context = &M.getContext();
verifyTypeSymbolTable(M.getTypeSymbolTable());
// If this is a real pass, in a pass manager, we must abort before
@@ -211,6 +213,7 @@ namespace {
if (RealPass) DT = &getAnalysis<DominatorTree>();
Mod = F.getParent();
+ if (!Context) Context = &F.getContext();
visit(F);
InstsInThisBlock.clear();
@@ -314,6 +317,7 @@ namespace {
void visitStoreInst(StoreInst &SI);
void visitInstruction(Instruction &I);
void visitTerminatorInst(TerminatorInst &I);
+ void visitBranchInst(BranchInst &BI);
void visitReturnInst(ReturnInst &RI);
void visitSwitchInst(SwitchInst &SI);
void visitSelectInst(SelectInst &SI);
@@ -429,7 +433,7 @@ void Verifier::visitGlobalValue(GlobalValue &GV) {
if (GV.hasAppendingLinkage()) {
GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV);
- Assert1(GVar && isa<ArrayType>(GVar->getType()->getElementType()),
+ Assert1(GVar && GVar->getType()->getElementType()->isArrayTy(),
"Only global arrays can have appending linkage!", GVar);
}
}
@@ -596,13 +600,16 @@ void Verifier::visitFunction(Function &F) {
const FunctionType *FT = F.getFunctionType();
unsigned NumArgs = F.arg_size();
+ Assert1(Context == &F.getContext(),
+ "Function context does not match Module context!", &F);
+
Assert1(!F.hasCommonLinkage(), "Functions may not have common linkage", &F);
Assert2(FT->getNumParams() == NumArgs,
"# formal arguments must match # of arguments for function type!",
&F, FT);
Assert1(F.getReturnType()->isFirstClassType() ||
F.getReturnType()->isVoidTy() ||
- isa<StructType>(F.getReturnType()),
+ F.getReturnType()->isStructTy(),
"Functions cannot return aggregate values!", &F);
Assert1(!F.hasStructRetAttr() || F.getReturnType()->isVoidTy(),
@@ -743,6 +750,14 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) {
visitInstruction(I);
}
+void Verifier::visitBranchInst(BranchInst &BI) {
+ if (BI.isConditional()) {
+ Assert2(BI.getCondition()->getType()->isIntegerTy(1),
+ "Branch condition is not 'i1' type!", &BI, BI.getCondition());
+ }
+ visitTerminatorInst(BI);
+}
+
void Verifier::visitReturnInst(ReturnInst &RI) {
Function *F = RI.getParent()->getParent();
unsigned N = RI.getNumOperands();
@@ -821,9 +836,9 @@ void Verifier::visitTruncInst(TruncInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isIntOrIntVector(), "Trunc only operates on integer", &I);
- Assert1(DestTy->isIntOrIntVector(), "Trunc only produces integer", &I);
- Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ Assert1(SrcTy->isIntOrIntVectorTy(), "Trunc only operates on integer", &I);
+ Assert1(DestTy->isIntOrIntVectorTy(), "Trunc only produces integer", &I);
+ Assert1(SrcTy->isVectorTy() == DestTy->isVectorTy(),
"trunc source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for Trunc", &I);
@@ -836,9 +851,9 @@ void Verifier::visitZExtInst(ZExtInst &I) {
const Type *DestTy = I.getType();
// Get the size of the types in bits, we'll need this later
- Assert1(SrcTy->isIntOrIntVector(), "ZExt only operates on integer", &I);
- Assert1(DestTy->isIntOrIntVector(), "ZExt only produces an integer", &I);
- Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ Assert1(SrcTy->isIntOrIntVectorTy(), "ZExt only operates on integer", &I);
+ Assert1(DestTy->isIntOrIntVectorTy(), "ZExt only produces an integer", &I);
+ Assert1(SrcTy->isVectorTy() == DestTy->isVectorTy(),
"zext source and destination must both be a vector or neither", &I);
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
@@ -857,9 +872,9 @@ void Verifier::visitSExtInst(SExtInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isIntOrIntVector(), "SExt only operates on integer", &I);
- Assert1(DestTy->isIntOrIntVector(), "SExt only produces an integer", &I);
- Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ Assert1(SrcTy->isIntOrIntVectorTy(), "SExt only operates on integer", &I);
+ Assert1(DestTy->isIntOrIntVectorTy(), "SExt only produces an integer", &I);
+ Assert1(SrcTy->isVectorTy() == DestTy->isVectorTy(),
"sext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"Type too small for SExt", &I);
@@ -874,9 +889,9 @@ void Verifier::visitFPTruncInst(FPTruncInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isFPOrFPVector(),"FPTrunc only operates on FP", &I);
- Assert1(DestTy->isFPOrFPVector(),"FPTrunc only produces an FP", &I);
- Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ Assert1(SrcTy->isFPOrFPVectorTy(),"FPTrunc only operates on FP", &I);
+ Assert1(DestTy->isFPOrFPVectorTy(),"FPTrunc only produces an FP", &I);
+ Assert1(SrcTy->isVectorTy() == DestTy->isVectorTy(),
"fptrunc source and destination must both be a vector or neither",&I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for FPTrunc", &I);
@@ -892,9 +907,9 @@ void Verifier::visitFPExtInst(FPExtInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isFPOrFPVector(),"FPExt only operates on FP", &I);
- Assert1(DestTy->isFPOrFPVector(),"FPExt only produces an FP", &I);
- Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ Assert1(SrcTy->isFPOrFPVectorTy(),"FPExt only operates on FP", &I);
+ Assert1(DestTy->isFPOrFPVectorTy(),"FPExt only produces an FP", &I);
+ Assert1(SrcTy->isVectorTy() == DestTy->isVectorTy(),
"fpext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"DestTy too small for FPExt", &I);
@@ -906,14 +921,14 @@ void Verifier::visitUIToFPInst(UIToFPInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- bool SrcVec = isa<VectorType>(SrcTy);
- bool DstVec = isa<VectorType>(DestTy);
+ bool SrcVec = SrcTy->isVectorTy();
+ bool DstVec = DestTy->isVectorTy();
Assert1(SrcVec == DstVec,
"UIToFP source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isIntOrIntVector(),
+ Assert1(SrcTy->isIntOrIntVectorTy(),
"UIToFP source must be integer or integer vector", &I);
- Assert1(DestTy->isFPOrFPVector(),
+ Assert1(DestTy->isFPOrFPVectorTy(),
"UIToFP result must be FP or FP vector", &I);
if (SrcVec && DstVec)
@@ -929,14 +944,14 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- bool SrcVec = isa<VectorType>(SrcTy);
- bool DstVec = isa<VectorType>(DestTy);
+ bool SrcVec = SrcTy->isVectorTy();
+ bool DstVec = DestTy->isVectorTy();
Assert1(SrcVec == DstVec,
"SIToFP source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isIntOrIntVector(),
+ Assert1(SrcTy->isIntOrIntVectorTy(),
"SIToFP source must be integer or integer vector", &I);
- Assert1(DestTy->isFPOrFPVector(),
+ Assert1(DestTy->isFPOrFPVectorTy(),
"SIToFP result must be FP or FP vector", &I);
if (SrcVec && DstVec)
@@ -952,13 +967,14 @@ void Verifier::visitFPToUIInst(FPToUIInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- bool SrcVec = isa<VectorType>(SrcTy);
- bool DstVec = isa<VectorType>(DestTy);
+ bool SrcVec = SrcTy->isVectorTy();
+ bool DstVec = DestTy->isVectorTy();
Assert1(SrcVec == DstVec,
"FPToUI source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isFPOrFPVector(), "FPToUI source must be FP or FP vector", &I);
- Assert1(DestTy->isIntOrIntVector(),
+ Assert1(SrcTy->isFPOrFPVectorTy(), "FPToUI source must be FP or FP vector",
+ &I);
+ Assert1(DestTy->isIntOrIntVectorTy(),
"FPToUI result must be integer or integer vector", &I);
if (SrcVec && DstVec)
@@ -974,14 +990,14 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- bool SrcVec = isa<VectorType>(SrcTy);
- bool DstVec = isa<VectorType>(DestTy);
+ bool SrcVec = SrcTy->isVectorTy();
+ bool DstVec = DestTy->isVectorTy();
Assert1(SrcVec == DstVec,
"FPToSI source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isFPOrFPVector(),
+ Assert1(SrcTy->isFPOrFPVectorTy(),
"FPToSI source must be FP or FP vector", &I);
- Assert1(DestTy->isIntOrIntVector(),
+ Assert1(DestTy->isIntOrIntVectorTy(),
"FPToSI result must be integer or integer vector", &I);
if (SrcVec && DstVec)
@@ -997,8 +1013,8 @@ void Verifier::visitPtrToIntInst(PtrToIntInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- Assert1(isa<PointerType>(SrcTy), "PtrToInt source must be pointer", &I);
- Assert1(DestTy->isInteger(), "PtrToInt result must be integral", &I);
+ Assert1(SrcTy->isPointerTy(), "PtrToInt source must be pointer", &I);
+ Assert1(DestTy->isIntegerTy(), "PtrToInt result must be integral", &I);
visitInstruction(I);
}
@@ -1008,8 +1024,8 @@ void Verifier::visitIntToPtrInst(IntToPtrInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- Assert1(SrcTy->isInteger(), "IntToPtr source must be an integral", &I);
- Assert1(isa<PointerType>(DestTy), "IntToPtr result must be a pointer",&I);
+ Assert1(SrcTy->isIntegerTy(), "IntToPtr source must be an integral", &I);
+ Assert1(DestTy->isPointerTy(), "IntToPtr result must be a pointer",&I);
visitInstruction(I);
}
@@ -1025,7 +1041,7 @@ void Verifier::visitBitCastInst(BitCastInst &I) {
// BitCast implies a no-op cast of type only. No bits change.
// However, you can't cast pointers to anything but pointers.
- Assert1(isa<PointerType>(DestTy) == isa<PointerType>(DestTy),
+ Assert1(DestTy->isPointerTy() == DestTy->isPointerTy(),
"Bitcast requires both operands to be pointer or neither", &I);
Assert1(SrcBitSize == DestBitSize, "Bitcast requires types of same width",&I);
@@ -1068,11 +1084,11 @@ void Verifier::visitPHINode(PHINode &PN) {
void Verifier::VerifyCallSite(CallSite CS) {
Instruction *I = CS.getInstruction();
- Assert1(isa<PointerType>(CS.getCalledValue()->getType()),
+ Assert1(CS.getCalledValue()->getType()->isPointerTy(),
"Called function must be a pointer!", I);
const PointerType *FPTy = cast<PointerType>(CS.getCalledValue()->getType());
- Assert1(isa<FunctionType>(FPTy->getElementType()),
+ Assert1(FPTy->getElementType()->isFunctionTy(),
"Called function is not pointer to function type!", I);
const FunctionType *FTy = cast<FunctionType>(FPTy->getElementType());
@@ -1151,7 +1167,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::UDiv:
case Instruction::SRem:
case Instruction::URem:
- Assert1(B.getType()->isIntOrIntVector(),
+ Assert1(B.getType()->isIntOrIntVectorTy(),
"Integer arithmetic operators only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Integer arithmetic operators must have same type "
@@ -1164,7 +1180,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::FMul:
case Instruction::FDiv:
case Instruction::FRem:
- Assert1(B.getType()->isFPOrFPVector(),
+ Assert1(B.getType()->isFPOrFPVectorTy(),
"Floating-point arithmetic operators only work with "
"floating-point types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
@@ -1175,7 +1191,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
- Assert1(B.getType()->isIntOrIntVector(),
+ Assert1(B.getType()->isIntOrIntVectorTy(),
"Logical operators only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Logical operators must have same type for operands and result!",
@@ -1184,7 +1200,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
- Assert1(B.getType()->isIntOrIntVector(),
+ Assert1(B.getType()->isIntOrIntVectorTy(),
"Shifts only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Shift return type must be same as operands!", &B);
@@ -1203,7 +1219,7 @@ void Verifier::visitICmpInst(ICmpInst& IC) {
Assert1(Op0Ty == Op1Ty,
"Both operands to ICmp instruction are not of the same type!", &IC);
// Check that the operands are the right type
- Assert1(Op0Ty->isIntOrIntVector() || isa<PointerType>(Op0Ty),
+ Assert1(Op0Ty->isIntOrIntVectorTy() || Op0Ty->isPointerTy(),
"Invalid operand types for ICmp instruction", &IC);
visitInstruction(IC);
@@ -1216,7 +1232,7 @@ void Verifier::visitFCmpInst(FCmpInst& FC) {
Assert1(Op0Ty == Op1Ty,
"Both operands to FCmp instruction are not of the same type!", &FC);
// Check that the operands are the right type
- Assert1(Op0Ty->isFPOrFPVector(),
+ Assert1(Op0Ty->isFPOrFPVectorTy(),
"Invalid operand types for FCmp instruction", &FC);
visitInstruction(FC);
}
@@ -1270,7 +1286,7 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(),
Idxs.begin(), Idxs.end());
Assert1(ElTy, "Invalid indices for GEP pointer type!", &GEP);
- Assert2(isa<PointerType>(GEP.getType()) &&
+ Assert2(GEP.getType()->isPointerTy() &&
cast<PointerType>(GEP.getType())->getElementType() == ElTy,
"GEP is not of right type for indices!", &GEP, ElTy);
visitInstruction(GEP);
@@ -1302,7 +1318,7 @@ void Verifier::visitAllocaInst(AllocaInst &AI) {
&AI);
Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type",
&AI);
- Assert1(AI.getArraySize()->getType()->isInteger(32),
+ Assert1(AI.getArraySize()->getType()->isIntegerTy(32),
"Alloca array size must be i32", &AI);
visitInstruction(AI);
}
@@ -1481,7 +1497,7 @@ void Verifier::visitInstruction(Instruction &I) {
void Verifier::VerifyType(const Type *Ty) {
if (!Types.insert(Ty)) return;
- Assert1(&Mod->getContext() == &Ty->getContext(),
+ Assert1(Context == &Ty->getContext(),
"Type context does not match Module context!", Ty);
switch (Ty->getTypeID()) {
@@ -1509,6 +1525,15 @@ void Verifier::VerifyType(const Type *Ty) {
VerifyType(ElTy);
}
} break;
+ case Type::UnionTyID: {
+ const UnionType *UTy = cast<UnionType>(Ty);
+ for (unsigned i = 0, e = UTy->getNumElements(); i != e; ++i) {
+ const Type *ElTy = UTy->getElementType(i);
+ Assert2(UnionType::isValidElementType(ElTy),
+ "Union type with invalid element type", ElTy, UTy);
+ VerifyType(ElTy);
+ }
+ } break;
case Type::ArrayTyID: {
const ArrayType *ATy = cast<ArrayType>(Ty);
Assert1(ArrayType::isValidElementType(ATy->getElementType()),
@@ -1616,7 +1641,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
if (ID == Intrinsic::gcroot) {
AllocaInst *AI =
dyn_cast<AllocaInst>(CI.getOperand(1)->stripPointerCasts());
- Assert1(AI && isa<PointerType>(AI->getType()->getElementType()),
+ Assert1(AI && AI->getType()->getElementType()->isPointerTy(),
"llvm.gcroot parameter #1 must be a pointer alloca.", &CI);
Assert1(isa<Constant>(CI.getOperand(2)),
"llvm.gcroot parameter #2 must be a constant.", &CI);
@@ -1734,7 +1759,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
}
}
} else if (VT == MVT::iAny) {
- if (!EltTy->isInteger()) {
+ if (!EltTy->isIntegerTy()) {
CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
"an integer type.", F);
return false;
@@ -1759,7 +1784,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
break;
}
} else if (VT == MVT::fAny) {
- if (!EltTy->isFloatingPoint()) {
+ if (!EltTy->isFloatingPointTy()) {
CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
"a floating-point type.", F);
return false;
@@ -1778,7 +1803,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
}
Suffix += ".v" + utostr(NumElts) + EVT::getEVT(EltTy).getEVTString();
} else if (VT == MVT::iPTR) {
- if (!isa<PointerType>(Ty)) {
+ if (!Ty->isPointerTy()) {
CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a "
"pointer and a pointer is required.", F);
return false;
diff --git a/llvm-device-build.mk b/llvm-device-build.mk
new file mode 100644
index 0000000..d7c7e3d
--- /dev/null
+++ b/llvm-device-build.mk
@@ -0,0 +1,52 @@
+LOCAL_CFLAGS := \
+ -D_DEBUG \
+ -D_GNU_SOURCE \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS \
+ -DANDROID_TARGET_BUILD \
+ -O2 \
+ -fomit-frame-pointer \
+ -Woverloaded-virtual \
+ -Wall \
+ -W \
+ -Wno-unused-parameter \
+ -Wwrite-strings \
+ $(LOCAL_CFLAGS)
+
+ifneq ($(REQUIRES_EH),1)
+LOCAL_CFLAGS += -fno-exceptions
+else
+# No action. The device target should not have exception enabled since bionic
+# doesn't support it
+REQUIRES_EH := 0
+endif
+
+ifneq ($(REQUIRES_RTTI),1)
+LOCAL_CFLAGS += -fno-rtti
+else
+REQUIRES_RTTI := 0
+endif
+
+# Make sure bionic is first so we can include system headers.
+LOCAL_C_INCLUDES := \
+ bionic \
+ external/stlport/stlport \
+ $(LLVM_ROOT_PATH) \
+ $(LLVM_ROOT_PATH)/include \
+ $(LLVM_ROOT_PATH)/device/include \
+ $(LOCAL_C_INCLUDES)
+
+###########################################################
+## Commands for running tblgen to compile a td file
+###########################################################
+define transform-device-td-to-out
+@mkdir -p $(dir $@)
+@echo "Device TableGen (gen-$(1)): $(LOCAL_MODULE) <= $<"
+$(hide) $(TBLGEN) \
+ -I $(dir $<) \
+ -I $(LLVM_ROOT_PATH)/include \
+ -I $(LLVM_ROOT_PATH)/device/include \
+ -I $(LLVM_ROOT_PATH)/lib/Target \
+ -gen-$(strip $(1)) \
+ -o $@ $<
+endef
diff --git a/llvm-gen-intrinsics.mk b/llvm-gen-intrinsics.mk
new file mode 100644
index 0000000..decccdd
--- /dev/null
+++ b/llvm-gen-intrinsics.mk
@@ -0,0 +1,18 @@
+# We treat Intrinsics.td as a very special target just like what lib/VMCore/Makefile does
+INTRINSICTD := $(LLVM_ROOT_PATH)/include/llvm/Intrinsics.td
+INTRINSICTDS := $(wildcard $(dir $(INTRINSICTD))/Intrinsics*.td)
+
+LOCAL_SRC_FILES := $(INTRINSICTD) $(LOCAL_SRC_FILES)
+
+ifeq ($(LOCAL_MODULE_CLASS),)
+ LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+endif
+
+GENFILE := $(addprefix $(call local-intermediates-dir)/llvm/,Intrinsics.gen)
+LOCAL_GENERATED_SOURCES += $(GENFILE)
+$(GENFILE): $(INTRINSICTD) $(INTRINSICTDS) $(TBLGEN)
+ifeq ($(LOCAL_IS_HOST_MODULE),true)
+ $(call transform-host-td-to-out,intrinsic)
+else
+ $(call transform-device-td-to-out,intrinsic)
+endif
diff --git a/llvm-host-build.mk b/llvm-host-build.mk
new file mode 100644
index 0000000..263afe7
--- /dev/null
+++ b/llvm-host-build.mk
@@ -0,0 +1,50 @@
+LOCAL_CFLAGS := \
+ -D_DEBUG \
+ -D_GNU_SOURCE \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS \
+ -O2 \
+ -fomit-frame-pointer \
+ -Woverloaded-virtual \
+ -Wall \
+ -W \
+ -Wno-unused-parameter \
+ -Wwrite-strings \
+ $(LOCAL_CFLAGS)
+
+ifneq ($(REQUIRES_EH),1)
+LOCAL_CFLAGS += -fno-exceptions
+else
+REQUIRES_EH := 0
+LOCAL_CFLAGS += -fexceptions
+endif
+
+ifneq ($(REQUIRES_RTTI),1)
+LOCAL_CFLAGS += -fno-rtti
+else
+REQUIRES_RTTI := 0
+endif
+
+# Make sure bionic is first so we can include system headers.
+LOCAL_C_INCLUDES := \
+ $(LLVM_ROOT_PATH) \
+ $(LLVM_ROOT_PATH)/include \
+ $(LLVM_ROOT_PATH)/host/include \
+ $(LOCAL_C_INCLUDES)
+
+LOCAL_IS_HOST_MODULE := true
+
+###########################################################
+## Commands for running tblgen to compile a td file
+###########################################################
+define transform-host-td-to-out
+@mkdir -p $(dir $@)
+@echo "Host TableGen: $(LOCAL_MODULE) (gen-$(1)) <= $<"
+$(hide) $(TBLGEN) \
+ -I $(dir $<) \
+ -I $(LLVM_ROOT_PATH)/include \
+ -I $(LLVM_ROOT_PATH)/host/include \
+ -I $(LLVM_ROOT_PATH)/lib/Target \
+ -gen-$(strip $(1)) \
+ -o $@ $<
+endef
diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt
index 1a286db..415530e 100644
--- a/projects/CMakeLists.txt
+++ b/projects/CMakeLists.txt
@@ -4,7 +4,7 @@
file(GLOB entries *)
foreach(entry ${entries})
if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
- if(NOT (${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt))
+ if(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt)
add_subdirectory(${entry})
endif()
endif()
diff --git a/projects/sample/configure b/projects/sample/configure
index f6aa847..5a13388 100755
--- a/projects/sample/configure
+++ b/projects/sample/configure
@@ -2362,3 +2362,4 @@ if test "$no_create" != yes; then
$ac_cs_success || { (exit 1); exit 1; }
fi
+
diff --git a/runtime/Makefile b/runtime/Makefile
index 1e10451..7209867 100644
--- a/runtime/Makefile
+++ b/runtime/Makefile
@@ -20,6 +20,10 @@ ifeq ($(ARCH), Sparc)
PARALLEL_DIRS := $(filter-out libprofile, $(PARALLEL_DIRS))
endif
+ifeq ($(TARGET_OS), $(filter $(TARGET_OS), Cygwin MingW))
+PARALLEL_DIRS := $(filter-out libprofile, $(PARALLEL_DIRS))
+endif
+
endif
include $(LEVEL)/Makefile.common
diff --git a/runtime/libprofile/Makefile b/runtime/libprofile/Makefile
index 92a8558..15e6779 100644
--- a/runtime/libprofile/Makefile
+++ b/runtime/libprofile/Makefile
@@ -10,7 +10,7 @@
LEVEL = ../..
include $(LEVEL)/Makefile.config
-ifneq ($(wildcard $(LLVMGCC)),)
+ifneq ($(strip $(LLVMCC)),)
BYTECODE_LIBRARY = 1
endif
SHARED_LIBRARY = 1
diff --git a/tblgen-rules.mk b/tblgen-rules.mk
new file mode 100644
index 0000000..435bc42
--- /dev/null
+++ b/tblgen-rules.mk
@@ -0,0 +1,108 @@
+###########################################################
+## Commands for running tblgen to compile a td file
+##########################################################
+define transform-td-to-out
+$(if $(LOCAL_IS_HOST_MODULE), \
+ $(call transform-host-td-to-out,$(1)), \
+ $(call transform-device-td-to-out,$(1)))
+endef
+
+###########################################################
+## TableGen: Compile .td files to .inc.
+###########################################################
+ifeq ($(LOCAL_MODULE_CLASS),)
+ LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+endif
+
+ifneq ($(strip $(TBLGEN_TABLES)),)
+
+intermediates := $(call local-intermediates-dir)
+tblgen_gen_tables := $(addprefix $(intermediates)/,$(TBLGEN_TABLES))
+LOCAL_GENERATED_SOURCES += $(tblgen_gen_tables)
+
+tblgen_source_dir := $(LOCAL_PATH)
+ifneq ($(TBLGEN_TD_DIR),)
+tblgen_source_dir := $(TBLGEN_TD_DIR)
+endif
+
+ifneq ($(filter %GenRegisterNames.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenRegisterNames.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,register-enums)
+endif
+
+ifneq ($(filter %GenRegisterInfo.h.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenRegisterInfo.h.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,register-desc-header)
+endif
+
+ifneq ($(filter %GenRegisterInfo.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenRegisterInfo.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,register-desc)
+endif
+
+ifneq ($(filter %GenInstrNames.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenInstrNames.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,instr-enums)
+endif
+
+ifneq ($(filter %GenInstrInfo.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenInstrInfo.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,instr-desc)
+endif
+
+ifneq ($(filter %GenAsmWriter.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenAsmWriter.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,asm-writer)
+endif
+
+ifneq ($(filter %GenAsmWriter1.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenAsmWriter1.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,asm-writer -asmwriternum=1)
+endif
+
+ifneq ($(filter %GenAsmMatcher.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenAsmMatcher.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,asm-matcher)
+endif
+
+ifneq ($(filter %GenCodeEmitter.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenCodeEmitter.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,emitter)
+endif
+
+ifneq ($(filter %GenDAGISel.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenDAGISel.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,dag-isel)
+endif
+
+ifneq ($(filter %GenDisassemblerTables.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenDisassemblerTables.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,disassembler)
+endif
+
+ifneq ($(filter %GenEDInfo.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenEDInfo.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,enhanced-disassembly-info)
+endif
+
+ifneq ($(filter %GenFastISel.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenFastISel.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,fast-isel)
+endif
+
+ifneq ($(filter %GenSubtarget.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenSubtarget.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,subtarget)
+endif
+
+ifneq ($(filter %GenCallingConv.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenCallingConv.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,callingconv)
+endif
+
+ifneq ($(filter %GenIntrinsics.inc,$(tblgen_gen_tables)),)
+$(intermediates)/%GenIntrinsics.inc: $(tblgen_source_dir)/%.td $(TBLGEN)
+ $(call transform-td-to-out,tgt_intrinsics)
+endif
+
+endif
diff --git a/test/Analysis/Andersens/2007-11-19-InlineAsm.ll b/test/Analysis/Andersens/2007-11-19-InlineAsm.ll
deleted file mode 100644
index 5ba3499..0000000
--- a/test/Analysis/Andersens/2007-11-19-InlineAsm.ll
+++ /dev/null
@@ -1,8 +0,0 @@
-; RUN: opt < %s -anders-aa -disable-output
-
-define void @x(i16 %Y) {
-entry:
- %tmp = call i16 asm "bswap $0", "=r,r"(i16 %Y)
- ret void
-}
-
diff --git a/test/Analysis/Andersens/2008-03-19-External.ll b/test/Analysis/Andersens/2008-03-19-External.ll
deleted file mode 100644
index a973103..0000000
--- a/test/Analysis/Andersens/2008-03-19-External.ll
+++ /dev/null
@@ -1,12 +0,0 @@
-; RUN: opt < %s -anders-aa -gvn -S | not grep undef
-; PR2160
-
-declare void @f(i32*)
-
-define i32 @g() {
-entry:
- %tmp = alloca i32 ; <i32*> [#uses=2]
- call void @f( i32* %tmp )
- %tmp2 = load i32* %tmp ; <i32> [#uses=1]
- ret i32 %tmp2
-}
diff --git a/test/Analysis/Andersens/2008-04-07-Memcpy.ll b/test/Analysis/Andersens/2008-04-07-Memcpy.ll
deleted file mode 100644
index 5a50dd5..0000000
--- a/test/Analysis/Andersens/2008-04-07-Memcpy.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: opt < %s -anders-aa -gvn -S | not grep undef
-; PR2169
-
-declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind
-declare void @use(i8)
-
-define void @f(i8* %x) {
-entry:
- %copy = alloca i8 ; <i8*> [#uses=6]
- call void @llvm.memcpy.i32( i8* %copy, i8* %x, i32 1, i32 4 )
- %tmp = load i8* %copy ; <i8> [#uses=1]
- call void @use(i8 %tmp)
- ret void
-}
diff --git a/test/Analysis/Andersens/2008-12-27-BuiltinWrongType.ll b/test/Analysis/Andersens/2008-12-27-BuiltinWrongType.ll
deleted file mode 100644
index da67511..0000000
--- a/test/Analysis/Andersens/2008-12-27-BuiltinWrongType.ll
+++ /dev/null
@@ -1,19 +0,0 @@
-; RUN: opt < %s -anders-aa
-; PR3262
-
-@.str15 = external global [3 x i8] ; <[3 x i8]*> [#uses=1]
-
-declare i8* @strtok(...)
-declare i8* @memmove(...)
-
-define void @test1(i8* %want1) nounwind {
-entry:
- %0 = call i8* (...)* @strtok(i32 0, i8* getelementptr ([3 x i8]* @.str15, i32 0, i32 0)) nounwind ; <i8*> [#uses=0]
- unreachable
-}
-
-define void @test2() nounwind {
-entry:
- %0 = call i8* (...)* @memmove()
- unreachable
-}
diff --git a/test/Analysis/Andersens/basictest.ll b/test/Analysis/Andersens/basictest.ll
deleted file mode 100644
index 47226dd..0000000
--- a/test/Analysis/Andersens/basictest.ll
+++ /dev/null
@@ -1,28 +0,0 @@
-; RUN: opt < %s -anders-aa -aa-eval 2>/dev/null
-
-define void @test1() {
- %X = malloc i32*
- %Y = malloc i32
- %Z = ptrtoint i32* %Y to i32
- %W = inttoptr i32 %Z to i32*
- store i32* %W, i32** %X
- ret void
-}
-
-define void @test2(i32* %P) {
- %X = malloc i32*
- %Y = malloc i32
- store i32* %P, i32** %X
- ret void
-}
-
-define internal i32 *@test3(i32* %P) {
- ret i32* %P
-}
-
-define void @test4() {
- %X = malloc i32
- %Y = call i32* @test3(i32* %X)
- %ZZ = getelementptr i32* null, i32 17
- ret void
-}
diff --git a/test/Analysis/Andersens/dg.exp b/test/Analysis/Andersens/dg.exp
deleted file mode 100644
index 1eb4755..0000000
--- a/test/Analysis/Andersens/dg.exp
+++ /dev/null
@@ -1,4 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
-
diff --git a/test/Analysis/Andersens/external.ll b/test/Analysis/Andersens/external.ll
deleted file mode 100644
index 13c12dc..0000000
--- a/test/Analysis/Andersens/external.ll
+++ /dev/null
@@ -1,20 +0,0 @@
-; RUN: opt < %s -anders-aa -gvn -deadargelim -S | grep store | not grep null
-
-; Because the 'internal' function is passed to an external function, we don't
-; know what the incoming values will alias. As such, we cannot do the
-; optimization checked by the 'arg-must-alias.ll' test.
-
-declare void @external(i32(i32*)*)
-@G = internal constant i32* null
-
-define internal i32 @internal(i32* %ARG) {
- ;;; We *DON'T* know that ARG always points to null!
- store i32* %ARG, i32** @G
- ret i32 0
-}
-
-define i32 @foo() {
- call void @external(i32(i32*)* @internal)
- %V = call i32 @internal(i32* null)
- ret i32 %V
-}
diff --git a/test/Analysis/Andersens/modreftest.ll b/test/Analysis/Andersens/modreftest.ll
deleted file mode 100644
index e0c2edc..0000000
--- a/test/Analysis/Andersens/modreftest.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -anders-aa -gvn -instcombine -S \
-; RUN: | grep {ret i1 true}
-
-@G = internal global i32* null
-declare i32 *@ext()
-
-define i1 @bar() {
- %V1 = load i32** @G
- %X2 = call i32 *@ext()
- %V2 = load i32** @G
- store i32* %X2, i32** @G
-
- %C = icmp eq i32* %V1, %V2
- ret i1 %C
-}
diff --git a/test/Analysis/Andersens/modreftest2.ll b/test/Analysis/Andersens/modreftest2.ll
deleted file mode 100644
index 562c961..0000000
--- a/test/Analysis/Andersens/modreftest2.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: opt < %s -anders-aa -gvn -S \
-; RUN: | not grep {ret i32 undef}
-
-;; From PR 2160
-declare void @f(i32*)
-
-define i32 @g() {
-entry:
- %tmp = alloca i32 ; <i32*> [#uses=2]
- call void @f( i32* %tmp )
- %tmp2 = load i32* %tmp ; <i32> [#uses=1]
- ret i32 %tmp2
-}
-
diff --git a/test/Analysis/Andersens/trivialtest.ll b/test/Analysis/Andersens/trivialtest.ll
deleted file mode 100644
index f9f938f..0000000
--- a/test/Analysis/Andersens/trivialtest.ll
+++ /dev/null
@@ -1,3 +0,0 @@
-; RUN: opt < %s -anders-aa -disable-output
-
-define void @foo() { ret void }
diff --git a/test/Analysis/ScalarEvolution/trip-count10.ll b/test/Analysis/ScalarEvolution/trip-count10.ll
new file mode 100644
index 0000000..0a992f9
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/trip-count10.ll
@@ -0,0 +1,76 @@
+; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
+
+; Trip counts with trivial exit conditions.
+
+; CHECK: Determining loop execution counts for: @a
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+
+; CHECK: Determining loop execution counts for: @b
+; CHECK: Loop %loop: backedge-taken count is false
+; CHECK: Loop %loop: max backedge-taken count is false
+
+; CHECK: Determining loop execution counts for: @c
+; CHECK: Loop %loop: backedge-taken count is false
+; CHECK: Loop %loop: max backedge-taken count is false
+
+; CHECK: Determining loop execution counts for: @d
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+
+define void @a(i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 false, label %return, label %loop
+
+return:
+ ret void
+}
+define void @b(i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 true, label %return, label %loop
+
+return:
+ ret void
+}
+define void @c(i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 false, label %loop, label %return
+
+return:
+ ret void
+}
+define void @d(i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 true, label %loop, label %return
+
+return:
+ ret void
+}
diff --git a/test/Archive/GNU.a b/test/Archive/GNU.a
deleted file mode 100644
index 4c09881..0000000
--- a/test/Archive/GNU.a
+++ /dev/null
Binary files differ
diff --git a/test/Archive/IsNAN.o b/test/Archive/IsNAN.o
deleted file mode 100644
index 7b3a12a..0000000
--- a/test/Archive/IsNAN.o
+++ /dev/null
Binary files differ
diff --git a/test/Archive/MacOSX.a b/test/Archive/MacOSX.a
deleted file mode 100644
index 8ba1e6d..0000000
--- a/test/Archive/MacOSX.a
+++ /dev/null
Binary files differ
diff --git a/test/Archive/SVR4.a b/test/Archive/SVR4.a
deleted file mode 100644
index 3947813..0000000
--- a/test/Archive/SVR4.a
+++ /dev/null
Binary files differ
diff --git a/test/Archive/xpg4.a b/test/Archive/xpg4.a
deleted file mode 100644
index b2bdb51..0000000
--- a/test/Archive/xpg4.a
+++ /dev/null
Binary files differ
diff --git a/test/Assembler/2010-01-06-UnionType.ll b/test/Assembler/2010-01-06-UnionType.ll
new file mode 100644
index 0000000..37130d6
--- /dev/null
+++ b/test/Assembler/2010-01-06-UnionType.ll
@@ -0,0 +1,3 @@
+; RUN: llvm-as %s -o /dev/null
+
+%X = type union { i32, i32* }
diff --git a/test/Bindings/Ocaml/bitreader.ml b/test/Bindings/Ocaml/bitreader.ml
index 5c23041..112ca61 100644
--- a/test/Bindings/Ocaml/bitreader.ml
+++ b/test/Bindings/Ocaml/bitreader.ml
@@ -41,16 +41,16 @@ let _ =
true
end;
- (* get_module_provider *)
+ (* get_module *)
begin
let mb = Llvm.MemoryBuffer.of_file fn in
- let mp = begin try
- Llvm_bitreader.get_module_provider context mb
+ let m = begin try
+ Llvm_bitreader.get_module context mb
with x ->
Llvm.MemoryBuffer.dispose mb;
raise x
end in
- Llvm.ModuleProvider.dispose mp
+ Llvm.dispose_module m
end;
(* corrupt the bitcode *)
@@ -60,17 +60,17 @@ let _ =
close_out oc
end;
- (* test get_module_provider exceptions *)
+ (* test get_module exceptions *)
test begin
try
let mb = Llvm.MemoryBuffer.of_file fn in
- let mp = begin try
- Llvm_bitreader.get_module_provider context mb
+ let m = begin try
+ Llvm_bitreader.get_module context mb
with x ->
Llvm.MemoryBuffer.dispose mb;
raise x
end in
- Llvm.ModuleProvider.dispose mp;
+ Llvm.dispose_module m;
false
with Llvm_bitreader.Error _ ->
true
diff --git a/test/Bindings/Ocaml/bitwriter.ml b/test/Bindings/Ocaml/bitwriter.ml
index 57caac7..ef1c9ab 100644
--- a/test/Bindings/Ocaml/bitwriter.ml
+++ b/test/Bindings/Ocaml/bitwriter.ml
@@ -1,4 +1,4 @@
-(* RUN: %ocamlopt -warn-error A llvm.cmxa llvm_bitwriter.cmxa %s -o %t
+(* RUN: %ocamlopt -warn-error A unix.cmxa llvm.cmxa llvm_bitwriter.cmxa %s -o %t
* RUN: ./%t %t.bc
* RUN: llvm-dis < %t.bc | grep caml_int_ty
*)
@@ -10,9 +10,37 @@ let context = Llvm.global_context ()
let test x = if not x then exit 1 else ()
+let read_file name =
+ let ic = open_in_bin name in
+ let len = in_channel_length ic in
+ let buf = String.create len in
+
+ test ((input ic buf 0 len) = len);
+
+ close_in ic;
+
+ buf
+
+let temp_bitcode ?unbuffered m =
+ let temp_name, temp_oc = Filename.open_temp_file ~mode:[Open_binary] "" "" in
+
+ test (Llvm_bitwriter.output_bitcode ?unbuffered temp_oc m);
+ flush temp_oc;
+
+ let temp_buf = read_file temp_name in
+
+ close_out temp_oc;
+
+ temp_buf
+
let _ =
let m = Llvm.create_module context "ocaml_test_module" in
ignore (Llvm.define_type_name "caml_int_ty" (Llvm.i32_type context) m);
-
- test (Llvm_bitwriter.write_bitcode_file m Sys.argv.(1))
+
+ test (Llvm_bitwriter.write_bitcode_file m Sys.argv.(1));
+ let file_buf = read_file Sys.argv.(1) in
+
+ test (file_buf = temp_bitcode m);
+ test (file_buf = temp_bitcode ~unbuffered:false m);
+ test (file_buf = temp_bitcode ~unbuffered:true m)
diff --git a/test/Bindings/Ocaml/executionengine.ml b/test/Bindings/Ocaml/executionengine.ml
index ce56c50..2caeb82 100644
--- a/test/Bindings/Ocaml/executionengine.ml
+++ b/test/Bindings/Ocaml/executionengine.ml
@@ -64,9 +64,8 @@ let test_executionengine () =
let m2 = create_module (global_context ()) "test_module2" in
define_plus m2;
- let ee = ExecutionEngine.create (ModuleProvider.create m) in
- let mp2 = ModuleProvider.create m2 in
- ExecutionEngine.add_module_provider mp2 ee;
+ let ee = ExecutionEngine.create m in
+ ExecutionEngine.add_module m2 ee;
(* run_static_ctors *)
ExecutionEngine.run_static_ctors ee;
@@ -94,8 +93,8 @@ let test_executionengine () =
ee in
if 4 != GenericValue.as_int res then bomb "plus did not work";
- (* remove_module_provider *)
- Llvm.dispose_module (ExecutionEngine.remove_module_provider mp2 ee);
+ (* remove_module *)
+ Llvm.dispose_module (ExecutionEngine.remove_module m2 ee);
(* run_static_dtors *)
ExecutionEngine.run_static_dtors ee;
diff --git a/test/Bindings/Ocaml/scalar_opts.ml b/test/Bindings/Ocaml/scalar_opts.ml
index 0a65810..f28eff2 100644
--- a/test/Bindings/Ocaml/scalar_opts.ml
+++ b/test/Bindings/Ocaml/scalar_opts.ml
@@ -22,7 +22,6 @@ let suite name f =
let filename = Sys.argv.(1)
let m = create_module context filename
-let mp = ModuleProvider.create m
(*===-- Transforms --------------------------------------------------------===*)
@@ -36,13 +35,30 @@ let test_transforms () =
let td = TargetData.create (target_triple m) in
- ignore (PassManager.create_function mp
+ ignore (PassManager.create_function m
++ TargetData.add td
- ++ add_instruction_combining
+ ++ add_constant_propagation
+ ++ add_sccp
+ ++ add_dead_store_elimination
+ ++ add_aggressive_dce
+ ++ add_scalar_repl_aggregation
+ ++ add_ind_var_simplification
+ ++ add_instruction_combination
+ ++ add_licm
+ ++ add_loop_unswitch
+ ++ add_loop_unroll
+ ++ add_loop_rotation
+ ++ add_loop_index_split
+ ++ add_memory_to_register_promotion
+ ++ add_memory_to_register_demotion
++ add_reassociation
- ++ add_gvn
+ ++ add_jump_threading
++ add_cfg_simplification
- ++ add_constant_propagation
+ ++ add_tail_call_elimination
+ ++ add_gvn
+ ++ add_memcpy_opt
+ ++ add_loop_deletion
+ ++ add_lib_call_simplification
++ PassManager.initialize
++ PassManager.run_function fn
++ PassManager.finalize
@@ -55,4 +71,4 @@ let test_transforms () =
let _ =
suite "transforms" test_transforms;
- ModuleProvider.dispose mp
+ dispose_module m
diff --git a/test/Bindings/Ocaml/vmcore.ml b/test/Bindings/Ocaml/vmcore.ml
index dd0404a..506bf50 100644
--- a/test/Bindings/Ocaml/vmcore.ml
+++ b/test/Bindings/Ocaml/vmcore.ml
@@ -58,7 +58,6 @@ let suite name f =
let filename = Sys.argv.(1)
let m = create_module context filename
-let mp = ModuleProvider.create m
(*===-- Target ------------------------------------------------------------===*)
@@ -83,181 +82,189 @@ let test_target () =
(*===-- Types -------------------------------------------------------------===*)
let test_types () =
- (* RUN: grep {Ty01.*void} < %t.ll
+ (* RUN: grep {void_type.*void} < %t.ll
*)
group "void";
- insist (define_type_name "Ty01" void_type m);
+ insist (define_type_name "void_type" void_type m);
insist (TypeKind.Void == classify_type void_type);
- (* RUN: grep {Ty02.*i1} < %t.ll
+ (* RUN: grep {i1_type.*i1} < %t.ll
*)
group "i1";
- insist (define_type_name "Ty02" i1_type m);
+ insist (define_type_name "i1_type" i1_type m);
insist (TypeKind.Integer == classify_type i1_type);
- (* RUN: grep {Ty03.*i32} < %t.ll
+ (* RUN: grep {i32_type.*i32} < %t.ll
*)
group "i32";
- insist (define_type_name "Ty03" i32_type m);
+ insist (define_type_name "i32_type" i32_type m);
- (* RUN: grep {Ty04.*i42} < %t.ll
+ (* RUN: grep {i42_type.*i42} < %t.ll
*)
group "i42";
let ty = integer_type context 42 in
- insist (define_type_name "Ty04" ty m);
+ insist (define_type_name "i42_type" ty m);
- (* RUN: grep {Ty05.*float} < %t.ll
+ (* RUN: grep {float_type.*float} < %t.ll
*)
group "float";
- insist (define_type_name "Ty05" float_type m);
+ insist (define_type_name "float_type" float_type m);
insist (TypeKind.Float == classify_type float_type);
- (* RUN: grep {Ty06.*double} < %t.ll
+ (* RUN: grep {double_type.*double} < %t.ll
*)
group "double";
- insist (define_type_name "Ty06" double_type m);
+ insist (define_type_name "double_type" double_type m);
insist (TypeKind.Double == classify_type double_type);
- (* RUN: grep {Ty07.*i32.*i1, double} < %t.ll
+ (* RUN: grep {function_type.*i32.*i1, double} < %t.ll
*)
group "function";
let ty = function_type i32_type [| i1_type; double_type |] in
- insist (define_type_name "Ty07" ty m);
+ insist (define_type_name "function_type" ty m);
insist (TypeKind.Function = classify_type ty);
insist (not (is_var_arg ty));
insist (i32_type == return_type ty);
insist (double_type == (param_types ty).(1));
- (* RUN: grep {Ty08.*\.\.\.} < %t.ll
+ (* RUN: grep {var_arg_type.*\.\.\.} < %t.ll
*)
group "var arg function";
let ty = var_arg_function_type void_type [| i32_type |] in
- insist (define_type_name "Ty08" ty m);
+ insist (define_type_name "var_arg_type" ty m);
insist (is_var_arg ty);
- (* RUN: grep {Ty09.*\\\[7 x i8\\\]} < %t.ll
+ (* RUN: grep {array_type.*\\\[7 x i8\\\]} < %t.ll
*)
group "array";
let ty = array_type i8_type 7 in
- insist (define_type_name "Ty09" ty m);
+ insist (define_type_name "array_type" ty m);
insist (7 = array_length ty);
insist (i8_type == element_type ty);
insist (TypeKind.Array == classify_type ty);
begin group "pointer";
- (* RUN: grep {UnqualPtrTy.*float\*} < %t.ll
+ (* RUN: grep {pointer_type.*float\*} < %t.ll
*)
let ty = pointer_type float_type in
- insist (define_type_name "UnqualPtrTy" ty m);
+ insist (define_type_name "pointer_type" ty m);
insist (float_type == element_type ty);
insist (0 == address_space ty);
insist (TypeKind.Pointer == classify_type ty)
end;
begin group "qualified_pointer";
- (* RUN: grep {QualPtrTy.*i8.*3.*\*} < %t.ll
+ (* RUN: grep {qualified_pointer_type.*i8.*3.*\*} < %t.ll
*)
let ty = qualified_pointer_type i8_type 3 in
- insist (define_type_name "QualPtrTy" ty m);
+ insist (define_type_name "qualified_pointer_type" ty m);
insist (i8_type == element_type ty);
insist (3 == address_space ty)
end;
- (* RUN: grep {Ty11.*\<4 x i16\>} < %t.ll
+ (* RUN: grep {vector_type.*\<4 x i16\>} < %t.ll
*)
group "vector";
let ty = vector_type i16_type 4 in
- insist (define_type_name "Ty11" ty m);
+ insist (define_type_name "vector_type" ty m);
insist (i16_type == element_type ty);
insist (4 = vector_size ty);
- (* RUN: grep {Ty12.*opaque} < %t.ll
+ (* RUN: grep {opaque_type.*opaque} < %t.ll
*)
group "opaque";
let ty = opaque_type context in
- insist (define_type_name "Ty12" ty m);
+ insist (define_type_name "opaque_type" ty m);
insist (ty == ty);
insist (ty <> opaque_type context);
- (* RUN: grep -v {Ty13} < %t.ll
+ (* RUN: grep -v {delete_type} < %t.ll
*)
group "delete";
let ty = opaque_type context in
- insist (define_type_name "Ty13" ty m);
- delete_type_name "Ty13" m;
+ insist (define_type_name "delete_type" ty m);
+ delete_type_name "delete_type" m;
+
+ (* RUN: grep {type_name.*opaque} < %t.ll
+ *)
+ group "type_name"; begin
+ let ty = opaque_type context in
+ insist (define_type_name "type_name" ty m);
+ insist ((type_by_name m "type_name") = Some ty)
+ end;
- (* RUN: grep -v {RecursiveTy.*RecursiveTy} < %t.ll
+ (* RUN: grep -v {recursive_type.*recursive_type} < %t.ll
*)
group "recursive";
let ty = opaque_type context in
let th = handle_to_type ty in
refine_type ty (pointer_type ty);
let ty = type_of_handle th in
- insist (define_type_name "RecursiveTy" ty m);
+ insist (define_type_name "recursive_type" ty m);
insist (ty == element_type ty)
(*===-- Constants ---------------------------------------------------------===*)
let test_constants () =
- (* RUN: grep {Const01.*i32.*-1} < %t.ll
+ (* RUN: grep {const_int.*i32.*-1} < %t.ll
*)
group "int";
let c = const_int i32_type (-1) in
- ignore (define_global "Const01" c m);
+ ignore (define_global "const_int" c m);
insist (i32_type = type_of c);
insist (is_constant c);
- (* RUN: grep {Const02.*i64.*-1} < %t.ll
+ (* RUN: grep {const_sext_int.*i64.*-1} < %t.ll
*)
group "sext int";
let c = const_int i64_type (-1) in
- ignore (define_global "Const02" c m);
+ ignore (define_global "const_sext_int" c m);
insist (i64_type = type_of c);
- (* RUN: grep {Const03.*i64.*4294967295} < %t.ll
+ (* RUN: grep {const_zext_int64.*i64.*4294967295} < %t.ll
*)
group "zext int64";
let c = const_of_int64 i64_type (Int64.of_string "4294967295") false in
- ignore (define_global "Const03" c m);
+ ignore (define_global "const_zext_int64" c m);
insist (i64_type = type_of c);
- (* RUN: grep {ConstIntString.*i32.*-1} < %t.ll
+ (* RUN: grep {const_int_string.*i32.*-1} < %t.ll
*)
group "int string";
let c = const_int_of_string i32_type "-1" 10 in
- ignore (define_global "ConstIntString" c m);
+ ignore (define_global "const_int_string" c m);
insist (i32_type = type_of c);
- (* RUN: grep {Const04.*"cruel\\\\00world"} < %t.ll
+ (* RUN: grep {const_string.*"cruel\\\\00world"} < %t.ll
*)
group "string";
let c = const_string context "cruel\000world" in
- ignore (define_global "Const04" c m);
+ ignore (define_global "const_string" c m);
insist ((array_type i8_type 11) = type_of c);
- (* RUN: grep {Const05.*"hi\\\\00again\\\\00"} < %t.ll
+ (* RUN: grep {const_stringz.*"hi\\\\00again\\\\00"} < %t.ll
*)
group "stringz";
let c = const_stringz context "hi\000again" in
- ignore (define_global "Const05" c m);
+ ignore (define_global "const_stringz" c m);
insist ((array_type i8_type 9) = type_of c);
- (* RUN: grep {ConstSingle.*2.75} < %t.ll
- * RUN: grep {ConstDouble.*3.1459} < %t.ll
- * RUN: grep {ConstDoubleString.*1.25} < %t.ll
+ (* RUN: grep {const_single.*2.75} < %t.ll
+ * RUN: grep {const_double.*3.1459} < %t.ll
+ * RUN: grep {const_double_string.*1.25} < %t.ll
*)
begin group "real";
let cs = const_float float_type 2.75 in
- ignore (define_global "ConstSingle" cs m);
+ ignore (define_global "const_single" cs m);
insist (float_type = type_of cs);
let cd = const_float double_type 3.1459 in
- ignore (define_global "ConstDouble" cd m);
+ ignore (define_global "const_double" cd m);
insist (double_type = type_of cd);
let cd = const_float_of_string double_type "1.25" in
- ignore (define_global "ConstDoubleString" cd m);
+ ignore (define_global "const_double_string" cd m);
insist (double_type = type_of cd)
end;
@@ -266,67 +273,93 @@ let test_constants () =
let three = const_int i32_type 3 in
let four = const_int i32_type 4 in
- (* RUN: grep {Const07.*\\\[i32 3, i32 4\\\]} < %t.ll
+ (* RUN: grep {const_array.*\\\[i32 3, i32 4\\\]} < %t.ll
*)
group "array";
let c = const_array i32_type [| three; four |] in
- ignore (define_global "Const07" c m);
+ ignore (define_global "const_array" c m);
insist ((array_type i32_type 2) = (type_of c));
- (* RUN: grep {Const08.*<i16 1, i16 2.*>} < %t.ll
+ (* RUN: grep {const_vector.*<i16 1, i16 2.*>} < %t.ll
*)
group "vector";
let c = const_vector [| one; two; one; two;
one; two; one; two |] in
- ignore (define_global "Const08" c m);
+ ignore (define_global "const_vector" c m);
insist ((vector_type i16_type 8) = (type_of c));
- (* RUN: grep {Const09.*.i16 1, i16 2, i32 3, i32 4} < %t.ll
+ (* RUN: grep {const_structure.*.i16 1, i16 2, i32 3, i32 4} < %t.ll
*)
group "structure";
let c = const_struct context [| one; two; three; four |] in
- ignore (define_global "Const09" c m);
+ ignore (define_global "const_structure" c m);
insist ((struct_type context [| i16_type; i16_type; i32_type; i32_type |])
= (type_of c));
+
+ group "union";
+ let t = union_type context [| i1_type; i16_type; i64_type; double_type |] in
+ let c = const_union t one in
+ ignore (define_global "const_union" c m);
+ insist (t = (type_of c));
- (* RUN: grep {Const10.*zeroinit} < %t.ll
+ (* RUN: grep {const_null.*zeroinit} < %t.ll
*)
group "null";
let c = const_null (packed_struct_type context [| i1_type; i8_type; i64_type;
double_type |]) in
- ignore (define_global "Const10" c m);
+ ignore (define_global "const_null" c m);
- (* RUN: grep {Const11.*-1} < %t.ll
+ (* RUN: grep {const_all_ones.*-1} < %t.ll
*)
group "all ones";
let c = const_all_ones i64_type in
- ignore (define_global "Const11" c m);
+ ignore (define_global "const_all_ones" c m);
+
+ group "pointer null"; begin
+ (* RUN: grep {const_pointer_null = global i64\\* null} < %t.ll
+ *)
+ let c = const_pointer_null (pointer_type i64_type) in
+ ignore (define_global "const_pointer_null" c m);
+ end;
- (* RUN: grep {Const12.*undef} < %t.ll
+ (* RUN: grep {const_undef.*undef} < %t.ll
*)
group "undef";
let c = undef i1_type in
- ignore (define_global "Const12" c m);
+ ignore (define_global "const_undef" c m);
insist (i1_type = type_of c);
insist (is_undef c);
group "constant arithmetic";
- (* RUN: grep {ConstNeg.*sub} < %t.ll
- * RUN: grep {ConstNot.*xor} < %t.ll
- * RUN: grep {ConstAdd.*add} < %t.ll
- * RUN: grep {ConstSub.*sub} < %t.ll
- * RUN: grep {ConstMul.*mul} < %t.ll
- * RUN: grep {ConstUDiv.*udiv} < %t.ll
- * RUN: grep {ConstSDiv.*sdiv} < %t.ll
- * RUN: grep {ConstFDiv.*fdiv} < %t.ll
- * RUN: grep {ConstURem.*urem} < %t.ll
- * RUN: grep {ConstSRem.*srem} < %t.ll
- * RUN: grep {ConstFRem.*frem} < %t.ll
- * RUN: grep {ConstAnd.*and} < %t.ll
- * RUN: grep {ConstOr.*or} < %t.ll
- * RUN: grep {ConstXor.*xor} < %t.ll
- * RUN: grep {ConstICmp.*icmp} < %t.ll
- * RUN: grep {ConstFCmp.*fcmp} < %t.ll
+ (* RUN: grep {@const_neg = global i64 sub} < %t.ll
+ * RUN: grep {@const_nsw_neg = global i64 sub nsw } < %t.ll
+ * RUN: grep {@const_nuw_neg = global i64 sub nuw } < %t.ll
+ * RUN: grep {@const_fneg = global double fsub } < %t.ll
+ * RUN: grep {@const_not = global i64 xor } < %t.ll
+ * RUN: grep {@const_add = global i64 add } < %t.ll
+ * RUN: grep {@const_nsw_add = global i64 add nsw } < %t.ll
+ * RUN: grep {@const_nuw_add = global i64 add nuw } < %t.ll
+ * RUN: grep {@const_fadd = global double fadd } < %t.ll
+ * RUN: grep {@const_sub = global i64 sub } < %t.ll
+ * RUN: grep {@const_nsw_sub = global i64 sub nsw } < %t.ll
+ * RUN: grep {@const_nuw_sub = global i64 sub nuw } < %t.ll
+ * RUN: grep {@const_fsub = global double fsub } < %t.ll
+ * RUN: grep {@const_mul = global i64 mul } < %t.ll
+ * RUN: grep {@const_nsw_mul = global i64 mul nsw } < %t.ll
+ * RUN: grep {@const_nuw_mul = global i64 mul nuw } < %t.ll
+ * RUN: grep {@const_fmul = global double fmul } < %t.ll
+ * RUN: grep {@const_udiv = global i64 udiv } < %t.ll
+ * RUN: grep {@const_sdiv = global i64 sdiv } < %t.ll
+ * RUN: grep {@const_exact_sdiv = global i64 sdiv exact } < %t.ll
+ * RUN: grep {@const_fdiv = global double fdiv } < %t.ll
+ * RUN: grep {@const_urem = global i64 urem } < %t.ll
+ * RUN: grep {@const_srem = global i64 srem } < %t.ll
+ * RUN: grep {@const_frem = global double frem } < %t.ll
+ * RUN: grep {@const_and = global i64 and } < %t.ll
+ * RUN: grep {@const_or = global i64 or } < %t.ll
+ * RUN: grep {@const_xor = global i64 xor } < %t.ll
+ * RUN: grep {@const_icmp = global i1 icmp sle } < %t.ll
+ * RUN: grep {@const_fcmp = global i1 fcmp ole } < %t.ll
*)
let void_ptr = pointer_type i8_type in
let five = const_int i64_type 5 in
@@ -334,82 +367,105 @@ let test_constants () =
let foldbomb_gv = define_global "FoldBomb" (const_null i8_type) m in
let foldbomb = const_ptrtoint foldbomb_gv i64_type in
let ffoldbomb = const_uitofp foldbomb double_type in
- ignore (define_global "ConstNeg" (const_neg foldbomb) m);
- ignore (define_global "ConstNot" (const_not foldbomb) m);
- ignore (define_global "ConstAdd" (const_add foldbomb five) m);
- ignore (define_global "ConstSub" (const_sub foldbomb five) m);
- ignore (define_global "ConstMul" (const_mul foldbomb five) m);
- ignore (define_global "ConstUDiv" (const_udiv foldbomb five) m);
- ignore (define_global "ConstSDiv" (const_sdiv foldbomb five) m);
- ignore (define_global "ConstFDiv" (const_fdiv ffoldbomb ffive) m);
- ignore (define_global "ConstURem" (const_urem foldbomb five) m);
- ignore (define_global "ConstSRem" (const_srem foldbomb five) m);
- ignore (define_global "ConstFRem" (const_frem ffoldbomb ffive) m);
- ignore (define_global "ConstAnd" (const_and foldbomb five) m);
- ignore (define_global "ConstOr" (const_or foldbomb five) m);
- ignore (define_global "ConstXor" (const_xor foldbomb five) m);
- ignore (define_global "ConstICmp" (const_icmp Icmp.Sle foldbomb five) m);
- ignore (define_global "ConstFCmp" (const_fcmp Fcmp.Ole ffoldbomb ffive) m);
+ ignore (define_global "const_neg" (const_neg foldbomb) m);
+ ignore (define_global "const_nsw_neg" (const_nsw_neg foldbomb) m);
+ ignore (define_global "const_nuw_neg" (const_nuw_neg foldbomb) m);
+ ignore (define_global "const_fneg" (const_fneg ffoldbomb) m);
+ ignore (define_global "const_not" (const_not foldbomb) m);
+ ignore (define_global "const_add" (const_add foldbomb five) m);
+ ignore (define_global "const_nsw_add" (const_nsw_add foldbomb five) m);
+ ignore (define_global "const_nuw_add" (const_nuw_add foldbomb five) m);
+ ignore (define_global "const_fadd" (const_fadd ffoldbomb ffive) m);
+ ignore (define_global "const_sub" (const_sub foldbomb five) m);
+ ignore (define_global "const_nsw_sub" (const_nsw_sub foldbomb five) m);
+ ignore (define_global "const_nuw_sub" (const_nuw_sub foldbomb five) m);
+ ignore (define_global "const_fsub" (const_fsub ffoldbomb ffive) m);
+ ignore (define_global "const_mul" (const_mul foldbomb five) m);
+ ignore (define_global "const_nsw_mul" (const_nsw_mul foldbomb five) m);
+ ignore (define_global "const_nuw_mul" (const_nuw_mul foldbomb five) m);
+ ignore (define_global "const_fmul" (const_fmul ffoldbomb ffive) m);
+ ignore (define_global "const_udiv" (const_udiv foldbomb five) m);
+ ignore (define_global "const_sdiv" (const_sdiv foldbomb five) m);
+ ignore (define_global "const_exact_sdiv" (const_exact_sdiv foldbomb five) m);
+ ignore (define_global "const_fdiv" (const_fdiv ffoldbomb ffive) m);
+ ignore (define_global "const_urem" (const_urem foldbomb five) m);
+ ignore (define_global "const_srem" (const_srem foldbomb five) m);
+ ignore (define_global "const_frem" (const_frem ffoldbomb ffive) m);
+ ignore (define_global "const_and" (const_and foldbomb five) m);
+ ignore (define_global "const_or" (const_or foldbomb five) m);
+ ignore (define_global "const_xor" (const_xor foldbomb five) m);
+ ignore (define_global "const_icmp" (const_icmp Icmp.Sle foldbomb five) m);
+ ignore (define_global "const_fcmp" (const_fcmp Fcmp.Ole ffoldbomb ffive) m);
group "constant casts";
- (* RUN: grep {ConstTrunc.*trunc} < %t.ll
- * RUN: grep {ConstSExt.*sext} < %t.ll
- * RUN: grep {ConstZExt.*zext} < %t.ll
- * RUN: grep {ConstFPTrunc.*fptrunc} < %t.ll
- * RUN: grep {ConstFPExt.*fpext} < %t.ll
- * RUN: grep {ConstUIToFP.*uitofp} < %t.ll
- * RUN: grep {ConstSIToFP.*sitofp} < %t.ll
- * RUN: grep {ConstFPToUI.*fptoui} < %t.ll
- * RUN: grep {ConstFPToSI.*fptosi} < %t.ll
- * RUN: grep {ConstPtrToInt.*ptrtoint} < %t.ll
- * RUN: grep {ConstIntToPtr.*inttoptr} < %t.ll
- * RUN: grep {ConstBitCast.*bitcast} < %t.ll
+ (* RUN: grep {const_trunc.*trunc} < %t.ll
+ * RUN: grep {const_sext.*sext} < %t.ll
+ * RUN: grep {const_zext.*zext} < %t.ll
+ * RUN: grep {const_fptrunc.*fptrunc} < %t.ll
+ * RUN: grep {const_fpext.*fpext} < %t.ll
+ * RUN: grep {const_uitofp.*uitofp} < %t.ll
+ * RUN: grep {const_sitofp.*sitofp} < %t.ll
+ * RUN: grep {const_fptoui.*fptoui} < %t.ll
+ * RUN: grep {const_fptosi.*fptosi} < %t.ll
+ * RUN: grep {const_ptrtoint.*ptrtoint} < %t.ll
+ * RUN: grep {const_inttoptr.*inttoptr} < %t.ll
+ * RUN: grep {const_bitcast.*bitcast} < %t.ll
*)
let i128_type = integer_type context 128 in
- ignore (define_global "ConstTrunc" (const_trunc (const_add foldbomb five)
+ ignore (define_global "const_trunc" (const_trunc (const_add foldbomb five)
i8_type) m);
- ignore (define_global "ConstSExt" (const_sext foldbomb i128_type) m);
- ignore (define_global "ConstZExt" (const_zext foldbomb i128_type) m);
- ignore (define_global "ConstFPTrunc" (const_fptrunc ffoldbomb float_type) m);
- ignore (define_global "ConstFPExt" (const_fpext ffoldbomb fp128_type) m);
- ignore (define_global "ConstUIToFP" (const_uitofp foldbomb double_type) m);
- ignore (define_global "ConstSIToFP" (const_sitofp foldbomb double_type) m);
- ignore (define_global "ConstFPToUI" (const_fptoui ffoldbomb i32_type) m);
- ignore (define_global "ConstFPToSI" (const_fptosi ffoldbomb i32_type) m);
- ignore (define_global "ConstPtrToInt" (const_ptrtoint
+ ignore (define_global "const_sext" (const_sext foldbomb i128_type) m);
+ ignore (define_global "const_zext" (const_zext foldbomb i128_type) m);
+ ignore (define_global "const_fptrunc" (const_fptrunc ffoldbomb float_type) m);
+ ignore (define_global "const_fpext" (const_fpext ffoldbomb fp128_type) m);
+ ignore (define_global "const_uitofp" (const_uitofp foldbomb double_type) m);
+ ignore (define_global "const_sitofp" (const_sitofp foldbomb double_type) m);
+ ignore (define_global "const_fptoui" (const_fptoui ffoldbomb i32_type) m);
+ ignore (define_global "const_fptosi" (const_fptosi ffoldbomb i32_type) m);
+ ignore (define_global "const_ptrtoint" (const_ptrtoint
(const_gep (const_null (pointer_type i8_type))
[| const_int i32_type 1 |])
i32_type) m);
- ignore (define_global "ConstIntToPtr" (const_inttoptr (const_add foldbomb five)
+ ignore (define_global "const_inttoptr" (const_inttoptr (const_add foldbomb five)
void_ptr) m);
- ignore (define_global "ConstBitCast" (const_bitcast ffoldbomb i64_type) m);
+ ignore (define_global "const_bitcast" (const_bitcast ffoldbomb i64_type) m);
group "misc constants";
- (* RUN: grep {ConstSizeOf.*getelementptr.*null} < %t.ll
- * RUN: grep {ConstGEP.*getelementptr} < %t.ll
- * RUN: grep {ConstSelect.*select} < %t.ll
- * RUN: grep {ConstExtractElement.*extractelement} < %t.ll
- * RUN: grep {ConstInsertElement.*insertelement} < %t.ll
- * RUN: grep {ConstShuffleVector.*shufflevector} < %t.ll
+ (* RUN: grep {const_size_of.*getelementptr.*null} < %t.ll
+ * RUN: grep {const_gep.*getelementptr} < %t.ll
+ * RUN: grep {const_select.*select} < %t.ll
+ * RUN: grep {const_extractelement.*extractelement} < %t.ll
+ * RUN: grep {const_insertelement.*insertelement} < %t.ll
+ * RUN: grep {const_shufflevector.*shufflevector} < %t.ll
*)
- ignore (define_global "ConstSizeOf" (size_of (pointer_type i8_type)) m);
- ignore (define_global "ConstGEP" (const_gep foldbomb_gv [| five |]) m);
- ignore (define_global "ConstSelect" (const_select
+ ignore (define_global "const_size_of" (size_of (pointer_type i8_type)) m);
+ ignore (define_global "const_gep" (const_gep foldbomb_gv [| five |]) m);
+ ignore (define_global "const_select" (const_select
(const_icmp Icmp.Sle foldbomb five)
(const_int i8_type (-1))
(const_int i8_type 0)) m);
let zero = const_int i32_type 0 in
let one = const_int i32_type 1 in
- ignore (define_global "ConstExtractElement" (const_extractelement
+ ignore (define_global "const_extractelement" (const_extractelement
(const_vector [| zero; one; zero; one |])
(const_trunc foldbomb i32_type)) m);
- ignore (define_global "ConstInsertElement" (const_insertelement
+ ignore (define_global "const_insertelement" (const_insertelement
(const_vector [| zero; one; zero; one |])
zero (const_trunc foldbomb i32_type)) m);
- ignore (define_global "ConstShuffleVector" (const_shufflevector
+ ignore (define_global "const_shufflevector" (const_shufflevector
(const_vector [| zero; one |])
(const_vector [| one; zero |])
- (const_bitcast foldbomb (vector_type i32_type 2))) m)
+ (const_bitcast foldbomb (vector_type i32_type 2))) m);
+
+ group "asm"; begin
+ let ft = function_type void_type [| i32_type; i32_type; i32_type |] in
+ ignore (const_inline_asm
+ ft
+ ""
+ "{cx},{ax},{di},~{dirflag},~{fpsr},~{flags},~{edi},~{ecx}"
+ true
+ false)
+ end
(*===-- Global Values -----------------------------------------------------===*)
@@ -461,28 +517,46 @@ let test_global_variables () =
let (++) x f = f x; x in
let fourty_two32 = const_int i32_type 42 in
- (* RUN: grep {GVar01.*external} < %t.ll
- *)
- group "declarations";
- insist (None == lookup_global "GVar01" m);
- let g = declare_global i32_type "GVar01" m in
- insist (is_declaration g);
- insist (pointer_type float_type ==
- type_of (declare_global float_type "GVar01" m));
- insist (g == declare_global i32_type "GVar01" m);
- insist (match lookup_global "GVar01" m with Some x -> x = g
- | None -> false);
+ group "declarations"; begin
+ (* RUN: grep {GVar01.*external} < %t.ll
+ *)
+ insist (None == lookup_global "GVar01" m);
+ let g = declare_global i32_type "GVar01" m in
+ insist (is_declaration g);
+ insist (pointer_type float_type ==
+ type_of (declare_global float_type "GVar01" m));
+ insist (g == declare_global i32_type "GVar01" m);
+ insist (match lookup_global "GVar01" m with Some x -> x = g
+ | None -> false);
+
+ insist (None == lookup_global "QGVar01" m);
+ let g = declare_qualified_global i32_type "QGVar01" 3 m in
+ insist (is_declaration g);
+ insist (qualified_pointer_type float_type 3 ==
+ type_of (declare_qualified_global float_type "QGVar01" 3 m));
+ insist (g == declare_qualified_global i32_type "QGVar01" 3 m);
+ insist (match lookup_global "QGVar01" m with Some x -> x = g
+ | None -> false);
+ end;
- (* RUN: grep {GVar02.*42} < %t.ll
- * RUN: grep {GVar03.*42} < %t.ll
- *)
- group "definitions";
- let g = define_global "GVar02" fourty_two32 m in
- let g2 = declare_global i32_type "GVar03" m ++
+ group "definitions"; begin
+ (* RUN: grep {GVar02.*42} < %t.ll
+ * RUN: grep {GVar03.*42} < %t.ll
+ *)
+ let g = define_global "GVar02" fourty_two32 m in
+ let g2 = declare_global i32_type "GVar03" m ++
+ set_initializer fourty_two32 in
+ insist (not (is_declaration g));
+ insist (not (is_declaration g2));
+ insist ((global_initializer g) == (global_initializer g2));
+
+ let g = define_qualified_global "QGVar02" fourty_two32 3 m in
+ let g2 = declare_qualified_global i32_type "QGVar03" 3 m ++
set_initializer fourty_two32 in
- insist (not (is_declaration g));
- insist (not (is_declaration g2));
- insist ((global_initializer g) == (global_initializer g2));
+ insist (not (is_declaration g));
+ insist (not (is_declaration g2));
+ insist ((global_initializer g) == (global_initializer g2));
+ end;
(* RUN: grep {GVar04.*thread_local} < %t.ll
*)
@@ -532,6 +606,59 @@ let test_global_variables () =
end
+(*===-- Uses --------------------------------------------------------------===*)
+
+let test_uses () =
+ let ty = function_type i32_type [| i32_type; i32_type |] in
+ let fn = define_function "use_function" ty m in
+ let b = builder_at_end context (entry_block fn) in
+
+ let p1 = param fn 0 in
+ let p2 = param fn 1 in
+ let v1 = build_add p1 p2 "v1" b in
+ let v2 = build_add p1 v1 "v2" b in
+ let _ = build_add v1 v2 "v3" b in
+
+ let lf s u = value_name (user u) ^ "->" ^ s in
+ insist ("v2->v3->" = fold_left_uses lf "" v1);
+ let rf u s = value_name (user u) ^ "<-" ^ s in
+ insist ("v3<-v2<-" = fold_right_uses rf v1 "");
+
+ let lf s u = value_name (used_value u) ^ "->" ^ s in
+ insist ("v1->v1->" = fold_left_uses lf "" v1);
+
+ let rf u s = value_name (used_value u) ^ "<-" ^ s in
+ insist ("v1<-v1<-" = fold_right_uses rf v1 "");
+
+ ignore (build_unreachable b)
+
+
+(*===-- Users -------------------------------------------------------------===*)
+
+let test_users () =
+ let ty = function_type i32_type [| i32_type; i32_type |] in
+ let fn = define_function "user_function" ty m in
+ let b = builder_at_end context (entry_block fn) in
+
+ let p1 = param fn 0 in
+ let p2 = param fn 1 in
+ let i = build_add p1 p2 "sum" b in
+
+ insist ((operand i 0) = p1);
+ insist ((operand i 1) = p2);
+
+ ignore (build_unreachable b)
+
+
+(*===-- Aliases -----------------------------------------------------------===*)
+
+let test_aliases () =
+ (* RUN: grep {@alias = alias i32\\* @aliasee} < %t.ll
+ *)
+ let v = declare_global i32_type "aliasee" m in
+ ignore (add_alias m (pointer_type i32_type) v "alias")
+
+
(*===-- Functions ---------------------------------------------------------===*)
let test_functions () =
@@ -845,11 +972,11 @@ let test_builder () =
end;
group "cond_br"; begin
- (* RUN: grep {br.*Inst01.*Bb03.*Bb00} < %t.ll
+ (* RUN: grep {br.*build_br.*Bb03.*Bb00} < %t.ll
*)
let bb03 = append_block context "Bb03" fn in
let b = builder_at_end context bb03 in
- let cond = build_trunc p1 i1_type "Inst01" b in
+ let cond = build_trunc p1 i1_type "build_br" b in
ignore (build_cond_br cond bb03 bb00 b)
end;
@@ -865,14 +992,31 @@ let test_builder () =
let si = build_switch p1 bb3 1 (builder_at_end context bb1) in
ignore (add_case si (const_int i32_type 2) bb2)
end;
+
+ group "indirectbr"; begin
+ (* RUN: grep {indirectbr i8\\* blockaddress(@X7, %IBRBlock2), \\\[label %IBRBlock2, label %IBRBlock3\\\]} < %t.ll
+ *)
+ let bb1 = append_block context "IBRBlock1" fn in
+
+ let bb2 = append_block context "IBRBlock2" fn in
+ ignore (build_unreachable (builder_at_end context bb2));
+
+ let bb3 = append_block context "IBRBlock3" fn in
+ ignore (build_unreachable (builder_at_end context bb3));
+
+ let addr = block_address fn bb2 in
+ let ibr = build_indirect_br addr 2 (builder_at_end context bb1) in
+ ignore (add_destination ibr bb2);
+ ignore (add_destination ibr bb3)
+ end;
group "invoke"; begin
- (* RUN: grep {Inst02.*invoke.*P1.*P2} < %t.ll
+ (* RUN: grep {build_invoke.*invoke.*P1.*P2} < %t.ll
* RUN: grep {to.*Bb04.*unwind.*Bb00} < %t.ll
*)
let bb04 = append_block context "Bb04" fn in
let b = builder_at_end context bb04 in
- ignore (build_invoke fn [| p1; p2 |] bb04 bb00 "Inst02" b)
+ ignore (build_invoke fn [| p1; p2 |] bb04 bb00 "build_invoke" b)
end;
group "unwind"; begin
@@ -895,121 +1039,139 @@ let test_builder () =
let bb07 = append_block context "Bb07" fn in
let b = builder_at_end context bb07 in
- (* RUN: grep {Inst03.*add.*P1.*P2} < %t.ll
- * RUN: grep {Inst04.*sub.*P1.*Inst03} < %t.ll
- * RUN: grep {Inst05.*mul.*P1.*Inst04} < %t.ll
- * RUN: grep {Inst06.*udiv.*P1.*Inst05} < %t.ll
- * RUN: grep {Inst07.*sdiv.*P1.*Inst06} < %t.ll
- * RUN: grep {Inst08.*fdiv.*F1.*F2} < %t.ll
- * RUN: grep {Inst09.*urem.*P1.*Inst07} < %t.ll
- * RUN: grep {Inst10.*srem.*P1.*Inst09} < %t.ll
- * RUN: grep {Inst11.*frem.*F1.*Inst08} < %t.ll
- * RUN: grep {Inst12.*shl.*P1.*Inst10} < %t.ll
- * RUN: grep {Inst13.*lshr.*P1.*Inst12} < %t.ll
- * RUN: grep {Inst14.*ashr.*P1.*Inst13} < %t.ll
- * RUN: grep {Inst15.*and.*P1.*Inst14} < %t.ll
- * RUN: grep {Inst16.*or.*P1.*Inst15} < %t.ll
- * RUN: grep {Inst17.*xor.*P1.*Inst16} < %t.ll
- * RUN: grep {Inst18.*sub.*0.*Inst17} < %t.ll
- * RUN: grep {Inst19.*xor.*Inst18.*-1} < %t.ll
+ (* RUN: grep {%build_add = add i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_nsw_add = add nsw i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_nuw_add = add nuw i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_fadd = fadd float %F1, %F2} < %t.ll
+ * RUN: grep {%build_sub = sub i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_nsw_sub = sub nsw i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_nuw_sub = sub nuw i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_fsub = fsub float %F1, %F2} < %t.ll
+ * RUN: grep {%build_mul = mul i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_nsw_mul = mul nsw i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_nuw_mul = mul nuw i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_fmul = fmul float %F1, %F2} < %t.ll
+ * RUN: grep {%build_udiv = udiv i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_sdiv = sdiv i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_exact_sdiv = sdiv exact i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_fdiv = fdiv float %F1, %F2} < %t.ll
+ * RUN: grep {%build_urem = urem i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_srem = srem i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_frem = frem float %F1, %F2} < %t.ll
+ * RUN: grep {%build_shl = shl i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_lshl = lshr i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_ashl = ashr i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_and = and i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_or = or i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_xor = xor i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_neg = sub i32 0, %P1} < %t.ll
+ * RUN: grep {%build_nsw_neg = sub nsw i32 0, %P1} < %t.ll
+ * RUN: grep {%build_nuw_neg = sub nuw i32 0, %P1} < %t.ll
+ * RUN: grep {%build_fneg = fsub float .*0.*, %F1} < %t.ll
+ * RUN: grep {%build_not = xor i32 %P1, -1} < %t.ll
*)
- let inst03 = build_add p1 p2 "Inst03" b in
- let inst04 = build_sub p1 inst03 "Inst04" b in
- let inst05 = build_mul p1 inst04 "Inst05" b in
- let inst06 = build_udiv p1 inst05 "Inst06" b in
- let inst07 = build_sdiv p1 inst06 "Inst07" b in
- let inst08 = build_fdiv f1 f2 "Inst08" b in
- let inst09 = build_urem p1 inst07 "Inst09" b in
- let inst10 = build_srem p1 inst09 "Inst10" b in
- ignore(build_frem f1 inst08 "Inst11" b);
- let inst12 = build_shl p1 inst10 "Inst12" b in
- let inst13 = build_lshr p1 inst12 "Inst13" b in
- let inst14 = build_ashr p1 inst13 "Inst14" b in
- let inst15 = build_and p1 inst14 "Inst15" b in
- let inst16 = build_or p1 inst15 "Inst16" b in
- let inst17 = build_xor p1 inst16 "Inst17" b in
- let inst18 = build_neg inst17 "Inst18" b in
- ignore (build_not inst18 "Inst19" b);
- ignore (build_unreachable b)
+ ignore (build_add p1 p2 "build_add" b);
+ ignore (build_nsw_add p1 p2 "build_nsw_add" b);
+ ignore (build_nuw_add p1 p2 "build_nuw_add" b);
+ ignore (build_fadd f1 f2 "build_fadd" b);
+ ignore (build_sub p1 p2 "build_sub" b);
+ ignore (build_nsw_sub p1 p2 "build_nsw_sub" b);
+ ignore (build_nuw_sub p1 p2 "build_nuw_sub" b);
+ ignore (build_fsub f1 f2 "build_fsub" b);
+ ignore (build_mul p1 p2 "build_mul" b);
+ ignore (build_nsw_mul p1 p2 "build_nsw_mul" b);
+ ignore (build_nuw_mul p1 p2 "build_nuw_mul" b);
+ ignore (build_fmul f1 f2 "build_fmul" b);
+ ignore (build_udiv p1 p2 "build_udiv" b);
+ ignore (build_sdiv p1 p2 "build_sdiv" b);
+ ignore (build_exact_sdiv p1 p2 "build_exact_sdiv" b);
+ ignore (build_fdiv f1 f2 "build_fdiv" b);
+ ignore (build_urem p1 p2 "build_urem" b);
+ ignore (build_srem p1 p2 "build_srem" b);
+ ignore (build_frem f1 f2 "build_frem" b);
+ ignore (build_shl p1 p2 "build_shl" b);
+ ignore (build_lshr p1 p2 "build_lshl" b);
+ ignore (build_ashr p1 p2 "build_ashl" b);
+ ignore (build_and p1 p2 "build_and" b);
+ ignore (build_or p1 p2 "build_or" b);
+ ignore (build_xor p1 p2 "build_xor" b);
+ ignore (build_neg p1 "build_neg" b);
+ ignore (build_nsw_neg p1 "build_nsw_neg" b);
+ ignore (build_nuw_neg p1 "build_nuw_neg" b);
+ ignore (build_fneg f1 "build_fneg" b);
+ ignore (build_not p1 "build_not" b);
+ ignore (build_unreachable b)
end;
group "memory"; begin
let bb08 = append_block context "Bb08" fn in
let b = builder_at_end context bb08 in
- (* RUN: grep {Inst20.*malloc} < %t.ll
- * RUN: grep {Inst21.*malloc} < %t.ll
- * RUN: grep {Inst22.*alloca.*i32 } < %t.ll
- * RUN: grep {Inst23.*alloca.*i32.*P2} < %t.ll
- * RUN: grep {free.*Inst20} < %t.ll
- * RUN: grep {Inst25.*load.*Inst21} < %t.ll
- * RUN: grep {store.*P2.*Inst22} < %t.ll
- * RUN: grep {Inst27.*getelementptr.*Inst23.*P2} < %t.ll
+ (* RUN: grep {%build_alloca = alloca i32} < %t.ll
+ * RUN: grep {%build_array_alloca = alloca i32, i32 %P2} < %t.ll
+ * RUN: grep {%build_load = load i32\\* %build_array_alloca} < %t.ll
+ * RUN: grep {store i32 %P2, i32\\* %build_alloca} < %t.ll
+ * RUN: grep {%build_gep = getelementptr i32\\* %build_array_alloca, i32 %P2} < %t.ll
*)
- let inst20 = build_malloc i8_type "Inst20" b in
- let inst21 = build_array_malloc i8_type p1 "Inst21" b in
- let inst22 = build_alloca i32_type "Inst22" b in
- let inst23 = build_array_alloca i32_type p2 "Inst23" b in
- ignore(build_free inst20 b);
- ignore(build_load inst21 "Inst25" b);
- ignore(build_store p2 inst22 b);
- ignore(build_gep inst23 [| p2 |] "Inst27" b);
- ignore(build_unreachable b)
+ let alloca = build_alloca i32_type "build_alloca" b in
+ let array_alloca = build_array_alloca i32_type p2 "build_array_alloca" b in
+ ignore(build_load array_alloca "build_load" b);
+ ignore(build_store p2 alloca b);
+ ignore(build_gep array_alloca [| p2 |] "build_gep" b);
+ ignore(build_unreachable b)
end;
group "casts"; begin
let void_ptr = pointer_type i8_type in
- (* RUN: grep {Inst28.*trunc.*P1.*i8} < %t.ll
- * RUN: grep {Inst29.*zext.*Inst28.*i32} < %t.ll
- * RUN: grep {Inst30.*sext.*Inst29.*i64} < %t.ll
- * RUN: grep {Inst31.*uitofp.*Inst30.*float} < %t.ll
- * RUN: grep {Inst32.*sitofp.*Inst29.*double} < %t.ll
- * RUN: grep {Inst33.*fptoui.*Inst31.*i32} < %t.ll
- * RUN: grep {Inst34.*fptosi.*Inst32.*i64} < %t.ll
- * RUN: grep {Inst35.*fptrunc.*Inst32.*float} < %t.ll
- * RUN: grep {Inst36.*fpext.*Inst35.*double} < %t.ll
- * RUN: grep {Inst37.*inttoptr.*P1.*i8\*} < %t.ll
- * RUN: grep {Inst38.*ptrtoint.*Inst37.*i64} < %t.ll
- * RUN: grep {Inst39.*bitcast.*Inst38.*double} < %t.ll
+ (* RUN: grep {%build_trunc = trunc i32 %P1 to i8} < %t.ll
+ * RUN: grep {%build_zext = zext i8 %build_trunc to i32} < %t.ll
+ * RUN: grep {%build_sext = sext i32 %build_zext to i64} < %t.ll
+ * RUN: grep {%build_uitofp = uitofp i64 %build_sext to float} < %t.ll
+ * RUN: grep {%build_sitofp = sitofp i32 %build_zext to double} < %t.ll
+ * RUN: grep {%build_fptoui = fptoui float %build_uitofp to i32} < %t.ll
+ * RUN: grep {%build_fptosi = fptosi double %build_sitofp to i64} < %t.ll
+ * RUN: grep {%build_fptrunc = fptrunc double %build_sitofp to float} < %t.ll
+ * RUN: grep {%build_fpext = fpext float %build_fptrunc to double} < %t.ll
+ * RUN: grep {%build_inttoptr = inttoptr i32 %P1 to i8\\*} < %t.ll
+ * RUN: grep {%build_ptrtoint = ptrtoint i8\\* %build_inttoptr to i64} < %t.ll
+ * RUN: grep {%build_bitcast = bitcast i64 %build_ptrtoint to double} < %t.ll
*)
- let inst28 = build_trunc p1 i8_type "Inst28" atentry in
- let inst29 = build_zext inst28 i32_type "Inst29" atentry in
- let inst30 = build_sext inst29 i64_type "Inst30" atentry in
- let inst31 = build_uitofp inst30 float_type "Inst31" atentry in
- let inst32 = build_sitofp inst29 double_type "Inst32" atentry in
- ignore(build_fptoui inst31 i32_type "Inst33" atentry);
- ignore(build_fptosi inst32 i64_type "Inst34" atentry);
- let inst35 = build_fptrunc inst32 float_type "Inst35" atentry in
- ignore(build_fpext inst35 double_type "Inst36" atentry);
- let inst37 = build_inttoptr p1 void_ptr "Inst37" atentry in
- let inst38 = build_ptrtoint inst37 i64_type "Inst38" atentry in
- ignore(build_bitcast inst38 double_type "Inst39" atentry)
+ let inst28 = build_trunc p1 i8_type "build_trunc" atentry in
+ let inst29 = build_zext inst28 i32_type "build_zext" atentry in
+ let inst30 = build_sext inst29 i64_type "build_sext" atentry in
+ let inst31 = build_uitofp inst30 float_type "build_uitofp" atentry in
+ let inst32 = build_sitofp inst29 double_type "build_sitofp" atentry in
+ ignore(build_fptoui inst31 i32_type "build_fptoui" atentry);
+ ignore(build_fptosi inst32 i64_type "build_fptosi" atentry);
+ let inst35 = build_fptrunc inst32 float_type "build_fptrunc" atentry in
+ ignore(build_fpext inst35 double_type "build_fpext" atentry);
+ let inst37 = build_inttoptr p1 void_ptr "build_inttoptr" atentry in
+ let inst38 = build_ptrtoint inst37 i64_type "build_ptrtoint" atentry in
+ ignore(build_bitcast inst38 double_type "build_bitcast" atentry)
end;
group "comparisons"; begin
- (* RUN: grep {Inst40.*icmp.*ne.*P1.*P2} < %t.ll
- * RUN: grep {Inst41.*icmp.*sle.*P2.*P1} < %t.ll
- * RUN: grep {Inst42.*fcmp.*false.*F1.*F2} < %t.ll
- * RUN: grep {Inst43.*fcmp.*true.*F2.*F1} < %t.ll
+ (* RUN: grep {%build_icmp_ne = icmp ne i32 %P1, %P2} < %t.ll
+ * RUN: grep {%build_icmp_sle = icmp sle i32 %P2, %P1} < %t.ll
+ * RUN: grep {%build_icmp_false = fcmp false float %F1, %F2} < %t.ll
+ * RUN: grep {%build_icmp_true = fcmp true float %F2, %F1} < %t.ll
*)
- ignore (build_icmp Icmp.Ne p1 p2 "Inst40" atentry);
- ignore (build_icmp Icmp.Sle p2 p1 "Inst41" atentry);
- ignore (build_fcmp Fcmp.False f1 f2 "Inst42" atentry);
- ignore (build_fcmp Fcmp.True f2 f1 "Inst43" atentry)
+ ignore (build_icmp Icmp.Ne p1 p2 "build_icmp_ne" atentry);
+ ignore (build_icmp Icmp.Sle p2 p1 "build_icmp_sle" atentry);
+ ignore (build_fcmp Fcmp.False f1 f2 "build_icmp_false" atentry);
+ ignore (build_fcmp Fcmp.True f2 f1 "build_icmp_true" atentry)
end;
group "miscellaneous"; begin
- (* RUN: grep {CallInst.*call.*P2.*P1} < %t.ll
- * RUN: grep {CallInst.*cc63} < %t.ll
- * RUN: grep {Inst47.*select.*Inst46.*P1.*P2} < %t.ll
- * RUN: grep {Inst48.*va_arg.*null.*i32} < %t.ll
- * RUN: grep {Inst49.*extractelement.*Vec1.*P2} < %t.ll
- * RUN: grep {Inst50.*insertelement.*Vec1.*P1.*P2} < %t.ll
- * RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*1.*1.*0.*0} < %t.ll
- * RUN: grep {CallInst.*tail call} < %t.ll
+ (* RUN: grep {%build_call = tail call cc63 i32 @.*(i32 signext %P2, i32 %P1)} < %t.ll
+ * RUN: grep {%build_select = select i1 %build_icmp, i32 %P1, i32 %P2} < %t.ll
+ * RUN: grep {%build_va_arg = va_arg i8\\*\\* null, i32} < %t.ll
+ * RUN: grep {%build_extractelement = extractelement <4 x i32> %Vec1, i32 %P2} < %t.ll
+ * RUN: grep {%build_insertelement = insertelement <4 x i32> %Vec1, i32 %P1, i32 %P2} < %t.ll
+ * RUN: grep {%build_shufflevector = shufflevector <4 x i32> %Vec1, <4 x i32> %Vec2, <4 x i32> <i32 1, i32 1, i32 0, i32 0>} < %t.ll
*)
- let ci = build_call fn [| p2; p1 |] "CallInst" atentry in
+ let ci = build_call fn [| p2; p1 |] "build_call" atentry in
insist (CallConv.c = instruction_call_conv ci);
set_instruction_call_conv 63 ci;
insist (63 = instruction_call_conv ci);
@@ -1020,11 +1182,11 @@ let test_builder () =
add_instruction_param_attr ci 2 Attribute.Noalias;
remove_instruction_param_attr ci 2 Attribute.Noalias;
- let inst46 = build_icmp Icmp.Eq p1 p2 "Inst46" atentry in
- ignore (build_select inst46 p1 p2 "Inst47" atentry);
- ignore (build_va_arg
- (const_null (pointer_type (pointer_type i8_type)))
- i32_type "Inst48" atentry);
+ let inst46 = build_icmp Icmp.Eq p1 p2 "build_icmp" atentry in
+ ignore (build_select inst46 p1 p2 "build_select" atentry);
+ ignore (build_va_arg
+ (const_null (pointer_type (pointer_type i8_type)))
+ i32_type "build_va_arg" atentry);
(* Set up some vector vregs. *)
let one = const_int i32_type 1 in
@@ -1035,9 +1197,49 @@ let test_builder () =
let vec1 = build_insertelement t1 p1 p2 "Vec1" atentry in
let vec2 = build_insertelement t2 p1 p2 "Vec2" atentry in
- ignore (build_extractelement vec1 p2 "Inst49" atentry);
- ignore (build_insertelement vec1 p1 p2 "Inst50" atentry);
- ignore (build_shufflevector vec1 vec2 t3 "Inst51" atentry);
+ ignore (build_extractelement vec1 p2 "build_extractelement" atentry);
+ ignore (build_insertelement vec1 p1 p2 "build_insertelement" atentry);
+ ignore (build_shufflevector vec1 vec2 t3 "build_shufflevector" atentry);
+ end;
+
+ group "metadata"; begin
+ (* RUN: grep {%metadata = add i32 %P1, %P2, !test !0} < %t.ll
+ * RUN: grep {!0 = metadata !\{i32 1, metadata !"metadata test"\}} < %t.ll
+ *)
+ let i = build_add p1 p2 "metadata" atentry in
+ insist ((has_metadata i) = false);
+
+ let m1 = const_int i32_type 1 in
+ let m2 = mdstring context "metadata test" in
+ let md = mdnode context [| m1; m2 |] in
+
+ let kind = mdkind_id context "test" in
+ set_metadata i kind md;
+
+ insist ((has_metadata i) = true);
+ insist ((metadata i kind) = Some md);
+
+ clear_metadata i kind;
+
+ insist ((has_metadata i) = false);
+ insist ((metadata i kind) = None);
+
+ set_metadata i kind md
+ end;
+
+ group "dbg"; begin
+ (* RUN: grep {%dbg = add i32 %P1, %P2, !dbg !1} < %t.ll
+ * RUN: grep {!1 = metadata !\{i32 2, metadata !"dbg test"\}} < %t.ll
+ *)
+ let m1 = const_int i32_type 2 in
+ let m2 = mdstring context "dbg test" in
+ let md = mdnode context [| m1; m2 |] in
+ set_current_debug_location atentry md;
+
+ let i = build_add p1 p2 "dbg" atentry in
+ insist ((has_metadata i) = true);
+
+ clear_current_debug_location atentry
end;
group "phi"; begin
@@ -1061,14 +1263,6 @@ let test_builder () =
end
-(*===-- Module Provider ---------------------------------------------------===*)
-
-let test_module_provider () =
- let m = create_module context "test" in
- let mp = ModuleProvider.create m in
- ModuleProvider.dispose mp
-
-
(*===-- Pass Managers -----------------------------------------------------===*)
let test_pass_manager () =
@@ -1085,7 +1279,7 @@ let test_pass_manager () =
let fn = define_function "FunctionPassManager" fty m in
ignore (build_ret_void (builder_at_end context (entry_block fn)));
- ignore (PassManager.create_function mp
+ ignore (PassManager.create_function m
++ PassManager.initialize
++ PassManager.run_function fn
++ PassManager.finalize
@@ -1104,7 +1298,7 @@ let test_writer () =
group "writer";
insist (write_bitcode_file m filename);
- ModuleProvider.dispose mp
+ dispose_module m
(*===-- Driver ------------------------------------------------------------===*)
@@ -1115,12 +1309,14 @@ let _ =
suite "constants" test_constants;
suite "global values" test_global_values;
suite "global variables" test_global_variables;
+ suite "uses" test_uses;
+ suite "users" test_users;
+ suite "aliases" test_aliases;
suite "functions" test_functions;
suite "params" test_params;
suite "basic blocks" test_basic_blocks;
suite "instructions" test_instructions;
suite "builder" test_builder;
- suite "module provider" test_module_provider;
suite "pass manager" test_pass_manager;
suite "writer" test_writer; (* Keep this last; it disposes m. *)
exit !exit_status
diff --git a/test/CodeGen/ARM/2010-03-04-eabi-fp-spill.ll b/test/CodeGen/ARM/2010-03-04-eabi-fp-spill.ll
new file mode 100644
index 0000000..f7adf732
--- /dev/null
+++ b/test/CodeGen/ARM/2010-03-04-eabi-fp-spill.ll
@@ -0,0 +1,65 @@
+; RUN: llc < %s -mtriple=arm-unknown-linux-gnueabi
+
+define void @"java.lang.String::getChars"([84 x i8]* %method, i32 %base_pc, [788 x i8]* %thread) {
+ %1 = load i32* undef ; <i32> [#uses=1]
+ %2 = sub i32 %1, 48 ; <i32> [#uses=1]
+ br i1 undef, label %stack_overflow, label %no_overflow
+
+stack_overflow: ; preds = %0
+ unreachable
+
+no_overflow: ; preds = %0
+ %frame = inttoptr i32 %2 to [17 x i32]* ; <[17 x i32]*> [#uses=4]
+ %3 = load i32* undef ; <i32> [#uses=1]
+ %4 = load i32* null ; <i32> [#uses=1]
+ %5 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 13 ; <i32*> [#uses=1]
+ %6 = bitcast i32* %5 to [8 x i8]** ; <[8 x i8]**> [#uses=1]
+ %7 = load [8 x i8]** %6 ; <[8 x i8]*> [#uses=1]
+ %8 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 12 ; <i32*> [#uses=1]
+ %9 = load i32* %8 ; <i32> [#uses=1]
+ br i1 undef, label %bci_13, label %bci_4
+
+bci_13: ; preds = %no_overflow
+ br i1 undef, label %bci_30, label %bci_21
+
+bci_30: ; preds = %bci_13
+ br i1 undef, label %bci_46, label %bci_35
+
+bci_46: ; preds = %bci_30
+ %10 = sub i32 %4, %3 ; <i32> [#uses=1]
+ %11 = load [8 x i8]** null ; <[8 x i8]*> [#uses=1]
+ %callee = bitcast [8 x i8]* %11 to [84 x i8]* ; <[84 x i8]*> [#uses=1]
+ %12 = bitcast i8* undef to i32* ; <i32*> [#uses=1]
+ %base_pc7 = load i32* %12 ; <i32> [#uses=2]
+ %13 = add i32 %base_pc7, 0 ; <i32> [#uses=1]
+ %14 = inttoptr i32 %13 to void ([84 x i8]*, i32, [788 x i8]*)** ; <void ([84 x i8]*, i32, [788 x i8]*)**> [#uses=1]
+ %entry_point = load void ([84 x i8]*, i32, [788 x i8]*)** %14 ; <void ([84 x i8]*, i32, [788 x i8]*)*> [#uses=1]
+ %15 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 1 ; <i32*> [#uses=1]
+ %16 = ptrtoint i32* %15 to i32 ; <i32> [#uses=1]
+ %stack_pointer_addr9 = bitcast i8* undef to i32* ; <i32*> [#uses=1]
+ store i32 %16, i32* %stack_pointer_addr9
+ %17 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 2 ; <i32*> [#uses=1]
+ store i32 %9, i32* %17
+ store i32 %10, i32* undef
+ store [84 x i8]* %method, [84 x i8]** undef
+ %18 = add i32 %base_pc, 20 ; <i32> [#uses=1]
+ store i32 %18, i32* undef
+ store [8 x i8]* %7, [8 x i8]** undef
+ call void %entry_point([84 x i8]* %callee, i32 %base_pc7, [788 x i8]* %thread)
+ br i1 undef, label %no_exception, label %exception
+
+exception: ; preds = %bci_46
+ ret void
+
+no_exception: ; preds = %bci_46
+ ret void
+
+bci_35: ; preds = %bci_30
+ ret void
+
+bci_21: ; preds = %bci_13
+ ret void
+
+bci_4: ; preds = %no_overflow
+ ret void
+}
diff --git a/test/CodeGen/ARM/2010-03-04-stm-undef-addr.ll b/test/CodeGen/ARM/2010-03-04-stm-undef-addr.ll
new file mode 100644
index 0000000..b0b4cb3
--- /dev/null
+++ b/test/CodeGen/ARM/2010-03-04-stm-undef-addr.ll
@@ -0,0 +1,54 @@
+; RUN: llc < %s -march=arm
+
+define void @"java.lang.String::getChars"([84 x i8]* %method, i32 %base_pc, [788 x i8]* %thread) {
+ %1 = sub i32 undef, 48 ; <i32> [#uses=1]
+ br i1 undef, label %stack_overflow, label %no_overflow
+
+stack_overflow: ; preds = %0
+ unreachable
+
+no_overflow: ; preds = %0
+ %frame = inttoptr i32 %1 to [17 x i32]* ; <[17 x i32]*> [#uses=4]
+ %2 = load i32* null ; <i32> [#uses=2]
+ %3 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 14 ; <i32*> [#uses=1]
+ %4 = load i32* %3 ; <i32> [#uses=2]
+ %5 = load [8 x i8]** undef ; <[8 x i8]*> [#uses=2]
+ br i1 undef, label %bci_13, label %bci_4
+
+bci_13: ; preds = %no_overflow
+ br i1 undef, label %bci_30, label %bci_21
+
+bci_30: ; preds = %bci_13
+ %6 = icmp sle i32 %2, %4 ; <i1> [#uses=1]
+ br i1 %6, label %bci_46, label %bci_35
+
+bci_46: ; preds = %bci_30
+ store [84 x i8]* %method, [84 x i8]** undef
+ br i1 false, label %no_exception, label %exception
+
+exception: ; preds = %bci_46
+ ret void
+
+no_exception: ; preds = %bci_46
+ ret void
+
+bci_35: ; preds = %bci_30
+ %7 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 15 ; <i32*> [#uses=1]
+ store i32 %2, i32* %7
+ %8 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 14 ; <i32*> [#uses=1]
+ store i32 %4, i32* %8
+ %9 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 13 ; <i32*> [#uses=1]
+ %10 = bitcast i32* %9 to [8 x i8]** ; <[8 x i8]**> [#uses=1]
+ store [8 x i8]* %5, [8 x i8]** %10
+ call void inttoptr (i32 13839116 to void ([788 x i8]*, i32)*)([788 x i8]* %thread, i32 7)
+ ret void
+
+bci_21: ; preds = %bci_13
+ ret void
+
+bci_4: ; preds = %no_overflow
+ store [8 x i8]* %5, [8 x i8]** undef
+ store i32 undef, i32* undef
+ call void inttoptr (i32 13839116 to void ([788 x i8]*, i32)*)([788 x i8]* %thread, i32 7)
+ ret void
+}
diff --git a/test/CodeGen/ARM/arm-negative-stride.ll b/test/CodeGen/ARM/arm-negative-stride.ll
index 72ec8ef..52ab871 100644
--- a/test/CodeGen/ARM/arm-negative-stride.ll
+++ b/test/CodeGen/ARM/arm-negative-stride.ll
@@ -1,7 +1,32 @@
; RUN: llc < %s -march=arm | FileCheck %s
+; This loop is rewritten with an indvar which counts down, which
+; frees up a register from holding the trip count.
+
define void @test(i32* %P, i32 %A, i32 %i) nounwind {
entry:
+; CHECK: str r1, [{{r.*}}, +{{r.*}}, lsl #2]
+ icmp eq i32 %i, 0 ; <i1>:0 [#uses=1]
+ br i1 %0, label %return, label %bb
+
+bb: ; preds = %bb, %entry
+ %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2]
+ %i_addr.09.0 = sub i32 %i, %indvar ; <i32> [#uses=1]
+ %tmp2 = getelementptr i32* %P, i32 %i_addr.09.0 ; <i32*> [#uses=1]
+ store i32 %A, i32* %tmp2
+ %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
+ icmp eq i32 %indvar.next, %i ; <i1>:1 [#uses=1]
+ br i1 %1, label %return, label %bb
+
+return: ; preds = %bb, %entry
+ ret void
+}
+
+; This loop has a non-address use of the count-up indvar, so
+; it'll remain. Now the original store uses a negative-stride address.
+
+define void @test_with_forced_iv(i32* %P, i32 %A, i32 %i) nounwind {
+entry:
; CHECK: str r1, [{{r.*}}, -{{r.*}}, lsl #2]
icmp eq i32 %i, 0 ; <i1>:0 [#uses=1]
br i1 %0, label %return, label %bb
@@ -11,6 +36,7 @@ bb: ; preds = %bb, %entry
%i_addr.09.0 = sub i32 %i, %indvar ; <i32> [#uses=1]
%tmp2 = getelementptr i32* %P, i32 %i_addr.09.0 ; <i32*> [#uses=1]
store i32 %A, i32* %tmp2
+ store i32 %indvar, i32* null
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
icmp eq i32 %indvar.next, %i ; <i1>:1 [#uses=1]
br i1 %1, label %return, label %bb
diff --git a/test/CodeGen/ARM/armv4.ll b/test/CodeGen/ARM/armv4.ll
new file mode 100644
index 0000000..49b129d
--- /dev/null
+++ b/test/CodeGen/ARM/armv4.ll
@@ -0,0 +1,13 @@
+; RUN: llc < %s -mtriple=arm-unknown-eabi | FileCheck %s -check-prefix=THUMB
+; RUN: llc < %s -mtriple=arm-unknown-eabi -mcpu=strongarm | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=arm-unknown-eabi -mcpu=cortex-a8 | FileCheck %s -check-prefix=THUMB
+; RUN: llc < %s -mtriple=arm-unknown-eabi -mattr=+v6 | FileCheck %s -check-prefix=THUMB
+; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=armv4t-unknown-eabi | FileCheck %s -check-prefix=THUMB
+
+define arm_aapcscc i32 @test(i32 %a) nounwind readnone {
+entry:
+; ARM: mov pc
+; THUMB: bx
+ ret i32 %a
+}
diff --git a/test/CodeGen/ARM/call.ll b/test/CodeGen/ARM/call.ll
index 3dd66ae..c60b75b 100644
--- a/test/CodeGen/ARM/call.ll
+++ b/test/CodeGen/ARM/call.ll
@@ -20,3 +20,17 @@ define void @g.upgrd.1() {
%tmp.upgrd.2 = tail call i32 %tmp( ) ; <i32> [#uses=0]
ret void
}
+
+define i32* @m_231b(i32, i32, i32*, i32*, i32*) nounwind {
+; CHECKV4: m_231b
+; CHECKV4: bx r{{.*}}
+BB0:
+ %5 = inttoptr i32 %0 to i32* ; <i32*> [#uses=1]
+ %t35 = volatile load i32* %5 ; <i32> [#uses=1]
+ %6 = inttoptr i32 %t35 to i32** ; <i32**> [#uses=1]
+ %7 = getelementptr i32** %6, i32 86 ; <i32**> [#uses=1]
+ %8 = load i32** %7 ; <i32*> [#uses=1]
+ %9 = bitcast i32* %8 to i32* (i32, i32*, i32, i32*, i32*, i32*)* ; <i32* (i32, i32*, i32, i32*, i32*, i32*)*> [#uses=1]
+ %10 = call i32* %9(i32 %0, i32* null, i32 %1, i32* %2, i32* %3, i32* %4) ; <i32*> [#uses=1]
+ ret i32* %10
+}
diff --git a/test/CodeGen/ARM/lsr-code-insertion.ll b/test/CodeGen/ARM/lsr-code-insertion.ll
index 507ec2c..1bbb96d 100644
--- a/test/CodeGen/ARM/lsr-code-insertion.ll
+++ b/test/CodeGen/ARM/lsr-code-insertion.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -stats |& grep {40.*Number of machine instrs printed}
-; RUN: llc < %s -stats |& grep {.*Number of re-materialization}
+; RUN: llc < %s -stats |& grep {39.*Number of machine instrs printed}
+; RUN: llc < %s -stats |& not grep {.*Number of re-materialization}
; This test really wants to check that the resultant "cond_true" block only
; has a single store in it, and that cond_true55 only has code to materialize
; the constant and do a store. We do *not* want something like this:
diff --git a/test/CodeGen/ARM/neon_minmax.ll b/test/CodeGen/ARM/neon_minmax.ll
new file mode 100644
index 0000000..d301c6a
--- /dev/null
+++ b/test/CodeGen/ARM/neon_minmax.ll
@@ -0,0 +1,81 @@
+; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s
+
+define float @fmin_ole(float %x) nounwind {
+;CHECK: fmin_ole:
+;CHECK: vmin.f32
+ %cond = fcmp ole float 1.0, %x
+ %min1 = select i1 %cond, float 1.0, float %x
+ ret float %min1
+}
+
+define float @fmin_ole_zero(float %x) nounwind {
+;CHECK: fmin_ole_zero:
+;CHECK-NOT: vmin.f32
+ %cond = fcmp ole float 0.0, %x
+ %min1 = select i1 %cond, float 0.0, float %x
+ ret float %min1
+}
+
+define float @fmin_ult(float %x) nounwind {
+;CHECK: fmin_ult:
+;CHECK: vmin.f32
+ %cond = fcmp ult float %x, 1.0
+ %min1 = select i1 %cond, float %x, float 1.0
+ ret float %min1
+}
+
+define float @fmax_ogt(float %x) nounwind {
+;CHECK: fmax_ogt:
+;CHECK: vmax.f32
+ %cond = fcmp ogt float 1.0, %x
+ %max1 = select i1 %cond, float 1.0, float %x
+ ret float %max1
+}
+
+define float @fmax_uge(float %x) nounwind {
+;CHECK: fmax_uge:
+;CHECK: vmax.f32
+ %cond = fcmp uge float %x, 1.0
+ %max1 = select i1 %cond, float %x, float 1.0
+ ret float %max1
+}
+
+define float @fmax_uge_zero(float %x) nounwind {
+;CHECK: fmax_uge_zero:
+;CHECK-NOT: vmax.f32
+ %cond = fcmp uge float %x, 0.0
+ %max1 = select i1 %cond, float %x, float 0.0
+ ret float %max1
+}
+
+define float @fmax_olt_reverse(float %x) nounwind {
+;CHECK: fmax_olt_reverse:
+;CHECK: vmax.f32
+ %cond = fcmp olt float %x, 1.0
+ %max1 = select i1 %cond, float 1.0, float %x
+ ret float %max1
+}
+
+define float @fmax_ule_reverse(float %x) nounwind {
+;CHECK: fmax_ule_reverse:
+;CHECK: vmax.f32
+ %cond = fcmp ult float 1.0, %x
+ %max1 = select i1 %cond, float %x, float 1.0
+ ret float %max1
+}
+
+define float @fmin_oge_reverse(float %x) nounwind {
+;CHECK: fmin_oge_reverse:
+;CHECK: vmin.f32
+ %cond = fcmp oge float %x, 1.0
+ %min1 = select i1 %cond, float 1.0, float %x
+ ret float %min1
+}
+
+define float @fmin_ugt_reverse(float %x) nounwind {
+;CHECK: fmin_ugt_reverse:
+;CHECK: vmin.f32
+ %cond = fcmp ugt float 1.0, %x
+ %min1 = select i1 %cond, float %x, float 1.0
+ ret float %min1
+}
diff --git a/test/CodeGen/ARM/remat.ll b/test/CodeGen/ARM/remat.ll
index 367f782..92c1cf1 100644
--- a/test/CodeGen/ARM/remat.ll
+++ b/test/CodeGen/ARM/remat.ll
@@ -32,16 +32,16 @@ bb.i35: ; preds = %bb142
br label %phi1.exit
phi1.exit: ; preds = %bb.i35, %bb142
- %.pn = phi double [ %6, %bb.i35 ], [ 0.000000e+00, %bb142 ] ; <double> [#uses=0]
+ %.pn = phi double [ %6, %bb.i35 ], [ 0.000000e+00, %bb142 ] ; <double> [#uses=1]
%9 = phi double [ %8, %bb.i35 ], [ 0.000000e+00, %bb142 ] ; <double> [#uses=1]
- %10 = fmul double undef, %9 ; <double> [#uses=0]
+ %10 = fmul double %.pn, %9 ; <double> [#uses=1]
br i1 %14, label %phi0.exit, label %bb.i
bb.i: ; preds = %phi1.exit
unreachable
phi0.exit: ; preds = %phi1.exit
- %11 = fsub double %4, undef ; <double> [#uses=1]
+ %11 = fsub double %4, %10 ; <double> [#uses=1]
%12 = fadd double 0.000000e+00, %11 ; <double> [#uses=1]
store double %12, double* undef, align 4
br label %bb142
diff --git a/test/CodeGen/Alpha/add.ll b/test/CodeGen/Alpha/add.ll
index 24a7418..cd883f6 100644
--- a/test/CodeGen/Alpha/add.ll
+++ b/test/CodeGen/Alpha/add.ll
@@ -4,9 +4,8 @@
; RUN: grep { addl} %t.s | count 2
; RUN: grep { addq} %t.s | count 2
; RUN: grep { subl} %t.s | count 2
-; RUN: grep { subq} %t.s | count 1
+; RUN: grep { subq} %t.s | count 2
;
-; RUN: grep {lda \$0,-100(\$16)} %t.s | count 1
; RUN: grep {s4addl} %t.s | count 2
; RUN: grep {s8addl} %t.s | count 2
; RUN: grep {s4addq} %t.s | count 2
diff --git a/test/CodeGen/Blackfin/promote-logic.ll b/test/CodeGen/Blackfin/promote-logic.ll
index 46da566..1ac1408 100644
--- a/test/CodeGen/Blackfin/promote-logic.ll
+++ b/test/CodeGen/Blackfin/promote-logic.ll
@@ -1,5 +1,4 @@
-; RUN: llc < %s -march=bfin > %t
-; XFAIL: *
+; RUN: llc < %s -march=bfin
; DAGCombiner::SimplifyBinOpWithSameOpcodeHands can produce an illegal i16 OR
; operation after LegalizeOps.
diff --git a/test/CodeGen/CellSPU/bss.ll b/test/CodeGen/CellSPU/bss.ll
new file mode 100644
index 0000000..05a0f50
--- /dev/null
+++ b/test/CodeGen/CellSPU/bss.ll
@@ -0,0 +1,5 @@
+; RUN: llc < %s -march=cellspu > %t1.s
+; RUN: grep "\.section" %t1.s | grep "\.bss" | count 1
+
+@bssVar = global i32 zeroinitializer
+
diff --git a/test/CodeGen/Generic/2007-05-05-Personality.ll b/test/CodeGen/Generic/2007-05-05-Personality.ll
index 2749326..c92783e 100644
--- a/test/CodeGen/Generic/2007-05-05-Personality.ll
+++ b/test/CodeGen/Generic/2007-05-05-Personality.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=i686-pc-linux-gnu -enable-eh -o - | grep zPLR
+; RUN: llc < %s -mtriple=i686-pc-linux-gnu -enable-eh -o - | grep zPL
@error = external global i8 ; <i8*> [#uses=2]
diff --git a/test/CodeGen/Generic/GC/argpromotion.ll b/test/CodeGen/Generic/GC/argpromotion.ll
index dda376d..c63ce22 100644
--- a/test/CodeGen/Generic/GC/argpromotion.ll
+++ b/test/CodeGen/Generic/GC/argpromotion.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -anders-aa -argpromotion
+; RUN: opt < %s -argpromotion
declare void @llvm.gcroot(i8**, i8*)
diff --git a/test/CodeGen/Generic/debug-info.ll b/test/CodeGen/Generic/debug-info.ll
deleted file mode 100644
index 20d9f91..0000000
--- a/test/CodeGen/Generic/debug-info.ll
+++ /dev/null
@@ -1,19 +0,0 @@
-; RUN: llc < %s
-
- %lldb.compile_unit = type { i32, i16, i16, i8*, i8*, i8*, { }* }
-@d.compile_unit7 = external global %lldb.compile_unit ; <%lldb.compile_unit*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, %lldb.compile_unit*)
-
-define void @rb_raise(i32, ...) {
-entry:
- br i1 false, label %strlen.exit, label %no_exit.i
-
-no_exit.i: ; preds = %entry
- ret void
-
-strlen.exit: ; preds = %entry
- call void @llvm.dbg.stoppoint( i32 4358, i32 0, %lldb.compile_unit* @d.compile_unit7 )
- unreachable
-}
-
diff --git a/test/CodeGen/MBlaze/brind.ll b/test/CodeGen/MBlaze/brind.ll
new file mode 100644
index 0000000..7798e0f
--- /dev/null
+++ b/test/CodeGen/MBlaze/brind.ll
@@ -0,0 +1,73 @@
+; Ensure that the select instruction is supported and is lowered to
+; some sort of branch instruction.
+;
+; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s
+
+declare i32 @printf(i8*, ...)
+@MSG = internal constant [13 x i8] c"Message: %d\0A\00"
+
+@BLKS = private constant [5 x i8*]
+ [ i8* blockaddress(@brind, %L1),
+ i8* blockaddress(@brind, %L2),
+ i8* blockaddress(@brind, %L3),
+ i8* blockaddress(@brind, %L4),
+ i8* blockaddress(@brind, %L5) ]
+
+define i32 @brind(i32 %a, i32 %b)
+{
+ ; CHECK: brind:
+entry:
+ br label %loop
+
+loop:
+ %tmp.0 = phi i32 [ 0, %entry ], [ %tmp.8, %finish ]
+ %dst.0 = getelementptr [5 x i8*]* @BLKS, i32 0, i32 %tmp.0
+ %dst.1 = load i8** %dst.0
+ indirectbr i8* %dst.1, [ label %L1,
+ label %L2,
+ label %L3,
+ label %L4,
+ label %L5 ]
+ ; CHECK: br {{r[0-9]*}}
+
+L1:
+ %tmp.1 = add i32 %a, %b
+ br label %finish
+ ; CHECK: br
+
+L2:
+ %tmp.2 = sub i32 %a, %b
+ br label %finish
+ ; CHECK: br
+
+L3:
+ %tmp.3 = mul i32 %a, %b
+ br label %finish
+ ; CHECK: br
+
+L4:
+ %tmp.4 = sdiv i32 %a, %b
+ br label %finish
+ ; CHECK: br
+
+L5:
+ %tmp.5 = srem i32 %a, %b
+ br label %finish
+ ; CHECK: br
+
+finish:
+ %tmp.6 = phi i32 [ %tmp.1, %L1 ],
+ [ %tmp.2, %L2 ],
+ [ %tmp.3, %L3 ],
+ [ %tmp.4, %L4 ],
+ [ %tmp.5, %L5 ]
+
+ call i32 (i8*,...)* @printf( i8* getelementptr([13 x i8]* @MSG,i32 0,i32 0),
+ i32 %tmp.6)
+
+ %tmp.7 = add i32 %tmp.0, 1
+ %tmp.8 = urem i32 %tmp.7, 5
+
+ br label %loop
+ ; CHECK: br
+}
diff --git a/test/CodeGen/MBlaze/callind.ll b/test/CodeGen/MBlaze/callind.ll
new file mode 100644
index 0000000..bfc8d00
--- /dev/null
+++ b/test/CodeGen/MBlaze/callind.ll
@@ -0,0 +1,80 @@
+; Ensure that indirect calls work and that they are lowered to some
+; sort of branch and link instruction.
+;
+; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s
+
+declare i32 @printf(i8*, ...)
+@MSG = internal constant [13 x i8] c"Message: %d\0A\00"
+
+@FUNS = private constant [5 x i32 (i32,i32)*]
+ [ i32 (i32,i32)* @doadd,
+ i32 (i32,i32)* @dosub,
+ i32 (i32,i32)* @domul,
+ i32 (i32,i32)* @dodiv,
+ i32 (i32,i32)* @dorem ]
+
+define i32 @doadd(i32 %a, i32 %b)
+{
+ ; CHECK: doadd:
+ %tmp.0 = add i32 %a, %b
+ ret i32 %tmp.0
+ ; CHECK: rtsd
+}
+
+define i32 @dosub(i32 %a, i32 %b)
+{
+ ; CHECK: dosub:
+ %tmp.0 = sub i32 %a, %b
+ ret i32 %tmp.0
+ ; CHECK: rtsd
+}
+
+define i32 @domul(i32 %a, i32 %b)
+{
+ ; CHECK: domul:
+ %tmp.0 = mul i32 %a, %b
+ ret i32 %tmp.0
+ ; CHECK: rtsd
+}
+
+define i32 @dodiv(i32 %a, i32 %b)
+{
+ ; CHECK: dodiv:
+ %tmp.0 = sdiv i32 %a, %b
+ ret i32 %tmp.0
+ ; CHECK: rtsd
+}
+
+define i32 @dorem(i32 %a, i32 %b)
+{
+ ; CHECK: dorem:
+ %tmp.0 = srem i32 %a, %b
+ ret i32 %tmp.0
+ ; CHECK: rtsd
+}
+
+define i32 @callind(i32 %a, i32 %b)
+{
+ ; CHECK: callind:
+entry:
+ br label %loop
+
+loop:
+ %tmp.0 = phi i32 [ 0, %entry ], [ %tmp.3, %loop ]
+ %dst.0 = getelementptr [5 x i32 (i32,i32)*]* @FUNS, i32 0, i32 %tmp.0
+ %dst.1 = load i32 (i32,i32)** %dst.0
+ %tmp.1 = call i32 %dst.1(i32 %a, i32 %b)
+ ; CHECK-NOT: brli
+ ; CHECK-NOT: brlai
+ ; CHECK: brl
+
+ call i32 (i8*,...)* @printf( i8* getelementptr([13 x i8]* @MSG,i32 0,i32 0),
+ i32 %tmp.1)
+ ; CHECK: brl
+
+ %tmp.2 = add i32 %tmp.0, 1
+ %tmp.3 = urem i32 %tmp.2, 5
+
+ br label %loop
+ ; CHECK: br
+}
diff --git a/test/CodeGen/MBlaze/cc.ll b/test/CodeGen/MBlaze/cc.ll
new file mode 100644
index 0000000..aaa918f
--- /dev/null
+++ b/test/CodeGen/MBlaze/cc.ll
@@ -0,0 +1,315 @@
+; Test some of the calling convention lowering done by the MBlaze backend.
+; We test that integer values are passed in the correct registers and
+; returned in the correct registers. Additionally, we test that the stack
+; is used as appropriate for passing arguments that cannot be placed into
+; registers.
+;
+; RUN: llc < %s -march=mblaze | FileCheck %s
+
+declare i32 @printf(i8*, ...)
+@MSG = internal constant [13 x i8] c"Message: %d\0A\00"
+
+define void @params0_noret() {
+ ; CHECK: params0_noret:
+ ret void
+ ; CHECK-NOT: {{.* r3, r0, 1}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i8 @params0_8bitret() {
+ ; CHECK: params0_8bitret:
+ ret i8 1
+ ; CHECK: {{.* r3, r0, 1}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i16 @params0_16bitret() {
+ ; CHECK: params0_16bitret:
+ ret i16 1
+ ; CHECK: {{.* r3, r0, 1}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params0_32bitret() {
+ ; CHECK: params0_32bitret:
+ ret i32 1
+ ; CHECK: {{.* r3, r0, 1}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i64 @params0_64bitret() {
+ ; CHECK: params0_64bitret:
+ ret i64 1
+ ; CHECK: {{.* r3, r0, .*}}
+ ; CHECK: {{.* r4, r0, 1}}
+ ; CHECK: rtsd
+}
+
+define i32 @params1_32bitret(i32 %a) {
+ ; CHECK: params1_32bitret:
+ ret i32 %a
+ ; CHECK: {{.* r3, r5, r0}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params2_32bitret(i32 %a, i32 %b) {
+ ; CHECK: params2_32bitret:
+ ret i32 %b
+ ; CHECK: {{.* r3, r6, r0}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params3_32bitret(i32 %a, i32 %b, i32 %c) {
+ ; CHECK: params3_32bitret:
+ ret i32 %c
+ ; CHECK: {{.* r3, r7, r0}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params4_32bitret(i32 %a, i32 %b, i32 %c, i32 %d) {
+ ; CHECK: params4_32bitret:
+ ret i32 %d
+ ; CHECK: {{.* r3, r8, r0}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params5_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+ ; CHECK: params5_32bitret:
+ ret i32 %e
+ ; CHECK: {{.* r3, r9, r0}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params6_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) {
+ ; CHECK: params6_32bitret:
+ ret i32 %f
+ ; CHECK: {{.* r3, r10, r0}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params7_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
+ i32 %g) {
+ ; CHECK: params7_32bitret:
+ ret i32 %g
+ ; CHECK: {{lwi? r3, r1, 32}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params8_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
+ i32 %g, i32 %h) {
+ ; CHECK: params8_32bitret:
+ ret i32 %h
+ ; CHECK: {{lwi? r3, r1, 36}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params9_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
+ i32 %g, i32 %h, i32 %i) {
+ ; CHECK: params9_32bitret:
+ ret i32 %i
+ ; CHECK: {{lwi? r3, r1, 40}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define i32 @params10_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
+ i32 %g, i32 %h, i32 %i, i32 %j) {
+ ; CHECK: params10_32bitret:
+ ret i32 %j
+ ; CHECK: {{lwi? r3, r1, 44}}
+ ; CHECK-NOT: {{.* r4, .*, .*}}
+ ; CHECK: rtsd
+}
+
+define void @testing() {
+ %MSG.1 = getelementptr [13 x i8]* @MSG, i32 0, i32 0
+
+ call void @params0_noret()
+ ; CHECK: brlid
+
+ %tmp.1 = call i8 @params0_8bitret()
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i8 %tmp.1)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.2 = call i16 @params0_16bitret()
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i16 %tmp.2)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.3 = call i32 @params0_32bitret()
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.3)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.4 = call i64 @params0_64bitret()
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i64 %tmp.4)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK: {{.* r7, r4, r0}}
+ ; CHECK: brlid
+
+ %tmp.5 = call i32 @params1_32bitret(i32 1)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.5)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.6 = call i32 @params2_32bitret(i32 1, i32 2)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.6)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.7 = call i32 @params3_32bitret(i32 1, i32 2, i32 3)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.7)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.8 = call i32 @params4_32bitret(i32 1, i32 2, i32 3, i32 4)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: {{.* r8, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.8)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.9 = call i32 @params5_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: {{.* r8, .*, .*}}
+ ; CHECK: {{.* r9, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.9)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.10 = call i32 @params6_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
+ i32 6)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: {{.* r8, .*, .*}}
+ ; CHECK: {{.* r9, .*, .*}}
+ ; CHECK: {{.* r10, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.10)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.11 = call i32 @params7_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
+ i32 6, i32 7)
+ ; CHECK: {{swi? .*, r1, 28}}
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: {{.* r8, .*, .*}}
+ ; CHECK: {{.* r9, .*, .*}}
+ ; CHECK: {{.* r10, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.11)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.12 = call i32 @params8_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
+ i32 6, i32 7, i32 8)
+ ; CHECK: {{swi? .*, r1, 28}}
+ ; CHECK: {{swi? .*, r1, 32}}
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: {{.* r8, .*, .*}}
+ ; CHECK: {{.* r9, .*, .*}}
+ ; CHECK: {{.* r10, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.12)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.13 = call i32 @params9_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
+ i32 6, i32 7, i32 8, i32 9)
+ ; CHECK: {{swi? .*, r1, 28}}
+ ; CHECK: {{swi? .*, r1, 32}}
+ ; CHECK: {{swi? .*, r1, 36}}
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: {{.* r8, .*, .*}}
+ ; CHECK: {{.* r9, .*, .*}}
+ ; CHECK: {{.* r10, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.13)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ %tmp.14 = call i32 @params10_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
+ i32 6, i32 7, i32 8, i32 9, i32 10)
+ ; CHECK: {{swi? .*, r1, 28}}
+ ; CHECK: {{swi? .*, r1, 32}}
+ ; CHECK: {{swi? .*, r1, 36}}
+ ; CHECK: {{swi? .*, r1, 40}}
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, .*, .*}}
+ ; CHECK: {{.* r7, .*, .*}}
+ ; CHECK: {{.* r8, .*, .*}}
+ ; CHECK: {{.* r9, .*, .*}}
+ ; CHECK: {{.* r10, .*, .*}}
+ ; CHECK: brlid
+ call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.14)
+ ; CHECK: {{.* r5, .*, .*}}
+ ; CHECK: {{.* r6, r3, r0}}
+ ; CHECK-NOT: {{.* r7, .*, .*}}
+ ; CHECK: brlid
+
+ ret void
+}
diff --git a/test/CodeGen/MBlaze/dg.exp b/test/CodeGen/MBlaze/dg.exp
new file mode 100644
index 0000000..bfd5e47
--- /dev/null
+++ b/test/CodeGen/MBlaze/dg.exp
@@ -0,0 +1,5 @@
+load_lib llvm.exp
+
+if { [llvm_supports_target MBlaze] } {
+ RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
+}
diff --git a/test/CodeGen/MBlaze/div.ll b/test/CodeGen/MBlaze/div.ll
new file mode 100644
index 0000000..fae9830
--- /dev/null
+++ b/test/CodeGen/MBlaze/div.ll
@@ -0,0 +1,75 @@
+; Ensure that multiplication is lowered to function calls when the multiplier
+; unit is not available in the hardware and that function calls are not used
+; when the multiplier unit is available in the hardware.
+;
+; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
+; RUN: llc < %s -march=mblaze -mattr=+div | FileCheck -check-prefix=DIV %s
+
+define i8 @test_i8(i8 %a, i8 %b) {
+ ; FUN: test_i8:
+ ; DIV: test_i8:
+
+ %tmp.1 = udiv i8 %a, %b
+ ; FUN-NOT: idiv
+ ; FUN: brlid
+ ; DIV-NOT: brlid
+ ; DIV: idivu
+
+ %tmp.2 = sdiv i8 %a, %b
+ ; FUN-NOT: idiv
+ ; FUN: brlid
+ ; DIV-NOT: brlid
+ ; DIV-NOT: idivu
+ ; DIV: idiv
+
+ %tmp.3 = add i8 %tmp.1, %tmp.2
+ ret i8 %tmp.3
+ ; FUN: rtsd
+ ; DIV: rtsd
+}
+
+define i16 @test_i16(i16 %a, i16 %b) {
+ ; FUN: test_i16:
+ ; DIV: test_i16:
+
+ %tmp.1 = udiv i16 %a, %b
+ ; FUN-NOT: idiv
+ ; FUN: brlid
+ ; DIV-NOT: brlid
+ ; DIV: idivu
+
+ %tmp.2 = sdiv i16 %a, %b
+ ; FUN-NOT: idiv
+ ; FUN: brlid
+ ; DIV-NOT: brlid
+ ; DIV-NOT: idivu
+ ; DIV: idiv
+
+ %tmp.3 = add i16 %tmp.1, %tmp.2
+ ret i16 %tmp.3
+ ; FUN: rtsd
+ ; DIV: rtsd
+}
+
+define i32 @test_i32(i32 %a, i32 %b) {
+ ; FUN: test_i32:
+ ; DIV: test_i32:
+
+ %tmp.1 = udiv i32 %a, %b
+ ; FUN-NOT: idiv
+ ; FUN: brlid
+ ; DIV-NOT: brlid
+ ; DIV: idivu
+
+ %tmp.2 = sdiv i32 %a, %b
+ ; FUN-NOT: idiv
+ ; FUN: brlid
+ ; DIV-NOT: brlid
+ ; DIV-NOT: idivu
+ ; DIV: idiv
+
+ %tmp.3 = add i32 %tmp.1, %tmp.2
+ ret i32 %tmp.3
+ ; FUN: rtsd
+ ; DIV: rtsd
+}
diff --git a/test/CodeGen/MBlaze/fpu.ll b/test/CodeGen/MBlaze/fpu.ll
new file mode 100644
index 0000000..83f4d83
--- /dev/null
+++ b/test/CodeGen/MBlaze/fpu.ll
@@ -0,0 +1,66 @@
+; Ensure that floating point operations are lowered to function calls when the
+; FPU is not available in the hardware and that function calls are not used
+; when the FPU is available in the hardware.
+;
+; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
+; RUN: llc < %s -march=mblaze -mattr=+fpu | FileCheck -check-prefix=FPU %s
+
+define float @test_add(float %a, float %b) {
+ ; FUN: test_add:
+ ; FPU: test_add:
+
+ %tmp.1 = fadd float %a, %b
+ ; FUN-NOT: fadd
+ ; FUN: brlid
+ ; FPU-NOT: brlid
+ ; FPU: fadd
+
+ ret float %tmp.1
+ ; FUN: rtsd
+ ; FPU: rtsd
+}
+
+define float @test_sub(float %a, float %b) {
+ ; FUN: test_sub:
+ ; FPU: test_sub:
+
+ %tmp.1 = fsub float %a, %b
+ ; FUN-NOT: frsub
+ ; FUN: brlid
+ ; FPU-NOT: brlid
+ ; FPU: frsub
+
+ ret float %tmp.1
+ ; FUN: rtsd
+ ; FPU: rtsd
+}
+
+define float @test_mul(float %a, float %b) {
+ ; FUN: test_mul:
+ ; FPU: test_mul:
+
+ %tmp.1 = fmul float %a, %b
+ ; FUN-NOT: fmul
+ ; FUN: brlid
+ ; FPU-NOT: brlid
+ ; FPU: fmul
+
+ ret float %tmp.1
+ ; FUN: rtsd
+ ; FPU: rtsd
+}
+
+define float @test_div(float %a, float %b) {
+ ; FUN: test_div:
+ ; FPU: test_div:
+
+ %tmp.1 = fdiv float %a, %b
+ ; FUN-NOT: fdiv
+ ; FUN: brlid
+ ; FPU-NOT: brlid
+ ; FPU: fdiv
+
+ ret float %tmp.1
+ ; FUN: rtsd
+ ; FPU: rtsd
+}
diff --git a/test/CodeGen/MBlaze/fsl.ll b/test/CodeGen/MBlaze/fsl.ll
new file mode 100644
index 0000000..f9c6205
--- /dev/null
+++ b/test/CodeGen/MBlaze/fsl.ll
@@ -0,0 +1,323 @@
+; Ensure that the FSL instrinsic instruction generate single FSL instructions
+; at the machine level. Additionally, ensure that dynamic values use the
+; dynamic version of the instructions and that constant values use the
+; constant version of the instructions.
+;
+; RUN: llc < %s -march=mblaze | FileCheck %s
+
+declare i32 @llvm.mblaze.fsl.get(i32 %port)
+declare i32 @llvm.mblaze.fsl.aget(i32 %port)
+declare i32 @llvm.mblaze.fsl.cget(i32 %port)
+declare i32 @llvm.mblaze.fsl.caget(i32 %port)
+declare i32 @llvm.mblaze.fsl.eget(i32 %port)
+declare i32 @llvm.mblaze.fsl.eaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.ecget(i32 %port)
+declare i32 @llvm.mblaze.fsl.ecaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.nget(i32 %port)
+declare i32 @llvm.mblaze.fsl.naget(i32 %port)
+declare i32 @llvm.mblaze.fsl.ncget(i32 %port)
+declare i32 @llvm.mblaze.fsl.ncaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.neget(i32 %port)
+declare i32 @llvm.mblaze.fsl.neaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.necget(i32 %port)
+declare i32 @llvm.mblaze.fsl.necaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tget(i32 %port)
+declare i32 @llvm.mblaze.fsl.taget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tcget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tcaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.teget(i32 %port)
+declare i32 @llvm.mblaze.fsl.teaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tecget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tecaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tnget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tnaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tncget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tncaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tneget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tneaget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tnecget(i32 %port)
+declare i32 @llvm.mblaze.fsl.tnecaget(i32 %port)
+
+declare void @llvm.mblaze.fsl.put(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.aput(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.cput(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.caput(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.nput(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.naput(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.ncput(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.ncaput(i32 %value, i32 %port)
+declare void @llvm.mblaze.fsl.tput(i32 %port)
+declare void @llvm.mblaze.fsl.taput(i32 %port)
+declare void @llvm.mblaze.fsl.tcput(i32 %port)
+declare void @llvm.mblaze.fsl.tcaput(i32 %port)
+declare void @llvm.mblaze.fsl.tnput(i32 %port)
+declare void @llvm.mblaze.fsl.tnaput(i32 %port)
+declare void @llvm.mblaze.fsl.tncput(i32 %port)
+declare void @llvm.mblaze.fsl.tncaput(i32 %port)
+
+define i32 @fsl_get(i32 %port)
+{
+ ; CHECK: fsl_get:
+ %v0 = call i32 @llvm.mblaze.fsl.get(i32 %port)
+ ; CHECK: getd
+ %v1 = call i32 @llvm.mblaze.fsl.aget(i32 %port)
+ ; CHECK-NEXT: agetd
+ %v2 = call i32 @llvm.mblaze.fsl.cget(i32 %port)
+ ; CHECK-NEXT: cgetd
+ %v3 = call i32 @llvm.mblaze.fsl.caget(i32 %port)
+ ; CHECK-NEXT: cagetd
+ %v4 = call i32 @llvm.mblaze.fsl.eget(i32 %port)
+ ; CHECK-NEXT: egetd
+ %v5 = call i32 @llvm.mblaze.fsl.eaget(i32 %port)
+ ; CHECK-NEXT: eagetd
+ %v6 = call i32 @llvm.mblaze.fsl.ecget(i32 %port)
+ ; CHECK-NEXT: ecgetd
+ %v7 = call i32 @llvm.mblaze.fsl.ecaget(i32 %port)
+ ; CHECK-NEXT: ecagetd
+ %v8 = call i32 @llvm.mblaze.fsl.nget(i32 %port)
+ ; CHECK-NEXT: ngetd
+ %v9 = call i32 @llvm.mblaze.fsl.naget(i32 %port)
+ ; CHECK-NEXT: nagetd
+ %v10 = call i32 @llvm.mblaze.fsl.ncget(i32 %port)
+ ; CHECK-NEXT: ncgetd
+ %v11 = call i32 @llvm.mblaze.fsl.ncaget(i32 %port)
+ ; CHECK-NEXT: ncagetd
+ %v12 = call i32 @llvm.mblaze.fsl.neget(i32 %port)
+ ; CHECK-NEXT: negetd
+ %v13 = call i32 @llvm.mblaze.fsl.neaget(i32 %port)
+ ; CHECK-NEXT: neagetd
+ %v14 = call i32 @llvm.mblaze.fsl.necget(i32 %port)
+ ; CHECK-NEXT: necgetd
+ %v15 = call i32 @llvm.mblaze.fsl.necaget(i32 %port)
+ ; CHECK-NEXT: necagetd
+ %v16 = call i32 @llvm.mblaze.fsl.tget(i32 %port)
+ ; CHECK-NEXT: tgetd
+ %v17 = call i32 @llvm.mblaze.fsl.taget(i32 %port)
+ ; CHECK-NEXT: tagetd
+ %v18 = call i32 @llvm.mblaze.fsl.tcget(i32 %port)
+ ; CHECK-NEXT: tcgetd
+ %v19 = call i32 @llvm.mblaze.fsl.tcaget(i32 %port)
+ ; CHECK-NEXT: tcagetd
+ %v20 = call i32 @llvm.mblaze.fsl.teget(i32 %port)
+ ; CHECK-NEXT: tegetd
+ %v21 = call i32 @llvm.mblaze.fsl.teaget(i32 %port)
+ ; CHECK-NEXT: teagetd
+ %v22 = call i32 @llvm.mblaze.fsl.tecget(i32 %port)
+ ; CHECK-NEXT: tecgetd
+ %v23 = call i32 @llvm.mblaze.fsl.tecaget(i32 %port)
+ ; CHECK-NEXT: tecagetd
+ %v24 = call i32 @llvm.mblaze.fsl.tnget(i32 %port)
+ ; CHECK-NEXT: tngetd
+ %v25 = call i32 @llvm.mblaze.fsl.tnaget(i32 %port)
+ ; CHECK-NEXT: tnagetd
+ %v26 = call i32 @llvm.mblaze.fsl.tncget(i32 %port)
+ ; CHECK-NEXT: tncgetd
+ %v27 = call i32 @llvm.mblaze.fsl.tncaget(i32 %port)
+ ; CHECK-NEXT: tncagetd
+ %v28 = call i32 @llvm.mblaze.fsl.tneget(i32 %port)
+ ; CHECK-NEXT: tnegetd
+ %v29 = call i32 @llvm.mblaze.fsl.tneaget(i32 %port)
+ ; CHECK-NEXT: tneagetd
+ %v30 = call i32 @llvm.mblaze.fsl.tnecget(i32 %port)
+ ; CHECK-NEXT: tnecgetd
+ %v31 = call i32 @llvm.mblaze.fsl.tnecaget(i32 %port)
+ ; CHECK-NEXT: tnecagetd
+ ret i32 1
+ ; CHECK: rtsd
+}
+
+define i32 @fslc_get()
+{
+ ; CHECK: fslc_get:
+ %v0 = call i32 @llvm.mblaze.fsl.get(i32 1)
+ ; CHECK: get
+ %v1 = call i32 @llvm.mblaze.fsl.aget(i32 1)
+ ; CHECK-NOT: agetd
+ ; CHECK: aget
+ %v2 = call i32 @llvm.mblaze.fsl.cget(i32 1)
+ ; CHECK-NOT: cgetd
+ ; CHECK: cget
+ %v3 = call i32 @llvm.mblaze.fsl.caget(i32 1)
+ ; CHECK-NOT: cagetd
+ ; CHECK: caget
+ %v4 = call i32 @llvm.mblaze.fsl.eget(i32 1)
+ ; CHECK-NOT: egetd
+ ; CHECK: eget
+ %v5 = call i32 @llvm.mblaze.fsl.eaget(i32 1)
+ ; CHECK-NOT: eagetd
+ ; CHECK: eaget
+ %v6 = call i32 @llvm.mblaze.fsl.ecget(i32 1)
+ ; CHECK-NOT: ecgetd
+ ; CHECK: ecget
+ %v7 = call i32 @llvm.mblaze.fsl.ecaget(i32 1)
+ ; CHECK-NOT: ecagetd
+ ; CHECK: ecaget
+ %v8 = call i32 @llvm.mblaze.fsl.nget(i32 1)
+ ; CHECK-NOT: ngetd
+ ; CHECK: nget
+ %v9 = call i32 @llvm.mblaze.fsl.naget(i32 1)
+ ; CHECK-NOT: nagetd
+ ; CHECK: naget
+ %v10 = call i32 @llvm.mblaze.fsl.ncget(i32 1)
+ ; CHECK-NOT: ncgetd
+ ; CHECK: ncget
+ %v11 = call i32 @llvm.mblaze.fsl.ncaget(i32 1)
+ ; CHECK-NOT: ncagetd
+ ; CHECK: ncaget
+ %v12 = call i32 @llvm.mblaze.fsl.neget(i32 1)
+ ; CHECK-NOT: negetd
+ ; CHECK: neget
+ %v13 = call i32 @llvm.mblaze.fsl.neaget(i32 1)
+ ; CHECK-NOT: neagetd
+ ; CHECK: neaget
+ %v14 = call i32 @llvm.mblaze.fsl.necget(i32 1)
+ ; CHECK-NOT: necgetd
+ ; CHECK: necget
+ %v15 = call i32 @llvm.mblaze.fsl.necaget(i32 1)
+ ; CHECK-NOT: necagetd
+ ; CHECK: necaget
+ %v16 = call i32 @llvm.mblaze.fsl.tget(i32 1)
+ ; CHECK-NOT: tgetd
+ ; CHECK: tget
+ %v17 = call i32 @llvm.mblaze.fsl.taget(i32 1)
+ ; CHECK-NOT: tagetd
+ ; CHECK: taget
+ %v18 = call i32 @llvm.mblaze.fsl.tcget(i32 1)
+ ; CHECK-NOT: tcgetd
+ ; CHECK: tcget
+ %v19 = call i32 @llvm.mblaze.fsl.tcaget(i32 1)
+ ; CHECK-NOT: tcagetd
+ ; CHECK: tcaget
+ %v20 = call i32 @llvm.mblaze.fsl.teget(i32 1)
+ ; CHECK-NOT: tegetd
+ ; CHECK: teget
+ %v21 = call i32 @llvm.mblaze.fsl.teaget(i32 1)
+ ; CHECK-NOT: teagetd
+ ; CHECK: teaget
+ %v22 = call i32 @llvm.mblaze.fsl.tecget(i32 1)
+ ; CHECK-NOT: tecgetd
+ ; CHECK: tecget
+ %v23 = call i32 @llvm.mblaze.fsl.tecaget(i32 1)
+ ; CHECK-NOT: tecagetd
+ ; CHECK: tecaget
+ %v24 = call i32 @llvm.mblaze.fsl.tnget(i32 1)
+ ; CHECK-NOT: tngetd
+ ; CHECK: tnget
+ %v25 = call i32 @llvm.mblaze.fsl.tnaget(i32 1)
+ ; CHECK-NOT: tnagetd
+ ; CHECK: tnaget
+ %v26 = call i32 @llvm.mblaze.fsl.tncget(i32 1)
+ ; CHECK-NOT: tncgetd
+ ; CHECK: tncget
+ %v27 = call i32 @llvm.mblaze.fsl.tncaget(i32 1)
+ ; CHECK-NOT: tncagetd
+ ; CHECK: tncaget
+ %v28 = call i32 @llvm.mblaze.fsl.tneget(i32 1)
+ ; CHECK-NOT: tnegetd
+ ; CHECK: tneget
+ %v29 = call i32 @llvm.mblaze.fsl.tneaget(i32 1)
+ ; CHECK-NOT: tneagetd
+ ; CHECK: tneaget
+ %v30 = call i32 @llvm.mblaze.fsl.tnecget(i32 1)
+ ; CHECK-NOT: tnecgetd
+ ; CHECK: tnecget
+ %v31 = call i32 @llvm.mblaze.fsl.tnecaget(i32 1)
+ ; CHECK-NOT: tnecagetd
+ ; CHECK: tnecaget
+ ret i32 1
+ ; CHECK: rtsd
+}
+
+define void @putfsl(i32 %value, i32 %port)
+{
+ ; CHECK: putfsl:
+ call void @llvm.mblaze.fsl.put(i32 %value, i32 %port)
+ ; CHECK: putd
+ call void @llvm.mblaze.fsl.aput(i32 %value, i32 %port)
+ ; CHECK-NEXT: aputd
+ call void @llvm.mblaze.fsl.cput(i32 %value, i32 %port)
+ ; CHECK-NEXT: cputd
+ call void @llvm.mblaze.fsl.caput(i32 %value, i32 %port)
+ ; CHECK-NEXT: caputd
+ call void @llvm.mblaze.fsl.nput(i32 %value, i32 %port)
+ ; CHECK-NEXT: nputd
+ call void @llvm.mblaze.fsl.naput(i32 %value, i32 %port)
+ ; CHECK-NEXT: naputd
+ call void @llvm.mblaze.fsl.ncput(i32 %value, i32 %port)
+ ; CHECK-NEXT: ncputd
+ call void @llvm.mblaze.fsl.ncaput(i32 %value, i32 %port)
+ ; CHECK-NEXT: ncaputd
+ call void @llvm.mblaze.fsl.tput(i32 %port)
+ ; CHECK-NEXT: tputd
+ call void @llvm.mblaze.fsl.taput(i32 %port)
+ ; CHECK-NEXT: taputd
+ call void @llvm.mblaze.fsl.tcput(i32 %port)
+ ; CHECK-NEXT: tcputd
+ call void @llvm.mblaze.fsl.tcaput(i32 %port)
+ ; CHECK-NEXT: tcaputd
+ call void @llvm.mblaze.fsl.tnput(i32 %port)
+ ; CHECK-NEXT: tnputd
+ call void @llvm.mblaze.fsl.tnaput(i32 %port)
+ ; CHECK-NEXT: tnaputd
+ call void @llvm.mblaze.fsl.tncput(i32 %port)
+ ; CHECK-NEXT: tncputd
+ call void @llvm.mblaze.fsl.tncaput(i32 %port)
+ ; CHECK-NEXT: tncaputd
+ ret void
+ ; CHECK: rtsd
+}
+
+define void @putfsl_const(i32 %value)
+{
+ ; CHECK: putfsl_const:
+ call void @llvm.mblaze.fsl.put(i32 %value, i32 1)
+ ; CHECK-NOT: putd
+ ; CHECK: put
+ call void @llvm.mblaze.fsl.aput(i32 %value, i32 1)
+ ; CHECK-NOT: aputd
+ ; CHECK: aput
+ call void @llvm.mblaze.fsl.cput(i32 %value, i32 1)
+ ; CHECK-NOT: cputd
+ ; CHECK: cput
+ call void @llvm.mblaze.fsl.caput(i32 %value, i32 1)
+ ; CHECK-NOT: caputd
+ ; CHECK: caput
+ call void @llvm.mblaze.fsl.nput(i32 %value, i32 1)
+ ; CHECK-NOT: nputd
+ ; CHECK: nput
+ call void @llvm.mblaze.fsl.naput(i32 %value, i32 1)
+ ; CHECK-NOT: naputd
+ ; CHECK: naput
+ call void @llvm.mblaze.fsl.ncput(i32 %value, i32 1)
+ ; CHECK-NOT: ncputd
+ ; CHECK: ncput
+ call void @llvm.mblaze.fsl.ncaput(i32 %value, i32 1)
+ ; CHECK-NOT: ncaputd
+ ; CHECK: ncaput
+ call void @llvm.mblaze.fsl.tput(i32 1)
+ ; CHECK-NOT: tputd
+ ; CHECK: tput
+ call void @llvm.mblaze.fsl.taput(i32 1)
+ ; CHECK-NOT: taputd
+ ; CHECK: taput
+ call void @llvm.mblaze.fsl.tcput(i32 1)
+ ; CHECK-NOT: tcputd
+ ; CHECK: tcput
+ call void @llvm.mblaze.fsl.tcaput(i32 1)
+ ; CHECK-NOT: tcaputd
+ ; CHECK: tcaput
+ call void @llvm.mblaze.fsl.tnput(i32 1)
+ ; CHECK-NOT: tnputd
+ ; CHECK: tnput
+ call void @llvm.mblaze.fsl.tnaput(i32 1)
+ ; CHECK-NOT: tnaputd
+ ; CHECK: tnaput
+ call void @llvm.mblaze.fsl.tncput(i32 1)
+ ; CHECK-NOT: tncputd
+ ; CHECK: tncput
+ call void @llvm.mblaze.fsl.tncaput(i32 1)
+ ; CHECK-NOT: tncaputd
+ ; CHECK: tncaput
+ ret void
+ ; CHECK: rtsd
+}
diff --git a/test/CodeGen/MBlaze/imm.ll b/test/CodeGen/MBlaze/imm.ll
new file mode 100644
index 0000000..85fad17
--- /dev/null
+++ b/test/CodeGen/MBlaze/imm.ll
@@ -0,0 +1,70 @@
+; Ensure that all immediate values that are 32-bits or less can be loaded
+; using a single instruction and that immediate values 64-bits or less can
+; be loaded using two instructions.
+;
+; RUN: llc < %s -march=mblaze | FileCheck %s
+; RUN: llc < %s -march=mblaze -mattr=+fpu | FileCheck -check-prefix=FPU %s
+
+define i8 @retimm_i8() {
+ ; CHECK: retimm_i8:
+ ; CHECK: add
+ ; CHECK-NEXT: rtsd
+ ; FPU: retimm_i8:
+ ; FPU: add
+ ; FPU-NEXT: rtsd
+ ret i8 123
+}
+
+define i16 @retimm_i16() {
+ ; CHECK: retimm_i16:
+ ; CHECK: add
+ ; CHECK-NEXT: rtsd
+ ; FPU: retimm_i16:
+ ; FPU: add
+ ; FPU-NEXT: rtsd
+ ret i16 38212
+}
+
+define i32 @retimm_i32() {
+ ; CHECK: retimm_i32:
+ ; CHECK: add
+ ; CHECK-NEXT: rtsd
+ ; FPU: retimm_i32:
+ ; FPU: add
+ ; FPU-NEXT: rtsd
+ ret i32 2938128
+}
+
+define i64 @retimm_i64() {
+ ; CHECK: retimm_i64:
+ ; CHECK: add
+ ; CHECK-NEXT: add
+ ; CHECK-NEXT: rtsd
+ ; FPU: retimm_i64:
+ ; FPU: add
+ ; FPU-NEXT: add
+ ; FPU-NEXT: rtsd
+ ret i64 94581823
+}
+
+define float @retimm_float() {
+ ; CHECK: retimm_float:
+ ; CHECK: add
+ ; CHECK-NEXT: rtsd
+ ; FPU: retimm_float:
+ ; FPU: or
+ ; FPU: rtsd
+ ret float 12.0
+}
+
+define double @retimm_double() {
+ ; CHECK: retimm_double:
+ ; CHECK: add
+ ; CHECK-NEXT: add
+ ; CHECK-NEXT: rtsd
+ ; FPU: retimm_double:
+ ; FPU: add
+ ; FPU-NEXT: add
+ ; FPU-NEXT: rtsd
+ ret double 598382.39283873
+}
diff --git a/test/CodeGen/MBlaze/jumptable.ll b/test/CodeGen/MBlaze/jumptable.ll
new file mode 100644
index 0000000..3f27c12
--- /dev/null
+++ b/test/CodeGen/MBlaze/jumptable.ll
@@ -0,0 +1,79 @@
+; Ensure that jump tables can be handled by the mblaze backend. The
+; jump table should be lowered to a "br" instruction using one of the
+; available registers.
+;
+; RUN: llc < %s -march=mblaze | FileCheck %s
+
+define i32 @jmptable(i32 %arg)
+{
+ ; CHECK: jmptable:
+ switch i32 %arg, label %DEFAULT [ i32 0, label %L0
+ i32 1, label %L1
+ i32 2, label %L2
+ i32 3, label %L3
+ i32 4, label %L4
+ i32 5, label %L5
+ i32 6, label %L6
+ i32 7, label %L7
+ i32 8, label %L8
+ i32 9, label %L9 ]
+
+ ; CHECK: lw [[REG:r[0-9]*]]
+ ; CHECK: br [[REG]]
+L0:
+ %var0 = add i32 %arg, 0
+ br label %DONE
+
+L1:
+ %var1 = add i32 %arg, 1
+ br label %DONE
+
+L2:
+ %var2 = add i32 %arg, 2
+ br label %DONE
+
+L3:
+ %var3 = add i32 %arg, 3
+ br label %DONE
+
+L4:
+ %var4 = add i32 %arg, 4
+ br label %DONE
+
+L5:
+ %var5 = add i32 %arg, 5
+ br label %DONE
+
+L6:
+ %var6 = add i32 %arg, 6
+ br label %DONE
+
+L7:
+ %var7 = add i32 %arg, 7
+ br label %DONE
+
+L8:
+ %var8 = add i32 %arg, 8
+ br label %DONE
+
+L9:
+ %var9 = add i32 %arg, 9
+ br label %DONE
+
+DEFAULT:
+ unreachable
+
+DONE:
+ %rval = phi i32 [ %var0, %L0 ],
+ [ %var1, %L1 ],
+ [ %var2, %L2 ],
+ [ %var3, %L3 ],
+ [ %var4, %L4 ],
+ [ %var5, %L5 ],
+ [ %var6, %L6 ],
+ [ %var7, %L7 ],
+ [ %var8, %L8 ],
+ [ %var9, %L9 ]
+ ret i32 %rval
+ ; CHECK: rtsd
+}
diff --git a/test/CodeGen/MBlaze/loop.ll b/test/CodeGen/MBlaze/loop.ll
new file mode 100644
index 0000000..b473020
--- /dev/null
+++ b/test/CodeGen/MBlaze/loop.ll
@@ -0,0 +1,47 @@
+; Test some complicated looping constructs to ensure that they
+; compile successfully and that some sort of branching is used
+; in the resulting code.
+;
+; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s
+
+declare i32 @printf(i8*, ...)
+@MSG = internal constant [19 x i8] c"Message: %d %d %d\0A\00"
+
+define i32 @loop(i32 %a, i32 %b)
+{
+ ; CHECK: loop:
+entry:
+ br label %loop_outer
+
+loop_outer:
+ %outer.0 = phi i32 [ 0, %entry ], [ %outer.2, %loop_outer_finish ]
+ br label %loop_inner
+
+loop_inner:
+ %inner.0 = phi i32 [ %a, %loop_outer ], [ %inner.3, %loop_inner_finish ]
+ %inner.1 = phi i32 [ %b, %loop_outer ], [ %inner.4, %loop_inner_finish ]
+ %inner.2 = phi i32 [ 0, %loop_outer ], [ %inner.5, %loop_inner_finish ]
+ %inner.3 = add i32 %inner.0, %inner.1
+ %inner.4 = mul i32 %inner.2, 11
+ br label %loop_inner_finish
+
+loop_inner_finish:
+ %inner.5 = add i32 %inner.2, 1
+ ; CHECK: addi {{.*, 1}}
+
+ call i32 (i8*,...)* @printf( i8* getelementptr([19 x i8]* @MSG,i32 0,i32 0),
+ i32 %inner.0, i32 %inner.1, i32 %inner.2 )
+ ; CHECK: brlid
+
+ %inner.6 = icmp eq i32 %inner.5, 100
+ ; CHECK: cmp
+
+ br i1 %inner.6, label %loop_inner, label %loop_outer_finish
+ ; CHECK: {{beq|bne}}
+
+loop_outer_finish:
+ %outer.1 = add i32 %outer.0, 1
+ %outer.2 = urem i32 %outer.1, 1500
+ br label %loop_outer
+ ; CHECK: br
+}
diff --git a/test/CodeGen/MBlaze/mul.ll b/test/CodeGen/MBlaze/mul.ll
new file mode 100644
index 0000000..65d3e22
--- /dev/null
+++ b/test/CodeGen/MBlaze/mul.ll
@@ -0,0 +1,51 @@
+; Ensure that multiplication is lowered to function calls when the multiplier
+; unit is not available in the hardware and that function calls are not used
+; when the multiplier unit is available in the hardware.
+;
+; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
+; RUN: llc < %s -march=mblaze -mattr=+mul | FileCheck -check-prefix=MUL %s
+
+define i8 @test_i8(i8 %a, i8 %b) {
+ ; FUN: test_i8:
+ ; MUL: test_i8:
+
+ %tmp.1 = mul i8 %a, %b
+ ; FUN-NOT: mul
+ ; FUN: brlid
+ ; MUL-NOT: brlid
+ ; MUL: mul
+
+ ret i8 %tmp.1
+ ; FUN: rtsd
+ ; MUL: rtsd
+}
+
+define i16 @test_i16(i16 %a, i16 %b) {
+ ; FUN: test_i16:
+ ; MUL: test_i16:
+
+ %tmp.1 = mul i16 %a, %b
+ ; FUN-NOT: mul
+ ; FUN: brlid
+ ; MUL-NOT: brlid
+ ; MUL: mul
+
+ ret i16 %tmp.1
+ ; FUN: rtsd
+ ; MUL: rtsd
+}
+
+define i32 @test_i32(i32 %a, i32 %b) {
+ ; FUN: test_i32:
+ ; MUL: test_i32:
+
+ %tmp.1 = mul i32 %a, %b
+ ; FUN-NOT: mul
+ ; FUN: brlid
+ ; MUL-NOT: brlid
+ ; MUL: mul
+
+ ret i32 %tmp.1
+ ; FUN: rtsd
+ ; MUL: rtsd
+}
diff --git a/test/CodeGen/MBlaze/mul64.ll b/test/CodeGen/MBlaze/mul64.ll
new file mode 100644
index 0000000..e0ef413
--- /dev/null
+++ b/test/CodeGen/MBlaze/mul64.ll
@@ -0,0 +1,23 @@
+; Ensure that multiplication is lowered to function calls when the 64-bit
+; multiplier unit is not available in the hardware and that function calls
+; are not used when the 64-bit multiplier unit is available in the hardware.
+;
+; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
+; RUN: llc < %s -march=mblaze -mattr=+mul,+mul64 | \
+; RUN: FileCheck -check-prefix=MUL %s
+
+define i64 @test_i64(i64 %a, i64 %b) {
+ ; FUN: test_i64:
+ ; MUL: test_i64:
+
+ %tmp.1 = mul i64 %a, %b
+ ; FUN-NOT: mul
+ ; FUN: brlid
+ ; MUL-NOT: brlid
+ ; MUL: mulh
+ ; MUL: mul
+
+ ret i64 %tmp.1
+ ; FUN: rtsd
+ ; MUL: rtsd
+}
diff --git a/test/CodeGen/MBlaze/select.ll b/test/CodeGen/MBlaze/select.ll
new file mode 100644
index 0000000..47a88a1
--- /dev/null
+++ b/test/CodeGen/MBlaze/select.ll
@@ -0,0 +1,15 @@
+; Ensure that the select instruction is supported and is lowered to
+; some sort of branch instruction.
+;
+; RUN: llc < %s -march=mblaze | FileCheck %s
+
+define i32 @testsel(i32 %a, i32 %b)
+{
+ ; CHECK: testsel:
+ %tmp.1 = icmp eq i32 %a, %b
+ ; CHECK: cmp
+ %tmp.2 = select i1 %tmp.1, i32 %a, i32 %b
+ ; CHECK: {{bne|beq}}
+ ret i32 %tmp.2
+ ; CHECK: rtsd
+}
diff --git a/test/CodeGen/MBlaze/shift.ll b/test/CodeGen/MBlaze/shift.ll
new file mode 100644
index 0000000..186115e
--- /dev/null
+++ b/test/CodeGen/MBlaze/shift.ll
@@ -0,0 +1,117 @@
+; Ensure that shifts are lowered to loops when the barrel shifter unit is
+; not available in the hardware and that loops are not used when the
+; barrel shifter unit is available in the hardware.
+;
+; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
+; RUN: llc < %s -march=mblaze -mattr=+barrel | FileCheck -check-prefix=SHT %s
+
+define i8 @test_i8(i8 %a, i8 %b) {
+ ; FUN: test_i8:
+ ; SHT: test_i8:
+
+ %tmp.1 = shl i8 %a, %b
+ ; FUN-NOT: bsll
+ ; FUN: andi
+ ; FUN: add
+ ; FUN: bnei
+ ; SHT-NOT: andi
+ ; SHT-NOT: bnei
+ ; SHT: bsll
+
+ ret i8 %tmp.1
+ ; FUN: rtsd
+ ; SHT: rtsd
+}
+
+define i8 @testc_i8(i8 %a, i8 %b) {
+ ; FUN: testc_i8:
+ ; SHT: testc_i8:
+
+ %tmp.1 = shl i8 %a, 5
+ ; FUN-NOT: bsll
+ ; FUN: andi
+ ; FUN: add
+ ; FUN: bnei
+ ; SHT-NOT: andi
+ ; SHT-NOT: add
+ ; SHT-NOT: bnei
+ ; SHT: bslli
+
+ ret i8 %tmp.1
+ ; FUN: rtsd
+ ; SHT: rtsd
+}
+
+define i16 @test_i16(i16 %a, i16 %b) {
+ ; FUN: test_i16:
+ ; SHT: test_i16:
+
+ %tmp.1 = shl i16 %a, %b
+ ; FUN-NOT: bsll
+ ; FUN: andi
+ ; FUN: add
+ ; FUN: bnei
+ ; SHT-NOT: andi
+ ; SHT-NOT: bnei
+ ; SHT: bsll
+
+ ret i16 %tmp.1
+ ; FUN: rtsd
+ ; SHT: rtsd
+}
+
+define i16 @testc_i16(i16 %a, i16 %b) {
+ ; FUN: testc_i16:
+ ; SHT: testc_i16:
+
+ %tmp.1 = shl i16 %a, 5
+ ; FUN-NOT: bsll
+ ; FUN: andi
+ ; FUN: add
+ ; FUN: bnei
+ ; SHT-NOT: andi
+ ; SHT-NOT: add
+ ; SHT-NOT: bnei
+ ; SHT: bslli
+
+ ret i16 %tmp.1
+ ; FUN: rtsd
+ ; SHT: rtsd
+}
+
+define i32 @test_i32(i32 %a, i32 %b) {
+ ; FUN: test_i32:
+ ; SHT: test_i32:
+
+ %tmp.1 = shl i32 %a, %b
+ ; FUN-NOT: bsll
+ ; FUN: andi
+ ; FUN: add
+ ; FUN: bnei
+ ; SHT-NOT: andi
+ ; SHT-NOT: bnei
+ ; SHT: bsll
+
+ ret i32 %tmp.1
+ ; FUN: rtsd
+ ; SHT: rtsd
+}
+
+define i32 @testc_i32(i32 %a, i32 %b) {
+ ; FUN: testc_i32:
+ ; SHT: testc_i32:
+
+ %tmp.1 = shl i32 %a, 5
+ ; FUN-NOT: bsll
+ ; FUN: andi
+ ; FUN: add
+ ; FUN: bnei
+ ; SHT-NOT: andi
+ ; SHT-NOT: add
+ ; SHT-NOT: bnei
+ ; SHT: bslli
+
+ ret i32 %tmp.1
+ ; FUN: rtsd
+ ; SHT: rtsd
+}
diff --git a/test/CodeGen/MSP430/AddrMode-bis-rx.ll b/test/CodeGen/MSP430/AddrMode-bis-rx.ll
index 3340494..4f9a724 100644
--- a/test/CodeGen/MSP430/AddrMode-bis-rx.ll
+++ b/test/CodeGen/MSP430/AddrMode-bis-rx.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=msp430 | FileCheck %s
+; RUN: llc < %s -march=msp430 | FileCheck %s
target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:16"
target triple = "msp430-generic-generic"
@@ -29,7 +29,7 @@ define i8 @am3(i8 %x, i16 %n) nounwind {
ret i8 %3
}
; CHECK: am3:
-; CHECK: bis.b &bar(r14), r15
+; CHECK: bis.b bar(r14), r15
define i16 @am4(i16 %x) nounwind {
%1 = volatile load i16* inttoptr(i16 32 to i16*)
@@ -70,5 +70,5 @@ define i8 @am7(i8 %x, i16 %n) nounwind {
ret i8 %4
}
; CHECK: am7:
-; CHECK: bis.b &duh+2(r14), r15
+; CHECK: bis.b duh+2(r14), r15
diff --git a/test/CodeGen/MSP430/AddrMode-bis-xr.ll b/test/CodeGen/MSP430/AddrMode-bis-xr.ll
index ca79fb6..17ebd87 100644
--- a/test/CodeGen/MSP430/AddrMode-bis-xr.ll
+++ b/test/CodeGen/MSP430/AddrMode-bis-xr.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=msp430 | FileCheck %s
+; RUN: llc < %s -march=msp430 | FileCheck %s
target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:16"
target triple = "msp430-generic-generic"
@@ -32,7 +32,7 @@ define void @am3(i16 %i, i8 %x) nounwind {
ret void
}
; CHECK: am3:
-; CHECK: bis.b r14, &bar(r15)
+; CHECK: bis.b r14, bar(r15)
define void @am4(i16 %x) nounwind {
%1 = volatile load i16* inttoptr(i16 32 to i16*)
@@ -77,5 +77,5 @@ define void @am7(i16 %n, i8 %x) nounwind {
ret void
}
; CHECK: am7:
-; CHECK: bis.b r14, &duh+2(r15)
+; CHECK: bis.b r14, duh+2(r15)
diff --git a/test/CodeGen/MSP430/AddrMode-mov-rx.ll b/test/CodeGen/MSP430/AddrMode-mov-rx.ll
index 67cbb02..6676b88 100644
--- a/test/CodeGen/MSP430/AddrMode-mov-rx.ll
+++ b/test/CodeGen/MSP430/AddrMode-mov-rx.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=msp430 | FileCheck %s
+; RUN: llc < %s -march=msp430 | FileCheck %s
target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:16"
target triple = "msp430-generic-generic"
@@ -26,7 +26,7 @@ define i8 @am3(i16 %n) nounwind {
ret i8 %2
}
; CHECK: am3:
-; CHECK: mov.b &bar(r15), r15
+; CHECK: mov.b bar(r15), r15
define i16 @am4() nounwind {
%1 = volatile load i16* inttoptr(i16 32 to i16*)
@@ -63,5 +63,5 @@ define i8 @am7(i16 %n) nounwind {
ret i8 %3
}
; CHECK: am7:
-; CHECK: mov.b &duh+2(r15), r15
+; CHECK: mov.b duh+2(r15), r15
diff --git a/test/CodeGen/MSP430/AddrMode-mov-xr.ll b/test/CodeGen/MSP430/AddrMode-mov-xr.ll
index b8155d3..4b327b0 100644
--- a/test/CodeGen/MSP430/AddrMode-mov-xr.ll
+++ b/test/CodeGen/MSP430/AddrMode-mov-xr.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=msp430 | FileCheck %s
+; RUN: llc < %s -march=msp430 | FileCheck %s
target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:16"
target triple = "msp430-generic-generic"
@@ -26,7 +26,7 @@ define void @am3(i16 %i, i8 %a) nounwind {
ret void
}
; CHECK: am3:
-; CHECK: mov.b r14, &bar(r15)
+; CHECK: mov.b r14, bar(r15)
define void @am4(i16 %a) nounwind {
volatile store i16 %a, i16* inttoptr(i16 32 to i16*)
@@ -63,5 +63,5 @@ define void @am7(i16 %n, i8 %a) nounwind {
ret void
}
; CHECK: am7:
-; CHECK: mov.b r14, &duh+2(r15)
+; CHECK: mov.b r14, duh+2(r15)
diff --git a/test/CodeGen/MSP430/Inst16mm.ll b/test/CodeGen/MSP430/Inst16mm.ll
index 510afe3..2337c2c 100644
--- a/test/CodeGen/MSP430/Inst16mm.ll
+++ b/test/CodeGen/MSP430/Inst16mm.ll
@@ -1,4 +1,4 @@
-; RUN: llc -march=msp430 < %s | FileCheck %s
+; RUN: llc -march=msp430 -combiner-alias-analysis < %s | FileCheck %s
target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"
target triple = "msp430-generic-generic"
@foo = common global i16 0, align 2
@@ -52,3 +52,18 @@ define void @xor() nounwind {
ret void
}
+define i16 @mov2() nounwind {
+entry:
+ %retval = alloca i16 ; <i16*> [#uses=3]
+ %x = alloca i32, align 2 ; <i32*> [#uses=1]
+ %y = alloca i32, align 2 ; <i32*> [#uses=1]
+ store i16 0, i16* %retval
+ %tmp = load i32* %y ; <i32> [#uses=1]
+ store i32 %tmp, i32* %x
+ store i16 0, i16* %retval
+ %0 = load i16* %retval ; <i16> [#uses=1]
+ ret i16 %0
+; CHECK: mov2:
+; CHECK: mov.w 0(r1), 4(r1)
+; CHECK: mov.w 2(r1), 6(r1)
+}
diff --git a/test/CodeGen/MSP430/Inst8rr.ll b/test/CodeGen/MSP430/Inst8rr.ll
index 74feaae..0f5fc12 100644
--- a/test/CodeGen/MSP430/Inst8rr.ll
+++ b/test/CodeGen/MSP430/Inst8rr.ll
@@ -10,7 +10,7 @@ define i8 @mov(i8 %a, i8 %b) nounwind {
define i8 @add(i8 %a, i8 %b) nounwind {
; CHECK: add:
-; CHECK: add.b r14, r15
+; CHECK: add.b r12, r15
%1 = add i8 %a, %b
ret i8 %1
}
diff --git a/test/CodeGen/MSP430/bit.ll b/test/CodeGen/MSP430/bit.ll
index cd664a1..03d672b 100644
--- a/test/CodeGen/MSP430/bit.ll
+++ b/test/CodeGen/MSP430/bit.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=msp430 | FileCheck %s
+; RUN: llc < %s -march=msp430 | FileCheck %s
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 9db51cc..c99b17e 100644
--- a/test/CodeGen/MSP430/setcc.ll
+++ b/test/CodeGen/MSP430/setcc.ll
@@ -10,9 +10,9 @@ define i16 @sccweqand(i16 %a, i16 %b) nounwind {
}
; CHECK: sccweqand:
; CHECK: bit.w r14, r15
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: and.w #1, r15
-; CHECK-NEXT: xor.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: rra.w r15
+; CHECK: and.w #1, r15
define i16 @sccwneand(i16 %a, i16 %b) nounwind {
%t1 = and i16 %a, %b
@@ -22,8 +22,8 @@ define i16 @sccwneand(i16 %a, i16 %b) nounwind {
}
; CHECK: sccwneand:
; CHECK: bit.w r14, r15
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: and.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: and.w #1, r15
define i16 @sccwne(i16 %a, i16 %b) nounwind {
%t1 = icmp ne i16 %a, %b
@@ -32,9 +32,10 @@ define i16 @sccwne(i16 %a, i16 %b) nounwind {
}
; CHECK:sccwne:
; CHECK: cmp.w r14, r15
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: rra.w r15
-; CHECK-NEXT: and.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: rra.w r15
+; CHECK: and.w #1, r15
+; CHECK: xor.w #1, r15
define i16 @sccweq(i16 %a, i16 %b) nounwind {
%t1 = icmp eq i16 %a, %b
@@ -43,10 +44,9 @@ define i16 @sccweq(i16 %a, i16 %b) nounwind {
}
; CHECK:sccweq:
; CHECK: cmp.w r14, r15
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: rra.w r15
-; CHECK-NEXT: and.w #1, r15
-; CHECK-NEXT: xor.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: rra.w r15
+; CHECK: and.w #1, r15
define i16 @sccwugt(i16 %a, i16 %b) nounwind {
%t1 = icmp ugt i16 %a, %b
@@ -55,9 +55,9 @@ define i16 @sccwugt(i16 %a, i16 %b) nounwind {
}
; CHECK:sccwugt:
; CHECK: cmp.w r15, r14
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: and.w #1, r15
-; CHECK-NEXT: xor.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: and.w #1, r15
+; CHECK: xor.w #1, r15
define i16 @sccwuge(i16 %a, i16 %b) nounwind {
%t1 = icmp uge i16 %a, %b
@@ -66,8 +66,8 @@ define i16 @sccwuge(i16 %a, i16 %b) nounwind {
}
; CHECK:sccwuge:
; CHECK: cmp.w r14, r15
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: and.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: and.w #1, r15
define i16 @sccwult(i16 %a, i16 %b) nounwind {
%t1 = icmp ult i16 %a, %b
@@ -76,9 +76,9 @@ define i16 @sccwult(i16 %a, i16 %b) nounwind {
}
; CHECK:sccwult:
; CHECK: cmp.w r14, r15
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: and.w #1, r15
-; CHECK-NEXT: xor.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: and.w #1, r15
+; CHECK: xor.w #1, r15
define i16 @sccwule(i16 %a, i16 %b) nounwind {
%t1 = icmp ule i16 %a, %b
@@ -87,8 +87,8 @@ define i16 @sccwule(i16 %a, i16 %b) nounwind {
}
; CHECK:sccwule:
; CHECK: cmp.w r15, r14
-; CHECK-NEXT: mov.w r2, r15
-; CHECK-NEXT: and.w #1, r15
+; CHECK: mov.w r2, r15
+; CHECK: and.w #1, r15
define i16 @sccwsgt(i16 %a, i16 %b) nounwind {
%t1 = icmp sgt i16 %a, %b
diff --git a/test/CodeGen/PIC16/C16-11.ll b/test/CodeGen/PIC16/C16-11.ll
index e70092b..8a5a0ac 100644
--- a/test/CodeGen/PIC16/C16-11.ll
+++ b/test/CodeGen/PIC16/C16-11.ll
@@ -1,4 +1,7 @@
-;RUN: llc < %s -march=pic16
+; RUN: llc < %s -march=pic16
+; XFAIL: *
+; This fails because PIC16 doesn't define a (xor reg, reg) pattern.
+;
@c612.auto.a.b = internal global i1 false ; <i1*> [#uses=2]
@c612.auto.A.b = internal global i1 false ; <i1*> [#uses=2]
diff --git a/test/CodeGen/PIC16/C16-15.ll b/test/CodeGen/PIC16/C16-15.ll
index 2e1dc0c..5ca2d4a 100644
--- a/test/CodeGen/PIC16/C16-15.ll
+++ b/test/CodeGen/PIC16/C16-15.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=pic16 | grep "extern @.lib.unordered.f32" | count 3
+; RUN: llc < %s -march=pic16 | grep "extern" | grep "@.lib.unordered.f32" | count 3
@pc = global i8* inttoptr (i64 160 to i8*), align 1 ; <i8**> [#uses=2]
@aa = common global i16 0, align 1 ; <i16*> [#uses=0]
diff --git a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
index d1d28ae..be28a9a 100644
--- a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
+++ b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
@@ -1,6 +1,6 @@
; RUN: llc < %s | grep {subfc r3,r5,r4}
-; RUN: llc < %s | grep {subfze r4,r2}
-; RUN: llc < %s -regalloc=local | grep {subfc r2,r5,r4}
+; RUN: llc < %s | grep {subfze r4,r6}
+; RUN: llc < %s -regalloc=local | grep {subfc r6,r5,r4}
; RUN: llc < %s -regalloc=local | grep {subfze r3,r3}
; The first argument of subfc must not be the same as any other register.
diff --git a/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll b/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll
index 5d09696..50a0278 100644
--- a/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll
+++ b/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=ppc32 | FileCheck %s
+; RUN: llc < %s -march=ppc32 -mtriple=powerpc-apple-darwin10 -mcpu=g5 | FileCheck %s
; ModuleID = '<stdin>'
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-f128:64:128"
target triple = "powerpc-apple-darwin10.0"
@@ -10,8 +10,8 @@ target triple = "powerpc-apple-darwin10.0"
define void @foo(i32 %y) nounwind ssp {
entry:
; CHECK: foo
-; CHECK: add r2
-; CHECK: 0(r2)
+; CHECK: add r4
+; CHECK: 0(r4)
%y_addr = alloca i32 ; <i32*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i32 %y, i32* %y_addr
diff --git a/test/CodeGen/PowerPC/2010-02-12-saveCR.ll b/test/CodeGen/PowerPC/2010-02-12-saveCR.ll
new file mode 100644
index 0000000..b73382e
--- /dev/null
+++ b/test/CodeGen/PowerPC/2010-02-12-saveCR.ll
@@ -0,0 +1,30 @@
+; RUN: llc < %s -mtriple=powerpc-apple-darwin | FileCheck %s
+; ModuleID = 'hh.c'
+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-f128:64:128-n32"
+target triple = "powerpc-apple-darwin9.6"
+; This formerly used R0 for both the stack address and CR.
+
+define void @foo() nounwind {
+entry:
+;CHECK: mfcr r2
+;CHECK: rlwinm r2, r2, 8, 0, 31
+;CHECK: lis r0, 1
+;CHECK: ori r0, r0, 34540
+;CHECK: stwx r2, r1, r0
+ %x = alloca [100000 x i8] ; <[100000 x i8]*> [#uses=1]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ %x1 = bitcast [100000 x i8]* %x to i8* ; <i8*> [#uses=1]
+ call void @bar(i8* %x1) nounwind
+ call void asm sideeffect "", "~{cr2}"() nounwind
+ br label %return
+
+return: ; preds = %entry
+;CHECK: lis r0, 1
+;CHECK: ori r0, r0, 34540
+;CHECK: lwzx r2, r1, r0
+;CHECK: rlwinm r2, r2, 24, 0, 31
+;CHECK: mtcrf 32, r2
+ ret void
+}
+
+declare void @bar(i8*)
diff --git a/test/CodeGen/PowerPC/2010-02-26-FoldFloats.ll b/test/CodeGen/PowerPC/2010-02-26-FoldFloats.ll
new file mode 100644
index 0000000..f43f5ca
--- /dev/null
+++ b/test/CodeGen/PowerPC/2010-02-26-FoldFloats.ll
@@ -0,0 +1,433 @@
+; RUN: llc < %s -O3 | 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-f128:64:128-n32"
+target triple = "powerpc-apple-darwin9.6"
+
+; There should be no stfs spills
+; CHECK: main:
+; CHECK-NOT: stfs
+; CHECK: .section
+
+@.str66 = external constant [3 x i8], align 4 ; <[3 x i8]*> [#uses=1]
+@.str31 = external constant [6 x i8], align 4 ; <[6 x i8]*> [#uses=1]
+@.str61 = external constant [21 x i8], align 4 ; <[21 x i8]*> [#uses=1]
+@.str101 = external constant [61 x i8], align 4 ; <[61 x i8]*> [#uses=1]
+@.str104 = external constant [31 x i8], align 4 ; <[31 x i8]*> [#uses=1]
+@.str105 = external constant [45 x i8], align 4 ; <[45 x i8]*> [#uses=1]
+@.str112 = external constant [38 x i8], align 4 ; <[38 x i8]*> [#uses=1]
+@.str121 = external constant [36 x i8], align 4 ; <[36 x i8]*> [#uses=1]
+@.str12293 = external constant [67 x i8], align 4 ; <[67 x i8]*> [#uses=1]
+@.str123 = external constant [68 x i8], align 4 ; <[68 x i8]*> [#uses=1]
+@.str124 = external constant [52 x i8], align 4 ; <[52 x i8]*> [#uses=1]
+@.str125 = external constant [51 x i8], align 4 ; <[51 x i8]*> [#uses=1]
+
+define i32 @main(i32 %argc, i8** %argv) noreturn nounwind {
+entry:
+ br i1 undef, label %bb4.i1, label %my_fopen.exit
+
+bb4.i1: ; preds = %entry
+ unreachable
+
+my_fopen.exit: ; preds = %entry
+ br i1 undef, label %bb.i, label %bb1.i
+
+bb.i: ; preds = %my_fopen.exit
+ unreachable
+
+bb1.i: ; preds = %my_fopen.exit
+ br label %bb134.i
+
+bb2.i: ; preds = %bb134.i
+ %0 = icmp eq i32 undef, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb20.i, label %bb21.i
+
+bb20.i: ; preds = %bb2.i
+ br label %bb134.i
+
+bb21.i: ; preds = %bb2.i
+ %1 = call i32 @strcmp(i8* undef, i8* getelementptr inbounds ([6 x i8]* @.str31, i32 0, i32 0)) nounwind readonly ; <i32> [#uses=0]
+ br i1 undef, label %bb30.i, label %bb31.i
+
+bb30.i: ; preds = %bb21.i
+ br label %bb134.i
+
+bb31.i: ; preds = %bb21.i
+ br i1 undef, label %bb41.i, label %bb44.i
+
+bb41.i: ; preds = %bb31.i
+ %2 = icmp slt i32 undef, %argc ; <i1> [#uses=1]
+ br i1 %2, label %bb1.i77.i, label %bb2.i78.i
+
+bb1.i77.i: ; preds = %bb41.i
+ %3 = load float* undef, align 4 ; <float> [#uses=2]
+ %4 = fcmp ugt float %3, 0.000000e+00 ; <i1> [#uses=1]
+ br i1 %4, label %bb43.i, label %bb42.i
+
+bb2.i78.i: ; preds = %bb41.i
+ unreachable
+
+bb42.i: ; preds = %bb1.i77.i
+ unreachable
+
+bb43.i: ; preds = %bb1.i77.i
+ br label %bb134.i
+
+bb44.i: ; preds = %bb31.i
+ br i1 undef, label %bb45.i, label %bb49.i
+
+bb45.i: ; preds = %bb44.i
+ %5 = icmp slt i32 undef, %argc ; <i1> [#uses=1]
+ br i1 %5, label %bb1.i72.i, label %bb2.i73.i
+
+bb1.i72.i: ; preds = %bb45.i
+ %6 = load float* undef, align 4 ; <float> [#uses=3]
+ %7 = fcmp ult float %6, 1.000000e+00 ; <i1> [#uses=1]
+ %or.cond.i = and i1 undef, %7 ; <i1> [#uses=1]
+ br i1 %or.cond.i, label %bb48.i, label %bb47.i
+
+bb2.i73.i: ; preds = %bb45.i
+ unreachable
+
+bb47.i: ; preds = %bb1.i72.i
+ unreachable
+
+bb48.i: ; preds = %bb1.i72.i
+ br label %bb134.i
+
+bb49.i: ; preds = %bb44.i
+ br i1 undef, label %bb50.i, label %bb53.i
+
+bb50.i: ; preds = %bb49.i
+ br i1 false, label %bb1.i67.i, label %bb2.i68.i
+
+bb1.i67.i: ; preds = %bb50.i
+ br i1 false, label %read_float_option.exit69.i, label %bb1.i67.bb2.i68_crit_edge.i
+
+bb1.i67.bb2.i68_crit_edge.i: ; preds = %bb1.i67.i
+ br label %bb2.i68.i
+
+bb2.i68.i: ; preds = %bb1.i67.bb2.i68_crit_edge.i, %bb50.i
+ unreachable
+
+read_float_option.exit69.i: ; preds = %bb1.i67.i
+ br i1 undef, label %bb52.i, label %bb51.i
+
+bb51.i: ; preds = %read_float_option.exit69.i
+ unreachable
+
+bb52.i: ; preds = %read_float_option.exit69.i
+ br label %bb134.i
+
+bb53.i: ; preds = %bb49.i
+ %8 = call i32 @strcmp(i8* undef, i8* getelementptr inbounds ([21 x i8]* @.str61, i32 0, i32 0)) nounwind readonly ; <i32> [#uses=0]
+ br i1 false, label %bb89.i, label %bb92.i
+
+bb89.i: ; preds = %bb53.i
+ br i1 undef, label %bb1.i27.i, label %bb2.i28.i
+
+bb1.i27.i: ; preds = %bb89.i
+ unreachable
+
+bb2.i28.i: ; preds = %bb89.i
+ unreachable
+
+bb92.i: ; preds = %bb53.i
+ br i1 undef, label %bb93.i, label %bb96.i
+
+bb93.i: ; preds = %bb92.i
+ br i1 undef, label %bb1.i22.i, label %bb2.i23.i
+
+bb1.i22.i: ; preds = %bb93.i
+ br i1 undef, label %bb95.i, label %bb94.i
+
+bb2.i23.i: ; preds = %bb93.i
+ unreachable
+
+bb94.i: ; preds = %bb1.i22.i
+ unreachable
+
+bb95.i: ; preds = %bb1.i22.i
+ br label %bb134.i
+
+bb96.i: ; preds = %bb92.i
+ br i1 undef, label %bb97.i, label %bb100.i
+
+bb97.i: ; preds = %bb96.i
+ %9 = icmp slt i32 undef, %argc ; <i1> [#uses=1]
+ br i1 %9, label %bb1.i17.i, label %bb2.i18.i
+
+bb1.i17.i: ; preds = %bb97.i
+ %10 = call i32 (i8*, i8*, ...)* @"\01_sscanf$LDBL128"(i8* undef, i8* getelementptr inbounds ([3 x i8]* @.str66, i32 0, i32 0), float* undef) nounwind ; <i32> [#uses=1]
+ %phitmp.i16.i = icmp eq i32 %10, 1 ; <i1> [#uses=1]
+ br i1 %phitmp.i16.i, label %read_float_option.exit19.i, label %bb1.i17.bb2.i18_crit_edge.i
+
+bb1.i17.bb2.i18_crit_edge.i: ; preds = %bb1.i17.i
+ br label %bb2.i18.i
+
+bb2.i18.i: ; preds = %bb1.i17.bb2.i18_crit_edge.i, %bb97.i
+ unreachable
+
+read_float_option.exit19.i: ; preds = %bb1.i17.i
+ br i1 false, label %bb99.i, label %bb98.i
+
+bb98.i: ; preds = %read_float_option.exit19.i
+ unreachable
+
+bb99.i: ; preds = %read_float_option.exit19.i
+ br label %bb134.i
+
+bb100.i: ; preds = %bb96.i
+ br i1 false, label %bb101.i, label %bb104.i
+
+bb101.i: ; preds = %bb100.i
+ br i1 false, label %bb1.i12.i, label %bb2.i13.i
+
+bb1.i12.i: ; preds = %bb101.i
+ br i1 undef, label %bb102.i, label %bb103.i
+
+bb2.i13.i: ; preds = %bb101.i
+ unreachable
+
+bb102.i: ; preds = %bb1.i12.i
+ unreachable
+
+bb103.i: ; preds = %bb1.i12.i
+ br label %bb134.i
+
+bb104.i: ; preds = %bb100.i
+ unreachable
+
+bb134.i: ; preds = %bb103.i, %bb99.i, %bb95.i, %bb52.i, %bb48.i, %bb43.i, %bb30.i, %bb20.i, %bb1.i
+ %annealing_sched.1.0 = phi float [ 1.000000e+01, %bb1.i ], [ %annealing_sched.1.0, %bb20.i ], [ 1.000000e+00, %bb30.i ], [ %annealing_sched.1.0, %bb43.i ], [ %annealing_sched.1.0, %bb48.i ], [ %annealing_sched.1.0, %bb52.i ], [ %annealing_sched.1.0, %bb95.i ], [ %annealing_sched.1.0, %bb99.i ], [ %annealing_sched.1.0, %bb103.i ] ; <float> [#uses=8]
+ %annealing_sched.2.0 = phi float [ 1.000000e+02, %bb1.i ], [ %annealing_sched.2.0, %bb20.i ], [ %annealing_sched.2.0, %bb30.i ], [ %3, %bb43.i ], [ %annealing_sched.2.0, %bb48.i ], [ %annealing_sched.2.0, %bb52.i ], [ %annealing_sched.2.0, %bb95.i ], [ %annealing_sched.2.0, %bb99.i ], [ %annealing_sched.2.0, %bb103.i ] ; <float> [#uses=8]
+ %annealing_sched.3.0 = phi float [ 0x3FE99999A0000000, %bb1.i ], [ %annealing_sched.3.0, %bb20.i ], [ %annealing_sched.3.0, %bb30.i ], [ %annealing_sched.3.0, %bb43.i ], [ %6, %bb48.i ], [ %annealing_sched.3.0, %bb52.i ], [ %annealing_sched.3.0, %bb95.i ], [ %annealing_sched.3.0, %bb99.i ], [ %annealing_sched.3.0, %bb103.i ] ; <float> [#uses=8]
+ %annealing_sched.4.0 = phi float [ 0x3F847AE140000000, %bb1.i ], [ %annealing_sched.4.0, %bb20.i ], [ %annealing_sched.4.0, %bb30.i ], [ %annealing_sched.4.0, %bb43.i ], [ %annealing_sched.4.0, %bb48.i ], [ 0.000000e+00, %bb52.i ], [ %annealing_sched.4.0, %bb95.i ], [ %annealing_sched.4.0, %bb99.i ], [ %annealing_sched.4.0, %bb103.i ] ; <float> [#uses=8]
+ %router_opts.0.0 = phi float [ 0.000000e+00, %bb1.i ], [ %router_opts.0.0, %bb20.i ], [ 1.000000e+04, %bb30.i ], [ %router_opts.0.0, %bb43.i ], [ %router_opts.0.0, %bb48.i ], [ %router_opts.0.0, %bb52.i ], [ %router_opts.0.0, %bb95.i ], [ %router_opts.0.0, %bb99.i ], [ %router_opts.0.0, %bb103.i ] ; <float> [#uses=8]
+ %router_opts.1.0 = phi float [ 5.000000e-01, %bb1.i ], [ %router_opts.1.0, %bb20.i ], [ 1.000000e+04, %bb30.i ], [ %router_opts.1.0, %bb43.i ], [ %router_opts.1.0, %bb48.i ], [ %router_opts.1.0, %bb52.i ], [ undef, %bb95.i ], [ %router_opts.1.0, %bb99.i ], [ %router_opts.1.0, %bb103.i ] ; <float> [#uses=7]
+ %router_opts.2.0 = phi float [ 1.500000e+00, %bb1.i ], [ %router_opts.2.0, %bb20.i ], [ %router_opts.2.0, %bb30.i ], [ %router_opts.2.0, %bb43.i ], [ %router_opts.2.0, %bb48.i ], [ %router_opts.2.0, %bb52.i ], [ %router_opts.2.0, %bb95.i ], [ undef, %bb99.i ], [ %router_opts.2.0, %bb103.i ] ; <float> [#uses=8]
+ %router_opts.3.0 = phi float [ 0x3FC99999A0000000, %bb1.i ], [ %router_opts.3.0, %bb20.i ], [ %router_opts.3.0, %bb30.i ], [ %router_opts.3.0, %bb43.i ], [ %router_opts.3.0, %bb48.i ], [ %router_opts.3.0, %bb52.i ], [ %router_opts.3.0, %bb95.i ], [ %router_opts.3.0, %bb99.i ], [ 0.000000e+00, %bb103.i ] ; <float> [#uses=8]
+ %11 = phi float [ 0x3FC99999A0000000, %bb1.i ], [ %11, %bb20.i ], [ %11, %bb30.i ], [ %11, %bb43.i ], [ %11, %bb48.i ], [ %11, %bb52.i ], [ %11, %bb95.i ], [ %11, %bb99.i ], [ 0.000000e+00, %bb103.i ] ; <float> [#uses=8]
+ %12 = phi float [ 1.500000e+00, %bb1.i ], [ %12, %bb20.i ], [ %12, %bb30.i ], [ %12, %bb43.i ], [ %12, %bb48.i ], [ %12, %bb52.i ], [ %12, %bb95.i ], [ undef, %bb99.i ], [ %12, %bb103.i ] ; <float> [#uses=8]
+ %13 = phi float [ 5.000000e-01, %bb1.i ], [ %13, %bb20.i ], [ 1.000000e+04, %bb30.i ], [ %13, %bb43.i ], [ %13, %bb48.i ], [ %13, %bb52.i ], [ undef, %bb95.i ], [ %13, %bb99.i ], [ %13, %bb103.i ] ; <float> [#uses=7]
+ %14 = phi float [ 0.000000e+00, %bb1.i ], [ %14, %bb20.i ], [ 1.000000e+04, %bb30.i ], [ %14, %bb43.i ], [ %14, %bb48.i ], [ %14, %bb52.i ], [ %14, %bb95.i ], [ %14, %bb99.i ], [ %14, %bb103.i ] ; <float> [#uses=8]
+ %15 = phi float [ 0x3FE99999A0000000, %bb1.i ], [ %15, %bb20.i ], [ %15, %bb30.i ], [ %15, %bb43.i ], [ %6, %bb48.i ], [ %15, %bb52.i ], [ %15, %bb95.i ], [ %15, %bb99.i ], [ %15, %bb103.i ] ; <float> [#uses=8]
+ %16 = phi float [ 0x3F847AE140000000, %bb1.i ], [ %16, %bb20.i ], [ %16, %bb30.i ], [ %16, %bb43.i ], [ %16, %bb48.i ], [ 0.000000e+00, %bb52.i ], [ %16, %bb95.i ], [ %16, %bb99.i ], [ %16, %bb103.i ] ; <float> [#uses=8]
+ %17 = phi float [ 1.000000e+01, %bb1.i ], [ %17, %bb20.i ], [ 1.000000e+00, %bb30.i ], [ %17, %bb43.i ], [ %17, %bb48.i ], [ %17, %bb52.i ], [ %17, %bb95.i ], [ %17, %bb99.i ], [ %17, %bb103.i ] ; <float> [#uses=8]
+ %18 = icmp slt i32 undef, %argc ; <i1> [#uses=1]
+ br i1 %18, label %bb2.i, label %bb135.i
+
+bb135.i: ; preds = %bb134.i
+ br i1 undef, label %bb141.i, label %bb142.i
+
+bb141.i: ; preds = %bb135.i
+ unreachable
+
+bb142.i: ; preds = %bb135.i
+ br i1 undef, label %bb145.i, label %bb144.i
+
+bb144.i: ; preds = %bb142.i
+ unreachable
+
+bb145.i: ; preds = %bb142.i
+ br i1 undef, label %bb146.i, label %bb147.i
+
+bb146.i: ; preds = %bb145.i
+ unreachable
+
+bb147.i: ; preds = %bb145.i
+ br i1 undef, label %bb148.i, label %bb155.i
+
+bb148.i: ; preds = %bb147.i
+ br label %bb155.i
+
+bb155.i: ; preds = %bb148.i, %bb147.i
+ br i1 undef, label %bb156.i, label %bb161.i
+
+bb156.i: ; preds = %bb155.i
+ unreachable
+
+bb161.i: ; preds = %bb155.i
+ br i1 undef, label %bb162.i, label %bb163.i
+
+bb162.i: ; preds = %bb161.i
+ %19 = fpext float %17 to double ; <double> [#uses=1]
+ %20 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([61 x i8]* @.str101, i32 0, i32 0), double %19) nounwind ; <i32> [#uses=0]
+ unreachable
+
+bb163.i: ; preds = %bb161.i
+ %21 = fpext float %16 to double ; <double> [#uses=1]
+ %22 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([31 x i8]* @.str104, i32 0, i32 0), double %21) nounwind ; <i32> [#uses=0]
+ %23 = fpext float %15 to double ; <double> [#uses=1]
+ %24 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([45 x i8]* @.str105, i32 0, i32 0), double %23) nounwind ; <i32> [#uses=0]
+ %25 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([38 x i8]* @.str112, i32 0, i32 0), double undef) nounwind ; <i32> [#uses=0]
+ br i1 undef, label %parse_command.exit, label %bb176.i
+
+bb176.i: ; preds = %bb163.i
+ br i1 undef, label %bb177.i, label %bb178.i
+
+bb177.i: ; preds = %bb176.i
+ unreachable
+
+bb178.i: ; preds = %bb176.i
+ %26 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([36 x i8]* @.str121, i32 0, i32 0), double undef) nounwind ; <i32> [#uses=0]
+ %27 = fpext float %14 to double ; <double> [#uses=1]
+ %28 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([67 x i8]* @.str12293, i32 0, i32 0), double %27) nounwind ; <i32> [#uses=0]
+ %29 = fpext float %13 to double ; <double> [#uses=1]
+ %30 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([68 x i8]* @.str123, i32 0, i32 0), double %29) nounwind ; <i32> [#uses=0]
+ %31 = fpext float %12 to double ; <double> [#uses=1]
+ %32 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([52 x i8]* @.str124, i32 0, i32 0), double %31) nounwind ; <i32> [#uses=0]
+ %33 = fpext float %11 to double ; <double> [#uses=1]
+ %34 = call i32 (i8*, ...)* @"\01_printf$LDBL128"(i8* getelementptr inbounds ([51 x i8]* @.str125, i32 0, i32 0), double %33) nounwind ; <i32> [#uses=0]
+ unreachable
+
+parse_command.exit: ; preds = %bb163.i
+ br i1 undef, label %bb4.i152.i, label %my_fopen.exit.i
+
+bb4.i152.i: ; preds = %parse_command.exit
+ unreachable
+
+my_fopen.exit.i: ; preds = %parse_command.exit
+ br i1 undef, label %bb.i6.i99, label %bb49.preheader.i.i
+
+bb.i6.i99: ; preds = %my_fopen.exit.i
+ br i1 undef, label %bb3.i.i100, label %bb1.i8.i
+
+bb1.i8.i: ; preds = %bb.i6.i99
+ unreachable
+
+bb3.i.i100: ; preds = %bb.i6.i99
+ unreachable
+
+bb49.preheader.i.i: ; preds = %my_fopen.exit.i
+ br i1 undef, label %bb7.i11.i, label %bb50.i.i
+
+bb7.i11.i: ; preds = %bb49.preheader.i.i
+ unreachable
+
+bb50.i.i: ; preds = %bb49.preheader.i.i
+ br i1 undef, label %bb.i.i.i20.i, label %my_calloc.exit.i.i.i
+
+bb.i.i.i20.i: ; preds = %bb50.i.i
+ unreachable
+
+my_calloc.exit.i.i.i: ; preds = %bb50.i.i
+ br i1 undef, label %bb.i.i37.i.i, label %alloc_hash_table.exit.i21.i
+
+bb.i.i37.i.i: ; preds = %my_calloc.exit.i.i.i
+ unreachable
+
+alloc_hash_table.exit.i21.i: ; preds = %my_calloc.exit.i.i.i
+ br i1 undef, label %bb51.i.i, label %bb3.i23.i.i
+
+bb51.i.i: ; preds = %alloc_hash_table.exit.i21.i
+ unreachable
+
+bb3.i23.i.i: ; preds = %alloc_hash_table.exit.i21.i
+ br i1 undef, label %bb.i8.i.i, label %bb.nph.i.i
+
+bb.nph.i.i: ; preds = %bb3.i23.i.i
+ unreachable
+
+bb.i8.i.i: ; preds = %bb3.i.i34.i, %bb3.i23.i.i
+ br i1 undef, label %bb3.i.i34.i, label %bb1.i.i32.i
+
+bb1.i.i32.i: ; preds = %bb.i8.i.i
+ unreachable
+
+bb3.i.i34.i: ; preds = %bb.i8.i.i
+ br i1 undef, label %free_hash_table.exit.i.i, label %bb.i8.i.i
+
+free_hash_table.exit.i.i: ; preds = %bb3.i.i34.i
+ br i1 undef, label %check_netlist.exit.i, label %bb59.i.i
+
+bb59.i.i: ; preds = %free_hash_table.exit.i.i
+ unreachable
+
+check_netlist.exit.i: ; preds = %free_hash_table.exit.i.i
+ br label %bb.i.i3.i
+
+bb.i.i3.i: ; preds = %bb3.i.i4.i, %check_netlist.exit.i
+ br i1 false, label %bb3.i.i4.i, label %bb1.i.i.i122
+
+bb1.i.i.i122: ; preds = %bb1.i.i.i122, %bb.i.i3.i
+ br i1 false, label %bb3.i.i4.i, label %bb1.i.i.i122
+
+bb3.i.i4.i: ; preds = %bb1.i.i.i122, %bb.i.i3.i
+ br i1 undef, label %read_net.exit, label %bb.i.i3.i
+
+read_net.exit: ; preds = %bb3.i.i4.i
+ br i1 undef, label %bb.i44, label %bb3.i47
+
+bb.i44: ; preds = %read_net.exit
+ unreachable
+
+bb3.i47: ; preds = %read_net.exit
+ br i1 false, label %bb9.i50, label %bb8.i49
+
+bb8.i49: ; preds = %bb3.i47
+ unreachable
+
+bb9.i50: ; preds = %bb3.i47
+ br i1 undef, label %bb11.i51, label %bb12.i52
+
+bb11.i51: ; preds = %bb9.i50
+ unreachable
+
+bb12.i52: ; preds = %bb9.i50
+ br i1 undef, label %bb.i.i53, label %my_malloc.exit.i54
+
+bb.i.i53: ; preds = %bb12.i52
+ unreachable
+
+my_malloc.exit.i54: ; preds = %bb12.i52
+ br i1 undef, label %bb.i2.i55, label %my_malloc.exit3.i56
+
+bb.i2.i55: ; preds = %my_malloc.exit.i54
+ unreachable
+
+my_malloc.exit3.i56: ; preds = %my_malloc.exit.i54
+ br i1 undef, label %bb.i.i.i57, label %my_malloc.exit.i.i
+
+bb.i.i.i57: ; preds = %my_malloc.exit3.i56
+ unreachable
+
+my_malloc.exit.i.i: ; preds = %my_malloc.exit3.i56
+ br i1 undef, label %bb, label %bb10
+
+bb: ; preds = %my_malloc.exit.i.i
+ unreachable
+
+bb10: ; preds = %my_malloc.exit.i.i
+ br i1 false, label %bb12, label %bb11
+
+bb11: ; preds = %bb10
+ unreachable
+
+bb12: ; preds = %bb10
+ store float %annealing_sched.1.0, float* null, align 4
+ store float %annealing_sched.2.0, float* undef, align 8
+ store float %annealing_sched.3.0, float* undef, align 4
+ store float %annealing_sched.4.0, float* undef, align 8
+ store float %router_opts.0.0, float* undef, align 8
+ store float %router_opts.1.0, float* undef, align 4
+ store float %router_opts.2.0, float* null, align 8
+ store float %router_opts.3.0, float* undef, align 4
+ br i1 undef, label %place_and_route.exit, label %bb7.i22
+
+bb7.i22: ; preds = %bb12
+ br i1 false, label %bb8.i23, label %bb9.i26
+
+bb8.i23: ; preds = %bb7.i22
+ unreachable
+
+bb9.i26: ; preds = %bb7.i22
+ unreachable
+
+place_and_route.exit: ; preds = %bb12
+ unreachable
+}
+
+declare i32 @"\01_printf$LDBL128"(i8*, ...) nounwind
+
+declare i32 @strcmp(i8* nocapture, i8* nocapture) nounwind readonly
+
+declare i32 @"\01_sscanf$LDBL128"(i8*, i8*, ...) nounwind
diff --git a/test/CodeGen/PowerPC/Frames-alloca.ll b/test/CodeGen/PowerPC/Frames-alloca.ll
index aed4fdb..466ae80 100644
--- a/test/CodeGen/PowerPC/Frames-alloca.ll
+++ b/test/CodeGen/PowerPC/Frames-alloca.ll
@@ -24,7 +24,7 @@
; CHECK-PPC64-NOFP: ld r1, 0(r1)
; CHECK-PPC64-NOFP: ld r31, -8(r1)
-define i32* @f1(i32 %n) {
+define i32* @f1(i32 %n) nounwind {
%tmp = alloca i32, i32 %n ; <i32*> [#uses=1]
ret i32* %tmp
}
diff --git a/test/CodeGen/PowerPC/LargeAbsoluteAddr.ll b/test/CodeGen/PowerPC/LargeAbsoluteAddr.ll
index 0f7acac..b10a996 100644
--- a/test/CodeGen/PowerPC/LargeAbsoluteAddr.ll
+++ b/test/CodeGen/PowerPC/LargeAbsoluteAddr.ll
@@ -3,14 +3,14 @@
; RUN: llc < %s -march=ppc64 -mtriple=powerpc-apple-darwin | \
; RUN: grep {stw r3, 32751}
; RUN: llc < %s -march=ppc64 -mtriple=powerpc-apple-darwin | \
-; RUN: grep {std r2, 9024}
+; RUN: grep {std r3, 9024}
-define void @test() {
+define void @test() nounwind {
store i32 0, i32* inttoptr (i64 48725999 to i32*)
ret void
}
-define void @test2() {
+define void @test2() nounwind {
store i64 0, i64* inttoptr (i64 74560 to i64*)
ret void
}
diff --git a/test/CodeGen/PowerPC/addc.ll b/test/CodeGen/PowerPC/addc.ll
index 09a7fbd..8c928ce 100644
--- a/test/CodeGen/PowerPC/addc.ll
+++ b/test/CodeGen/PowerPC/addc.ll
@@ -1,26 +1,33 @@
; All of these should be codegen'd without loading immediates
-; RUN: llc < %s -march=ppc32 -o %t
-; RUN: grep addc %t | count 1
-; RUN: grep adde %t | count 1
-; RUN: grep addze %t | count 1
-; RUN: grep addme %t | count 1
-; RUN: grep addic %t | count 2
+; RUN: llc < %s -mtriple=powerpc-apple-darwin | FileCheck %s
-define i64 @add_ll(i64 %a, i64 %b) {
+define i64 @add_ll(i64 %a, i64 %b) nounwind {
entry:
%tmp.2 = add i64 %b, %a ; <i64> [#uses=1]
ret i64 %tmp.2
+; CHECK: add_ll:
+; CHECK: addc r4, r6, r4
+; CHECK: adde r3, r5, r3
+; CHECK: blr
}
-define i64 @add_l_5(i64 %a) {
+define i64 @add_l_5(i64 %a) nounwind {
entry:
%tmp.1 = add i64 %a, 5 ; <i64> [#uses=1]
ret i64 %tmp.1
+; CHECK: add_l_5:
+; CHECK: addic r4, r4, 5
+; CHECK: addze r3, r3
+; CHECK: blr
}
-define i64 @add_l_m5(i64 %a) {
+define i64 @add_l_m5(i64 %a) nounwind {
entry:
%tmp.1 = add i64 %a, -5 ; <i64> [#uses=1]
ret i64 %tmp.1
+; CHECK: add_l_m5:
+; CHECK: addic r4, r4, -5
+; CHECK: addme r3, r3
+; CHECK: blr
}
diff --git a/test/CodeGen/PowerPC/indirectbr.ll b/test/CodeGen/PowerPC/indirectbr.ll
index fbc7bd2..2094e10 100644
--- a/test/CodeGen/PowerPC/indirectbr.ll
+++ b/test/CodeGen/PowerPC/indirectbr.ll
@@ -43,13 +43,13 @@ L2: ; preds = %L3, %bb2
L1: ; preds = %L2, %bb2
%res.3 = phi i32 [ %phitmp, %L2 ], [ 2, %bb2 ] ; <i32> [#uses=1]
-; PIC: addis r4, r2, ha16(L_BA4__foo_L5-"L1$pb")
-; PIC: li r5, lo16(L_BA4__foo_L5-"L1$pb")
-; PIC: add r4, r4, r5
-; PIC: stw r4
-; STATIC: li r2, lo16(L_BA4__foo_L5)
-; STATIC: addis r2, r2, ha16(L_BA4__foo_L5)
-; STATIC: stw r2
+; PIC: addis r5, r4, ha16(L_BA4__foo_L5-"L1$pb")
+; PIC: li r6, lo16(L_BA4__foo_L5-"L1$pb")
+; PIC: add r5, r5, r6
+; PIC: stw r5
+; STATIC: li r4, lo16(L_BA4__foo_L5)
+; STATIC: addis r4, r4, ha16(L_BA4__foo_L5)
+; STATIC: stw r4
store i8* blockaddress(@foo, %L5), i8** @nextaddr, align 4
ret i32 %res.3
}
diff --git a/test/CodeGen/PowerPC/lsr-postinc-pos.ll b/test/CodeGen/PowerPC/lsr-postinc-pos.ll
new file mode 100644
index 0000000..f441e42
--- /dev/null
+++ b/test/CodeGen/PowerPC/lsr-postinc-pos.ll
@@ -0,0 +1,32 @@
+; RUN: llc < %s -print-lsr-output |& FileCheck %s
+
+; The icmp is a post-inc use, and the increment is in %bb11, but the
+; scevgep needs to be inserted in %bb so that it is dominated by %t.
+
+; CHECK: %t = load i8** undef
+; CHECK: %scevgep = getelementptr i8* %t, i32 %lsr.iv.next
+; CHECK: %c1 = icmp ult i8* %scevgep, undef
+
+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-f128:64:128-n32"
+target triple = "powerpc-apple-darwin9"
+
+define void @foo() nounwind {
+entry:
+ br label %bb11
+
+bb11:
+ %i = phi i32 [ 0, %entry ], [ %i.next, %bb ] ; <i32> [#uses=3]
+ %ii = shl i32 %i, 2 ; <i32> [#uses=1]
+ %c0 = icmp eq i32 %i, undef ; <i1> [#uses=1]
+ br i1 %c0, label %bb13, label %bb
+
+bb:
+ %t = load i8** undef, align 16 ; <i8*> [#uses=1]
+ %p = getelementptr i8* %t, i32 %ii ; <i8*> [#uses=1]
+ %c1 = icmp ult i8* %p, undef ; <i1> [#uses=1]
+ %i.next = add i32 %i, 1 ; <i32> [#uses=1]
+ br i1 %c1, label %bb11, label %bb13
+
+bb13:
+ unreachable
+}
diff --git a/test/CodeGen/PowerPC/mem_update.ll b/test/CodeGen/PowerPC/mem_update.ll
index b267719..17e7e28 100644
--- a/test/CodeGen/PowerPC/mem_update.ll
+++ b/test/CodeGen/PowerPC/mem_update.ll
@@ -3,66 +3,66 @@
; RUN: llc < %s -march=ppc64 -enable-ppc-preinc | \
; RUN: not grep addi
-@Glob = global i64 4 ; <i64*> [#uses=2]
+@Glob = global i64 4
-define i32* @test0(i32* %X, i32* %dest) {
- %Y = getelementptr i32* %X, i32 4 ; <i32*> [#uses=2]
- %A = load i32* %Y ; <i32> [#uses=1]
+define i32* @test0(i32* %X, i32* %dest) nounwind {
+ %Y = getelementptr i32* %X, i32 4
+ %A = load i32* %Y
store i32 %A, i32* %dest
ret i32* %Y
}
-define i32* @test1(i32* %X, i32* %dest) {
- %Y = getelementptr i32* %X, i32 4 ; <i32*> [#uses=2]
- %A = load i32* %Y ; <i32> [#uses=1]
+define i32* @test1(i32* %X, i32* %dest) nounwind {
+ %Y = getelementptr i32* %X, i32 4
+ %A = load i32* %Y
store i32 %A, i32* %dest
ret i32* %Y
}
-define i16* @test2(i16* %X, i32* %dest) {
- %Y = getelementptr i16* %X, i32 4 ; <i16*> [#uses=2]
- %A = load i16* %Y ; <i16> [#uses=1]
- %B = sext i16 %A to i32 ; <i32> [#uses=1]
+define i16* @test2(i16* %X, i32* %dest) nounwind {
+ %Y = getelementptr i16* %X, i32 4
+ %A = load i16* %Y
+ %B = sext i16 %A to i32
store i32 %B, i32* %dest
ret i16* %Y
}
-define i16* @test3(i16* %X, i32* %dest) {
- %Y = getelementptr i16* %X, i32 4 ; <i16*> [#uses=2]
- %A = load i16* %Y ; <i16> [#uses=1]
- %B = zext i16 %A to i32 ; <i32> [#uses=1]
+define i16* @test3(i16* %X, i32* %dest) nounwind {
+ %Y = getelementptr i16* %X, i32 4
+ %A = load i16* %Y
+ %B = zext i16 %A to i32
store i32 %B, i32* %dest
ret i16* %Y
}
-define i16* @test3a(i16* %X, i64* %dest) {
- %Y = getelementptr i16* %X, i32 4 ; <i16*> [#uses=2]
- %A = load i16* %Y ; <i16> [#uses=1]
- %B = sext i16 %A to i64 ; <i64> [#uses=1]
+define i16* @test3a(i16* %X, i64* %dest) nounwind {
+ %Y = getelementptr i16* %X, i32 4
+ %A = load i16* %Y
+ %B = sext i16 %A to i64
store i64 %B, i64* %dest
ret i16* %Y
}
-define i64* @test4(i64* %X, i64* %dest) {
- %Y = getelementptr i64* %X, i32 4 ; <i64*> [#uses=2]
- %A = load i64* %Y ; <i64> [#uses=1]
+define i64* @test4(i64* %X, i64* %dest) nounwind {
+ %Y = getelementptr i64* %X, i32 4
+ %A = load i64* %Y
store i64 %A, i64* %dest
ret i64* %Y
}
-define i16* @test5(i16* %X) {
- %Y = getelementptr i16* %X, i32 4 ; <i16*> [#uses=2]
+define i16* @test5(i16* %X) nounwind {
+ %Y = getelementptr i16* %X, i32 4
store i16 7, i16* %Y
ret i16* %Y
}
-define i64* @test6(i64* %X, i64 %A) {
- %Y = getelementptr i64* %X, i32 4 ; <i64*> [#uses=2]
+define i64* @test6(i64* %X, i64 %A) nounwind {
+ %Y = getelementptr i64* %X, i32 4
store i64 %A, i64* %Y
ret i64* %Y
}
-define i64* @test7(i64* %X, i64 %A) {
+define i64* @test7(i64* %X, i64 %A) nounwind {
store i64 %A, i64* @Glob
ret i64* @Glob
}
diff --git a/test/CodeGen/PowerPC/retaddr.ll b/test/CodeGen/PowerPC/retaddr.ll
index 9f8647d..cf16b4c 100644
--- a/test/CodeGen/PowerPC/retaddr.ll
+++ b/test/CodeGen/PowerPC/retaddr.ll
@@ -4,7 +4,7 @@
target triple = "powerpc-apple-darwin8"
-define void @foo(i8** %X) {
+define void @foo(i8** %X) nounwind {
entry:
%tmp = tail call i8* @llvm.returnaddress( i32 0 ) ; <i8*> [#uses=1]
store i8* %tmp, i8** %X, align 4
diff --git a/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll b/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
new file mode 100644
index 0000000..363f571
--- /dev/null
+++ b/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
@@ -0,0 +1,76 @@
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin | 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"
+
+define arm_apcscc i32 @test(i32 %n) nounwind {
+; CHECK: test:
+; CHECK-NOT: mov
+; CHECK: return
+entry:
+ %0 = icmp eq i32 %n, 1 ; <i1> [#uses=1]
+ br i1 %0, label %return, label %bb.nph
+
+bb.nph: ; preds = %entry
+ %tmp = add i32 %n, -1 ; <i32> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb.nph, %bb
+ %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=1]
+ %u.05 = phi i64 [ undef, %bb.nph ], [ %ins, %bb ] ; <i64> [#uses=1]
+ %1 = tail call arm_apcscc i32 @f() nounwind ; <i32> [#uses=1]
+ %tmp4 = zext i32 %1 to i64 ; <i64> [#uses=1]
+ %mask = and i64 %u.05, -4294967296 ; <i64> [#uses=1]
+ %ins = or i64 %tmp4, %mask ; <i64> [#uses=2]
+ tail call arm_apcscc void @g(i64 %ins) nounwind
+ %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb, %entry
+ ret i32 undef
+}
+
+define arm_apcscc i32 @test_dead_cycle(i32 %n) nounwind {
+; CHECK: test_dead_cycle:
+; CHECK: blx
+; CHECK-NOT: mov
+; CHECK: blx
+entry:
+ %0 = icmp eq i32 %n, 1 ; <i1> [#uses=1]
+ br i1 %0, label %return, label %bb.nph
+
+bb.nph: ; preds = %entry
+ %tmp = add i32 %n, -1 ; <i32> [#uses=2]
+ br label %bb
+
+bb: ; preds = %bb.nph, %bb2
+ %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb2 ] ; <i32> [#uses=2]
+ %u.17 = phi i64 [ undef, %bb.nph ], [ %u.0, %bb2 ] ; <i64> [#uses=2]
+ %tmp9 = sub i32 %tmp, %indvar ; <i32> [#uses=1]
+ %1 = icmp sgt i32 %tmp9, 1 ; <i1> [#uses=1]
+ br i1 %1, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ %2 = tail call arm_apcscc i32 @f() nounwind ; <i32> [#uses=1]
+ %tmp6 = zext i32 %2 to i64 ; <i64> [#uses=1]
+ %mask = and i64 %u.17, -4294967296 ; <i64> [#uses=1]
+ %ins = or i64 %tmp6, %mask ; <i64> [#uses=1]
+ tail call arm_apcscc void @g(i64 %ins) nounwind
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+; also check for duplicate induction variables (radar 7645034)
+; CHECK: subs r{{.*}}, #1
+; CHECK-NOT: subs r{{.*}}, #1
+; CHECK: pop
+ %u.0 = phi i64 [ %ins, %bb1 ], [ %u.17, %bb ] ; <i64> [#uses=2]
+ %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb2, %entry
+ ret i32 undef
+}
+
+declare arm_apcscc i32 @f()
+
+declare arm_apcscc void @g(i64)
diff --git a/test/CodeGen/Thumb2/2010-02-24-BigStack.ll b/test/CodeGen/Thumb2/2010-02-24-BigStack.ll
new file mode 100644
index 0000000..533546b
--- /dev/null
+++ b/test/CodeGen/Thumb2/2010-02-24-BigStack.ll
@@ -0,0 +1,15 @@
+; RUN: llc < %s -O0 -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 -mattr=+vfp2
+; This test creates a big stack frame without spilling any callee-saved registers.
+; Make sure the whole stack frame is addrerssable wiothout scavenger crashes.
+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-darwin3.0.0-iphoneos"
+
+define arm_apcscc void @FindMin(double* %panelTDEL, i8* %dclOfRow, i32 %numRows, i32 %numCols, double* %retMin_RES_TDEL) {
+entry:
+ %panelTDEL.addr = alloca double*, align 4 ; <double**> [#uses=1]
+ %panelResTDEL = alloca [2560 x double], align 4 ; <[2560 x double]*> [#uses=0]
+ store double* %panelTDEL, double** %panelTDEL.addr
+ store double* %retMin_RES_TDEL, double** undef
+ store i32 0, i32* undef
+ unreachable
+}
diff --git a/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll b/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll
index 8f6449e..2b20931 100644
--- a/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll
+++ b/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep vmov.f32 | count 7
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep vmov.f32 | count 3
define arm_apcscc void @fht(float* nocapture %fz, i16 signext %n) nounwind {
entry:
diff --git a/test/CodeGen/Thumb2/ldr-str-imm12.ll b/test/CodeGen/Thumb2/ldr-str-imm12.ll
index 47d85b1..f007b5c 100644
--- a/test/CodeGen/Thumb2/ldr-str-imm12.ll
+++ b/test/CodeGen/Thumb2/ldr-str-imm12.ll
@@ -52,7 +52,7 @@ bb420: ; preds = %bb20, %bb20
; CHECK: str r{{[0-7]}}, [sp]
; CHECK: str r{{[0-7]}}, [sp, #+4]
; CHECK: str r{{[0-7]}}, [sp, #+8]
-; CHECK: str r{{[0-7]}}, [sp, #+24]
+; CHECK: str{{(.w)?}} r{{[0-9]+}}, [sp, #+24]
store %union.rec* null, %union.rec** @zz_hold, align 4
store %union.rec* null, %union.rec** @zz_res, align 4
store %union.rec* %x, %union.rec** @zz_hold, align 4
diff --git a/test/CodeGen/Thumb2/lsr-deficiency.ll b/test/CodeGen/Thumb2/lsr-deficiency.ll
index 7b1b57a..ac2cd34 100644
--- a/test/CodeGen/Thumb2/lsr-deficiency.ll
+++ b/test/CodeGen/Thumb2/lsr-deficiency.ll
@@ -1,25 +1,29 @@
; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -relocation-model=pic | FileCheck %s
; rdar://7387640
-; FIXME: We still need to rewrite array reference iv of stride -4 with loop
-; count iv of stride -1.
+; This now reduces to a single induction variable.
+
+; TODO: It still gets a GPR shuffle at the end of the loop
+; This is because something in instruction selection has decided
+; that comparing the pre-incremented value with zero is better
+; than comparing the post-incremented value with -4.
@G = external global i32 ; <i32*> [#uses=2]
@array = external global i32* ; <i32**> [#uses=1]
define arm_apcscc void @t() nounwind optsize {
; CHECK: t:
-; CHECK: mov.w r2, #4000
-; CHECK: movw r3, #1001
+; CHECK: mov.w r2, #1000
entry:
%.pre = load i32* @G, align 4 ; <i32> [#uses=1]
br label %bb
bb: ; preds = %bb, %entry
; CHECK: LBB1_1:
-; CHECK: subs r3, #1
-; CHECK: cmp r3, #0
-; CHECK: sub.w r2, r2, #4
+; CHECK: cmp r2, #0
+; CHECK: sub.w r9, r2, #1
+; CHECK: mov r2, r9
+
%0 = phi i32 [ %.pre, %entry ], [ %3, %bb ] ; <i32> [#uses=1]
%indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2]
%tmp5 = sub i32 1000, %indvar ; <i32> [#uses=1]
diff --git a/test/CodeGen/Thumb2/thumb2-ifcvt1.ll b/test/CodeGen/Thumb2/thumb2-ifcvt1.ll
index 71199ab..1d26756 100644
--- a/test/CodeGen/Thumb2/thumb2-ifcvt1.ll
+++ b/test/CodeGen/Thumb2/thumb2-ifcvt1.ll
@@ -1,6 +1,6 @@
; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
-define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) {
+define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
; CHECK: t1:
; CHECK: it ne
; CHECK: cmpne
@@ -20,12 +20,12 @@ cond_next:
}
; FIXME: Check for # of unconditional branch after adding branch folding post ifcvt.
-define i32 @t2(i32 %a, i32 %b) {
+define i32 @t2(i32 %a, i32 %b) nounwind {
entry:
; CHECK: t2:
-; CHECK: ite le
-; CHECK: suble
+; CHECK: ite gt
; CHECK: subgt
+; CHECK: suble
%tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1]
br i1 %tmp1434, label %bb17, label %bb.outer
@@ -60,14 +60,14 @@ bb17: ; preds = %cond_false, %cond_true, %entry
@x = external global i32* ; <i32**> [#uses=1]
-define void @foo(i32 %a) {
+define void @foo(i32 %a) nounwind {
entry:
%tmp = load i32** @x ; <i32*> [#uses=1]
store i32 %a, i32* %tmp
ret void
}
-define void @t3(i32 %a, i32 %b) {
+define void @t3(i32 %a, i32 %b) nounwind {
entry:
; CHECK: t3:
; CHECK: it lt
diff --git a/test/CodeGen/Thumb2/thumb2-spill-q.ll b/test/CodeGen/Thumb2/thumb2-spill-q.ll
index 7935163..ff178b4 100644
--- a/test/CodeGen/Thumb2/thumb2-spill-q.ll
+++ b/test/CodeGen/Thumb2/thumb2-spill-q.ll
@@ -12,8 +12,8 @@ declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*) nounwind readonly
define arm_apcscc void @aaa(%quuz* %this, i8* %block) {
; CHECK: aaa:
; CHECK: bic r4, r4, #15
-; CHECK: vst1.64 {{.*}}[r{{.*}}, :128]
-; CHECK: vld1.64 {{.*}}[r{{.*}}, :128]
+; CHECK: vst1.64 {{.*}}[{{.*}}, :128]
+; CHECK: vld1.64 {{.*}}[{{.*}}, :128]
entry:
%0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef) nounwind ; <<4 x float>> [#uses=1]
store float 6.300000e+01, float* undef, align 4
diff --git a/test/CodeGen/Thumb2/thumb2-uxtb.ll b/test/CodeGen/Thumb2/thumb2-uxtb.ll
index 4e23f53..91598cd 100644
--- a/test/CodeGen/Thumb2/thumb2-uxtb.ll
+++ b/test/CodeGen/Thumb2/thumb2-uxtb.ll
@@ -2,14 +2,14 @@
define i32 @test1(i32 %x) {
; CHECK: test1
-; CHECK: uxtb16.w r0, r0
+; CHECK: uxtb16 r0, r0
%tmp1 = and i32 %x, 16711935 ; <i32> [#uses=1]
ret i32 %tmp1
}
define i32 @test2(i32 %x) {
; CHECK: test2
-; CHECK: uxtb16.w r0, r0, ror #8
+; CHECK: uxtb16 r0, r0, ror #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp2
@@ -17,7 +17,7 @@ define i32 @test2(i32 %x) {
define i32 @test3(i32 %x) {
; CHECK: test3
-; CHECK: uxtb16.w r0, r0, ror #8
+; CHECK: uxtb16 r0, r0, ror #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp2
@@ -25,7 +25,7 @@ define i32 @test3(i32 %x) {
define i32 @test4(i32 %x) {
; CHECK: test4
-; CHECK: uxtb16.w r0, r0, ror #8
+; CHECK: uxtb16 r0, r0, ror #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp6 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp6
@@ -33,7 +33,7 @@ define i32 @test4(i32 %x) {
define i32 @test5(i32 %x) {
; CHECK: test5
-; CHECK: uxtb16.w r0, r0, ror #8
+; CHECK: uxtb16 r0, r0, ror #8
%tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1]
ret i32 %tmp2
@@ -41,7 +41,7 @@ define i32 @test5(i32 %x) {
define i32 @test6(i32 %x) {
; CHECK: test6
-; CHECK: uxtb16.w r0, r0, ror #16
+; CHECK: uxtb16 r0, r0, ror #16
%tmp1 = lshr i32 %x, 16 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 255 ; <i32> [#uses=1]
%tmp4 = shl i32 %x, 16 ; <i32> [#uses=1]
@@ -52,7 +52,7 @@ define i32 @test6(i32 %x) {
define i32 @test7(i32 %x) {
; CHECK: test7
-; CHECK: uxtb16.w r0, r0, ror #16
+; CHECK: uxtb16 r0, r0, ror #16
%tmp1 = lshr i32 %x, 16 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 255 ; <i32> [#uses=1]
%tmp4 = shl i32 %x, 16 ; <i32> [#uses=1]
@@ -63,7 +63,7 @@ define i32 @test7(i32 %x) {
define i32 @test8(i32 %x) {
; CHECK: test8
-; CHECK: uxtb16.w r0, r0, ror #24
+; CHECK: uxtb16 r0, r0, ror #24
%tmp1 = shl i32 %x, 8 ; <i32> [#uses=1]
%tmp2 = and i32 %tmp1, 16711680 ; <i32> [#uses=1]
%tmp5 = lshr i32 %x, 24 ; <i32> [#uses=1]
@@ -73,7 +73,7 @@ define i32 @test8(i32 %x) {
define i32 @test9(i32 %x) {
; CHECK: test9
-; CHECK: uxtb16.w r0, r0, ror #24
+; CHECK: uxtb16 r0, r0, ror #24
%tmp1 = lshr i32 %x, 24 ; <i32> [#uses=1]
%tmp4 = shl i32 %x, 8 ; <i32> [#uses=1]
%tmp5 = and i32 %tmp4, 16711680 ; <i32> [#uses=1]
@@ -86,7 +86,7 @@ define i32 @test10(i32 %p0) {
; CHECK: mov.w r1, #16253176
; CHECK: and.w r0, r1, r0, lsr #7
; CHECK: lsrs r1, r0, #5
-; CHECK: uxtb16.w r1, r1
+; CHECK: uxtb16 r1, r1
; CHECK: orr.w r0, r1, r0
%tmp1 = lshr i32 %p0, 7 ; <i32> [#uses=1]
diff --git a/test/CodeGen/X86/2005-01-17-CycleInDAG.ll b/test/CodeGen/X86/2005-01-17-CycleInDAG.ll
index 32fafc6..fe6674d 100644
--- a/test/CodeGen/X86/2005-01-17-CycleInDAG.ll
+++ b/test/CodeGen/X86/2005-01-17-CycleInDAG.ll
@@ -7,7 +7,7 @@
@GLOBAL = external global i32 ; <i32*> [#uses=1]
-define i32 @test(i32* %P1, i32* %P2, i32* %P3) {
+define i32 @test(i32* %P1, i32* %P2, i32* %P3) nounwind {
%L = load i32* @GLOBAL ; <i32> [#uses=1]
store i32 12, i32* %P2
%Y = load i32* %P3 ; <i32> [#uses=1]
diff --git a/test/CodeGen/X86/2006-05-11-InstrSched.ll b/test/CodeGen/X86/2006-05-11-InstrSched.ll
index bdbe713..56d6aa9 100644
--- a/test/CodeGen/X86/2006-05-11-InstrSched.ll
+++ b/test/CodeGen/X86/2006-05-11-InstrSched.ll
@@ -1,5 +1,5 @@
; RUN: llc < %s -march=x86 -mattr=+sse2 -stats -realign-stack=0 |&\
-; RUN: grep {asm-printer} | grep 31
+; RUN: grep {asm-printer} | grep 34
target datalayout = "e-p:32:32"
define void @foo(i32* %mc, i32* %bp, i32* %ms, i32* %xmb, i32* %mpp, i32* %tpmm, i32* %ip, i32* %tpim, i32* %dpp, i32* %tpdm, i32* %bpi, i32 %M) nounwind {
@@ -40,7 +40,7 @@ cond_true: ; preds = %cond_true, %entry
%tmp137.upgrd.7 = bitcast i32* %tmp137 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
store <2 x i64> %tmp131, <2 x i64>* %tmp137.upgrd.7
%tmp147 = add nsw i32 %tmp.10, 8 ; <i32> [#uses=1]
- %tmp.upgrd.8 = icmp slt i32 %tmp147, %M ; <i1> [#uses=1]
+ %tmp.upgrd.8 = icmp ne i32 %tmp147, %M ; <i1> [#uses=1]
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
br i1 %tmp.upgrd.8, label %cond_true, label %return
diff --git a/test/CodeGen/X86/2006-10-07-ScalarSSEMiscompile.ll b/test/CodeGen/X86/2006-10-07-ScalarSSEMiscompile.ll
index bf9fa57..d09d061 100644
--- a/test/CodeGen/X86/2006-10-07-ScalarSSEMiscompile.ll
+++ b/test/CodeGen/X86/2006-10-07-ScalarSSEMiscompile.ll
@@ -5,7 +5,7 @@
target datalayout = "e-p:32:32"
target triple = "i686-apple-darwin8.7.2"
-define <4 x float> @test(<4 x float> %A, <4 x float>* %B) {
+define <4 x float> @test(<4 x float> %A, <4 x float>* %B) nounwind {
%BV = load <4 x float>* %B ; <<4 x float>> [#uses=1]
%tmp28 = tail call <4 x float> @llvm.x86.sse.sub.ss( <4 x float> %A, <4 x float> %BV ) ; <<4 x float>> [#uses=1]
ret <4 x float> %tmp28
diff --git a/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll b/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll
index 4cac9b4..e1f8901 100644
--- a/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll
+++ b/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s -march=x86 -mtriple=i686-darwin | \
; RUN: grep push | count 3
-define void @foo(i8** %buf, i32 %size, i32 %col, i8* %p) {
+define void @foo(i8** %buf, i32 %size, i32 %col, i8* %p) nounwind {
entry:
icmp sgt i32 %size, 0 ; <i1>:0 [#uses=1]
br i1 %0, label %bb.preheader, label %return
diff --git a/test/CodeGen/X86/2007-10-05-3AddrConvert.ll b/test/CodeGen/X86/2007-10-05-3AddrConvert.ll
index 67323e8..2c2706d 100644
--- a/test/CodeGen/X86/2007-10-05-3AddrConvert.ll
+++ b/test/CodeGen/X86/2007-10-05-3AddrConvert.ll
@@ -36,7 +36,9 @@ bb.i6.i: ; preds = %bb.i6.i, %stepsystem.exit.i
bb107.i.i: ; preds = %bb107.i.i, %bb.i6.i
%q_addr.0.i.i.in = phi %struct.bnode** [ null, %bb107.i.i ], [ %4, %bb.i6.i ] ; <%struct.bnode**> [#uses=1]
- %q_addr.0.i.i = load %struct.bnode** %q_addr.0.i.i.in ; <%struct.bnode*> [#uses=0]
+ %q_addr.0.i.i = load %struct.bnode** %q_addr.0.i.i.in ; <%struct.bnode*> [#uses=1]
+ %q_addr.1 = getelementptr %struct.anon* %0, i32 0, i32 4, i32 1
+ store %struct.bnode* %q_addr.0.i.i, %struct.bnode** %q_addr.1, align 4
br label %bb107.i.i
bb47.loopexit.i: ; preds = %bb32.i
diff --git a/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll b/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll
index 721d4c9..8e315f4 100644
--- a/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll
+++ b/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll
@@ -35,7 +35,7 @@ cond_next36.i: ; preds = %cond_next.i
bb.i28.i: ; preds = %bb.i28.i, %cond_next36.i
; CHECK: %bb.i28.i
; CHECK: addl $2
-; CHECK: addl $2
+; CHECK: addl $-2
%j.0.reg2mem.0.i16.i = phi i32 [ 0, %cond_next36.i ], [ %indvar.next39.i, %bb.i28.i ] ; <i32> [#uses=2]
%din_addr.1.reg2mem.0.i17.i = phi double [ 0.000000e+00, %cond_next36.i ], [ %tmp16.i25.i, %bb.i28.i ] ; <double> [#uses=1]
%tmp1.i18.i = fptosi double %din_addr.1.reg2mem.0.i17.i to i32 ; <i32> [#uses=2]
diff --git a/test/CodeGen/X86/2008-02-22-ReMatBug.ll b/test/CodeGen/X86/2008-02-22-ReMatBug.ll
index 8d6bb0d..a91ac27 100644
--- a/test/CodeGen/X86/2008-02-22-ReMatBug.ll
+++ b/test/CodeGen/X86/2008-02-22-ReMatBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86 -stats |& grep {Number of re-materialization} | grep 3
+; RUN: llc < %s -march=x86 -stats |& grep {Number of re-materialization} | grep 2
; rdar://5761454
%struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* }
diff --git a/test/CodeGen/X86/2008-07-11-SpillerBug.ll b/test/CodeGen/X86/2008-07-11-SpillerBug.ll
index cd99c0e..548b44d 100644
--- a/test/CodeGen/X86/2008-07-11-SpillerBug.ll
+++ b/test/CodeGen/X86/2008-07-11-SpillerBug.ll
@@ -1,9 +1,7 @@
; RUN: llc < %s -march=x86 -relocation-model=static -disable-fp-elim -post-RA-scheduler=false -asm-verbose=0 | FileCheck %s
; PR2536
-
-; CHECK: movw %cx
-; CHECK-NEXT: andl $65534, %
+; CHECK: andl $65534, %
; CHECK-NEXT: movl %
; CHECK-NEXT: movl $17
diff --git a/test/CodeGen/X86/2008-08-05-SpillerBug.ll b/test/CodeGen/X86/2008-08-05-SpillerBug.ll
index 67e14ff..4c64934 100644
--- a/test/CodeGen/X86/2008-08-05-SpillerBug.ll
+++ b/test/CodeGen/X86/2008-08-05-SpillerBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin -disable-fp-elim -stats |& grep asm-printer | grep 58
+; RUN: llc < %s -mtriple=i386-apple-darwin -disable-fp-elim -stats |& grep asm-printer | grep 55
; PR2568
@g_3 = external global i16 ; <i16*> [#uses=1]
diff --git a/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll b/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll
index 72c7ee9..0dca14d 100644
--- a/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll
+++ b/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll
@@ -3,74 +3,83 @@
; PR3538
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-darwin9"
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.block.type = type { i32, { }* }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
- %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.subrange.type = type { i32, i64, i64 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [4 x i8] c"t.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [2 x i8] c".\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@.str2 = internal constant [6 x i8] c"clang\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([2 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str4 = internal constant [5 x i8] c"test\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str5 = internal constant [2 x i8] c"X\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.block = internal constant %llvm.dbg.block.type { i32 458763, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) }, section "llvm.metadata" ; <%llvm.dbg.block.type*> [#uses=1]
-@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type { i32 458785, i64 0, i64 0 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1]
-@llvm.dbg.array = internal constant [1 x { }*] [{ }* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange to { }*)], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458753, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* null, i32 0, i64 0, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast ([1 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str6 = internal constant [2 x i8] c"Y\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable7 = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.block.type* @llvm.dbg.block to { }*), i8* getelementptr ([2 x i8]* @.str6, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-
-define i32 @test(i32 %X) nounwind {
+define signext i8 @foo(i8* %s1) nounwind ssp {
entry:
- %retval = alloca i32 ; <i32*> [#uses=1]
- %X.addr = alloca i32 ; <i32*> [#uses=3]
- %saved_stack = alloca i8* ; <i8**> [#uses=2]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- store i32 %X, i32* %X.addr
- %0 = bitcast i32* %X.addr to { }* ; <{ }*> [#uses=1]
- call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*))
- call void @llvm.dbg.region.start({ }* bitcast (%llvm.dbg.block.type* @llvm.dbg.block to { }*))
- call void @llvm.dbg.stoppoint(i32 4, i32 3, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %1 = call i8* @llvm.stacksave() ; <i8*> [#uses=1]
- store i8* %1, i8** %saved_stack
- %tmp = load i32* %X.addr ; <i32> [#uses=1]
- %2 = mul i32 4, %tmp ; <i32> [#uses=1]
- %vla = alloca i8, i32 %2 ; <i8*> [#uses=1]
- %tmp1 = bitcast i8* %vla to i32* ; <i32*> [#uses=1]
- %3 = bitcast i32* %tmp1 to { }* ; <{ }*> [#uses=1]
- call void @llvm.dbg.declare({ }* %3, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable7 to { }*))
- call void @llvm.dbg.stoppoint(i32 5, i32 1, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.block.type* @llvm.dbg.block to { }*))
- br label %cleanup
+ %s1_addr = alloca i8* ; <i8**> [#uses=2]
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %saved_stack.1 = alloca i8* ; <i8**> [#uses=2]
+ %0 = alloca i32 ; <i32*> [#uses=2]
+ %str.0 = alloca [0 x i8]* ; <[0 x i8]**> [#uses=3]
+ %1 = alloca i64 ; <i64*> [#uses=2]
+ %2 = alloca i64 ; <i64*> [#uses=1]
+ %3 = alloca i64 ; <i64*> [#uses=6]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.declare(metadata !{i8** %s1_addr}, metadata !0), !dbg !7
+ store i8* %s1, i8** %s1_addr
+ call void @llvm.dbg.declare(metadata !{[0 x i8]** %str.0}, metadata !8), !dbg !7
+ %4 = call i8* @llvm.stacksave(), !dbg !7 ; <i8*> [#uses=1]
+ store i8* %4, i8** %saved_stack.1, align 8, !dbg !7
+ %5 = load i8** %s1_addr, align 8, !dbg !13 ; <i8*> [#uses=1]
+ %6 = call i64 @strlen(i8* %5) nounwind readonly, !dbg !13 ; <i64> [#uses=1]
+ %7 = add i64 %6, 1, !dbg !13 ; <i64> [#uses=1]
+ store i64 %7, i64* %3, align 8, !dbg !13
+ %8 = load i64* %3, align 8, !dbg !13 ; <i64> [#uses=1]
+ %9 = sub nsw i64 %8, 1, !dbg !13 ; <i64> [#uses=0]
+ %10 = load i64* %3, align 8, !dbg !13 ; <i64> [#uses=1]
+ %11 = mul i64 %10, 8, !dbg !13 ; <i64> [#uses=0]
+ %12 = load i64* %3, align 8, !dbg !13 ; <i64> [#uses=1]
+ store i64 %12, i64* %2, align 8, !dbg !13
+ %13 = load i64* %3, align 8, !dbg !13 ; <i64> [#uses=1]
+ %14 = mul i64 %13, 8, !dbg !13 ; <i64> [#uses=0]
+ %15 = load i64* %3, align 8, !dbg !13 ; <i64> [#uses=1]
+ store i64 %15, i64* %1, align 8, !dbg !13
+ %16 = load i64* %1, align 8, !dbg !13 ; <i64> [#uses=1]
+ %17 = trunc i64 %16 to i32, !dbg !13 ; <i32> [#uses=1]
+ %18 = alloca i8, i32 %17, !dbg !13 ; <i8*> [#uses=1]
+ %19 = bitcast i8* %18 to [0 x i8]*, !dbg !13 ; <[0 x i8]*> [#uses=1]
+ store [0 x i8]* %19, [0 x i8]** %str.0, align 8, !dbg !13
+ %20 = load [0 x i8]** %str.0, align 8, !dbg !15 ; <[0 x i8]*> [#uses=1]
+ %21 = getelementptr inbounds [0 x i8]* %20, i64 0, i64 0, !dbg !15 ; <i8*> [#uses=1]
+ store i8 0, i8* %21, align 1, !dbg !15
+ %22 = load [0 x i8]** %str.0, align 8, !dbg !16 ; <[0 x i8]*> [#uses=1]
+ %23 = getelementptr inbounds [0 x i8]* %22, i64 0, i64 0, !dbg !16 ; <i8*> [#uses=1]
+ %24 = load i8* %23, align 1, !dbg !16 ; <i8> [#uses=1]
+ %25 = sext i8 %24 to i32, !dbg !16 ; <i32> [#uses=1]
+ store i32 %25, i32* %0, align 4, !dbg !16
+ %26 = load i8** %saved_stack.1, align 8, !dbg !16 ; <i8*> [#uses=1]
+ call void @llvm.stackrestore(i8* %26), !dbg !16
+ %27 = load i32* %0, align 4, !dbg !16 ; <i32> [#uses=1]
+ store i32 %27, i32* %retval, align 4, !dbg !16
+ br label %return, !dbg !16
-cleanup: ; preds = %entry
- %tmp2 = load i8** %saved_stack ; <i8*> [#uses=1]
- call void @llvm.stackrestore(i8* %tmp2)
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- %4 = load i32* %retval ; <i32> [#uses=1]
- ret i32 %4
+return: ; preds = %entry
+ %retval1 = load i32* %retval, !dbg !16 ; <i32> [#uses=1]
+ %retval12 = trunc i32 %retval1 to i8, !dbg !16 ; <i8> [#uses=1]
+ ret i8 %retval12, !dbg !16
}
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.declare({ }*, { }*) nounwind
-
-declare void @llvm.dbg.region.start({ }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
declare i8* @llvm.stacksave() nounwind
+declare i64 @strlen(i8*) nounwind readonly
+
declare void @llvm.stackrestore(i8*) nounwind
-declare void @llvm.dbg.region.end({ }*) nounwind
+!0 = metadata !{i32 459009, metadata !1, metadata !"s1", metadata !2, i32 2, metadata !6} ; [ DW_TAG_arg_variable ]
+!1 = metadata !{i32 458798, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
+!2 = metadata !{i32 458769, i32 0, i32 1, metadata !"vla.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!3 = metadata !{i32 458773, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
+!4 = metadata !{metadata !5, metadata !6}
+!5 = metadata !{i32 458788, metadata !2, metadata !"char", metadata !2, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ]
+!6 = metadata !{i32 458767, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ]
+!7 = metadata !{i32 2, i32 0, metadata !1, null}
+!8 = metadata !{i32 459008, metadata !1, metadata !"str.0", metadata !2, i32 3, metadata !9} ; [ DW_TAG_auto_variable ]
+!9 = metadata !{i32 458767, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !10} ; [ DW_TAG_pointer_type ]
+!10 = metadata !{i32 458753, metadata !2, metadata !"", metadata !2, i32 0, i64 8, i64 8, i64 0, i32 0, metadata !5, metadata !11, i32 0, null} ; [ DW_TAG_array_type ]
+!11 = metadata !{metadata !12}
+!12 = metadata !{i32 458785, i64 0, i64 0} ; [ DW_TAG_subrange_type ]
+!13 = metadata !{i32 3, i32 0, metadata !14, null}
+!14 = metadata !{i32 458763, metadata !1, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!15 = metadata !{i32 4, i32 0, metadata !14, null}
+!16 = metadata !{i32 5, i32 0, metadata !14, null}
diff --git a/test/CodeGen/X86/2009-07-16-LoadFoldingBug.ll b/test/CodeGen/X86/2009-07-16-LoadFoldingBug.ll
deleted file mode 100644
index e21c892..0000000
--- a/test/CodeGen/X86/2009-07-16-LoadFoldingBug.ll
+++ /dev/null
@@ -1,102 +0,0 @@
-; RUN: llc < %s -mtriple=x86_64-apple-darwin10 | FileCheck %s
-
-; CHECK: _foo:
-; CHECK: pavgw LCPI1_4(%rip)
-
-; rdar://7057804
-
-define void @foo(i16* %out8x8, i16* %in8x8, i32 %lastrow) optsize ssp {
-entry:
- %0 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> <i16 6518, i16 6518, i16 6518, i16 6518, i16 6518, i16 6518, i16 6518, i16 6518>, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=2]
- %1 = call <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16> %0, <8 x i16> <i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384>) nounwind readnone ; <<8 x i16>> [#uses=1]
- %2 = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> zeroinitializer, i32 14) nounwind readnone ; <<8 x i16>> [#uses=1]
- %3 = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %2, <8 x i16> zeroinitializer) nounwind readnone ; <<8 x i16>> [#uses=1]
- %tmp.i.i10 = add <8 x i16> %0, %3 ; <<8 x i16>> [#uses=1]
- %4 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> zeroinitializer, <8 x i16> %1) nounwind readnone ; <<8 x i16>> [#uses=1]
- %5 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %tmp.i.i10, <8 x i16> %4) nounwind readnone ; <<8 x i16>> [#uses=3]
- %6 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> %5, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=1]
- %7 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> <i16 6518, i16 6518, i16 6518, i16 6518, i16 6518, i16 6518, i16 6518, i16 6518>, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=2]
- %8 = call <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16> %7, <8 x i16> <i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384>) nounwind readnone ; <<8 x i16>> [#uses=1]
- %9 = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> zeroinitializer, i32 14) nounwind readnone ; <<8 x i16>> [#uses=1]
- %10 = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %9, <8 x i16> zeroinitializer) nounwind readnone ; <<8 x i16>> [#uses=1]
- %tmp.i.i8 = add <8 x i16> %7, %10 ; <<8 x i16>> [#uses=1]
- %11 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> undef, <8 x i16> %8) nounwind readnone ; <<8 x i16>> [#uses=1]
- %12 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %tmp.i.i8, <8 x i16> %11) nounwind readnone ; <<8 x i16>> [#uses=1]
- %13 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> undef, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=1]
- %14 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> %5, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=1]
- %15 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %5, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=1]
- %16 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %6, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=1]
- %17 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %12, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=1]
- %18 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> %13, <8 x i16> %15) nounwind readnone ; <<8 x i16>> [#uses=1]
- %19 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> undef, <8 x i16> %14) nounwind readnone ; <<8 x i16>> [#uses=2]
- %20 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> undef, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=4]
- %21 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> undef, <8 x i16> %17) nounwind readnone ; <<8 x i16>> [#uses=1]
- %22 = bitcast <8 x i16> %21 to <2 x i64> ; <<2 x i64>> [#uses=1]
- %23 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> <i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170>, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=2]
- %24 = call <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16> %23, <8 x i16> <i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384>) nounwind readnone ; <<8 x i16>> [#uses=1]
- %25 = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> zeroinitializer, i32 14) nounwind readnone ; <<8 x i16>> [#uses=1]
- %26 = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %25, <8 x i16> zeroinitializer) nounwind readnone ; <<8 x i16>> [#uses=1]
- %tmp.i.i6 = add <8 x i16> %23, %26 ; <<8 x i16>> [#uses=1]
- %27 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> undef, <8 x i16> %24) nounwind readnone ; <<8 x i16>> [#uses=1]
- %28 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %tmp.i.i6, <8 x i16> %27) nounwind readnone ; <<8 x i16>> [#uses=1]
- %29 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> <i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170>, <8 x i16> undef) nounwind readnone ; <<8 x i16>> [#uses=2]
- %30 = call <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16> %29, <8 x i16> <i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384>) nounwind readnone ; <<8 x i16>> [#uses=1]
- %31 = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> zeroinitializer, i32 14) nounwind readnone ; <<8 x i16>> [#uses=1]
- %32 = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %31, <8 x i16> zeroinitializer) nounwind readnone ; <<8 x i16>> [#uses=1]
- %tmp.i.i4 = add <8 x i16> %29, %32 ; <<8 x i16>> [#uses=1]
- %33 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> undef, <8 x i16> %30) nounwind readnone ; <<8 x i16>> [#uses=1]
- %34 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %tmp.i.i4, <8 x i16> %33) nounwind readnone ; <<8 x i16>> [#uses=1]
- %35 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> <i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170>, <8 x i16> %20) nounwind readnone ; <<8 x i16>> [#uses=2]
- %tmp.i2.i1 = mul <8 x i16> %20, <i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170, i16 23170> ; <<8 x i16>> [#uses=1]
- %36 = call <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16> %35, <8 x i16> <i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384>) nounwind readnone ; <<8 x i16>> [#uses=1]
- %37 = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %tmp.i2.i1, i32 14) nounwind readnone ; <<8 x i16>> [#uses=1]
- %38 = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %37, <8 x i16> zeroinitializer) nounwind readnone ; <<8 x i16>> [#uses=1]
- %tmp.i.i2 = add <8 x i16> %35, %38 ; <<8 x i16>> [#uses=1]
- %39 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> %19, <8 x i16> %36) nounwind readnone ; <<8 x i16>> [#uses=1]
- %40 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %tmp.i.i2, <8 x i16> %39) nounwind readnone ; <<8 x i16>> [#uses=1]
- %41 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> <i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170>, <8 x i16> %20) nounwind readnone ; <<8 x i16>> [#uses=2]
- %tmp.i2.i = mul <8 x i16> %20, <i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170, i16 -23170> ; <<8 x i16>> [#uses=1]
- %42 = call <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16> %41, <8 x i16> <i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384, i16 16384>) nounwind readnone ; <<8 x i16>> [#uses=1]
- %43 = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %tmp.i2.i, i32 14) nounwind readnone ; <<8 x i16>> [#uses=1]
- %44 = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %43, <8 x i16> zeroinitializer) nounwind readnone ; <<8 x i16>> [#uses=1]
- %tmp.i.i = add <8 x i16> %41, %44 ; <<8 x i16>> [#uses=1]
- %45 = call <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16> %19, <8 x i16> %42) nounwind readnone ; <<8 x i16>> [#uses=1]
- %46 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %tmp.i.i, <8 x i16> %45) nounwind readnone ; <<8 x i16>> [#uses=1]
- %47 = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %18, <8 x i16> %16) nounwind readnone ; <<8 x i16>> [#uses=1]
- %48 = bitcast <8 x i16> %47 to <2 x i64> ; <<2 x i64>> [#uses=1]
- %49 = bitcast <8 x i16> %28 to <2 x i64> ; <<2 x i64>> [#uses=1]
- %50 = getelementptr i16* %out8x8, i64 8 ; <i16*> [#uses=1]
- %51 = bitcast i16* %50 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
- store <2 x i64> %49, <2 x i64>* %51, align 16
- %52 = bitcast <8 x i16> %40 to <2 x i64> ; <<2 x i64>> [#uses=1]
- %53 = getelementptr i16* %out8x8, i64 16 ; <i16*> [#uses=1]
- %54 = bitcast i16* %53 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
- store <2 x i64> %52, <2 x i64>* %54, align 16
- %55 = getelementptr i16* %out8x8, i64 24 ; <i16*> [#uses=1]
- %56 = bitcast i16* %55 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
- store <2 x i64> %48, <2 x i64>* %56, align 16
- %57 = bitcast <8 x i16> %46 to <2 x i64> ; <<2 x i64>> [#uses=1]
- %58 = getelementptr i16* %out8x8, i64 40 ; <i16*> [#uses=1]
- %59 = bitcast i16* %58 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
- store <2 x i64> %57, <2 x i64>* %59, align 16
- %60 = bitcast <8 x i16> %34 to <2 x i64> ; <<2 x i64>> [#uses=1]
- %61 = getelementptr i16* %out8x8, i64 48 ; <i16*> [#uses=1]
- %62 = bitcast i16* %61 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
- store <2 x i64> %60, <2 x i64>* %62, align 16
- %63 = getelementptr i16* %out8x8, i64 56 ; <i16*> [#uses=1]
- %64 = bitcast i16* %63 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
- store <2 x i64> %22, <2 x i64>* %64, align 16
- ret void
-}
-
-declare <8 x i16> @llvm.x86.sse2.psubs.w(<8 x i16>, <8 x i16>) nounwind readnone
-
-declare <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16>, <8 x i16>) nounwind readnone
-
-declare <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16>, <8 x i16>) nounwind readnone
-
-declare <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16>, <8 x i16>) nounwind readnone
-
-declare <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16>, <8 x i16>) nounwind readnone
-
-declare <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16>, i32) nounwind readnone
diff --git a/test/CodeGen/X86/2009-09-07-CoalescerBug.ll b/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
index a5b4a79..41b4bc0 100644
--- a/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
+++ b/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
@@ -8,8 +8,7 @@
define i64 @hammer_time(i64 %modulep, i64 %physfree) nounwind ssp noredzone noimplicitfloat {
; CHECK: hammer_time:
; CHECK: movq $Xrsvd, %rax
-; CHECK: movq $Xrsvd, %rsi
-; CHECK: movq $Xrsvd, %rdi
+; CHECK: movq $Xrsvd, %rcx
entry:
br i1 undef, label %if.then, label %if.end
diff --git a/test/CodeGen/X86/2010-02-11-NonTemporal.ll b/test/CodeGen/X86/2010-02-11-NonTemporal.ll
new file mode 100644
index 0000000..5789a0b
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-11-NonTemporal.ll
@@ -0,0 +1,22 @@
+; RUN: llc < %s -march=x86-64 | FileCheck %s
+; CHECK: movnt
+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"
+
+!0 = metadata !{ i32 1 }
+
+define void @sub_(i32* noalias %n) {
+"file movnt.f90, line 2, bb1":
+ %n1 = alloca i32*, align 8
+ %i = alloca i32, align 4
+ %"$LCS_0" = alloca i64, align 8
+ %"$LCS_S2" = alloca <2 x double>, align 16
+ %r9 = load <2 x double>* %"$LCS_S2", align 8
+ %r10 = load i64* %"$LCS_0", align 8
+ %r11 = inttoptr i64 %r10 to <2 x double>*
+ store <2 x double> %r9, <2 x double>* %r11, align 16, !nontemporal !0
+ br label %"file movnt.f90, line 18, bb5"
+
+"file movnt.f90, line 18, bb5":
+ ret void
+}
diff --git a/test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll b/test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll
new file mode 100644
index 0000000..c5d3d16
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll
@@ -0,0 +1,260 @@
+; RUN: llc < %s > %t
+; PR6283
+
+; Tricky coalescer bug:
+; After coalescing %RAX with a virtual register, this instruction was rematted:
+;
+; %EAX<def> = MOV32rr %reg1070<kill>
+;
+; This instruction silently defined %RAX, and when rematting removed the
+; instruction, the live interval for %RAX was not properly updated. The valno
+; referred to a deleted instruction and bad things happened.
+;
+; The fix is to implicitly define %RAX when coalescing:
+;
+; %EAX<def> = MOV32rr %reg1070<kill>, %RAX<imp-def>
+;
+
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+module asm "\09.ident\09\22GCC: (GNU) 4.5.0 20100212 (experimental) LLVM: 95975\22"
+
+%0 = type { %"union gimple_statement_d"* }
+%"BITMAP_WORD[]" = type [2 x i64]
+%"char[]" = type [4 x i8]
+%"enum dom_state[]" = type [2 x i32]
+%"int[]" = type [4 x i32]
+%"struct VEC_basic_block_base" = type { i32, i32, [1 x %"struct basic_block_def"*] }
+%"struct VEC_basic_block_gc" = type { %"struct VEC_basic_block_base" }
+%"struct VEC_edge_base" = type { i32, i32, [1 x %"struct edge_def"*] }
+%"struct VEC_edge_gc" = type { %"struct VEC_edge_base" }
+%"struct VEC_gimple_base" = type { i32, i32, [1 x %"union gimple_statement_d"*] }
+%"struct VEC_gimple_gc" = type { %"struct VEC_gimple_base" }
+%"struct VEC_iv_cand_p_base" = type { i32, i32, [1 x %"struct iv_cand"*] }
+%"struct VEC_iv_cand_p_heap" = type { %"struct VEC_iv_cand_p_base" }
+%"struct VEC_iv_use_p_base" = type { i32, i32, [1 x %"struct iv_use"*] }
+%"struct VEC_iv_use_p_heap" = type { %"struct VEC_iv_use_p_base" }
+%"struct VEC_loop_p_base" = type { i32, i32, [1 x %"struct loop"*] }
+%"struct VEC_loop_p_gc" = type { %"struct VEC_loop_p_base" }
+%"struct VEC_rtx_base" = type { i32, i32, [1 x %"struct rtx_def"*] }
+%"struct VEC_rtx_gc" = type { %"struct VEC_rtx_base" }
+%"struct VEC_tree_base" = type { i32, i32, [1 x %"union tree_node"*] }
+%"struct VEC_tree_gc" = type { %"struct VEC_tree_base" }
+%"struct _obstack_chunk" = type { i8*, %"struct _obstack_chunk"*, %"char[]" }
+%"struct basic_block_def" = type { %"struct VEC_edge_gc"*, %"struct VEC_edge_gc"*, i8*, %"struct loop"*, [2 x %"struct et_node"*], %"struct basic_block_def"*, %"struct basic_block_def"*, %"union basic_block_il_dependent", i64, i32, i32, i32, i32, i32 }
+%"struct bitmap_element" = type { %"struct bitmap_element"*, %"struct bitmap_element"*, i32, %"BITMAP_WORD[]" }
+%"struct bitmap_head_def" = type { %"struct bitmap_element"*, %"struct bitmap_element"*, i32, %"struct bitmap_obstack"* }
+%"struct bitmap_obstack" = type { %"struct bitmap_element"*, %"struct bitmap_head_def"*, %"struct obstack" }
+%"struct block_symbol" = type { [3 x %"union rtunion"], %"struct object_block"*, i64 }
+%"struct comp_cost" = type { i32, i32 }
+%"struct control_flow_graph" = type { %"struct basic_block_def"*, %"struct basic_block_def"*, %"struct VEC_basic_block_gc"*, i32, i32, i32, %"struct VEC_basic_block_gc"*, i32, %"enum dom_state[]", %"enum dom_state[]", i32, i32 }
+%"struct cost_pair" = type { %"struct iv_cand"*, %"struct comp_cost", %"struct bitmap_head_def"*, %"union tree_node"* }
+%"struct def_optype_d" = type { %"struct def_optype_d"*, %"union tree_node"** }
+%"struct double_int" = type { i64, i64 }
+%"struct edge_def" = type { %"struct basic_block_def"*, %"struct basic_block_def"*, %"union edge_def_insns", i8*, %"union tree_node"*, i32, i32, i32, i32, i64 }
+%"struct eh_status" = type opaque
+%"struct et_node" = type opaque
+%"struct function" = type { %"struct eh_status"*, %"struct control_flow_graph"*, %"struct gimple_seq_d"*, %"struct gimple_df"*, %"struct loops"*, %"struct htab"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"struct machine_function"*, %"struct language_function"*, %"struct htab"*, i32, i32, i32, i32, i32, i32, i8*, i8, i8, i8, i8 }
+%"struct gimple_bb_info" = type { %"struct gimple_seq_d"*, %"struct gimple_seq_d"* }
+%"struct gimple_df" = type { %"struct htab"*, %"struct VEC_gimple_gc"*, %"struct VEC_tree_gc"*, %"union tree_node"*, %"struct pt_solution", %"struct pt_solution", %"struct pointer_map_t"*, %"union tree_node"*, %"struct htab"*, %"struct bitmap_head_def"*, i8, %"struct ssa_operands" }
+%"struct gimple_seq_d" = type { %"struct gimple_seq_node_d"*, %"struct gimple_seq_node_d"*, %"struct gimple_seq_d"* }
+%"struct gimple_seq_node_d" = type { %"union gimple_statement_d"*, %"struct gimple_seq_node_d"*, %"struct gimple_seq_node_d"* }
+%"struct gimple_statement_base" = type { i8, i8, i16, i32, i32, i32, %"struct basic_block_def"*, %"union tree_node"* }
+%"struct gimple_statement_phi" = type { %"struct gimple_statement_base", i32, i32, %"union tree_node"*, %"struct phi_arg_d[]" }
+%"struct htab" = type { i32 (i8*)*, i32 (i8*, i8*)*, void (i8*)*, i8**, i64, i64, i64, i32, i32, i8* (i64, i64)*, void (i8*)*, i8*, i8* (i8*, i64, i64)*, void (i8*, i8*)*, i32 }
+%"struct iv" = type { %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, i8, i8, i32 }
+%"struct iv_cand" = type { i32, i8, i32, %"union gimple_statement_d"*, %"union tree_node"*, %"union tree_node"*, %"struct iv"*, i32, i32, %"struct iv_use"*, %"struct bitmap_head_def"* }
+%"struct iv_use" = type { i32, i32, %"struct iv"*, %"union gimple_statement_d"*, %"union tree_node"**, %"struct bitmap_head_def"*, i32, %"struct cost_pair"*, %"struct iv_cand"* }
+%"struct ivopts_data" = type { %"struct loop"*, %"struct pointer_map_t"*, i32, i32, %"struct version_info"*, %"struct bitmap_head_def"*, %"struct VEC_iv_use_p_heap"*, %"struct VEC_iv_cand_p_heap"*, %"struct bitmap_head_def"*, i32, i8, i8 }
+%"struct lang_decl" = type opaque
+%"struct language_function" = type opaque
+%"struct loop" = type { i32, i32, %"struct basic_block_def"*, %"struct basic_block_def"*, %"struct comp_cost", i32, i32, %"struct VEC_loop_p_gc"*, %"struct loop"*, %"struct loop"*, i8*, %"union tree_node"*, %"struct double_int", %"struct double_int", i8, i8, i32, %"struct nb_iter_bound"*, %"struct loop_exit"*, i8, %"union tree_node"* }
+%"struct loop_exit" = type { %"struct edge_def"*, %"struct loop_exit"*, %"struct loop_exit"*, %"struct loop_exit"* }
+%"struct loops" = type { i32, %"struct VEC_loop_p_gc"*, %"struct htab"*, %"struct loop"* }
+%"struct machine_cfa_state" = type { %"struct rtx_def"*, i64 }
+%"struct machine_function" = type { %"struct stack_local_entry"*, i8*, i32, i32, %"int[]", i32, %"struct machine_cfa_state", i32, i8 }
+%"struct nb_iter_bound" = type { %"union gimple_statement_d"*, %"struct double_int", i8, %"struct nb_iter_bound"* }
+%"struct object_block" = type { %"union section"*, i32, i64, %"struct VEC_rtx_gc"*, %"struct VEC_rtx_gc"* }
+%"struct obstack" = type { i64, %"struct _obstack_chunk"*, i8*, i8*, i8*, i64, i32, %"struct _obstack_chunk"* (i8*, i64)*, void (i8*, %"struct _obstack_chunk"*)*, i8*, i8 }
+%"struct phi_arg_d" = type { %"struct ssa_use_operand_d", %"union tree_node"*, i32 }
+%"struct phi_arg_d[]" = type [1 x %"struct phi_arg_d"]
+%"struct pointer_map_t" = type opaque
+%"struct pt_solution" = type { i8, %"struct bitmap_head_def"* }
+%"struct rtx_def" = type { i16, i8, i8, %"union u" }
+%"struct section_common" = type { i32 }
+%"struct ssa_operand_memory_d" = type { %"struct ssa_operand_memory_d"*, %"uchar[]" }
+%"struct ssa_operands" = type { %"struct ssa_operand_memory_d"*, i32, i32, i8, %"struct def_optype_d"*, %"struct use_optype_d"* }
+%"struct ssa_use_operand_d" = type { %"struct ssa_use_operand_d"*, %"struct ssa_use_operand_d"*, %0, %"union tree_node"** }
+%"struct stack_local_entry" = type opaque
+%"struct tree_base" = type <{ i16, i8, i8, i8, [2 x i8], i8 }>
+%"struct tree_common" = type { %"struct tree_base", %"union tree_node"*, %"union tree_node"* }
+%"struct tree_decl_common" = type { %"struct tree_decl_minimal", %"union tree_node"*, i8, i8, i8, i8, i8, i32, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"struct lang_decl"* }
+%"struct tree_decl_minimal" = type { %"struct tree_common", i32, i32, %"union tree_node"*, %"union tree_node"* }
+%"struct tree_decl_non_common" = type { %"struct tree_decl_with_vis", %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"* }
+%"struct tree_decl_with_rtl" = type { %"struct tree_decl_common", %"struct rtx_def"* }
+%"struct tree_decl_with_vis" = type { %"struct tree_decl_with_rtl", %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, i8, i8, i8 }
+%"struct tree_function_decl" = type { %"struct tree_decl_non_common", %"struct function"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, i16, i8, i8 }
+%"struct unnamed_section" = type { %"struct section_common", void (i8*)*, i8*, %"union section"* }
+%"struct use_optype_d" = type { %"struct use_optype_d"*, %"struct ssa_use_operand_d" }
+%"struct version_info" = type { %"union tree_node"*, %"struct iv"*, i8, i32, i8 }
+%"uchar[]" = type [1 x i8]
+%"union basic_block_il_dependent" = type { %"struct gimple_bb_info"* }
+%"union edge_def_insns" = type { %"struct gimple_seq_d"* }
+%"union gimple_statement_d" = type { %"struct gimple_statement_phi" }
+%"union rtunion" = type { i8* }
+%"union section" = type { %"struct unnamed_section" }
+%"union tree_node" = type { %"struct tree_function_decl" }
+%"union u" = type { %"struct block_symbol" }
+
+declare fastcc %"union tree_node"* @get_computation_at(%"struct loop"*, %"struct iv_use"* nocapture, %"struct iv_cand"* nocapture, %"union gimple_statement_d"*) nounwind
+
+declare fastcc i32 @computation_cost(%"union tree_node"*, i8 zeroext) nounwind
+
+define fastcc i64 @get_computation_cost_at(%"struct ivopts_data"* %data, %"struct iv_use"* nocapture %use, %"struct iv_cand"* nocapture %cand, i8 zeroext %address_p, %"struct bitmap_head_def"** %depends_on, %"union gimple_statement_d"* %at, i8* %can_autoinc) nounwind {
+entry:
+ br i1 undef, label %"100", label %"4"
+
+"4": ; preds = %entry
+ br i1 undef, label %"6", label %"5"
+
+"5": ; preds = %"4"
+ unreachable
+
+"6": ; preds = %"4"
+ br i1 undef, label %"8", label %"7"
+
+"7": ; preds = %"6"
+ unreachable
+
+"8": ; preds = %"6"
+ br i1 undef, label %"100", label %"10"
+
+"10": ; preds = %"8"
+ br i1 undef, label %"17", label %"16"
+
+"16": ; preds = %"10"
+ unreachable
+
+"17": ; preds = %"10"
+ br i1 undef, label %"19", label %"18"
+
+"18": ; preds = %"17"
+ unreachable
+
+"19": ; preds = %"17"
+ br i1 undef, label %"93", label %"20"
+
+"20": ; preds = %"19"
+ br i1 undef, label %"23", label %"21"
+
+"21": ; preds = %"20"
+ unreachable
+
+"23": ; preds = %"20"
+ br i1 undef, label %"100", label %"25"
+
+"25": ; preds = %"23"
+ br i1 undef, label %"100", label %"26"
+
+"26": ; preds = %"25"
+ br i1 undef, label %"30", label %"28"
+
+"28": ; preds = %"26"
+ unreachable
+
+"30": ; preds = %"26"
+ br i1 undef, label %"59", label %"51"
+
+"51": ; preds = %"30"
+ br i1 undef, label %"55", label %"52"
+
+"52": ; preds = %"51"
+ unreachable
+
+"55": ; preds = %"51"
+ %0 = icmp ugt i32 0, undef ; <i1> [#uses=1]
+ br i1 %0, label %"50.i", label %"9.i"
+
+"9.i": ; preds = %"55"
+ unreachable
+
+"50.i": ; preds = %"55"
+ br i1 undef, label %"55.i", label %"54.i"
+
+"54.i": ; preds = %"50.i"
+ br i1 undef, label %"57.i", label %"55.i"
+
+"55.i": ; preds = %"54.i", %"50.i"
+ unreachable
+
+"57.i": ; preds = %"54.i"
+ br label %"63.i"
+
+"61.i": ; preds = %"63.i"
+ br i1 undef, label %"64.i", label %"62.i"
+
+"62.i": ; preds = %"61.i"
+ br label %"63.i"
+
+"63.i": ; preds = %"62.i", %"57.i"
+ br i1 undef, label %"61.i", label %"64.i"
+
+"64.i": ; preds = %"63.i", %"61.i"
+ unreachable
+
+"59": ; preds = %"30"
+ br i1 undef, label %"60", label %"82"
+
+"60": ; preds = %"59"
+ br i1 undef, label %"61", label %"82"
+
+"61": ; preds = %"60"
+ br i1 undef, label %"62", label %"82"
+
+"62": ; preds = %"61"
+ br i1 undef, label %"100", label %"63"
+
+"63": ; preds = %"62"
+ br i1 undef, label %"65", label %"64"
+
+"64": ; preds = %"63"
+ unreachable
+
+"65": ; preds = %"63"
+ br i1 undef, label %"66", label %"67"
+
+"66": ; preds = %"65"
+ unreachable
+
+"67": ; preds = %"65"
+ %1 = load i32* undef, align 4 ; <i32> [#uses=0]
+ br label %"100"
+
+"82": ; preds = %"61", %"60", %"59"
+ unreachable
+
+"93": ; preds = %"19"
+ %2 = call fastcc %"union tree_node"* @get_computation_at(%"struct loop"* undef, %"struct iv_use"* %use, %"struct iv_cand"* %cand, %"union gimple_statement_d"* %at) nounwind ; <%"union tree_node"*> [#uses=1]
+ br i1 undef, label %"100", label %"97"
+
+"97": ; preds = %"93"
+ br i1 undef, label %"99", label %"98"
+
+"98": ; preds = %"97"
+ br label %"99"
+
+"99": ; preds = %"98", %"97"
+ %3 = phi %"union tree_node"* [ undef, %"98" ], [ %2, %"97" ] ; <%"union tree_node"*> [#uses=1]
+ %4 = call fastcc i32 @computation_cost(%"union tree_node"* %3, i8 zeroext undef) nounwind ; <i32> [#uses=1]
+ br label %"100"
+
+"100": ; preds = %"99", %"93", %"67", %"62", %"25", %"23", %"8", %entry
+ %memtmp1.1.0 = phi i32 [ 0, %"99" ], [ 10000000, %entry ], [ 10000000, %"8" ], [ 10000000, %"23" ], [ 10000000, %"25" ], [ undef, %"62" ], [ undef, %"67" ], [ 10000000, %"93" ] ; <i32> [#uses=1]
+ %memtmp1.0.0 = phi i32 [ %4, %"99" ], [ 10000000, %entry ], [ 10000000, %"8" ], [ 10000000, %"23" ], [ 10000000, %"25" ], [ undef, %"62" ], [ undef, %"67" ], [ 10000000, %"93" ] ; <i32> [#uses=1]
+ %5 = zext i32 %memtmp1.0.0 to i64 ; <i64> [#uses=1]
+ %6 = zext i32 %memtmp1.1.0 to i64 ; <i64> [#uses=1]
+ %7 = shl i64 %6, 32 ; <i64> [#uses=1]
+ %8 = or i64 %7, %5 ; <i64> [#uses=1]
+ ret i64 %8
+}
diff --git a/test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll b/test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll
new file mode 100644
index 0000000..c429172
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll
@@ -0,0 +1,80 @@
+; RUN: llc < %s > %t
+; PR6300
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+; When the "154" loops back onto itself, it defines a register after using it.
+; The first value of the register is implicit-def.
+
+%"struct location_chain_def" = type { %"struct location_chain_def"*, %"struct rtx_def"*, %"struct rtx_def"*, i32 }
+%"struct real_value" = type { i32, [5 x i32] }
+%"struct rtx_def" = type { i16, i8, i8, %"union u" }
+%"union u" = type { %"struct real_value" }
+
+define i32 @variable_union(i8** nocapture %slot, i8* nocapture %data) nounwind {
+entry:
+ br i1 undef, label %"4.thread", label %"3"
+
+"4.thread": ; preds = %entry
+ unreachable
+
+"3": ; preds = %entry
+ br i1 undef, label %"19", label %"20"
+
+"19": ; preds = %"3"
+ unreachable
+
+"20": ; preds = %"3"
+ br i1 undef, label %"56.preheader", label %dv_onepart_p.exit
+
+dv_onepart_p.exit: ; preds = %"20"
+ unreachable
+
+"56.preheader": ; preds = %"20"
+ br label %"56"
+
+"50": ; preds = %"57"
+ br label %"56"
+
+"56": ; preds = %"50", %"56.preheader"
+ br i1 undef, label %"57", label %"58"
+
+"57": ; preds = %"56"
+ br i1 undef, label %"50", label %"58"
+
+"58": ; preds = %"57", %"56"
+ br i1 undef, label %"62", label %"63"
+
+"62": ; preds = %"58"
+ unreachable
+
+"63": ; preds = %"58"
+ br i1 undef, label %"67", label %"66"
+
+"66": ; preds = %"63"
+ br label %"67"
+
+"67": ; preds = %"66", %"63"
+ br label %"68"
+
+"68": ; preds = %"161", %"67"
+ br i1 undef, label %"153", label %"161"
+
+"153": ; preds = %"68"
+ br i1 undef, label %"160", label %bb.nph46
+
+bb.nph46: ; preds = %"153"
+ br label %"154"
+
+"154": ; preds = %"154", %bb.nph46
+ %0 = phi %"struct location_chain_def"** [ undef, %bb.nph46 ], [ %1, %"154" ] ; <%"struct location_chain_def"**> [#uses=1]
+ %1 = bitcast i8* undef to %"struct location_chain_def"** ; <%"struct location_chain_def"**> [#uses=1]
+ store %"struct location_chain_def"* undef, %"struct location_chain_def"** %0, align 4
+ br i1 undef, label %"160", label %"154"
+
+"160": ; preds = %"154", %"153"
+ br label %"161"
+
+"161": ; preds = %"160", %"68"
+ br label %"68"
+}
diff --git a/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll b/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll
new file mode 100644
index 0000000..eb21dc2
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll
@@ -0,0 +1,55 @@
+; RUN: llc -mtriple=i386-apple-darwin -tailcallopt < %s | FileCheck %s
+; Check that lowered argumens do not overwrite the return address before it is moved.
+; Bug 6225
+;
+; If a call is a fastcc tail call and tail call optimization is enabled, the
+; caller frame is replaced by the callee frame. This can require that arguments are
+; placed on the former return address stack slot. Special care needs to be taken
+; taken that the return address is moved / or stored in a register before
+; lowering of arguments potentially overwrites the value.
+;
+; Move return address (76(%esp)) to a temporary register (%ebp)
+; CHECK: movl 76(%esp), %ebp
+; Overwrite return addresss
+; CHECK: movl %ecx, 76(%esp)
+; Move return address from temporary register (%ebp) to new stack location (60(%esp))
+; CHECK: movl %ebp, 60(%esp)
+
+%tupl_p = type [9 x i32]*
+
+declare fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) noreturn nounwind
+declare fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) noreturn nounwind
+
+define fastcc void @l186(%tupl_p %r1) noreturn nounwind {
+entry:
+ %ptr1 = getelementptr %tupl_p %r1, i32 0, i32 0
+ %r2 = load i32* %ptr1
+ %ptr3 = getelementptr %tupl_p %r1, i32 0, i32 1
+ %r3 = load i32* %ptr3
+ %ptr5 = getelementptr %tupl_p %r1, i32 0, i32 2
+ %r4 = load i32* %ptr5
+ %ptr7 = getelementptr %tupl_p %r1, i32 0, i32 3
+ %r5 = load i32* %ptr7
+ %ptr9 = getelementptr %tupl_p %r1, i32 0, i32 4
+ %r6 = load i32* %ptr9
+ %ptr11 = getelementptr %tupl_p %r1, i32 0, i32 5
+ %r7 = load i32* %ptr11
+ %ptr13 = getelementptr %tupl_p %r1, i32 0, i32 6
+ %r8 = load i32* %ptr13
+ %ptr15 = getelementptr %tupl_p %r1, i32 0, i32 7
+ %r9 = load i32* %ptr15
+ %ptr17 = getelementptr %tupl_p %r1, i32 0, i32 8
+ %r10 = load i32* %ptr17
+ %cond = icmp eq i32 %r10, 3
+ br i1 %cond, label %true, label %false
+
+true:
+ tail call fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32 %r5, i32 %r3, i32 %r2) noreturn nounwind
+ ret void
+
+false:
+ tail call fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) noreturn nounwind
+ ret void
+}
+
+
diff --git a/test/CodeGen/X86/2010-02-23-DAGCombineBug.ll b/test/CodeGen/X86/2010-02-23-DAGCombineBug.ll
new file mode 100644
index 0000000..6a58e9e
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-23-DAGCombineBug.ll
@@ -0,0 +1,18 @@
+; RUN: llc < %s -march=x86 | FileCheck %s
+
+define i32* @t() nounwind optsize ssp {
+entry:
+; CHECK: t:
+; CHECK: testl %eax, %eax
+; CHECK: js
+ %cmp = icmp slt i32 undef, 0 ; <i1> [#uses=1]
+ %outsearch.0 = select i1 %cmp, i1 false, i1 true ; <i1> [#uses=1]
+ br i1 %outsearch.0, label %if.then27, label %if.else29
+
+if.then27: ; preds = %entry
+ ret i32* undef
+
+if.else29: ; preds = %entry
+ unreachable
+}
+
diff --git a/test/CodeGen/X86/2010-02-23-DIV8rDefinesAX.ll b/test/CodeGen/X86/2010-02-23-DIV8rDefinesAX.ll
new file mode 100644
index 0000000..8543c80
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-23-DIV8rDefinesAX.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s
+; PR6374
+;
+; This test produces a DIV8r instruction and uses %AX instead of %AH and %AL.
+; The DIV8r must have the right imp-defs for that to work.
+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"
+target triple = "x86_64-apple-darwin10.0.0"
+
+%struct._i386_state = type { %union.anon }
+%union.anon = type { [0 x i8] }
+
+define void @i386_aam(%struct._i386_state* nocapture %cpustate) nounwind ssp {
+entry:
+ %call = tail call fastcc signext i8 @FETCH() ; <i8> [#uses=1]
+ %rem = urem i8 0, %call ; <i8> [#uses=1]
+ store i8 %rem, i8* undef
+ ret void
+}
+
+declare fastcc signext i8 @FETCH() nounwind readnone ssp
diff --git a/test/CodeGen/X86/2010-02-23-RematImplicitSubreg.ll b/test/CodeGen/X86/2010-02-23-RematImplicitSubreg.ll
new file mode 100644
index 0000000..4a26ba0
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-23-RematImplicitSubreg.ll
@@ -0,0 +1,49 @@
+; RUN: llc < %s
+; PR6372
+;
+; This test produces a move instruction with an implicitly defined super-register:
+;
+; %DL<def> = MOV8rr %reg1038<kill>, %RDX<imp-def>
+;
+; When %DL is rematerialized, we must remember to update live intervals for
+; sub-registers %DX and %EDX.
+
+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"
+target triple = "x86_64-apple-darwin10.0.0"
+
+define noalias i8* @foo() nounwind ssp {
+entry:
+ br i1 undef, label %for.end, label %for.body
+
+for.body: ; preds = %if.end40, %entry
+ %tmp6 = load i8* undef, align 2 ; <i8> [#uses=3]
+ %conv11 = sext i8 %tmp6 to i64 ; <i64> [#uses=1]
+ %cmp15 = icmp slt i64 %conv11, undef ; <i1> [#uses=1]
+ br i1 %cmp15, label %if.end, label %if.then
+
+if.then: ; preds = %for.body
+ %conv18 = sext i8 %tmp6 to i32 ; <i32> [#uses=1]
+ %call = tail call i32 (...)* @invalid(i32 0, i32 0, i32 %conv18) nounwind ; <i32> [#uses=0]
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ %index.0 = phi i8 [ 0, %if.then ], [ %tmp6, %for.body ] ; <i8> [#uses=1]
+ store i8 %index.0, i8* undef
+ %tmp24 = load i8* undef ; <i8> [#uses=2]
+ br i1 undef, label %if.end40, label %if.then36
+
+if.then36: ; preds = %if.end
+ %conv38 = sext i8 %tmp24 to i32 ; <i32> [#uses=1]
+ %call39 = tail call i32 (...)* @invalid(i32 0, i32 0, i32 %conv38) nounwind ; <i32> [#uses=0]
+ br label %if.end40
+
+if.end40: ; preds = %if.then36, %if.end
+ %index.1 = phi i8 [ 0, %if.then36 ], [ %tmp24, %if.end ] ; <i8> [#uses=1]
+ store i8 %index.1, i8* undef
+ br i1 false, label %for.body, label %for.end
+
+for.end: ; preds = %if.end40, %entry
+ ret i8* undef
+}
+
+declare i32 @invalid(...)
diff --git a/test/CodeGen/X86/2010-02-23-SingleDefPhiJoin.ll b/test/CodeGen/X86/2010-02-23-SingleDefPhiJoin.ll
new file mode 100644
index 0000000..aeed401
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-23-SingleDefPhiJoin.ll
@@ -0,0 +1,146 @@
+; RUN: llc < %s
+; PR6363
+;
+; This test case creates a phi join register with a single definition. The other
+; predecessor blocks are implicit-def.
+;
+; If LiveIntervalAnalysis fails to recognize this as a phi join, the coalescer
+; will detect an infinity valno loop.
+;
+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 i32 @decode(i8* nocapture %input, i32 %offset, i8* nocapture %output) nounwind {
+entry:
+ br i1 undef, label %meshBB86, label %meshBB102
+
+bb: ; preds = %meshBB106, %meshBB102
+ br i1 false, label %bb9, label %meshBB90
+
+bb.nph: ; preds = %meshBB90
+ br label %meshBB114
+
+bb.nph.fragment: ; preds = %meshBB114
+ br label %meshBB118
+
+bb1.fragment: ; preds = %meshBB118
+ br i1 false, label %bb2, label %bb3
+
+bb2: ; preds = %bb1.fragment
+ br label %meshBB74
+
+bb2.fragment15: ; preds = %meshBB74
+ br label %meshBB98
+
+bb3: ; preds = %bb1.fragment
+ br i1 undef, label %meshBB, label %meshBB102
+
+bb4: ; preds = %meshBB
+ br label %meshBB118
+
+bb4.fragment: ; preds = %meshBB118
+ br label %meshBB82
+
+bb5: ; preds = %meshBB102, %meshBB82
+ br i1 false, label %bb6, label %bb7
+
+bb6: ; preds = %bb5
+ br label %bb7
+
+bb7: ; preds = %meshBB98, %bb6, %bb5
+ br label %meshBB114
+
+bb7.fragment: ; preds = %meshBB114
+ br i1 undef, label %meshBB74, label %bb9
+
+bb9: ; preds = %bb7.fragment, %bb
+ br label %bb1.i23
+
+bb1.i23: ; preds = %meshBB110, %bb9
+ br i1 undef, label %meshBB106, label %meshBB110
+
+skip_to_newline.exit26: ; preds = %meshBB106
+ br label %meshBB86
+
+skip_to_newline.exit26.fragment: ; preds = %meshBB86
+ br i1 false, label %meshBB90, label %meshBB106
+
+bb11.fragment: ; preds = %meshBB90, %meshBB86
+ br label %meshBB122
+
+bb1.i: ; preds = %meshBB122, %meshBB
+ %ooffset.2.lcssa.phi.SV.phi203 = phi i32 [ 0, %meshBB122 ], [ %ooffset.2.lcssa.phi.SV.phi233, %meshBB ] ; <i32> [#uses=1]
+ br label %meshBB98
+
+bb1.i.fragment: ; preds = %meshBB98
+ br i1 undef, label %meshBB78, label %meshBB
+
+skip_to_newline.exit: ; preds = %meshBB78
+ br i1 undef, label %bb12, label %meshBB110
+
+bb12: ; preds = %skip_to_newline.exit
+ br label %meshBB94
+
+bb12.fragment: ; preds = %meshBB94
+ br i1 false, label %bb13, label %meshBB78
+
+bb13: ; preds = %bb12.fragment
+ br label %meshBB82
+
+bb13.fragment: ; preds = %meshBB82
+ br i1 undef, label %meshBB94, label %meshBB122
+
+bb14: ; preds = %meshBB94
+ ret i32 %ooffset.2.lcssa.phi.SV.phi250
+
+bb15: ; preds = %meshBB122, %meshBB110, %meshBB78
+ unreachable
+
+meshBB: ; preds = %bb1.i.fragment, %bb3
+ %ooffset.2.lcssa.phi.SV.phi233 = phi i32 [ undef, %bb3 ], [ %ooffset.2.lcssa.phi.SV.phi209, %bb1.i.fragment ] ; <i32> [#uses=1]
+ br i1 undef, label %bb1.i, label %bb4
+
+meshBB74: ; preds = %bb7.fragment, %bb2
+ br i1 false, label %meshBB118, label %bb2.fragment15
+
+meshBB78: ; preds = %bb12.fragment, %bb1.i.fragment
+ %ooffset.2.lcssa.phi.SV.phi239 = phi i32 [ %ooffset.2.lcssa.phi.SV.phi209, %bb1.i.fragment ], [ %ooffset.2.lcssa.phi.SV.phi250, %bb12.fragment ] ; <i32> [#uses=1]
+ br i1 false, label %bb15, label %skip_to_newline.exit
+
+meshBB82: ; preds = %bb13, %bb4.fragment
+ br i1 false, label %bb5, label %bb13.fragment
+
+meshBB86: ; preds = %skip_to_newline.exit26, %entry
+ br i1 undef, label %skip_to_newline.exit26.fragment, label %bb11.fragment
+
+meshBB90: ; preds = %skip_to_newline.exit26.fragment, %bb
+ br i1 false, label %bb11.fragment, label %bb.nph
+
+meshBB94: ; preds = %bb13.fragment, %bb12
+ %ooffset.2.lcssa.phi.SV.phi250 = phi i32 [ 0, %bb13.fragment ], [ %ooffset.2.lcssa.phi.SV.phi239, %bb12 ] ; <i32> [#uses=2]
+ br i1 false, label %bb12.fragment, label %bb14
+
+meshBB98: ; preds = %bb1.i, %bb2.fragment15
+ %ooffset.2.lcssa.phi.SV.phi209 = phi i32 [ undef, %bb2.fragment15 ], [ %ooffset.2.lcssa.phi.SV.phi203, %bb1.i ] ; <i32> [#uses=2]
+ br i1 undef, label %bb1.i.fragment, label %bb7
+
+meshBB102: ; preds = %bb3, %entry
+ br i1 undef, label %bb5, label %bb
+
+meshBB106: ; preds = %skip_to_newline.exit26.fragment, %bb1.i23
+ br i1 undef, label %bb, label %skip_to_newline.exit26
+
+meshBB110: ; preds = %skip_to_newline.exit, %bb1.i23
+ br i1 false, label %bb15, label %bb1.i23
+
+meshBB114: ; preds = %bb7, %bb.nph
+ %meshStackVariable115.phi = phi i32 [ 19, %bb7 ], [ 8, %bb.nph ] ; <i32> [#uses=0]
+ br i1 undef, label %bb.nph.fragment, label %bb7.fragment
+
+meshBB118: ; preds = %meshBB74, %bb4, %bb.nph.fragment
+ %meshCmp121 = icmp eq i32 undef, 10 ; <i1> [#uses=1]
+ br i1 %meshCmp121, label %bb4.fragment, label %bb1.fragment
+
+meshBB122: ; preds = %bb13.fragment, %bb11.fragment
+ br i1 false, label %bb1.i, label %bb15
+}
diff --git a/test/CodeGen/X86/2010-03-04-Mul8Bug.ll b/test/CodeGen/X86/2010-03-04-Mul8Bug.ll
new file mode 100644
index 0000000..48e75e9
--- /dev/null
+++ b/test/CodeGen/X86/2010-03-04-Mul8Bug.ll
@@ -0,0 +1,25 @@
+; RUN: llc < %s
+; PR6489
+;
+; This test case produces a MUL8 instruction and then tries to read the result
+; from the AX register instead of AH/AL. That confuses live interval analysis.
+;
+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"
+target triple = "x86_64-apple-darwin10.0.0"
+
+define void @func_56(i64 %p_57, i32*** %p_58) nounwind ssp {
+for.end:
+ %conv49 = trunc i32 undef to i8 ; <i8> [#uses=1]
+ %div.i = udiv i8 %conv49, 5 ; <i8> [#uses=1]
+ %conv51 = zext i8 %div.i to i32 ; <i32> [#uses=1]
+ %call55 = call i32 @qux(i32 undef, i32 -2) nounwind ; <i32> [#uses=1]
+ %rem.i = urem i32 %call55, -1 ; <i32> [#uses=1]
+ %cmp57 = icmp uge i32 %conv51, %rem.i ; <i1> [#uses=1]
+ %conv58 = zext i1 %cmp57 to i32 ; <i32> [#uses=1]
+ %call85 = call i32 @func_35(i32*** undef, i32 undef, i32 %conv58, i32 1247, i32 0) nounwind ; <i32> [#uses=0]
+ ret void
+}
+
+declare i32 @func_35(i32***, i32, i32, i32, i32)
+
+declare i32 @qux(i32, i32)
diff --git a/test/CodeGen/X86/2010-03-05-ConstantFoldCFG.ll b/test/CodeGen/X86/2010-03-05-ConstantFoldCFG.ll
new file mode 100644
index 0000000..5de1966
--- /dev/null
+++ b/test/CodeGen/X86/2010-03-05-ConstantFoldCFG.ll
@@ -0,0 +1,42 @@
+; RUN: llc < %s -verify-machineinstrs
+;
+; When BRCOND is constant-folded to BR, make sure that PHI nodes don't get
+; spurious operands when the CFG is trimmed.
+;
+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"
+target triple = "x86_64-apple-darwin10.2"
+
+define fastcc void @_ZSt16__introsort_loopIPdl17less_than_functorEvT_S2_T0_T1_(double* %__first, double* %__last, i64 %__depth_limit) nounwind ssp {
+entry:
+ br i1 undef, label %bb1, label %bb2
+
+bb1: ; preds = %entry
+ ret void
+
+bb2: ; preds = %entry
+ br label %bb2.outer.i
+
+bb2.outer.i: ; preds = %bb9.i, %bb2
+ br i1 undef, label %bb1.i, label %bb5.preheader.i
+
+bb1.i: ; preds = %bb1.i, %bb2.outer.i
+ %indvar5.i = phi i64 [ %tmp, %bb1.i ], [ 0, %bb2.outer.i ] ; <i64> [#uses=1]
+ %tmp = add i64 %indvar5.i, 1 ; <i64> [#uses=2]
+ %scevgep.i = getelementptr double* undef, i64 %tmp ; <double*> [#uses=0]
+ br i1 undef, label %bb1.i, label %bb5.preheader.i
+
+bb5.preheader.i: ; preds = %bb1.i, %bb2.outer.i
+ br label %bb5.i
+
+bb5.i: ; preds = %bb5.i, %bb5.preheader.i
+ br i1 undef, label %bb5.i, label %bb7.i6
+
+bb7.i6: ; preds = %bb5.i
+ br i1 undef, label %bb9.i, label %_ZSt21__unguarded_partitionIPdd17less_than_functorET_S2_S2_T0_T1_.exit
+
+bb9.i: ; preds = %bb7.i6
+ br label %bb2.outer.i
+
+_ZSt21__unguarded_partitionIPdd17less_than_functorET_S2_S2_T0_T1_.exit: ; preds = %bb7.i6
+ unreachable
+}
diff --git a/test/CodeGen/X86/2010-03-05-EFLAGS-Redef.ll b/test/CodeGen/X86/2010-03-05-EFLAGS-Redef.ll
new file mode 100644
index 0000000..3cca10e
--- /dev/null
+++ b/test/CodeGen/X86/2010-03-05-EFLAGS-Redef.ll
@@ -0,0 +1,49 @@
+; RUN: llc < %s -verify-machineinstrs
+;
+; This test case is transformed into a single basic block by the machine
+; branch folding pass. That makes a complete mess of the %EFLAGS liveness, but
+; we don't care about liveness this late anyway.
+
+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"
+target triple = "x86_64-apple-darwin10.2"
+
+define i32 @main(i32 %argc, i8** nocapture %argv) ssp {
+entry:
+ br i1 undef, label %bb, label %bb2
+
+bb: ; preds = %entry
+ br label %bb2
+
+bb2: ; preds = %bb, %entry
+ br i1 undef, label %bb3, label %bb5
+
+bb3: ; preds = %bb2
+ br label %bb5
+
+bb5: ; preds = %bb3, %bb2
+ br i1 undef, label %bb.nph239, label %bb8
+
+bb.nph239: ; preds = %bb5
+ unreachable
+
+bb8: ; preds = %bb5
+ br i1 undef, label %bb.nph237, label %bb47
+
+bb.nph237: ; preds = %bb8
+ unreachable
+
+bb47: ; preds = %bb8
+ br i1 undef, label %bb49, label %bb48
+
+bb48: ; preds = %bb47
+ unreachable
+
+bb49: ; preds = %bb47
+ br i1 undef, label %bb51, label %bb50
+
+bb50: ; preds = %bb49
+ ret i32 0
+
+bb51: ; preds = %bb49
+ ret i32 0
+}
diff --git a/test/CodeGen/X86/addr-label-difference.ll b/test/CodeGen/X86/addr-label-difference.ll
index 547d6b5..be0908a 100644
--- a/test/CodeGen/X86/addr-label-difference.ll
+++ b/test/CodeGen/X86/addr-label-difference.ll
@@ -9,14 +9,18 @@ target triple = "i386-apple-darwin10.0"
define void @test(i32 %i) nounwind ssp {
entry:
+ call void @test(i32 1)
br label %foo
-foo: ; preds = %indirectgoto, %indirectgoto, %indirectgoto, %indirectgoto, %indirectgoto
+foo:
+ call void @test(i32 1)
br label %bar
-bar: ; preds = %foo, %indirectgoto
+bar:
+ call void @test(i32 1)
br label %hack
-hack: ; preds = %bar, %indirectgoto
+hack:
+ call void @test(i32 1)
ret void
}
diff --git a/test/CodeGen/X86/and-or-fold.ll b/test/CodeGen/X86/and-or-fold.ll
index 7733b8a..836b5f1 100644
--- a/test/CodeGen/X86/and-or-fold.ll
+++ b/test/CodeGen/X86/and-or-fold.ll
@@ -1,14 +1,26 @@
-; RUN: llc < %s -march=x86 | grep and | count 1
+; RUN: llc < %s -mtriple=i686-apple-darwin | FileCheck -check-prefix=DARWIN %s
+; RUN: opt < %s -O2 | llc -mtriple=x86_64-apple-darwin | FileCheck -check-prefix=DARWIN-OPT %s
; The dag combiner should fold together (x&127)|(y&16711680) -> (x|y)&c1
; in this case.
-define i32 @test6(i32 %x, i16 %y) {
- %tmp1 = zext i16 %y to i32 ; <i32> [#uses=1]
- %tmp2 = and i32 %tmp1, 127 ; <i32> [#uses=1]
- %tmp4 = shl i32 %x, 16 ; <i32> [#uses=1]
- %tmp5 = and i32 %tmp4, 16711680 ; <i32> [#uses=1]
- %tmp6 = or i32 %tmp2, %tmp5 ; <i32> [#uses=1]
- ret i32 %tmp6
+define i32 @test1(i32 %x, i16 %y) {
+ %tmp1 = zext i16 %y to i32
+ %tmp2 = and i32 %tmp1, 127
+ %tmp4 = shl i32 %x, 16
+ %tmp5 = and i32 %tmp4, 16711680
+ %tmp6 = or i32 %tmp2, %tmp5
+ ret i32 %tmp6
+; DARWIN: andl $16711807, %eax
}
+; <rdar://problem/7529774> The optimizer shouldn't fold this into (and (or, C), D)
+; if (C & D) == 0
+define i64 @test2(i64 %x) nounwind readnone ssp {
+entry:
+ %tmp1 = and i64 %x, 123127
+ %tmp2 = or i64 %tmp1, 3
+ ret i64 %tmp2
+; DARWIN-OPT: andq $123124
+; DARWIN-OPT-NEXT: leaq 3
+}
diff --git a/test/CodeGen/X86/bswap-inline-asm.ll b/test/CodeGen/X86/bswap-inline-asm.ll
index 5bf58fa..2b70193 100644
--- a/test/CodeGen/X86/bswap-inline-asm.ll
+++ b/test/CodeGen/X86/bswap-inline-asm.ll
@@ -1,17 +1,80 @@
; RUN: llc < %s -march=x86-64 > %t
; RUN: not grep APP %t
-; RUN: grep bswapq %t | count 2
-; RUN: grep bswapl %t | count 1
+; RUN: FileCheck %s < %t
+; CHECK: foo:
+; CHECK: bswapq
define i64 @foo(i64 %x) nounwind {
%asmtmp = tail call i64 asm "bswap $0", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %x) nounwind
ret i64 %asmtmp
}
+
+; CHECK: bar:
+; CHECK: bswapq
define i64 @bar(i64 %x) nounwind {
%asmtmp = tail call i64 asm "bswapq ${0:q}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %x) nounwind
ret i64 %asmtmp
}
+
+; CHECK: pen:
+; CHECK: bswapl
define i32 @pen(i32 %x) nounwind {
%asmtmp = tail call i32 asm "bswapl ${0:q}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %x) nounwind
ret i32 %asmtmp
}
+
+; CHECK: s16:
+; CHECK: rolw $8,
+define zeroext i16 @s16(i16 zeroext %x) nounwind {
+ %asmtmp = tail call i16 asm "rorw $$8, ${0:w}", "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i16 %x) nounwind
+ ret i16 %asmtmp
+}
+
+; CHECK: t16:
+; CHECK: rolw $8,
+define zeroext i16 @t16(i16 zeroext %x) nounwind {
+ %asmtmp = tail call i16 asm "rorw $$8, ${0:w}", "=r,0,~{cc},~{dirflag},~{fpsr},~{flags}"(i16 %x) nounwind
+ ret i16 %asmtmp
+}
+
+; CHECK: u16:
+; CHECK: rolw $8,
+define zeroext i16 @u16(i16 zeroext %x) nounwind {
+ %asmtmp = tail call i16 asm "rolw $$8, ${0:w}", "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i16 %x) nounwind
+ ret i16 %asmtmp
+}
+
+; CHECK: v16:
+; CHECK: rolw $8,
+define zeroext i16 @v16(i16 zeroext %x) nounwind {
+ %asmtmp = tail call i16 asm "rolw $$8, ${0:w}", "=r,0,~{cc},~{dirflag},~{fpsr},~{flags}"(i16 %x) nounwind
+ ret i16 %asmtmp
+}
+
+; CHECK: s32:
+; CHECK: bswapl
+define i32 @s32(i32 %x) nounwind {
+ %asmtmp = tail call i32 asm "bswap $0", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %x) nounwind
+ ret i32 %asmtmp
+}
+
+; CHECK: t32:
+; CHECK: bswapl
+define i32 @t32(i32 %x) nounwind {
+ %asmtmp = tail call i32 asm "bswap $0", "=r,0,~{dirflag},~{flags},~{fpsr}"(i32 %x) nounwind
+ ret i32 %asmtmp
+}
+
+; CHECK: s64:
+; CHECK: bswapq
+define i64 @s64(i64 %x) nounwind {
+ %asmtmp = tail call i64 asm "bswap ${0:q}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %x) nounwind
+ ret i64 %asmtmp
+}
+
+; CHECK: t64:
+; CHECK: bswapq
+define i64 @t64(i64 %x) nounwind {
+ %asmtmp = tail call i64 asm "bswap ${0:q}", "=r,0,~{fpsr},~{dirflag},~{flags}"(i64 %x) nounwind
+ ret i64 %asmtmp
+}
diff --git a/test/CodeGen/X86/code_placement_eh.ll b/test/CodeGen/X86/code_placement_eh.ll
new file mode 100644
index 0000000..172d591
--- /dev/null
+++ b/test/CodeGen/X86/code_placement_eh.ll
@@ -0,0 +1,45 @@
+; RUN: llc < %s
+
+; CodePlacementOpt shouldn't try to modify this loop because
+; it involves EH edges.
+
+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"
+target triple = "i386-apple-darwin10.0"
+
+define void @foo() {
+invcont5:
+ br label %bb15
+
+.noexc3: ; preds = %bb15
+ br i1 undef, label %bb18.i5.i, label %bb15
+
+.noexc6.i.i: ; preds = %bb18.i5.i
+ %tmp2021 = invoke float @cosf(float 0.000000e+00) readonly
+ to label %bb18.i5.i unwind label %lpad.i.i ; <float> [#uses=0]
+
+bb18.i5.i: ; preds = %.noexc6.i.i, %bb51.i
+ %tmp2019 = invoke float @sinf(float 0.000000e+00) readonly
+ to label %.noexc6.i.i unwind label %lpad.i.i ; <float> [#uses=0]
+
+lpad.i.i: ; preds = %bb18.i5.i, %.noexc6.i.i
+ %eh_ptr.i.i = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
+ unreachable
+
+lpad59.i: ; preds = %bb15
+ %eh_ptr60.i = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
+ unreachable
+
+bb15: ; preds = %.noexc3, %invcont5
+ invoke fastcc void @_ZN28btHashedOverlappingPairCacheC2Ev()
+ to label %.noexc3 unwind label %lpad59.i
+}
+
+declare i8* @llvm.eh.exception() nounwind readonly
+
+declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
+
+declare float @sinf(float) readonly
+
+declare float @cosf(float) readonly
+
+declare fastcc void @_ZN28btHashedOverlappingPairCacheC2Ev() align 2
diff --git a/test/CodeGen/X86/crash.ll b/test/CodeGen/X86/crash.ll
new file mode 100644
index 0000000..1e13046
--- /dev/null
+++ b/test/CodeGen/X86/crash.ll
@@ -0,0 +1,20 @@
+; RUN: llc -march=x86 %s -o -
+; RUN: llc -march=x86-64 %s -o -
+
+; PR6497
+
+; Chain and flag folding issues.
+define i32 @test1() nounwind ssp {
+entry:
+ %tmp5.i = volatile load i32* undef ; <i32> [#uses=1]
+ %conv.i = zext i32 %tmp5.i to i64 ; <i64> [#uses=1]
+ %tmp12.i = volatile load i32* undef ; <i32> [#uses=1]
+ %conv13.i = zext i32 %tmp12.i to i64 ; <i64> [#uses=1]
+ %shl.i = shl i64 %conv13.i, 32 ; <i64> [#uses=1]
+ %or.i = or i64 %shl.i, %conv.i ; <i64> [#uses=1]
+ %add16.i = add i64 %or.i, 256 ; <i64> [#uses=1]
+ %shr.i = lshr i64 %add16.i, 8 ; <i64> [#uses=1]
+ %conv19.i = trunc i64 %shr.i to i32 ; <i32> [#uses=1]
+ volatile store i32 %conv19.i, i32* undef
+ ret i32 undef
+}
diff --git a/test/CodeGen/X86/critical-edge-split.ll b/test/CodeGen/X86/critical-edge-split.ll
index 4fe554d..f29cbf3 100644
--- a/test/CodeGen/X86/critical-edge-split.ll
+++ b/test/CodeGen/X86/critical-edge-split.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin -tailcallopt=false -stats -info-output-file - | grep asm-printer | grep 31
+; RUN: llc < %s -mtriple=i386-apple-darwin -stats -info-output-file - | grep asm-printer | grep 29
%CC = type { %Register }
%II = type { %"struct.XX::II::$_74" }
diff --git a/test/CodeGen/X86/dllexport.ll b/test/CodeGen/X86/dllexport.ll
new file mode 100644
index 0000000..2c699bf
--- /dev/null
+++ b/test/CodeGen/X86/dllexport.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s | FileCheck %s
+; PR2936
+
+target triple = "i386-mingw32"
+
+define dllexport x86_fastcallcc i32 @foo() nounwind {
+entry:
+ ret i32 0
+}
+
+; CHECK: .section .drectve
+; CHECK: -export:@foo@0 \ No newline at end of file
diff --git a/test/CodeGen/X86/fastcall-correct-mangling.ll b/test/CodeGen/X86/fastcall-correct-mangling.ll
index 2b48f5f..33b18bb 100644
--- a/test/CodeGen/X86/fastcall-correct-mangling.ll
+++ b/test/CodeGen/X86/fastcall-correct-mangling.ll
@@ -1,9 +1,9 @@
-; RUN: llc < %s -mtriple=i386-unknown-mingw32 | \
-; RUN: grep {@12}
+; RUN: llc < %s -mtriple=i386-unknown-mingw32 | FileCheck %s
; Check that a fastcall function gets correct mangling
define x86_fastcallcc void @func(i64 %X, i8 %Y, i8 %G, i16 %Z) {
+; CHECK: @func@20:
ret void
}
diff --git a/test/CodeGen/X86/full-lsr.ll b/test/CodeGen/X86/full-lsr.ll
index 3bd58b6..ff9b1b0 100644
--- a/test/CodeGen/X86/full-lsr.ll
+++ b/test/CodeGen/X86/full-lsr.ll
@@ -1,12 +1,7 @@
; 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
+; RUN: grep {addl \\\$4,} %t | count 3
+; RUN: not grep {,%} %t
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 1a7b577..d79c56b 100644
--- a/test/CodeGen/X86/global-sections.ll
+++ b/test/CodeGen/X86/global-sections.ll
@@ -100,7 +100,7 @@
@G8 = constant [4 x i16] [ i16 1, i16 2, i16 3, i16 0 ]
-; DARWIN: .section __TEXT,__ustring
+; DARWIN: .section __TEXT,__const
; DARWIN: .globl _G8
; DARWIN: _G8:
@@ -110,7 +110,6 @@
@G9 = constant [4 x i32] [ i32 1, i32 2, i32 3, i32 0 ]
-; DARWIN: .section __TEXT,__const
; DARWIN: .globl _G9
; DARWIN: _G9:
diff --git a/test/CodeGen/X86/ins_subreg_coalesce-3.ll b/test/CodeGen/X86/ins_subreg_coalesce-3.ll
index 627edc5..8c1c409 100644
--- a/test/CodeGen/X86/ins_subreg_coalesce-3.ll
+++ b/test/CodeGen/X86/ins_subreg_coalesce-3.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86-64 | grep mov | count 5
+; RUN: llc < %s -march=x86-64 | grep mov | count 3
%struct.COMPOSITE = type { i8, i16, i16 }
%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 }
diff --git a/test/CodeGen/X86/iv-users-in-other-loops.ll b/test/CodeGen/X86/iv-users-in-other-loops.ll
index c695c29..408fb20 100644
--- a/test/CodeGen/X86/iv-users-in-other-loops.ll
+++ b/test/CodeGen/X86/iv-users-in-other-loops.ll
@@ -1,11 +1,11 @@
; RUN: llc < %s -march=x86-64 -o %t
-; RUN: grep inc %t | count 1
+; RUN: not grep inc %t
; RUN: grep dec %t | count 2
; RUN: grep addq %t | count 13
; RUN: not grep addb %t
-; RUN: grep leaq %t | count 9
-; RUN: grep leal %t | count 3
-; RUN: grep movq %t | count 5
+; RUN: not grep leaq %t
+; RUN: not grep leal %t
+; RUN: not grep movq %t
; IV users in each of the loops from other loops shouldn't cause LSR
; to insert new induction variables. Previously it would create a
diff --git a/test/CodeGen/X86/licm-symbol.ll b/test/CodeGen/X86/licm-symbol.ll
new file mode 100644
index 0000000..d61bbfc
--- /dev/null
+++ b/test/CodeGen/X86/licm-symbol.ll
@@ -0,0 +1,39 @@
+; RUN: llc < %s | FileCheck %s
+
+; MachineLICM should be able to hoist the sF reference out of the loop.
+
+; CHECK: pushl %esi
+; CHECK: subl $8, %esp
+; CHECK: movl $176, %esi
+; CHECK: addl L___sF$non_lazy_ptr, %esi
+; CHECK: .align 4, 0x90
+
+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"
+target triple = "i386-apple-darwin8"
+
+%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.__sFILEX = type opaque
+%struct.__sbuf = type { i8*, i32 }
+%struct.gcov_ctr_summary = type { i32, i32, i64, i64, i64 }
+%struct.gcov_summary = type { i32, [1 x %struct.gcov_ctr_summary] }
+
+@__sF = external global [0 x %struct.FILE] ; <[0 x %struct.FILE]*> [#uses=1]
+
+declare i32 @fprintf(%struct.FILE* nocapture) nounwind
+
+define void @gcov_exit() nounwind {
+entry:
+ br label %bb151
+
+bb151: ; preds = %bb59, %bb56, %bb14
+ br i1 undef, label %bb56, label %bb59
+
+bb56: ; preds = %bb151
+ %t0 = call i32 (%struct.FILE*)* @fprintf(%struct.FILE* getelementptr inbounds ([0 x %struct.FILE]* @__sF, i32 0, i32 2)) nounwind
+ br label %bb151
+
+bb59: ; preds = %bb151
+ %t1 = call i32 (%struct.FILE*)* @fprintf(%struct.FILE* getelementptr inbounds ([0 x %struct.FILE]* @__sF, i32 0, i32 2)) nounwind
+ br label %bb151
+}
+
diff --git a/test/CodeGen/X86/loop-strength-reduce-2.ll b/test/CodeGen/X86/loop-strength-reduce-2.ll
index 30b5114..b546462 100644
--- a/test/CodeGen/X86/loop-strength-reduce-2.ll
+++ b/test/CodeGen/X86/loop-strength-reduce-2.ll
@@ -1,11 +1,24 @@
-; RUN: llc < %s -march=x86 -relocation-model=pic | \
-; RUN: grep {, 4} | count 1
-; RUN: llc < %s -march=x86 | not grep lea
+; RUN: llc < %s -march=x86 -relocation-model=pic | FileCheck %s -check-prefix=PIC
+; RUN: llc < %s -march=x86 -relocation-model=static | FileCheck %s -check-prefix=STATIC
;
; Make sure the common loop invariant A is hoisted up to preheader,
; since too many registers are needed to subsume it into the addressing modes.
; It's safe to sink A in when it's not pic.
+; PIC: align
+; PIC: movl $4, -4([[REG:%e[a-z]+]])
+; PIC: movl $5, ([[REG]])
+; PIC: addl $4, [[REG]]
+; PIC: decl {{%e[[a-z]+}}
+; PIC: jne
+
+; STATIC: align
+; STATIC: movl $4, -4(%ecx)
+; STATIC: movl $5, (%ecx)
+; STATIC: addl $4, %ecx
+; STATIC: decl %eax
+; STATIC: jne
+
@A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2]
define void @test(i32 %row, i32 %N.in) nounwind {
diff --git a/test/CodeGen/X86/loop-strength-reduce-3.ll b/test/CodeGen/X86/loop-strength-reduce-3.ll
index 70c9134..b1c9fb9 100644
--- a/test/CodeGen/X86/loop-strength-reduce-3.ll
+++ b/test/CodeGen/X86/loop-strength-reduce-3.ll
@@ -1,8 +1,11 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin -relocation-model=dynamic-no-pic | \
-; RUN: grep {A+} | count 2
-;
-; Make sure the common loop invariant A is not hoisted up to preheader,
-; since it can be subsumed it into the addressing modes.
+; RUN: llc < %s -mtriple=i386-apple-darwin -relocation-model=dynamic-no-pic | FileCheck %s
+
+; CHECK: align
+; CHECK: movl $4, -4(%ecx)
+; CHECK: movl $5, (%ecx)
+; CHECK: addl $4, %ecx
+; CHECK: decl %eax
+; CHECK: jne
@A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2]
diff --git a/test/CodeGen/X86/loop-strength-reduce.ll b/test/CodeGen/X86/loop-strength-reduce.ll
index 4cb56ca..42c6ac4 100644
--- a/test/CodeGen/X86/loop-strength-reduce.ll
+++ b/test/CodeGen/X86/loop-strength-reduce.ll
@@ -1,8 +1,11 @@
-; RUN: llc < %s -march=x86 -relocation-model=static | \
-; RUN: grep {A+} | count 2
-;
-; Make sure the common loop invariant A is not hoisted up to preheader,
-; since it can be subsumed into the addressing mode in all uses.
+; RUN: llc < %s -march=x86 -relocation-model=static | FileCheck %s
+
+; CHECK: align
+; CHECK: movl $4, -4(%ecx)
+; CHECK: movl $5, (%ecx)
+; CHECK: addl $4, %ecx
+; CHECK: decl %eax
+; CHECK: jne
@A = internal global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2]
diff --git a/test/CodeGen/X86/loop-strength-reduce4.ll b/test/CodeGen/X86/loop-strength-reduce4.ll
index 07e46ec..6c0eb8c 100644
--- a/test/CodeGen/X86/loop-strength-reduce4.ll
+++ b/test/CodeGen/X86/loop-strength-reduce4.ll
@@ -1,5 +1,19 @@
-; RUN: llc < %s -march=x86 | grep cmp | grep 64
-; RUN: llc < %s -march=x86 | not grep inc
+; RUN: llc < %s -march=x86 -relocation-model=static -mtriple=i686-apple-darwin | FileCheck %s -check-prefix=STATIC
+; RUN: llc < %s -march=x86 -relocation-model=pic | FileCheck %s -check-prefix=PIC
+
+; By starting the IV at -64 instead of 0, a cmp is eliminated,
+; as the flags from the add can be used directly.
+
+; STATIC: movl $-64, %ecx
+
+; STATIC: movl %eax, _state+76(%ecx)
+; STATIC: addl $16, %ecx
+; STATIC: jne
+
+; In PIC mode the symbol can't be folded, so the change-compare-stride
+; trick applies.
+
+; PIC: cmpl $64
@state = external global [0 x i32] ; <[0 x i32]*> [#uses=4]
@S = external global [0 x i32] ; <[0 x i32]*> [#uses=4]
diff --git a/test/CodeGen/X86/loop-strength-reduce8.ll b/test/CodeGen/X86/loop-strength-reduce8.ll
index e14cd8a..6b2247d 100644
--- a/test/CodeGen/X86/loop-strength-reduce8.ll
+++ b/test/CodeGen/X86/loop-strength-reduce8.ll
@@ -1,4 +1,10 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin | grep leal | not grep 16
+; RUN: llc < %s -mtriple=i386-apple-darwin | FileCheck %s
+
+; CHECK: leal 16(%eax), %edx
+; CHECK: align
+; CHECK: addl $4, %edx
+; CHECK: decl %ecx
+; CHECK: jne LBB1_2
%struct.CUMULATIVE_ARGS = type { i32, i32, i32, i32, i32, i32, i32 }
%struct.bitmap_element = type { %struct.bitmap_element*, %struct.bitmap_element*, i32, [2 x i64] }
diff --git a/test/CodeGen/X86/lsr-overflow.ll b/test/CodeGen/X86/lsr-overflow.ll
new file mode 100644
index 0000000..0b0214c
--- /dev/null
+++ b/test/CodeGen/X86/lsr-overflow.ll
@@ -0,0 +1,26 @@
+; RUN: llc < %s -march=x86-64 | FileCheck %s
+
+; The comparison uses the pre-inc value, which could lead LSR to
+; try to compute -INT64_MIN.
+
+; CHECK: movabsq $-9223372036854775808, %rax
+; CHECK: cmpq %rax, %rbx
+; CHECK: sete %al
+
+declare i64 @bar()
+
+define i1 @foo() nounwind {
+entry:
+ br label %for.cond.i
+
+for.cond.i:
+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.cond.i ]
+ %t = call i64 @bar()
+ %indvar.next = add i64 %indvar, 1
+ %s = icmp ne i64 %indvar.next, %t
+ br i1 %s, label %for.cond.i, label %__ABContainsLabel.exit
+
+__ABContainsLabel.exit:
+ %cmp = icmp eq i64 %indvar, 9223372036854775807
+ ret i1 %cmp
+}
diff --git a/test/CodeGen/X86/lsr-reuse-trunc.ll b/test/CodeGen/X86/lsr-reuse-trunc.ll
new file mode 100644
index 0000000..d1d7144
--- /dev/null
+++ b/test/CodeGen/X86/lsr-reuse-trunc.ll
@@ -0,0 +1,59 @@
+; RUN: llc < %s -march=x86-64 | FileCheck %s
+
+; Full strength reduction wouldn't reduce register pressure, so LSR should
+; stick with indexing here.
+
+; CHECK: movaps (%rsi,%rax,4), %xmm3
+; CHECK: movaps %xmm3, (%rdi,%rax,4)
+; CHECK: addq $4, %rax
+; CHECK: cmpl %eax, (%rdx)
+; CHECK-NEXT: jg
+
+define void @vvfloorf(float* nocapture %y, float* nocapture %x, i32* nocapture %n) nounwind {
+entry:
+ %0 = load i32* %n, align 4
+ %1 = icmp sgt i32 %0, 0
+ br i1 %1, label %bb, label %return
+
+bb:
+ %indvar = phi i64 [ %indvar.next, %bb ], [ 0, %entry ]
+ %tmp = shl i64 %indvar, 2
+ %scevgep = getelementptr float* %y, i64 %tmp
+ %scevgep9 = bitcast float* %scevgep to <4 x float>*
+ %scevgep10 = getelementptr float* %x, i64 %tmp
+ %scevgep1011 = bitcast float* %scevgep10 to <4 x float>*
+ %2 = load <4 x float>* %scevgep1011, align 16
+ %3 = bitcast <4 x float> %2 to <4 x i32>
+ %4 = and <4 x i32> %3, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
+ %5 = bitcast <4 x i32> %4 to <4 x float>
+ %6 = and <4 x i32> %3, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
+ %7 = tail call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> %5, <4 x float> <float 8.388608e+06, float 8.388608e+06, float 8.388608e+06, float 8.388608e+06>, i8 5) nounwind
+ %tmp.i4 = bitcast <4 x float> %7 to <4 x i32>
+ %8 = xor <4 x i32> %tmp.i4, <i32 -1, i32 -1, i32 -1, i32 -1>
+ %9 = and <4 x i32> %8, <i32 1258291200, i32 1258291200, i32 1258291200, i32 1258291200>
+ %10 = or <4 x i32> %9, %6
+ %11 = bitcast <4 x i32> %10 to <4 x float>
+ %12 = fadd <4 x float> %2, %11
+ %13 = fsub <4 x float> %12, %11
+ %14 = tail call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> %2, <4 x float> %13, i8 1) nounwind
+ %15 = bitcast <4 x float> %14 to <4 x i32>
+ %16 = tail call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %15) nounwind readnone
+ %17 = fadd <4 x float> %13, %16
+ %tmp.i = bitcast <4 x float> %17 to <4 x i32>
+ %18 = or <4 x i32> %tmp.i, %6
+ %19 = bitcast <4 x i32> %18 to <4 x float>
+ store <4 x float> %19, <4 x float>* %scevgep9, align 16
+ %tmp12 = add i64 %tmp, 4
+ %tmp13 = trunc i64 %tmp12 to i32
+ %20 = load i32* %n, align 4
+ %21 = icmp sgt i32 %20, %tmp13
+ %indvar.next = add i64 %indvar, 1
+ br i1 %21, label %bb, label %return
+
+return:
+ ret void
+}
+
+declare <4 x float> @llvm.x86.sse.cmp.ps(<4 x float>, <4 x float>, i8) nounwind readnone
+
+declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>) nounwind readnone
diff --git a/test/CodeGen/X86/lsr-reuse.ll b/test/CodeGen/X86/lsr-reuse.ll
new file mode 100644
index 0000000..2f6fb3f
--- /dev/null
+++ b/test/CodeGen/X86/lsr-reuse.ll
@@ -0,0 +1,442 @@
+; RUN: llc < %s -march=x86-64 -O3 -asm-verbose=false | FileCheck %s
+target datalayout = "e-p:64:64:64"
+target triple = "x86_64-unknown-unknown"
+
+; Full strength reduction reduces register pressure from 5 to 4 here.
+; Instruction selection should use the FLAGS value from the dec for
+; the branch. Scheduling should push the adds upwards.
+
+; CHECK: full_me_0:
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: mulsd (%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @full_me_0(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; Mostly-full strength reduction means we do full strength reduction on all
+; except for the offsets.
+;
+; Given a choice between constant offsets -2048 and 2048, choose the negative
+; value, because at boundary conditions it has a smaller encoding.
+; TODO: That's an over-general heuristic. It would be better for the target
+; to indicate what the encoding cost would be. Then using a 2048 offset
+; would be better on x86-64, since the start value would be 0 instead of
+; 2048.
+
+; CHECK: mostly_full_me_0:
+; CHECK: movsd -2048(%rsi), %xmm0
+; CHECK: mulsd -2048(%rdx), %xmm0
+; CHECK: movsd %xmm0, -2048(%rdi)
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: divsd (%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @mostly_full_me_0(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %j = add i64 %i, 256
+ %Aj = getelementptr inbounds double* %A, i64 %j
+ %Bj = getelementptr inbounds double* %B, i64 %j
+ %Cj = getelementptr inbounds double* %C, i64 %j
+ %t3 = load double* %Bj
+ %t4 = load double* %Cj
+ %o = fdiv double %t3, %t4
+ store double %o, double* %Aj
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; A minor variation on mostly_full_me_0.
+; Prefer to start the indvar at 0.
+
+; CHECK: mostly_full_me_1:
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: mulsd (%rdx), %xmm0
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: movsd -2048(%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: divsd -2048(%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, -2048(%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @mostly_full_me_1(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %j = sub i64 %i, 256
+ %Aj = getelementptr inbounds double* %A, i64 %j
+ %Bj = getelementptr inbounds double* %B, i64 %j
+ %Cj = getelementptr inbounds double* %C, i64 %j
+ %t3 = load double* %Bj
+ %t4 = load double* %Cj
+ %o = fdiv double %t3, %t4
+ store double %o, double* %Aj
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; A slightly less minor variation on mostly_full_me_0.
+
+; CHECK: mostly_full_me_2:
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: mulsd (%rdx), %xmm0
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: movsd -4096(%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: divsd -4096(%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, -4096(%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @mostly_full_me_2(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %k = add i64 %i, 256
+ %Ak = getelementptr inbounds double* %A, i64 %k
+ %Bk = getelementptr inbounds double* %B, i64 %k
+ %Ck = getelementptr inbounds double* %C, i64 %k
+ %t1 = load double* %Bk
+ %t2 = load double* %Ck
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ak
+ %j = sub i64 %i, 256
+ %Aj = getelementptr inbounds double* %A, i64 %j
+ %Bj = getelementptr inbounds double* %B, i64 %j
+ %Cj = getelementptr inbounds double* %C, i64 %j
+ %t3 = load double* %Bj
+ %t4 = load double* %Cj
+ %o = fdiv double %t3, %t4
+ store double %o, double* %Aj
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; In this test, the counting IV exit value is used, so full strength reduction
+; would not reduce register pressure. IndVarSimplify ought to simplify such
+; cases away, but it's useful here to verify that LSR's register pressure
+; heuristics are working as expected.
+
+; CHECK: count_me_0:
+; CHECK: movsd (%rsi,%rax,8), %xmm0
+; CHECK: mulsd (%rdx,%rax,8), %xmm0
+; CHECK: movsd %xmm0, (%rdi,%rax,8)
+; CHECK: incq %rax
+; CHECK: cmpq %rax, %rcx
+; CHECK: jne
+
+define i64 @count_me_0(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ %q = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+ ret i64 %q
+}
+
+; In this test, the trip count value is used, so full strength reduction
+; would not reduce register pressure.
+; (though it would reduce register pressure inside the loop...)
+
+; CHECK: count_me_1:
+; CHECK: movsd (%rsi,%rax,8), %xmm0
+; CHECK: mulsd (%rdx,%rax,8), %xmm0
+; CHECK: movsd %xmm0, (%rdi,%rax,8)
+; CHECK: incq %rax
+; CHECK: cmpq %rax, %rcx
+; CHECK: jne
+
+define i64 @count_me_1(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ %q = phi i64 [ 0, %entry ], [ %n, %loop ]
+ ret i64 %q
+}
+
+; Full strength reduction doesn't save any registers here because the
+; loop tripcount is a constant.
+
+; CHECK: count_me_2:
+; CHECK: movl $10, %eax
+; CHECK: align
+; CHECK: BB7_1:
+; CHECK: movsd -40(%rdi,%rax,8), %xmm0
+; CHECK: addsd -40(%rsi,%rax,8), %xmm0
+; CHECK: movsd %xmm0, -40(%rdx,%rax,8)
+; CHECK: movsd (%rdi,%rax,8), %xmm0
+; CHECK: subsd (%rsi,%rax,8), %xmm0
+; CHECK: movsd %xmm0, (%rdx,%rax,8)
+; CHECK: incq %rax
+; CHECK: cmpq $5010, %rax
+; CHECK: jne
+
+define void @count_me_2(double* nocapture %A, double* nocapture %B, double* nocapture %C) nounwind {
+entry:
+ br label %loop
+
+loop:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+ %i5 = add i64 %i, 5
+ %Ai = getelementptr double* %A, i64 %i5
+ %t2 = load double* %Ai
+ %Bi = getelementptr double* %B, i64 %i5
+ %t4 = load double* %Bi
+ %t5 = fadd double %t2, %t4
+ %Ci = getelementptr double* %C, i64 %i5
+ store double %t5, double* %Ci
+ %i10 = add i64 %i, 10
+ %Ai10 = getelementptr double* %A, i64 %i10
+ %t9 = load double* %Ai10
+ %Bi10 = getelementptr double* %B, i64 %i10
+ %t11 = load double* %Bi10
+ %t12 = fsub double %t9, %t11
+ %Ci10 = getelementptr double* %C, i64 %i10
+ store double %t12, double* %Ci10
+ %i.next = add i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, 5000
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; This should be fully strength-reduced to reduce register pressure.
+
+; CHECK: full_me_1:
+; CHECK: align
+; CHECK: BB8_1:
+; CHECK: movsd (%rdi), %xmm0
+; CHECK: addsd (%rsi), %xmm0
+; CHECK: movsd %xmm0, (%rdx)
+; CHECK: movsd 40(%rdi), %xmm0
+; CHECK: addq $8, %rdi
+; CHECK: subsd 40(%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: movsd %xmm0, 40(%rdx)
+; CHECK: addq $8, %rdx
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @full_me_1(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ br label %loop
+
+loop:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+ %i5 = add i64 %i, 5
+ %Ai = getelementptr double* %A, i64 %i5
+ %t2 = load double* %Ai
+ %Bi = getelementptr double* %B, i64 %i5
+ %t4 = load double* %Bi
+ %t5 = fadd double %t2, %t4
+ %Ci = getelementptr double* %C, i64 %i5
+ store double %t5, double* %Ci
+ %i10 = add i64 %i, 10
+ %Ai10 = getelementptr double* %A, i64 %i10
+ %t9 = load double* %Ai10
+ %Bi10 = getelementptr double* %B, i64 %i10
+ %t11 = load double* %Bi10
+ %t12 = fsub double %t9, %t11
+ %Ci10 = getelementptr double* %C, i64 %i10
+ store double %t12, double* %Ci10
+ %i.next = add i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; This is a variation on full_me_0 in which the 0,+,1 induction variable
+; has a non-address use, pinning that value in a register.
+
+; CHECK: count_me_3:
+; CHECK: call
+; CHECK: movsd (%r15,%r13,8), %xmm0
+; CHECK: mulsd (%r14,%r13,8), %xmm0
+; CHECK: movsd %xmm0, (%r12,%r13,8)
+; CHECK: incq %r13
+; CHECK: cmpq %r13, %rbx
+; CHECK: jne
+
+declare void @use(i64)
+
+define void @count_me_3(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ call void @use(i64 %i)
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; LSR should use only one indvar for the inner loop.
+; rdar://7657764
+
+; CHECK: asd:
+; CHECK: BB10_5:
+; CHECK-NEXT: addl (%r{{[^,]*}},%rdi,4), %e
+; CHECK-NEXT: incq %rdi
+; CHECK-NEXT: cmpq %rdi, %r{{[^,]*}}
+; CHECK-NEXT: jg
+
+%struct.anon = type { i32, [4200 x i32] }
+
+@bars = common global [123123 x %struct.anon] zeroinitializer, align 32 ; <[123123 x %struct.anon]*> [#uses=2]
+
+define i32 @asd(i32 %n) nounwind readonly {
+entry:
+ %0 = icmp sgt i32 %n, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb.nph14, label %bb5
+
+bb.nph14: ; preds = %entry
+ %tmp18 = zext i32 %n to i64 ; <i64> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb3, %bb.nph14
+ %indvar16 = phi i64 [ 0, %bb.nph14 ], [ %indvar.next17, %bb3 ] ; <i64> [#uses=3]
+ %s.113 = phi i32 [ 0, %bb.nph14 ], [ %s.0.lcssa, %bb3 ] ; <i32> [#uses=2]
+ %scevgep2526 = getelementptr [123123 x %struct.anon]* @bars, i64 0, i64 %indvar16, i32 0 ; <i32*> [#uses=1]
+ %1 = load i32* %scevgep2526, align 4 ; <i32> [#uses=2]
+ %2 = icmp sgt i32 %1, 0 ; <i1> [#uses=1]
+ br i1 %2, label %bb.nph, label %bb3
+
+bb.nph: ; preds = %bb
+ %tmp23 = sext i32 %1 to i64 ; <i64> [#uses=1]
+ br label %bb1
+
+bb1: ; preds = %bb.nph, %bb1
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp19, %bb1 ] ; <i64> [#uses=2]
+ %s.07 = phi i32 [ %s.113, %bb.nph ], [ %4, %bb1 ] ; <i32> [#uses=1]
+ %c.08 = getelementptr [123123 x %struct.anon]* @bars, i64 0, i64 %indvar16, i32 1, i64 %indvar ; <i32*> [#uses=1]
+ %3 = load i32* %c.08, align 4 ; <i32> [#uses=1]
+ %4 = add nsw i32 %3, %s.07 ; <i32> [#uses=2]
+ %tmp19 = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %5 = icmp sgt i64 %tmp23, %tmp19 ; <i1> [#uses=1]
+ br i1 %5, label %bb1, label %bb3
+
+bb3: ; preds = %bb1, %bb
+ %s.0.lcssa = phi i32 [ %s.113, %bb ], [ %4, %bb1 ] ; <i32> [#uses=2]
+ %indvar.next17 = add i64 %indvar16, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %indvar.next17, %tmp18 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb5, label %bb
+
+bb5: ; preds = %bb3, %entry
+ %s.1.lcssa = phi i32 [ 0, %entry ], [ %s.0.lcssa, %bb3 ] ; <i32> [#uses=1]
+ ret i32 %s.1.lcssa
+}
diff --git a/test/CodeGen/X86/lsr-wrap.ll b/test/CodeGen/X86/lsr-wrap.ll
new file mode 100644
index 0000000..ec8db50
--- /dev/null
+++ b/test/CodeGen/X86/lsr-wrap.ll
@@ -0,0 +1,37 @@
+; RUN: llc -march=x86-64 < %s | FileCheck %s
+
+; LSR would like to use a single IV for both of these, however it's
+; not safe due to wraparound.
+
+; CHECK: addb $-4, %r
+; CHECK: decw %
+
+@g_19 = common global i32 0 ; <i32*> [#uses=2]
+
+declare i32 @func_8(i8 zeroext) nounwind
+
+declare i32 @func_3(i8 signext) nounwind
+
+define void @func_1() nounwind {
+entry:
+ br label %bb
+
+bb: ; preds = %bb, %entry
+ %indvar = phi i16 [ 0, %entry ], [ %indvar.next, %bb ] ; <i16> [#uses=2]
+ %tmp = sub i16 0, %indvar ; <i16> [#uses=1]
+ %tmp27 = trunc i16 %tmp to i8 ; <i8> [#uses=1]
+ %tmp1 = load i32* @g_19, align 4 ; <i32> [#uses=2]
+ %tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1]
+ store i32 %tmp2, i32* @g_19, align 4
+ %tmp3 = trunc i32 %tmp1 to i8 ; <i8> [#uses=1]
+ %tmp4 = tail call i32 @func_8(i8 zeroext %tmp3) nounwind ; <i32> [#uses=0]
+ %tmp5 = shl i8 %tmp27, 2 ; <i8> [#uses=1]
+ %tmp6 = add i8 %tmp5, -112 ; <i8> [#uses=1]
+ %tmp7 = tail call i32 @func_3(i8 signext %tmp6) nounwind ; <i32> [#uses=0]
+ %indvar.next = add i16 %indvar, 1 ; <i16> [#uses=2]
+ %exitcond = icmp eq i16 %indvar.next, -28 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb
+ ret void
+}
diff --git a/test/CodeGen/X86/masked-iv-safe.ll b/test/CodeGen/X86/masked-iv-safe.ll
index bc493bd..0b4d73a 100644
--- a/test/CodeGen/X86/masked-iv-safe.ll
+++ b/test/CodeGen/X86/masked-iv-safe.ll
@@ -169,7 +169,7 @@ loop:
%indvar.i24 = and i64 %indvar, 16777215
%t3 = getelementptr double* %d, i64 %indvar.i24
%t4 = load double* %t3
- %t5 = fmul double %t4, 2.3
+ %t5 = fdiv double %t4, 2.3
store double %t5, double* %t3
%t6 = getelementptr double* %d, i64 %indvar
%t7 = load double* %t6
@@ -199,7 +199,7 @@ loop:
%indvar.i24 = ashr i64 %s1, 24
%t3 = getelementptr double* %d, i64 %indvar.i24
%t4 = load double* %t3
- %t5 = fmul double %t4, 2.3
+ %t5 = fdiv double %t4, 2.3
store double %t5, double* %t3
%t6 = getelementptr double* %d, i64 %indvar
%t7 = load double* %t6
@@ -229,7 +229,7 @@ loop:
%indvar.i24 = ashr i64 %s1, 24
%t3 = getelementptr double* %d, i64 %indvar.i24
%t4 = load double* %t3
- %t5 = fmul double %t4, 2.3
+ %t5 = fdiv double %t4, 2.3
store double %t5, double* %t3
%t6 = getelementptr double* %d, i64 %indvar
%t7 = load double* %t6
diff --git a/test/CodeGen/X86/omit-label.ll b/test/CodeGen/X86/omit-label.ll
deleted file mode 100644
index 0ec03eb..0000000
--- a/test/CodeGen/X86/omit-label.ll
+++ /dev/null
@@ -1,57 +0,0 @@
-; RUN: llc < %s -asm-verbose=false -mtriple=x86_64-linux-gnu | FileCheck %s
-; PR4126
-; PR4732
-
-; Don't omit these labels' definitions.
-
-; CHECK: bux:
-; CHECK: LBB1_1:
-
-define void @bux(i32 %p_53) nounwind optsize {
-entry:
- %0 = icmp eq i32 %p_53, 0 ; <i1> [#uses=1]
- %1 = icmp sgt i32 %p_53, 0 ; <i1> [#uses=1]
- %or.cond = and i1 %0, %1 ; <i1> [#uses=1]
- br i1 %or.cond, label %bb.i, label %bb3
-
-bb.i: ; preds = %entry
- %2 = add i32 %p_53, 1 ; <i32> [#uses=1]
- %3 = icmp slt i32 %2, 0 ; <i1> [#uses=0]
- br label %bb3
-
-bb3: ; preds = %bb.i, %entry
- %4 = tail call i32 (...)* @baz(i32 0) nounwind ; <i32> [#uses=0]
- ret void
-}
-
-declare i32 @baz(...)
-
-; Don't omit this label in the assembly output.
-; CHECK: int321:
-; CHECK: LBB2_1
-; CHECK: LBB2_1
-; CHECK: LBB2_1:
-
-define void @int321(i8 signext %p_103, i32 %uint8p_104) nounwind readnone {
-entry:
- %tobool = icmp eq i8 %p_103, 0 ; <i1> [#uses=1]
- %cmp.i = icmp sgt i8 %p_103, 0 ; <i1> [#uses=1]
- %or.cond = and i1 %tobool, %cmp.i ; <i1> [#uses=1]
- br i1 %or.cond, label %land.end.i, label %for.cond.preheader
-
-land.end.i: ; preds = %entry
- %conv3.i = sext i8 %p_103 to i32 ; <i32> [#uses=1]
- %div.i = sdiv i32 1, %conv3.i ; <i32> [#uses=1]
- %tobool.i = icmp eq i32 %div.i, -2147483647 ; <i1> [#uses=0]
- br label %for.cond.preheader
-
-for.cond.preheader: ; preds = %land.end.i, %entry
- %cmp = icmp sgt i8 %p_103, 1 ; <i1> [#uses=1]
- br i1 %cmp, label %for.end.split, label %for.cond
-
-for.cond: ; preds = %for.cond.preheader, %for.cond
- br label %for.cond
-
-for.end.split: ; preds = %for.cond.preheader
- ret void
-}
diff --git a/test/CodeGen/X86/pr1505b.ll b/test/CodeGen/X86/pr1505b.ll
index 12736cd..6a08dae 100644
--- a/test/CodeGen/X86/pr1505b.ll
+++ b/test/CodeGen/X86/pr1505b.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -mcpu=i486 | grep fstpl | count 4
-; RUN: llc < %s -mcpu=i486 | grep fstps | count 3
+; RUN: llc < %s -mcpu=i486 | grep fstpl | count 5
+; RUN: llc < %s -mcpu=i486 | grep fstps | count 2
; PR1505
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"
diff --git a/test/CodeGen/X86/pr3495-2.ll b/test/CodeGen/X86/pr3495-2.ll
index 71aa5a0..98c064a 100644
--- a/test/CodeGen/X86/pr3495-2.ll
+++ b/test/CodeGen/X86/pr3495-2.ll
@@ -1,4 +1,8 @@
-; RUN: llc < %s -march=x86 -relocation-model=pic -disable-fp-elim -stats |& grep {Number of reloads omited}
+; RUN: llc < %s -march=x86 -relocation-model=pic -disable-fp-elim -stats |& grep {Number of loads added} | grep 1
+; PR3495
+;
+; This test may not be testing what it was supposed to test.
+; It used to have two spills and four reloads, but not it only has one spill and one reload.
target datalayout = "e-p:32:32:32"
target triple = "i386-apple-darwin9.6"
diff --git a/test/CodeGen/X86/pr3495.ll b/test/CodeGen/X86/pr3495.ll
index 1795970..e84a84f 100644
--- a/test/CodeGen/X86/pr3495.ll
+++ b/test/CodeGen/X86/pr3495.ll
@@ -1,8 +1,7 @@
; 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
+; RUN: llc < %s -march=x86 -stats |& grep {Number of machine instrs printed} | grep 34
; PR3495
-; The loop reversal kicks in once here, resulting in one fewer instruction.
target triple = "i386-pc-linux-gnu"
@x = external global [8 x i32], align 32 ; <[8 x i32]*> [#uses=1]
diff --git a/test/CodeGen/X86/pre-split8.ll b/test/CodeGen/X86/pre-split8.ll
index ea4b949..0684bd0 100644
--- a/test/CodeGen/X86/pre-split8.ll
+++ b/test/CodeGen/X86/pre-split8.ll
@@ -20,7 +20,7 @@ bb: ; preds = %bb9.i, %entry
bb9.i: ; preds = %bb
%2 = fsub double %.rle4, %0 ; <double> [#uses=0]
- %3 = tail call double @asin(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
+ %3 = tail call double @asin(double %.rle4) nounwind readonly ; <double> [#uses=0]
%4 = fmul double 0.000000e+00, %0 ; <double> [#uses=1]
%5 = tail call double @tan(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
%6 = fmul double %4, 0.000000e+00 ; <double> [#uses=1]
diff --git a/test/CodeGen/X86/pre-split9.ll b/test/CodeGen/X86/pre-split9.ll
index c27d925..86dda33 100644
--- a/test/CodeGen/X86/pre-split9.ll
+++ b/test/CodeGen/X86/pre-split9.ll
@@ -22,7 +22,7 @@ bb: ; preds = %bb9.i, %entry
bb9.i: ; preds = %bb
%2 = fsub double %.rle4, %0 ; <double> [#uses=0]
- %3 = tail call double @asin(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
+ %3 = tail call double @asin(double %.rle4) nounwind readonly ; <double> [#uses=0]
%4 = tail call double @sin(double 0.000000e+00) nounwind readonly ; <double> [#uses=1]
%5 = fmul double %4, %0 ; <double> [#uses=1]
%6 = tail call double @tan(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
diff --git a/test/CodeGen/X86/ptrtoint-constexpr.ll b/test/CodeGen/X86/ptrtoint-constexpr.ll
index dd97905..d1cb34b 100644
--- a/test/CodeGen/X86/ptrtoint-constexpr.ll
+++ b/test/CodeGen/X86/ptrtoint-constexpr.ll
@@ -9,6 +9,6 @@
; CHECK: .globl x
; CHECK: x:
-; CHECK: .quad 3
+; CHECK: .quad ((0+1)&4294967295)*3
@x = global i64 mul (i64 3, i64 ptrtoint (i2* getelementptr (i2* null, i64 1) to i64))
diff --git a/test/CodeGen/X86/scalar_widen_div.ll b/test/CodeGen/X86/scalar_widen_div.ll
index fc67e44..77f320f 100644
--- a/test/CodeGen/X86/scalar_widen_div.ll
+++ b/test/CodeGen/X86/scalar_widen_div.ll
@@ -152,3 +152,32 @@ define <5 x i64> @test_ulong_rem(<5 x i64> %num, <5 x i64> %rem) {
%rem.r = urem <5 x i64> %num, %rem
ret <5 x i64> %rem.r
}
+
+define void @test_int_div(<3 x i32>* %dest, <3 x i32>* %old, i32 %n) {
+; CHECK: idivl
+; CHECK: idivl
+; CHECK: idivl
+; CHECK-NOT: idivl
+; CHECK: ret
+entry:
+ %cmp13 = icmp sgt i32 %n, 0
+ br i1 %cmp13, label %bb.nph, label %for.end
+
+bb.nph:
+ br label %for.body
+
+for.body:
+ %i.014 = phi i32 [ 0, %bb.nph ], [ %inc, %for.body ]
+ %arrayidx11 = getelementptr <3 x i32>* %dest, i32 %i.014
+ %tmp4 = load <3 x i32>* %arrayidx11 ; <<3 x i32>> [#uses=1]
+ %arrayidx7 = getelementptr inbounds <3 x i32>* %old, i32 %i.014
+ %tmp8 = load <3 x i32>* %arrayidx7 ; <<3 x i32>> [#uses=1]
+ %div = sdiv <3 x i32> %tmp4, %tmp8
+ store <3 x i32> %div, <3 x i32>* %arrayidx11
+ %inc = add nsw i32 %i.014, 1
+ %exitcond = icmp eq i32 %inc, %n
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
diff --git a/test/CodeGen/X86/sse-minmax.ll b/test/CodeGen/X86/sse-minmax.ll
index 17ffb5e..19fbed0 100644
--- a/test/CodeGen/X86/sse-minmax.ll
+++ b/test/CodeGen/X86/sse-minmax.ll
@@ -1,17 +1,26 @@
; RUN: llc < %s -march=x86-64 -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -march=x86-64 -asm-verbose=false -enable-unsafe-fp-math | FileCheck -check-prefix=UNSAFE %s
+; RUN: llc < %s -march=x86-64 -asm-verbose=false -enable-finite-only-fp-math | FileCheck -check-prefix=FINITE %s
; Some of these patterns can be matched as SSE min or max. Some of
; then can be matched provided that the operands are swapped.
; Some of them can't be matched at all and require a comparison
; and a conditional branch.
-; The naming convention is {,x_}{o,u}{gt,lt,ge,le}{,_inverse}
+; The naming convention is {,x_,y_}{o,u}{gt,lt,ge,le}{,_inverse}
; x_ : use 0.0 instead of %y
+; y_ : use -0.0 instead of %y
; _inverse : swap the arms of the select.
; CHECK: ogt:
; CHECK-NEXT: maxsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: ogt:
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ogt:
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ogt(double %x, double %y) nounwind {
%c = fcmp ogt double %x, %y
%d = select i1 %c, double %x, double %y
@@ -21,6 +30,12 @@ define double @ogt(double %x, double %y) nounwind {
; CHECK: olt:
; CHECK-NEXT: minsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: olt:
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: olt:
+; FINITE-NEXT: minsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @olt(double %x, double %y) nounwind {
%c = fcmp olt double %x, %y
%d = select i1 %c, double %x, double %y
@@ -31,6 +46,14 @@ define double @olt(double %x, double %y) nounwind {
; CHECK-NEXT: minsd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: ogt_inverse:
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ogt_inverse:
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ogt_inverse(double %x, double %y) nounwind {
%c = fcmp ogt double %x, %y
%d = select i1 %c, double %y, double %x
@@ -41,6 +64,14 @@ define double @ogt_inverse(double %x, double %y) nounwind {
; CHECK-NEXT: maxsd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: olt_inverse:
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: olt_inverse:
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @olt_inverse(double %x, double %y) nounwind {
%c = fcmp olt double %x, %y
%d = select i1 %c, double %y, double %x
@@ -49,6 +80,12 @@ define double @olt_inverse(double %x, double %y) nounwind {
; CHECK: oge:
; CHECK-NEXT: ucomisd %xmm1, %xmm0
+; UNSAFE: oge:
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: oge:
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @oge(double %x, double %y) nounwind {
%c = fcmp oge double %x, %y
%d = select i1 %c, double %x, double %y
@@ -57,6 +94,10 @@ define double @oge(double %x, double %y) nounwind {
; CHECK: ole:
; CHECK-NEXT: ucomisd %xmm0, %xmm1
+; UNSAFE: ole:
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; FINITE: ole:
+; FINITE-NEXT: minsd %xmm1, %xmm0
define double @ole(double %x, double %y) nounwind {
%c = fcmp ole double %x, %y
%d = select i1 %c, double %x, double %y
@@ -65,6 +106,14 @@ define double @ole(double %x, double %y) nounwind {
; CHECK: oge_inverse:
; CHECK-NEXT: ucomisd %xmm1, %xmm0
+; UNSAFE: oge_inverse:
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: oge_inverse:
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @oge_inverse(double %x, double %y) nounwind {
%c = fcmp oge double %x, %y
%d = select i1 %c, double %y, double %x
@@ -73,6 +122,14 @@ define double @oge_inverse(double %x, double %y) nounwind {
; CHECK: ole_inverse:
; CHECK-NEXT: ucomisd %xmm0, %xmm1
+; UNSAFE: ole_inverse:
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ole_inverse:
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ole_inverse(double %x, double %y) nounwind {
%c = fcmp ole double %x, %y
%d = select i1 %c, double %y, double %x
@@ -83,6 +140,14 @@ define double @ole_inverse(double %x, double %y) nounwind {
; CHECK-NEXT: pxor %xmm1, %xmm1
; CHECK-NEXT: maxsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_ogt:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ogt:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ogt(double %x) nounwind {
%c = fcmp ogt double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -93,6 +158,14 @@ define double @x_ogt(double %x) nounwind {
; CHECK-NEXT: pxor %xmm1, %xmm1
; CHECK-NEXT: minsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_olt:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_olt:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_olt(double %x) nounwind {
%c = fcmp olt double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -104,6 +177,16 @@ define double @x_olt(double %x) nounwind {
; CHECK-NEXT: minsd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_ogt_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ogt_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ogt_inverse(double %x) nounwind {
%c = fcmp ogt double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
@@ -115,6 +198,16 @@ define double @x_ogt_inverse(double %x) nounwind {
; CHECK-NEXT: maxsd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_olt_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_olt_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_olt_inverse(double %x) nounwind {
%c = fcmp olt double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
@@ -122,9 +215,15 @@ define double @x_olt_inverse(double %x) nounwind {
}
; CHECK: x_oge:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: maxsd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: x_oge:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_oge:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_oge(double %x) nounwind {
%c = fcmp oge double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -132,9 +231,15 @@ define double @x_oge(double %x) nounwind {
}
; CHECK: x_ole:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: minsd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: x_ole:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ole:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ole(double %x) nounwind {
%c = fcmp ole double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -142,10 +247,17 @@ define double @x_ole(double %x) nounwind {
}
; CHECK: x_oge_inverse:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: minsd %xmm0, %xmm1
-; CHECK-NEXT: movapd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: x_oge_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_oge_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_oge_inverse(double %x) nounwind {
%c = fcmp oge double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
@@ -153,10 +265,17 @@ define double @x_oge_inverse(double %x) nounwind {
}
; CHECK: x_ole_inverse:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: maxsd %xmm0, %xmm1
-; CHECK-NEXT: movapd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: x_ole_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ole_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ole_inverse(double %x) nounwind {
%c = fcmp ole double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
@@ -164,7 +283,13 @@ define double @x_ole_inverse(double %x) nounwind {
}
; CHECK: ugt:
-; CHECK-NEXT: ucomisd %xmm0, %xmm1
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: ugt:
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ugt:
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ugt(double %x, double %y) nounwind {
%c = fcmp ugt double %x, %y
%d = select i1 %c, double %x, double %y
@@ -172,7 +297,13 @@ define double @ugt(double %x, double %y) nounwind {
}
; CHECK: ult:
-; CHECK-NEXT: ucomisd %xmm1, %xmm0
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: ult:
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ult:
+; FINITE-NEXT: minsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ult(double %x, double %y) nounwind {
%c = fcmp ult double %x, %y
%d = select i1 %c, double %x, double %y
@@ -180,7 +311,15 @@ define double @ult(double %x, double %y) nounwind {
}
; CHECK: ugt_inverse:
-; CHECK-NEXT: ucomisd %xmm0, %xmm1
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: ugt_inverse:
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ugt_inverse:
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ugt_inverse(double %x, double %y) nounwind {
%c = fcmp ugt double %x, %y
%d = select i1 %c, double %y, double %x
@@ -188,7 +327,15 @@ define double @ugt_inverse(double %x, double %y) nounwind {
}
; CHECK: ult_inverse:
-; CHECK-NEXT: ucomisd %xmm1, %xmm0
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: ult_inverse:
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ult_inverse:
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ult_inverse(double %x, double %y) nounwind {
%c = fcmp ult double %x, %y
%d = select i1 %c, double %y, double %x
@@ -196,9 +343,15 @@ define double @ult_inverse(double %x, double %y) nounwind {
}
; CHECK: uge:
-; CHECK-NEXT: maxsd %xmm0, %xmm1
-; CHECK-NEXT: movapd %xmm1, %xmm0
+; CHECK-NEXT: maxsd %xmm0, %xmm1
+; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: uge:
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: uge:
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @uge(double %x, double %y) nounwind {
%c = fcmp uge double %x, %y
%d = select i1 %c, double %x, double %y
@@ -209,6 +362,12 @@ define double @uge(double %x, double %y) nounwind {
; CHECK-NEXT: minsd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: ule:
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ule:
+; FINITE-NEXT: minsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ule(double %x, double %y) nounwind {
%c = fcmp ule double %x, %y
%d = select i1 %c, double %x, double %y
@@ -218,6 +377,14 @@ define double @ule(double %x, double %y) nounwind {
; CHECK: uge_inverse:
; CHECK-NEXT: minsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: uge_inverse:
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: uge_inverse:
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @uge_inverse(double %x, double %y) nounwind {
%c = fcmp uge double %x, %y
%d = select i1 %c, double %y, double %x
@@ -227,6 +394,14 @@ define double @uge_inverse(double %x, double %y) nounwind {
; CHECK: ule_inverse:
; CHECK-NEXT: maxsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: ule_inverse:
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: ule_inverse:
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @ule_inverse(double %x, double %y) nounwind {
%c = fcmp ule double %x, %y
%d = select i1 %c, double %y, double %x
@@ -234,10 +409,15 @@ define double @ule_inverse(double %x, double %y) nounwind {
}
; CHECK: x_ugt:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: maxsd %xmm0, %xmm1
-; CHECK-NEXT: movapd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: x_ugt:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ugt:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ugt(double %x) nounwind {
%c = fcmp ugt double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -245,10 +425,15 @@ define double @x_ugt(double %x) nounwind {
}
; CHECK: x_ult:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: minsd %xmm0, %xmm1
-; CHECK-NEXT: movapd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: x_ult:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ult:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ult(double %x) nounwind {
%c = fcmp ult double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -256,9 +441,17 @@ define double @x_ult(double %x) nounwind {
}
; CHECK: x_ugt_inverse:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: minsd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: x_ugt_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ugt_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ugt_inverse(double %x) nounwind {
%c = fcmp ugt double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
@@ -266,9 +459,17 @@ define double @x_ugt_inverse(double %x) nounwind {
}
; CHECK: x_ult_inverse:
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: maxsd %xmm1, %xmm0
-; CHECK-NEXT: ret
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: x_ult_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ult_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ult_inverse(double %x) nounwind {
%c = fcmp ult double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
@@ -280,6 +481,14 @@ define double @x_ult_inverse(double %x) nounwind {
; CHECK-NEXT: maxsd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_uge:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_uge:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_uge(double %x) nounwind {
%c = fcmp uge double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -291,6 +500,14 @@ define double @x_uge(double %x) nounwind {
; CHECK-NEXT: minsd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_ule:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ule:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ule(double %x) nounwind {
%c = fcmp ule double %x, 0.000000e+00
%d = select i1 %c, double %x, double 0.000000e+00
@@ -301,6 +518,16 @@ define double @x_ule(double %x) nounwind {
; CHECK-NEXT: pxor %xmm1, %xmm1
; CHECK-NEXT: minsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_uge_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_uge_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_uge_inverse(double %x) nounwind {
%c = fcmp uge double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
@@ -311,16 +538,301 @@ define double @x_uge_inverse(double %x) nounwind {
; CHECK-NEXT: pxor %xmm1, %xmm1
; CHECK-NEXT: maxsd %xmm1, %xmm0
; CHECK-NEXT: ret
+; UNSAFE: x_ule_inverse:
+; UNSAFE-NEXT: pxor %xmm1, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: x_ule_inverse:
+; FINITE-NEXT: pxor %xmm1, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
define double @x_ule_inverse(double %x) nounwind {
%c = fcmp ule double %x, 0.000000e+00
%d = select i1 %c, double 0.000000e+00, double %x
ret double %d
}
+; CHECK: y_ogt:
+; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_ogt:
+; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ogt:
+; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_ogt(double %x) nounwind {
+ %c = fcmp ogt double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_olt:
+; CHECK-NEXT: minsd {{[^,]*}}, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_olt:
+; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_olt:
+; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_olt(double %x) nounwind {
+ %c = fcmp olt double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_ogt_inverse:
+; CHECK-NEXT: movsd {{[^,]*}}, %xmm1
+; CHECK-NEXT: minsd %xmm0, %xmm1
+; CHECK-NEXT: movapd %xmm1, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_ogt_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ogt_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_ogt_inverse(double %x) nounwind {
+ %c = fcmp ogt double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
+
+; CHECK: y_olt_inverse:
+; CHECK-NEXT: movsd {{[^,]*}}, %xmm1
+; CHECK-NEXT: maxsd %xmm0, %xmm1
+; CHECK-NEXT: movapd %xmm1, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_olt_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_olt_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_olt_inverse(double %x) nounwind {
+ %c = fcmp olt double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
+
+; CHECK: y_oge:
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: y_oge:
+; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_oge:
+; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_oge(double %x) nounwind {
+ %c = fcmp oge double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_ole:
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: y_ole:
+; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ole:
+; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_ole(double %x) nounwind {
+ %c = fcmp ole double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_oge_inverse:
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: y_oge_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_oge_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_oge_inverse(double %x) nounwind {
+ %c = fcmp oge double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
+
+; CHECK: y_ole_inverse:
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: y_ole_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ole_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_ole_inverse(double %x) nounwind {
+ %c = fcmp ole double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
+
+; CHECK: y_ugt:
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: y_ugt:
+; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ugt:
+; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_ugt(double %x) nounwind {
+ %c = fcmp ugt double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_ult:
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: y_ult:
+; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ult:
+; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_ult(double %x) nounwind {
+ %c = fcmp ult double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_ugt_inverse:
+; CHECK: ucomisd %xmm0, %xmm1
+; UNSAFE: y_ugt_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ugt_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_ugt_inverse(double %x) nounwind {
+ %c = fcmp ugt double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
+
+; CHECK: y_ult_inverse:
+; CHECK: ucomisd %xmm1, %xmm0
+; UNSAFE: y_ult_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ult_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_ult_inverse(double %x) nounwind {
+ %c = fcmp ult double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
+
+; CHECK: y_uge:
+; CHECK-NEXT: movsd {{[^,]*}}, %xmm1
+; CHECK-NEXT: maxsd %xmm0, %xmm1
+; CHECK-NEXT: movapd %xmm1, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_uge:
+; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_uge:
+; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_uge(double %x) nounwind {
+ %c = fcmp uge double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_ule:
+; CHECK-NEXT: movsd {{[^,]*}}, %xmm1
+; CHECK-NEXT: minsd %xmm0, %xmm1
+; CHECK-NEXT: movapd %xmm1, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_ule:
+; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ule:
+; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
+; FINITE-NEXT: ret
+define double @y_ule(double %x) nounwind {
+ %c = fcmp ule double %x, -0.000000e+00
+ %d = select i1 %c, double %x, double -0.000000e+00
+ ret double %d
+}
+
+; CHECK: y_uge_inverse:
+; CHECK-NEXT: minsd {{[^,]*}}, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_uge_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: minsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_uge_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: minsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_uge_inverse(double %x) nounwind {
+ %c = fcmp uge double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
+
+; CHECK: y_ule_inverse:
+; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0
+; CHECK-NEXT: ret
+; UNSAFE: y_ule_inverse:
+; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
+; UNSAFE-NEXT: maxsd %xmm0, %xmm1
+; UNSAFE-NEXT: movapd %xmm1, %xmm0
+; UNSAFE-NEXT: ret
+; FINITE: y_ule_inverse:
+; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
+; FINITE-NEXT: maxsd %xmm0, %xmm1
+; FINITE-NEXT: movapd %xmm1, %xmm0
+; FINITE-NEXT: ret
+define double @y_ule_inverse(double %x) nounwind {
+ %c = fcmp ule double %x, -0.000000e+00
+ %d = select i1 %c, double -0.000000e+00, double %x
+ ret double %d
+}
; Test a few more misc. cases.
; CHECK: clampTo3k_a:
; CHECK: minsd
+; UNSAFE: clampTo3k_a:
+; UNSAFE: minsd
+; FINITE: clampTo3k_a:
+; FINITE: minsd
define double @clampTo3k_a(double %x) nounwind readnone {
entry:
%0 = fcmp ogt double %x, 3.000000e+03 ; <i1> [#uses=1]
@@ -330,6 +842,10 @@ entry:
; CHECK: clampTo3k_b:
; CHECK: minsd
+; UNSAFE: clampTo3k_b:
+; UNSAFE: minsd
+; FINITE: clampTo3k_b:
+; FINITE: minsd
define double @clampTo3k_b(double %x) nounwind readnone {
entry:
%0 = fcmp uge double %x, 3.000000e+03 ; <i1> [#uses=1]
@@ -339,6 +855,10 @@ entry:
; CHECK: clampTo3k_c:
; CHECK: maxsd
+; UNSAFE: clampTo3k_c:
+; UNSAFE: maxsd
+; FINITE: clampTo3k_c:
+; FINITE: maxsd
define double @clampTo3k_c(double %x) nounwind readnone {
entry:
%0 = fcmp olt double %x, 3.000000e+03 ; <i1> [#uses=1]
@@ -348,6 +868,10 @@ entry:
; CHECK: clampTo3k_d:
; CHECK: maxsd
+; UNSAFE: clampTo3k_d:
+; UNSAFE: maxsd
+; FINITE: clampTo3k_d:
+; FINITE: maxsd
define double @clampTo3k_d(double %x) nounwind readnone {
entry:
%0 = fcmp ule double %x, 3.000000e+03 ; <i1> [#uses=1]
@@ -357,6 +881,10 @@ entry:
; CHECK: clampTo3k_e:
; CHECK: maxsd
+; UNSAFE: clampTo3k_e:
+; UNSAFE: maxsd
+; FINITE: clampTo3k_e:
+; FINITE: maxsd
define double @clampTo3k_e(double %x) nounwind readnone {
entry:
%0 = fcmp olt double %x, 3.000000e+03 ; <i1> [#uses=1]
@@ -366,6 +894,10 @@ entry:
; CHECK: clampTo3k_f:
; CHECK: maxsd
+; UNSAFE: clampTo3k_f:
+; UNSAFE: maxsd
+; FINITE: clampTo3k_f:
+; FINITE: maxsd
define double @clampTo3k_f(double %x) nounwind readnone {
entry:
%0 = fcmp ule double %x, 3.000000e+03 ; <i1> [#uses=1]
@@ -375,6 +907,10 @@ entry:
; CHECK: clampTo3k_g:
; CHECK: minsd
+; UNSAFE: clampTo3k_g:
+; UNSAFE: minsd
+; FINITE: clampTo3k_g:
+; FINITE: minsd
define double @clampTo3k_g(double %x) nounwind readnone {
entry:
%0 = fcmp ogt double %x, 3.000000e+03 ; <i1> [#uses=1]
@@ -384,6 +920,10 @@ entry:
; CHECK: clampTo3k_h:
; CHECK: minsd
+; UNSAFE: clampTo3k_h:
+; UNSAFE: minsd
+; FINITE: clampTo3k_h:
+; FINITE: minsd
define double @clampTo3k_h(double %x) nounwind readnone {
entry:
%0 = fcmp uge double %x, 3.000000e+03 ; <i1> [#uses=1]
diff --git a/test/CodeGen/X86/sse3.ll b/test/CodeGen/X86/sse3.ll
index b2af7c9..921161e 100644
--- a/test/CodeGen/X86/sse3.ll
+++ b/test/CodeGen/X86/sse3.ll
@@ -144,10 +144,9 @@ define void @t9(<4 x float>* %r, <2 x i32>* %A) nounwind {
store <4 x float> %tmp13, <4 x float>* %r
ret void
; X64: t9:
-; X64: movsd (%rsi), %xmm0
-; X64: movaps (%rdi), %xmm1
-; X64: movlhps %xmm0, %xmm1
-; X64: movaps %xmm1, (%rdi)
+; X64: movaps (%rdi), %xmm0
+; X64: movhps (%rsi), %xmm0
+; X64: movaps %xmm0, (%rdi)
; X64: ret
}
diff --git a/test/CodeGen/X86/stack-align.ll b/test/CodeGen/X86/stack-align.ll
index cb65e9b..e971ef7 100644
--- a/test/CodeGen/X86/stack-align.ll
+++ b/test/CodeGen/X86/stack-align.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -relocation-model=static -mcpu=yonah | grep {andpd.*4(%esp), %xmm}
+; RUN: llc < %s -relocation-model=static -realign-stack=1 -mcpu=yonah | FileCheck %s
; The double argument is at 4(esp) which is 16-byte aligned, allowing us to
; fold the load into the andpd.
@@ -12,6 +12,7 @@ entry:
%tmp = getelementptr { double, double }* %z, i32 0, i32 0 ; <double*> [#uses=1]
%tmp1 = load double* %tmp, align 8 ; <double> [#uses=1]
%tmp2 = tail call double @fabs( double %tmp1 ) ; <double> [#uses=1]
+ ; CHECK: andpd{{.*}}4(%esp), %xmm
%tmp3 = load double* @G, align 16 ; <double> [#uses=1]
%tmp4 = tail call double @fabs( double %tmp3 ) ; <double> [#uses=1]
%tmp6 = fadd double %tmp4, %tmp2 ; <double> [#uses=1]
@@ -19,4 +20,20 @@ entry:
ret void
}
+define void @test2() alignstack(16) {
+entry:
+ ; CHECK: andl{{.*}}$-16, %esp
+ ret void
+}
+
+; Use a call to force a spill.
+define <2 x double> @test3(<2 x double> %x, <2 x double> %y) alignstack(32) {
+entry:
+ ; CHECK: andl{{.*}}$-32, %esp
+ call void @test2()
+ %A = mul <2 x double> %x, %y
+ ret <2 x double> %A
+}
+
declare double @fabs(double)
+
diff --git a/test/CodeGen/X86/stack-color-with-reg.ll b/test/CodeGen/X86/stack-color-with-reg.ll
index 7d85818..42e7a39 100644
--- a/test/CodeGen/X86/stack-color-with-reg.ll
+++ b/test/CodeGen/X86/stack-color-with-reg.ll
@@ -1,5 +1,5 @@
; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim -color-ss-with-regs -stats -info-output-file - > %t
-; RUN: grep stackcoloring %t | grep "stack slot refs replaced with reg refs" | grep 14
+; RUN: grep stackcoloring %t | grep "stack slot refs replaced with reg refs" | grep 8
type { [62 x %struct.Bitvec*] } ; type %0
type { i8* } ; type %1
diff --git a/test/CodeGen/X86/stdcall.ll b/test/CodeGen/X86/stdcall.ll
new file mode 100644
index 0000000..70204bc
--- /dev/null
+++ b/test/CodeGen/X86/stdcall.ll
@@ -0,0 +1,16 @@
+; RUN: llc < %s | FileCheck %s
+; PR5851
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-mingw32"
+
+%0 = type { void (...)* }
+
+@B = global %0 { void (...)* bitcast (void ()* @MyFunc to void (...)*) }, align 4
+; CHECK: _B:
+; CHECK: .long _MyFunc@0
+
+define internal x86_stdcallcc void @MyFunc() nounwind {
+entry:
+ ret void
+}
diff --git a/test/CodeGen/X86/store_op_load_fold.ll b/test/CodeGen/X86/store_op_load_fold.ll
index 66d0e47..6e47eb3 100644
--- a/test/CodeGen/X86/store_op_load_fold.ll
+++ b/test/CodeGen/X86/store_op_load_fold.ll
@@ -4,7 +4,7 @@
@X = internal global i16 0 ; <i16*> [#uses=2]
-define void @foo() {
+define void @foo() nounwind {
%tmp.0 = load i16* @X ; <i16> [#uses=1]
%tmp.3 = add i16 %tmp.0, 329 ; <i16> [#uses=1]
store i16 %tmp.3, i16* @X
diff --git a/test/CodeGen/X86/store_op_load_fold2.ll b/test/CodeGen/X86/store_op_load_fold2.ll
index 0ccfe47..46e59e9 100644
--- a/test/CodeGen/X86/store_op_load_fold2.ll
+++ b/test/CodeGen/X86/store_op_load_fold2.ll
@@ -1,21 +1,12 @@
-; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | \
-; RUN: grep {and DWORD PTR} | count 2
+; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | FileCheck %s
target datalayout = "e-p:32:32"
%struct.Macroblock = type { i32, i32, i32, i32, i32, [8 x i32], %struct.Macroblock*, %struct.Macroblock*, i32, [2 x [4 x [4 x [2 x i32]]]], [16 x i8], [16 x i8], i32, i64, [4 x i32], [4 x i32], i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, double, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
-define internal fastcc i32 @dct_chroma(i32 %uv, i32 %cr_cbp) {
-entry:
- br i1 true, label %cond_true2732.preheader, label %cond_true129
-cond_true129: ; preds = %entry
- ret i32 0
+define internal fastcc i32 @dct_chroma(i32 %uv, i32 %cr_cbp) nounwind {
cond_true2732.preheader: ; preds = %entry
%tmp2666 = getelementptr %struct.Macroblock* null, i32 0, i32 13 ; <i64*> [#uses=2]
%tmp2674 = trunc i32 0 to i8 ; <i8> [#uses=1]
- br i1 true, label %cond_true2732.preheader.split.us, label %cond_true2732.preheader.split
-cond_true2732.preheader.split.us: ; preds = %cond_true2732.preheader
- br i1 true, label %cond_true2732.outer.us.us, label %cond_true2732.outer.us
-cond_true2732.outer.us.us: ; preds = %cond_true2732.preheader.split.us
%tmp2667.us.us = load i64* %tmp2666 ; <i64> [#uses=1]
%tmp2670.us.us = load i64* null ; <i64> [#uses=1]
%shift.upgrd.1 = zext i8 %tmp2674 to i64 ; <i64> [#uses=1]
@@ -24,11 +15,10 @@ cond_true2732.outer.us.us: ; preds = %cond_true2732.preheader.split
%tmp2676.us.us = and i64 %tmp2667.us.us, %tmp2675not.us.us ; <i64> [#uses=1]
store i64 %tmp2676.us.us, i64* %tmp2666
ret i32 0
-cond_true2732.outer.us: ; preds = %cond_true2732.preheader.split.us
- ret i32 0
-cond_true2732.preheader.split: ; preds = %cond_true2732.preheader
- ret i32 0
-cond_next2752: ; No predecessors!
- ret i32 0
+
+; CHECK: and {{E..}}, DWORD PTR [360]
+; CHECK: and DWORD PTR [356], {{E..}}
+; CHECK: mov DWORD PTR [360], {{E..}}
+
}
diff --git a/test/CodeGen/X86/tailcall2.ll b/test/CodeGen/X86/tailcall2.ll
index 80bab61..90315fd 100644
--- a/test/CodeGen/X86/tailcall2.ll
+++ b/test/CodeGen/X86/tailcall2.ll
@@ -195,3 +195,24 @@ bb2:
}
declare i32 @foo6(i32, i32, %struct.t* byval align 4)
+
+; rdar://r7717598
+%struct.ns = type { i32, i32 }
+%struct.cp = type { float, float }
+
+define %struct.ns* @t13(%struct.cp* %yy) nounwind ssp {
+; 32: t13:
+; 32-NOT: jmp
+; 32: call
+; 32: ret
+
+; 64: t13:
+; 64-NOT: jmp
+; 64: call
+; 64: ret
+entry:
+ %0 = tail call fastcc %struct.ns* @foo7(%struct.cp* byval align 4 %yy, i8 signext 0) nounwind
+ ret %struct.ns* %0
+}
+
+declare fastcc %struct.ns* @foo7(%struct.cp* byval align 4, i8 signext) nounwind ssp
diff --git a/test/CodeGen/X86/trunc-to-bool.ll b/test/CodeGen/X86/trunc-to-bool.ll
index bfab1ae..6062084 100644
--- a/test/CodeGen/X86/trunc-to-bool.ll
+++ b/test/CodeGen/X86/trunc-to-bool.ll
@@ -3,13 +3,14 @@
; value and as the operand of a branch.
; RUN: llc < %s -march=x86 | FileCheck %s
-define i1 @test1(i32 %X) zeroext {
+define i1 @test1(i32 %X) zeroext nounwind {
%Y = trunc i32 %X to i1
ret i1 %Y
}
+; CHECK: test1:
; CHECK: andl $1, %eax
-define i1 @test2(i32 %val, i32 %mask) {
+define i1 @test2(i32 %val, i32 %mask) nounwind {
entry:
%shifted = ashr i32 %val, %mask
%anded = and i32 %shifted, 1
@@ -20,9 +21,10 @@ ret_true:
ret_false:
ret i1 false
}
-; CHECK: testb $1, %al
+; CHECK: test2:
+; CHECK: btl %eax
-define i32 @test3(i8* %ptr) {
+define i32 @test3(i8* %ptr) nounwind {
%val = load i8* %ptr
%tmp = trunc i8 %val to i1
br i1 %tmp, label %cond_true, label %cond_false
@@ -31,9 +33,10 @@ cond_true:
cond_false:
ret i32 42
}
-; CHECK: testb $1, %al
+; CHECK: test3:
+; CHECK: testb $1, (%eax)
-define i32 @test4(i8* %ptr) {
+define i32 @test4(i8* %ptr) nounwind {
%tmp = ptrtoint i8* %ptr to i1
br i1 %tmp, label %cond_true, label %cond_false
cond_true:
@@ -41,9 +44,10 @@ cond_true:
cond_false:
ret i32 42
}
-; CHECK: testb $1, %al
+; CHECK: test4:
+; CHECK: testb $1, 4(%esp)
-define i32 @test6(double %d) {
+define i32 @test5(double %d) nounwind {
%tmp = fptosi double %d to i1
br i1 %tmp, label %cond_true, label %cond_false
cond_true:
@@ -51,4 +55,5 @@ cond_true:
cond_false:
ret i32 42
}
+; CHECK: test5:
; CHECK: testb $1
diff --git a/test/CodeGen/X86/twoaddr-coalesce.ll b/test/CodeGen/X86/twoaddr-coalesce.ll
index d0e13f6..4c37225 100644
--- a/test/CodeGen/X86/twoaddr-coalesce.ll
+++ b/test/CodeGen/X86/twoaddr-coalesce.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86 | grep mov | count 5
+; RUN: llc < %s -march=x86 | grep mov | count 4
; rdar://6523745
@"\01LC" = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1]
diff --git a/test/CodeGen/X86/use-add-flags.ll b/test/CodeGen/X86/use-add-flags.ll
index 2dd2a4a..c2f0c23 100644
--- a/test/CodeGen/X86/use-add-flags.ll
+++ b/test/CodeGen/X86/use-add-flags.ll
@@ -5,13 +5,13 @@
; Use the flags on the add.
-; CHECK: add_zf:
+; CHECK: test1:
; CHECK: addl (%rdi), %esi
; CHECK-NEXT: movl %edx, %eax
; CHECK-NEXT: cmovnsl %ecx, %eax
; CHECK-NEXT: ret
-define i32 @add_zf(i32* %x, i32 %y, i32 %a, i32 %b) nounwind {
+define i32 @test1(i32* %x, i32 %y, i32 %a, i32 %b) nounwind {
%tmp2 = load i32* %x, align 4 ; <i32> [#uses=1]
%tmp4 = add i32 %tmp2, %y ; <i32> [#uses=1]
%tmp5 = icmp slt i32 %tmp4, 0 ; <i1> [#uses=1]
@@ -24,10 +24,10 @@ declare void @foo(i32)
; Don't use the flags result of the and here, since the and has no
; other use. A simple test is better.
-; CHECK: bar:
+; CHECK: test2:
; CHECK: testb $16, %dil
-define void @bar(i32 %x) nounwind {
+define void @test2(i32 %x) nounwind {
%y = and i32 %x, 16
%t = icmp eq i32 %y, 0
br i1 %t, label %true, label %false
@@ -40,11 +40,11 @@ false:
; Do use the flags result of the and here, since the and has another use.
-; CHECK: qux:
+; CHECK: test3:
; CHECK: andl $16, %edi
; CHECK-NEXT: jne
-define void @qux(i32 %x) nounwind {
+define void @test3(i32 %x) nounwind {
%y = and i32 %x, 16
%t = icmp eq i32 %y, 0
br i1 %t, label %true, label %false
diff --git a/test/CodeGen/X86/vec_cast.ll b/test/CodeGen/X86/vec_cast.ll
index 1f899b3..6f18d13 100644
--- a/test/CodeGen/X86/vec_cast.ll
+++ b/test/CodeGen/X86/vec_cast.ll
@@ -31,11 +31,10 @@ define <1 x i32> @f(<1 x i16> %a) nounwind {
ret <1 x i32> %c
}
-; TODO: Legalize doesn't yet handle this.
-;define <8 x i16> @g(<8 x i32> %a) nounwind {
-; %c = trunc <8 x i32> %a to <8 x i16>
-; ret <8 x i16> %c
-;}
+define <8 x i16> @g(<8 x i32> %a) nounwind {
+ %c = trunc <8 x i32> %a to <8 x i16>
+ ret <8 x i16> %c
+}
define <3 x i16> @h(<3 x i32> %a) nounwind {
%c = trunc <3 x i32> %a to <3 x i16>
@@ -46,3 +45,12 @@ define <1 x i16> @i(<1 x i32> %a) nounwind {
%c = trunc <1 x i32> %a to <1 x i16>
ret <1 x i16> %c
}
+
+; PR6438
+define void @__OpenCL_math_kernel4_kernel() nounwind {
+ %tmp12.i = and <4 x i32> zeroinitializer, <i32 2139095040, i32 2139095040, i32 2139095040, i32 2139095040> ; <<4 x i32>> [#uses=1]
+ %cmp13.i = icmp eq <4 x i32> %tmp12.i, <i32 2139095040, i32 2139095040, i32 2139095040, i32 2139095040> ; <<4 x i1>> [#uses=2]
+ %cmp.ext14.i = sext <4 x i1> %cmp13.i to <4 x i32> ; <<4 x i32>> [#uses=0]
+ %tmp2110.i = and <4 x i1> %cmp13.i, zeroinitializer ; <<4 x i1>> [#uses=0]
+ ret void
+}
diff --git a/test/CodeGen/X86/vec_insert.ll b/test/CodeGen/X86/vec_insert.ll
index a7274a9..4e5d445 100644
--- a/test/CodeGen/X86/vec_insert.ll
+++ b/test/CodeGen/X86/vec_insert.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s -march=x86 -mattr=+sse2,-sse41 | grep movss | count 1
; RUN: llc < %s -march=x86 -mattr=+sse2,-sse41 | not grep pinsrw
-define void @test(<4 x float>* %F, i32 %I) {
+define void @test(<4 x float>* %F, i32 %I) nounwind {
%tmp = load <4 x float>* %F ; <<4 x float>> [#uses=1]
%f = sitofp i32 %I to float ; <float> [#uses=1]
%tmp1 = insertelement <4 x float> %tmp, float %f, i32 0 ; <<4 x float>> [#uses=2]
@@ -10,7 +10,7 @@ define void @test(<4 x float>* %F, i32 %I) {
ret void
}
-define void @test2(<4 x float>* %F, i32 %I, float %g) {
+define void @test2(<4 x float>* %F, i32 %I, float %g) nounwind {
%tmp = load <4 x float>* %F ; <<4 x float>> [#uses=1]
%f = sitofp i32 %I to float ; <float> [#uses=1]
%tmp1 = insertelement <4 x float> %tmp, float %f, i32 2 ; <<4 x float>> [#uses=1]
diff --git a/test/CodeGen/X86/vec_shuffle-36.ll b/test/CodeGen/X86/vec_shuffle-36.ll
index 8a93a7e..1ea37c8 100644
--- a/test/CodeGen/X86/vec_shuffle-36.ll
+++ b/test/CodeGen/X86/vec_shuffle-36.ll
@@ -1,9 +1,16 @@
-; RUN: llc < %s -march=x86 -mattr=sse41 -o %t
-; RUN: grep pshufb %t | count 1
-
+; RUN: llc < %s -march=x86-64 -mattr=sse41 | FileCheck %s
define <8 x i16> @shuf6(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone {
+; CHECK: pshufb
+; CHECK-NOT: pshufb
+; CHECK: ret
entry:
- %tmp9 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 3, i32 2, i32 0, i32 2, i32 1, i32 5, i32 6 , i32 undef >
- ret <8 x i16> %tmp9
+ %tmp9 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 3, i32 2, i32 0, i32 2, i32 1, i32 5, i32 6 , i32 undef >
+ ret <8 x i16> %tmp9
}
+
+define <8 x i16> @shuf7(<8 x i16> %t0) {
+; CHECK: pshufd
+ %tmp10 = shufflevector <8 x i16> %t0, <8 x i16> undef, <8 x i32> < i32 undef, i32 2, i32 2, i32 2, i32 2, i32 2, i32 undef, i32 undef >
+ ret <8 x i16> %tmp10
+} \ No newline at end of file
diff --git a/test/CodeGen/X86/vec_ss_load_fold.ll b/test/CodeGen/X86/vec_ss_load_fold.ll
index b1613fb..c8b2927 100644
--- a/test/CodeGen/X86/vec_ss_load_fold.ll
+++ b/test/CodeGen/X86/vec_ss_load_fold.ll
@@ -1,6 +1,4 @@
-; RUN: llc < %s -march=x86 -mattr=+sse,+sse2 -o %t
-; RUN: grep minss %t | grep CPI | count 2
-; RUN: grep CPI %t | not grep movss
+; RUN: llc < %s -march=x86 -mattr=+sse,+sse2,+sse41 | FileCheck %s
target datalayout = "e-p:32:32"
target triple = "i686-apple-darwin8.7.2"
@@ -17,6 +15,10 @@ define i16 @test1(float %f) nounwind {
%tmp.upgrd.1 = tail call i32 @llvm.x86.sse.cvttss2si( <4 x float> %tmp59 ) ; <i32> [#uses=1]
%tmp69 = trunc i32 %tmp.upgrd.1 to i16 ; <i16> [#uses=1]
ret i16 %tmp69
+; CHECK: test1:
+; CHECK: subss LCPI1_
+; CHECK: mulss LCPI1_
+; CHECK: minss LCPI1_
}
define i16 @test2(float %f) nounwind {
@@ -28,6 +30,10 @@ define i16 @test2(float %f) nounwind {
%tmp = tail call i32 @llvm.x86.sse.cvttss2si( <4 x float> %tmp59 ) ; <i32> [#uses=1]
%tmp69 = trunc i32 %tmp to i16 ; <i16> [#uses=1]
ret i16 %tmp69
+; CHECK: test2:
+; CHECK: addss LCPI2_
+; CHECK: mulss LCPI2_
+; CHECK: minss LCPI2_
}
declare <4 x float> @llvm.x86.sse.sub.ss(<4 x float>, <4 x float>)
@@ -39,3 +45,28 @@ declare <4 x float> @llvm.x86.sse.min.ss(<4 x float>, <4 x float>)
declare <4 x float> @llvm.x86.sse.max.ss(<4 x float>, <4 x float>)
declare i32 @llvm.x86.sse.cvttss2si(<4 x float>)
+
+
+declare <4 x float> @llvm.x86.sse41.round.ss(<4 x float>, <4 x float>, i32)
+declare <4 x float> @f()
+
+define <4 x float> @test3(<4 x float> %A, float *%b, i32 %C) nounwind {
+ %a = load float *%b
+ %B = insertelement <4 x float> undef, float %a, i32 0
+ %X = call <4 x float> @llvm.x86.sse41.round.ss(<4 x float> %A, <4 x float> %B, i32 4)
+ ret <4 x float> %X
+; CHECK: test3:
+; CHECK: roundss $4, (%eax), %xmm0
+}
+
+define <4 x float> @test4(<4 x float> %A, float *%b, i32 %C) nounwind {
+ %a = load float *%b
+ %B = insertelement <4 x float> undef, float %a, i32 0
+ %q = call <4 x float> @f()
+ %X = call <4 x float> @llvm.x86.sse41.round.ss(<4 x float> %q, <4 x float> %B, i32 4)
+ ret <4 x float> %X
+; CHECK: test4:
+; CHECK: movss (%eax), %xmm
+; CHECK: call
+; CHECK: roundss $4, %xmm{{.*}}, %xmm0
+}
diff --git a/test/CodeGen/X86/xor-icmp.ll b/test/CodeGen/X86/xor-icmp.ll
index a6bdb13..2d75c5d 100644
--- a/test/CodeGen/X86/xor-icmp.ll
+++ b/test/CodeGen/X86/xor-icmp.ll
@@ -1,5 +1,6 @@
; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32
; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X64
+; rdar://7367229
define i32 @t(i32 %a, i32 %b) nounwind ssp {
entry:
@@ -34,3 +35,33 @@ bb1: ; preds = %entry
declare i32 @foo(...)
declare i32 @bar(...)
+
+define i32 @t2(i32 %x, i32 %y) nounwind ssp {
+; X32: t2:
+; X32: cmpl
+; X32: sete
+; X32: cmpl
+; X32: sete
+; X32-NOT: xor
+; X32: je
+
+; X64: t2:
+; X64: testl
+; X64: sete
+; X64: testl
+; X64: sete
+; X64-NOT: xor
+; X64: je
+entry:
+ %0 = icmp eq i32 %x, 0 ; <i1> [#uses=1]
+ %1 = icmp eq i32 %y, 0 ; <i1> [#uses=1]
+ %2 = xor i1 %1, %0 ; <i1> [#uses=1]
+ br i1 %2, label %bb, label %return
+
+bb: ; preds = %entry
+ %3 = tail call i32 (...)* @foo() nounwind ; <i32> [#uses=0]
+ ret i32 undef
+
+return: ; preds = %entry
+ ret i32 undef
+}
diff --git a/test/CodeGen/XCore/2010-02-25-LSR-Crash.ll b/test/CodeGen/XCore/2010-02-25-LSR-Crash.ll
new file mode 100644
index 0000000..6ad9a73
--- /dev/null
+++ b/test/CodeGen/XCore/2010-02-25-LSR-Crash.ll
@@ -0,0 +1,26 @@
+; RUN: llc < %s -march=xcore
+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 = "xcore-xmos-elf"
+
+%0 = type { i32 }
+%struct.dwarf_fde = type <{ i32, i32, [0 x i8] }>
+%struct.object = type { i8*, i8*, i8*, %union.anon, %0, %struct.object* }
+%union.anon = type { %struct.dwarf_fde* }
+
+define %struct.dwarf_fde* @search_object(%struct.object* %ob, i8* %pc) {
+entry:
+ br i1 undef, label %bb3.i15.i.i, label %bb2
+
+bb3.i15.i.i: ; preds = %bb3.i15.i.i, %entry
+ %indvar.i.i.i = phi i32 [ %indvar.next.i.i.i, %bb3.i15.i.i ], [ 0, %entry ] ; <i32> [#uses=2]
+ %tmp137 = sub i32 0, %indvar.i.i.i ; <i32> [#uses=1]
+ %scevgep13.i.i.i = getelementptr i32* undef, i32 %tmp137 ; <i32*> [#uses=2]
+ %scevgep1314.i.i.i = bitcast i32* %scevgep13.i.i.i to %struct.dwarf_fde** ; <%struct.dwarf_fde**> [#uses=1]
+ %0 = load %struct.dwarf_fde** %scevgep1314.i.i.i, align 4 ; <%struct.dwarf_fde*> [#uses=0]
+ store i32 undef, i32* %scevgep13.i.i.i
+ %indvar.next.i.i.i = add i32 %indvar.i.i.i, 1 ; <i32> [#uses=1]
+ br label %bb3.i15.i.i
+
+bb2: ; preds = %entry
+ ret %struct.dwarf_fde* undef
+}
diff --git a/test/CodeGen/XCore/switch.ll b/test/CodeGen/XCore/switch.ll
new file mode 100644
index 0000000..9cc27f2
--- /dev/null
+++ b/test/CodeGen/XCore/switch.ll
@@ -0,0 +1,24 @@
+; RUN: llc -march=xcore < %s | FileCheck %s
+
+define i32 @switch(i32 %i) {
+entry:
+ switch i32 %i, label %default [
+ i32 0, label %bb0
+ i32 1, label %bb1
+ i32 2, label %bb2
+ i32 3, label %bb3
+ ]
+; CHECK-NOT: shl
+; CHECK: bru
+; CHECK: .jmptable
+bb0:
+ ret i32 0
+bb1:
+ ret i32 1
+bb2:
+ ret i32 2
+bb3:
+ ret i32 3
+default:
+ ret i32 4
+}
diff --git a/test/CodeGen/XCore/switch_long.ll b/test/CodeGen/XCore/switch_long.ll
new file mode 100644
index 0000000..30c9e3d
--- /dev/null
+++ b/test/CodeGen/XCore/switch_long.ll
@@ -0,0 +1,132 @@
+; RUN: llc -march=xcore < %s | FileCheck %s
+
+define i32 @switch(i32 %i) {
+entry:
+ switch i32 %i, label %default [
+ i32 0, label %bb0
+ i32 1, label %bb1
+ i32 2, label %bb2
+ i32 3, label %bb3
+ i32 4, label %bb4
+ i32 5, label %bb5
+ i32 6, label %bb6
+ i32 7, label %bb7
+ i32 8, label %bb8
+ i32 9, label %bb9
+ i32 10, label %bb10
+ i32 11, label %bb11
+ i32 12, label %bb12
+ i32 13, label %bb13
+ i32 14, label %bb14
+ i32 15, label %bb15
+ i32 16, label %bb16
+ i32 17, label %bb17
+ i32 18, label %bb18
+ i32 19, label %bb19
+ i32 20, label %bb20
+ i32 21, label %bb21
+ i32 22, label %bb22
+ i32 23, label %bb23
+ i32 24, label %bb24
+ i32 25, label %bb25
+ i32 26, label %bb26
+ i32 27, label %bb27
+ i32 28, label %bb28
+ i32 29, label %bb29
+ i32 30, label %bb30
+ i32 31, label %bb31
+ i32 32, label %bb32
+ i32 33, label %bb33
+ i32 34, label %bb34
+ i32 35, label %bb35
+ i32 36, label %bb36
+ i32 37, label %bb37
+ i32 38, label %bb38
+ i32 39, label %bb39
+ ]
+; CHECK: shl
+; CHECK: bru
+; CHECK: .jmptable
+bb0:
+ ret i32 0
+bb1:
+ ret i32 1
+bb2:
+ ret i32 2
+bb3:
+ ret i32 3
+bb4:
+ ret i32 4
+bb5:
+ ret i32 5
+bb6:
+ ret i32 6
+bb7:
+ ret i32 7
+bb8:
+ ret i32 8
+bb9:
+ ret i32 9
+bb10:
+ ret i32 0
+bb11:
+ ret i32 1
+bb12:
+ ret i32 2
+bb13:
+ ret i32 3
+bb14:
+ ret i32 4
+bb15:
+ ret i32 5
+bb16:
+ ret i32 6
+bb17:
+ ret i32 7
+bb18:
+ ret i32 8
+bb19:
+ ret i32 9
+bb20:
+ ret i32 0
+bb21:
+ ret i32 1
+bb22:
+ ret i32 2
+bb23:
+ ret i32 3
+bb24:
+ ret i32 4
+bb25:
+ ret i32 5
+bb26:
+ ret i32 6
+bb27:
+ ret i32 7
+bb28:
+ ret i32 8
+bb29:
+ ret i32 9
+bb30:
+ ret i32 0
+bb31:
+ ret i32 1
+bb32:
+ ret i32 2
+bb33:
+ ret i32 3
+bb34:
+ ret i32 4
+bb35:
+ ret i32 5
+bb36:
+ ret i32 6
+bb37:
+ ret i32 7
+bb38:
+ ret i32 8
+bb39:
+ ret i32 9
+default:
+ ret i32 0
+}
diff --git a/test/DebugInfo/2009-02-27-licm.ll b/test/DebugInfo/2009-02-27-licm.ll
deleted file mode 100644
index b490a28..0000000
--- a/test/DebugInfo/2009-02-27-licm.ll
+++ /dev/null
@@ -1,83 +0,0 @@
-;RUN: opt < %s -licm -S | grep {load } | count 4
-; ModuleID = '2009-02-27-licm.bc'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
-target triple = "i386-pc-linux-gnu"
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i32 }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [12 x i8] c"mt19937ar.c\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str1 = internal constant [58 x i8] c"/developer2/home5/youxiangc/work/project/pr965/test-licm/\00", section "llvm.metadata" ; <[58 x i8]*> [#uses=1]
-@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5641) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([12 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([58 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@mti = internal global i32 625 ; <i32*> [#uses=7]
-@.str5 = internal constant [18 x i8] c"long unsigned int\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.basictype6 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 7 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [2 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to { }*)], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str7 = internal constant [13 x i8] c"init_genrand\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([13 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str7, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 13, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@mt = internal global [624 x i32] zeroinitializer, align 32 ; <[624 x i32]*> [#uses=4]
-
-define void @init_genrand(i32 %s) nounwind {
-entry:
- tail call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- tail call void @llvm.dbg.stoppoint(i32 14, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- store i32 %s, i32* getelementptr ([624 x i32]* @mt, i32 0, i32 0), align 32
- tail call void @llvm.dbg.stoppoint(i32 15, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- store i32 1, i32* @mti
- tail call void @llvm.dbg.stoppoint(i32 15, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %0 = load i32* @mti, align 4 ; <i32> [#uses=1]
- %1 = icmp sgt i32 %0, 623 ; <i1> [#uses=1]
- br i1 %1, label %return, label %bb.nph
-
-bb.nph: ; preds = %entry
- br label %bb
-
-bb: ; preds = %bb1, %bb.nph
- %storemerge1 = phi i32 [ %16, %bb1 ], [ 1, %bb.nph ] ; <i32> [#uses=0]
- tail call void @llvm.dbg.stoppoint(i32 16, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %2 = load i32* @mti, align 4 ; <i32> [#uses=3]
- %3 = add i32 %2, -1 ; <i32> [#uses=1]
- %4 = getelementptr [624 x i32]* @mt, i32 0, i32 %3 ; <i32*> [#uses=1]
- %5 = load i32* %4, align 4 ; <i32> [#uses=1]
- %6 = add i32 %2, -1 ; <i32> [#uses=1]
- %7 = getelementptr [624 x i32]* @mt, i32 0, i32 %6 ; <i32*> [#uses=1]
- %8 = load i32* %7, align 4 ; <i32> [#uses=1]
- %9 = lshr i32 %8, 30 ; <i32> [#uses=1]
- %10 = xor i32 %9, %5 ; <i32> [#uses=1]
- %11 = mul i32 %10, 1812433253 ; <i32> [#uses=1]
- %12 = load i32* @mti, align 4 ; <i32> [#uses=1]
- %13 = add i32 %11, %12 ; <i32> [#uses=1]
- %14 = getelementptr [624 x i32]* @mt, i32 0, i32 %2 ; <i32*> [#uses=1]
- store i32 %13, i32* %14, align 4
- tail call void @llvm.dbg.stoppoint(i32 15, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %15 = load i32* @mti, align 4 ; <i32> [#uses=1]
- %16 = add i32 %15, 1 ; <i32> [#uses=2]
- br label %bb1
-
-bb1: ; preds = %bb
- %storemerge = phi i32 [ %16, %bb ] ; <i32> [#uses=1]
- store i32 %storemerge, i32* @mti
- tail call void @llvm.dbg.stoppoint(i32 15, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %17 = load i32* @mti, align 4 ; <i32> [#uses=1]
- %18 = icmp sgt i32 %17, 623 ; <i1> [#uses=1]
- br i1 %18, label %bb1.return_crit_edge, label %bb
-
-bb1.return_crit_edge: ; preds = %bb1
- br label %return
-
-return: ; preds = %bb1.return_crit_edge, %entry
- tail call void @llvm.dbg.stoppoint(i32 25, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- tail call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- ret void
-}
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @llvm.dbg.region.end({ }*) nounwind
diff --git a/test/DebugInfo/2009-03-03-cheapdse.ll b/test/DebugInfo/2009-03-03-cheapdse.ll
deleted file mode 100644
index 9f47f16..0000000
--- a/test/DebugInfo/2009-03-03-cheapdse.ll
+++ /dev/null
@@ -1,80 +0,0 @@
-; RUN: opt < %s -instcombine -S | grep store | count 5
-; ModuleID = '<stdin>'
-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-darwin9.6"
- type { } ; type %0
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, %0*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0*, %0*, i32 }
- %llvm.dbg.derivedtype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0* }
- %llvm.dbg.subprogram.type = type { i32, %0*, %0*, i8*, i8*, i8*, %0*, i32, %0*, i1, i1 }
- %struct.Matrix = type { float*, i32, i32, i32, i32 }
-@llvm.dbg.compile_units = internal constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [15 x i8] c"himenobmtxpa.c\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@.str1 = internal constant [74 x i8] c"/Volumes/MacOS9/gcc/llvm/projects/llvm-test/SingleSource/Benchmarks/Misc/\00", section "llvm.metadata" ; <[74 x i8]*> [#uses=1]
-@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5641) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 1, i8* getelementptr ([15 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([74 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str3 = internal constant [6 x i8] c"float\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str3, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 4 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str5 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype6 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str5, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.subprograms = internal constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str90 = internal constant [4 x i8] c"Mat\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype92 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str93 = internal constant [2 x i8] c"m\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype94 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([2 x i8]* @.str93, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 46, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype92 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str95 = internal constant [6 x i8] c"mnums\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype96 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str95, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 47, i64 32, i64 32, i64 32, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str97 = internal constant [6 x i8] c"mrows\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype98 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str97, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 48, i64 32, i64 32, i64 64, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str99 = internal constant [6 x i8] c"mcols\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype100 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str99, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 49, i64 32, i64 32, i64 96, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str101 = internal constant [6 x i8] c"mdeps\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype102 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str101, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 50, i64 32, i64 32, i64 128, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array103 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype94 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype96 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype98 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype100 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype102 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite104 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str90, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 45, i64 160, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array103 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str105 = internal constant [7 x i8] c"Matrix\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype106 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str105, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 54, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite104 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype107 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype106 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array108 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype107 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite109 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array108 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str110 = internal constant [7 x i8] c"newMat\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.subprogram111 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str110, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str110, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 195, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite109 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 (%struct.Matrix*, i32, i32, i32, i32)* @newMat to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]
-
-define i32 @newMat(%struct.Matrix* %Mat, i32 %mnums, i32 %mrows, i32 %mcols, i32 %mdeps) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram111 to %0*))
- call void @llvm.dbg.stoppoint(i32 196, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %struct.Matrix* %Mat, i32 0, i32 1 ; <i32*> [#uses=1]
- store i32 %mnums, i32* %0, align 4
- call void @llvm.dbg.stoppoint(i32 197, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = getelementptr %struct.Matrix* %Mat, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %mrows, i32* %1, align 4
- call void @llvm.dbg.stoppoint(i32 198, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %2 = getelementptr %struct.Matrix* %Mat, i32 0, i32 3 ; <i32*> [#uses=1]
- store i32 %mcols, i32* %2, align 4
- call void @llvm.dbg.stoppoint(i32 199, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %3 = getelementptr %struct.Matrix* %Mat, i32 0, i32 4 ; <i32*> [#uses=1]
- store i32 %mdeps, i32* %3, align 4
- call void @llvm.dbg.stoppoint(i32 201, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %4 = mul i32 %mnums, %mrows ; <i32> [#uses=1]
- %5 = mul i32 %4, %mcols ; <i32> [#uses=1]
- %6 = mul i32 %5, %mdeps ; <i32> [#uses=1]
- %7 = malloc float, i32 %6 ; <float*> [#uses=2]
- %8 = getelementptr %struct.Matrix* %Mat, i32 0, i32 0 ; <float**> [#uses=1]
- store float* %7, float** %8, align 4
- call void @llvm.dbg.stoppoint(i32 204, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %9 = icmp ne float* %7, null ; <i1> [#uses=1]
- %10 = zext i1 %9 to i32 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 204, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram111 to %0*))
- ret i32 %10
-}
-
-declare void @llvm.dbg.func.start(%0*) nounwind readnone
-
-declare void @llvm.dbg.stoppoint(i32, i32, %0*) nounwind readnone
-
-declare void @llvm.dbg.region.end(%0*) nounwind readnone
diff --git a/test/DebugInfo/2009-03-05-gvn.ll b/test/DebugInfo/2009-03-05-gvn.ll
deleted file mode 100644
index f363132..0000000
--- a/test/DebugInfo/2009-03-05-gvn.ll
+++ /dev/null
@@ -1,125 +0,0 @@
-; RUN: opt < %s -gvn -S | grep {load } | count 1
-; ModuleID = 'db2-before.bc'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
-target triple = "i386-pc-linux-gnu"
- type { } ; type %0
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, %0*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0*, %0*, i32 }
- %llvm.dbg.derivedtype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0* }
- %llvm.dbg.subprogram.type = type { i32, %0*, %0*, i8*, i8*, i8*, %0*, i32, %0*, i1, i1 }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [12 x i8] c"mt19937ar.c\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str1 = internal constant [34 x i8] c"/developer/home2/zsth/test/debug/\00", section "llvm.metadata" ; <[34 x i8]*> [#uses=1]
-@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5641) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 1, i8* getelementptr ([12 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([34 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@mti = internal global i32 625 ; <i32*> [#uses=14]
-@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str5 = internal constant [18 x i8] c"long unsigned int\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.basictype6 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str5, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 7 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str7 = internal constant [13 x i8] c"init_genrand\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str7, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 58, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@mt = internal global [624 x i32] zeroinitializer, align 32 ; <[624 x i32]*> [#uses=29]
-@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array9 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite10 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array9 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str11 = internal constant [14 x i8] c"init_by_array\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram12 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str11, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str11, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 77, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite10 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array23 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype6 to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite24 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array23 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str25 = internal constant [14 x i8] c"genrand_int32\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram26 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str25, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str25, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 103, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite24 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@mag01.1661 = internal constant [2 x i32] [i32 0, i32 -1727483681] ; <[2 x i32]*> [#uses=3]
-@.str35 = internal constant [9 x i8] c"long int\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.basictype36 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str35, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array37 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype36 to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite38 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array37 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str39 = internal constant [14 x i8] c"genrand_int31\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram40 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str39, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str39, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 141, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite38 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str41 = internal constant [7 x i8] c"double\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.basictype42 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str41, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 64, i64 0, i32 0, i32 4 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array43 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype42 to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite44 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array43 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str45 = internal constant [14 x i8] c"genrand_real1\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram46 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str45, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str45, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 147, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite44 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str47 = internal constant [14 x i8] c"genrand_real2\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram48 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str47, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str47, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 154, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite44 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str49 = internal constant [14 x i8] c"genrand_real3\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram50 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str49, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str49, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 161, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite44 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str51 = internal constant [14 x i8] c"genrand_res53\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram52 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str51, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str51, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 168, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite44 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array57 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite58 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array57 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str59 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.subprogram60 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str59, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str59, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 175, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite58 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str69 = internal constant [32 x i8] c"1000 outputs of genrand_int32()\00" ; <[32 x i8]*> [#uses=1]
-@.str70 = internal constant [7 x i8] c"%10lu \00" ; <[7 x i8]*> [#uses=1]
-@.str71 = internal constant [33 x i8] c"\0A1000 outputs of genrand_real2()\00" ; <[33 x i8]*> [#uses=1]
-@.str72 = internal constant [8 x i8] c"%10.8f \00" ; <[8 x i8]*> [#uses=1]
-
-define void @init_genrand(i32 %s) nounwind {
-entry:
- tail call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %0*))
- tail call void @llvm.dbg.stoppoint(i32 59, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- store i32 %s, i32* getelementptr ([624 x i32]* @mt, i32 0, i32 0), align 32
- tail call void @llvm.dbg.stoppoint(i32 60, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- store i32 1, i32* @mti
- tail call void @llvm.dbg.stoppoint(i32 60, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br i1 false, label %return, label %bb.nph
-
-bb.nph: ; preds = %entry
- %mti.promoted = load i32* @mti ; <i32> [#uses=1]
- br label %bb
-
-bb: ; preds = %bb1, %bb.nph
- %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; <i32> [#uses=2]
- %mti.tmp.0 = add i32 %indvar, %mti.promoted ; <i32> [#uses=5]
- tail call void @llvm.dbg.stoppoint(i32 61, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = add i32 %mti.tmp.0, -1 ; <i32> [#uses=1]
- %1 = getelementptr [624 x i32]* @mt, i32 0, i32 %0 ; <i32*> [#uses=1]
- %2 = load i32* %1, align 4 ; <i32> [#uses=1]
- %3 = add i32 %mti.tmp.0, -1 ; <i32> [#uses=1]
- %4 = getelementptr [624 x i32]* @mt, i32 0, i32 %3 ; <i32*> [#uses=1]
- %5 = load i32* %4, align 4 ; <i32> [#uses=1]
- %6 = lshr i32 %5, 30 ; <i32> [#uses=1]
- %7 = xor i32 %6, %2 ; <i32> [#uses=1]
- %8 = mul i32 %7, 1812433253 ; <i32> [#uses=1]
- %9 = add i32 %8, %mti.tmp.0 ; <i32> [#uses=1]
- %10 = getelementptr [624 x i32]* @mt, i32 0, i32 %mti.tmp.0 ; <i32*> [#uses=1]
- store i32 %9, i32* %10, align 4
- tail call void @llvm.dbg.stoppoint(i32 60, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %11 = add i32 %mti.tmp.0, 1 ; <i32> [#uses=2]
- br label %bb1
-
-bb1: ; preds = %bb
- tail call void @llvm.dbg.stoppoint(i32 60, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %12 = icmp sgt i32 %11, 623 ; <i1> [#uses=1]
- %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
- br i1 %12, label %bb1.return_crit_edge, label %bb
-
-bb1.return_crit_edge: ; preds = %bb1
- store i32 %11, i32* @mti
- br label %return
-
-return: ; preds = %bb1.return_crit_edge, %entry
- tail call void @llvm.dbg.stoppoint(i32 70, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- tail call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %0*))
- ret void
-}
-
-declare void @llvm.dbg.func.start(%0*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, %0*) nounwind
-
-declare void @llvm.dbg.region.end(%0*) nounwind
-
-declare i32 @puts(i8* nocapture) nounwind
-
-declare i32 @printf(i8* noalias nocapture, ...) nounwind
-
-declare i32 @putchar(i32) nounwind
diff --git a/test/DebugInfo/deaddebuglabel.ll b/test/DebugInfo/deaddebuglabel.ll
deleted file mode 100644
index a9af12b..0000000
--- a/test/DebugInfo/deaddebuglabel.ll
+++ /dev/null
@@ -1,62 +0,0 @@
-; RUN: llc %s -o - -O0 | grep "label" | count 8
-; PR2614
-; XFAIL: *
-
-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-f80:32:32-v64:64:64-v128:128:128-a0:0:64"
-target triple = "i686-pc-linux-gnu"
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* }
- %llvm.dbg.compositetype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
- %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
- %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=0]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [17 x i8] c"deaddebuglabel.d\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@.str1 = internal constant [50 x i8] c"/home/kamm/eigenes/projekte/llvmdc/llvmdc/mytests\00", section "llvm.metadata" ; <[50 x i8]*> [#uses=1]
-@.str2 = internal constant [48 x i8] c"LLVMDC (http://www.dsource.org/projects/llvmdc)\00", section "llvm.metadata" ; <[48 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type {
- i32 393233,
- { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*),
- i32 2,
- i8* getelementptr ([17 x i8]* @.str, i32 0, i32 0),
- i8* getelementptr ([50 x i8]* @.str1, i32 0, i32 0),
- i8* getelementptr ([48 x i8]* @.str2, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str5 = internal constant [20 x i8] c"deaddebuglabel.main\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@.str6 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.subprogram7 = internal constant %llvm.dbg.subprogram.type {
- i32 393262,
- { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*),
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i8* getelementptr ([20 x i8]* @.str5, i32 0, i32 0),
- i8* getelementptr ([20 x i8]* @.str5, i32 0, i32 0),
- i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0),
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i32 3,
- { }* null,
- i1 false,
- i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @llvm.dbg.region.end({ }*) nounwind
-
-define fastcc i32 @main() {
-entry.main:
- call void @llvm.dbg.func.start( { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*) )
- br i1 true, label %reachable, label %unreachable
-
-reachable: ; preds = %entry.main
- call void @llvm.dbg.region.end( { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*) )
- ret i32 1
-
-unreachable: ; preds = %entry.main
- call void @llvm.dbg.stoppoint( i32 7, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- call void @llvm.dbg.region.end( { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*) )
- ret i32 0
-}
diff --git a/test/DebugInfo/funccall.ll b/test/DebugInfo/funccall.ll
deleted file mode 100644
index e44b029..0000000
--- a/test/DebugInfo/funccall.ll
+++ /dev/null
@@ -1,147 +0,0 @@
-;; RUN: llc < %s
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* }
- %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type {
- i32 393262,
- { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*),
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i8* getelementptr ([4 x i8]* @str, i32 0, i32 0),
- i8* getelementptr ([4 x i8]* @str, i32 0, i32 0),
- i8* null,
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i32 4,
- { }* null,
- i1 false,
- i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@str = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type {
- i32 393233,
- { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*),
- i32 1,
- i8* getelementptr ([11 x i8]* @str1, i32 0, i32 0),
- i8* getelementptr ([50 x i8]* @str2, i32 0, i32 0),
- i8* getelementptr ([45 x i8]* @str3, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@str1 = internal constant [11 x i8] c"funccall.c\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@str2 = internal constant [50 x i8] c"/Volumes/Big2/llvm/llvm/test/Regression/Debugger/\00", section "llvm.metadata" ; <[50 x i8]*> [#uses=1]
-@str3 = internal constant [45 x i8] c"4.0.1 LLVM (Apple Computer, Inc. build 5421)\00", section "llvm.metadata" ; <[45 x i8]*> [#uses=1]
-@llvm.dbg.variable = internal constant %llvm.dbg.variable.type {
- i32 393472,
- { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*),
- i8* getelementptr ([2 x i8]* @str4, i32 0, i32 0),
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i32 5,
- { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@str4 = internal constant [2 x i8] c"t\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type {
- i32 393252,
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i8* getelementptr ([4 x i8]* @str15, i32 0, i32 0),
- { }* null,
- i32 0,
- i64 32,
- i64 32,
- i64 0,
- i32 0,
- i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@str15 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.subprogram2 = internal constant %llvm.dbg.subprogram.type {
- i32 393262,
- { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*),
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i8* getelementptr ([5 x i8]* @str6, i32 0, i32 0),
- i8* getelementptr ([5 x i8]* @str6, i32 0, i32 0),
- i8* null,
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i32 8,
- { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*),
- i1 false,
- i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@str6 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.variable3 = internal constant %llvm.dbg.variable.type {
- i32 393474,
- { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram2 to { }*),
- i8* getelementptr ([7 x i8]* @str7, i32 0, i32 0),
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i32 8,
- { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@str7 = internal constant [7 x i8] c"retval\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type {
- i32 393268,
- { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*),
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i8* getelementptr ([2 x i8]* @str4, i32 0, i32 0),
- i8* getelementptr ([2 x i8]* @str4, i32 0, i32 0),
- i8* null,
- { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),
- i32 2,
- { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*),
- i1 true,
- i1 true,
- { }* bitcast (i32* @q to { }*) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0]
-@str4.upgrd.1 = internal constant [2 x i8] c"q\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=0]
-@q = internal global i32 0 ; <i32*> [#uses=7]
-
-declare void @llvm.dbg.func.start({ }*)
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*)
-
-declare void @llvm.dbg.declare({ }*, { }*)
-
-declare void @llvm.dbg.region.start({ }*)
-
-declare void @llvm.dbg.region.end({ }*)
-
-define void @foo() {
-entry:
- %t = alloca i32, align 4 ; <i32*> [#uses=3]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start( { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) )
- call void @llvm.dbg.stoppoint( i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- %t.upgrd.2 = bitcast i32* %t to { }* ; <{ }*> [#uses=1]
- call void @llvm.dbg.declare( { }* %t.upgrd.2, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*) )
- call void @llvm.dbg.stoppoint( i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- %tmp = load i32* @q ; <i32> [#uses=1]
- store i32 %tmp, i32* %t
- call void @llvm.dbg.stoppoint( i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- %tmp1 = load i32* %t ; <i32> [#uses=1]
- %tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1]
- store i32 %tmp2, i32* @q
- call void @llvm.dbg.stoppoint( i32 7, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- call void @llvm.dbg.region.end( { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) )
- ret void
-}
-
-define i32 @main() {
-entry:
- %retval = alloca i32, align 4 ; <i32*> [#uses=3]
- %tmp = alloca i32, align 4 ; <i32*> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start( { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram2 to { }*) )
- call void @llvm.dbg.stoppoint( i32 8, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- %retval.upgrd.3 = bitcast i32* %retval to { }* ; <{ }*> [#uses=1]
- call void @llvm.dbg.declare( { }* %retval.upgrd.3, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable3 to { }*) )
- call void @llvm.dbg.stoppoint( i32 9, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- store i32 0, i32* @q
- call void @llvm.dbg.stoppoint( i32 10, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- call void (...)* bitcast (void ()* @foo to void (...)*)( )
- call void @llvm.dbg.stoppoint( i32 11, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- %tmp.upgrd.4 = load i32* @q ; <i32> [#uses=1]
- %tmp1 = sub i32 %tmp.upgrd.4, 1 ; <i32> [#uses=1]
- store i32 %tmp1, i32* @q
- call void @llvm.dbg.stoppoint( i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- %tmp2 = load i32* @q ; <i32> [#uses=1]
- store i32 %tmp2, i32* %tmp
- %tmp3 = load i32* %tmp ; <i32> [#uses=1]
- store i32 %tmp3, i32* %retval
- %retval.upgrd.5 = load i32* %retval ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint( i32 14, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*) )
- call void @llvm.dbg.region.end( { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram2 to { }*) )
- ret i32 %retval.upgrd.5
-}
diff --git a/test/DebugInfo/globalGetElementPtr.ll b/test/DebugInfo/globalGetElementPtr.ll
deleted file mode 100644
index 155deb7..0000000
--- a/test/DebugInfo/globalGetElementPtr.ll
+++ /dev/null
@@ -1,264 +0,0 @@
-; RUN: llc < %s
-; ModuleID = 'foo.c'
-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 = "i686-apple-darwin8"
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, %struct.anon*, i8*, %struct.anon*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, %struct.anon*, i32, i8*, i8*, i8* }
- %llvm.dbg.compositetype.type = type { i32, %struct.anon*, i8*, %struct.anon*, i32, i64, i64, i64, i32, %struct.anon*, %struct.anon* }
- %llvm.dbg.derivedtype.type = type { i32, %struct.anon*, i8*, %struct.anon*, i32, i64, i64, i64, i32, %struct.anon* }
- %llvm.dbg.global_variable.type = type { i32, %struct.anon*, %struct.anon*, i8*, i8*, i8*, %struct.anon*, i32, %struct.anon*, i1, i1, %struct.anon* }
- %llvm.dbg.subprogram.type = type { i32, %struct.anon*, %struct.anon*, i8*, i8*, i8*, %struct.anon*, i32, %struct.anon*, i1, i1 }
- %llvm.dbg.subrange.type = type { i32, i64, i64 }
- %llvm.dbg.variable.type = type { i32, %struct.anon*, i8*, %struct.anon*, i32, %struct.anon* }
- %struct.S271 = type { [0 x %struct.anon], %struct.anon }
- %struct.anon = type { }
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type {
- i32 393262,
- %struct.anon* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %struct.anon*),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0),
- i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0),
- i8* null,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 2,
- %struct.anon* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to %struct.anon*),
- i1 false,
- i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type {
- i32 393233,
- %struct.anon* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %struct.anon*),
- i32 1,
- i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0),
- i8* getelementptr ([23 x i8]* @.str1, i32 0, i32 0),
- i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [6 x i8] c"foo.c\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1 = internal constant [23 x i8] c"/Volumes/MacOS9/tests/\00", section "llvm.metadata" ; <[23 x i8]*> [#uses=1]
-@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5546) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@.str3 = internal constant [4 x i8] c"var\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type {
- i32 393231,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* null,
- %struct.anon* null,
- i32 0,
- i64 32,
- i64 32,
- i64 0,
- i32 0,
- %struct.anon* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type {
- i32 393252,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0),
- %struct.anon* null,
- i32 0,
- i64 8,
- i64 8,
- i64 0,
- i32 0,
- i32 6 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str4 = internal constant [5 x i8] c"char\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.variable = internal constant %llvm.dbg.variable.type {
- i32 393474,
- %struct.anon* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %struct.anon*),
- i8* getelementptr ([7 x i8]* @.str5, i32 0, i32 0),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 2,
- %struct.anon* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str5 = internal constant [7 x i8] c"retval\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@a271 = weak global [0 x %struct.S271] zeroinitializer ; <[0 x %struct.S271]*> [#uses=3]
-@llvm.dbg.subprogram6 = internal constant %llvm.dbg.subprogram.type {
- i32 393262,
- %struct.anon* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %struct.anon*),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* getelementptr ([5 x i8]* @.str7, i32 0, i32 0),
- i8* getelementptr ([5 x i8]* @.str7, i32 0, i32 0),
- i8* null,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 3,
- %struct.anon* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype8 to %struct.anon*),
- i1 false,
- i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str7 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.basictype8 = internal constant %llvm.dbg.basictype.type {
- i32 393252,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* getelementptr ([4 x i8]* @.str9, i32 0, i32 0),
- %struct.anon* null,
- i32 0,
- i64 32,
- i64 32,
- i64 0,
- i32 0,
- i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str9 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.variable10 = internal constant %llvm.dbg.variable.type {
- i32 393474,
- %struct.anon* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram6 to %struct.anon*),
- i8* getelementptr ([7 x i8]* @.str5, i32 0, i32 0),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 3,
- %struct.anon* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype8 to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type {
- i32 393268,
- %struct.anon* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to %struct.anon*),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* getelementptr ([5 x i8]* @.str11, i32 0, i32 0),
- i8* getelementptr ([5 x i8]* @.str11, i32 0, i32 0),
- i8* null,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 1,
- %struct.anon* bitcast (%llvm.dbg.compositetype.type* @llvm.dbg.compositetype to %struct.anon*),
- i1 false,
- i1 true,
- %struct.anon* getelementptr ([0 x %struct.S271]* @a271, i32 0, i32 0, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0]
-@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str11 = internal constant [5 x i8] c"a271\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.compositetype = internal constant %llvm.dbg.compositetype.type {
- i32 393217,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* null,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 0,
- i64 0,
- i64 8,
- i64 0,
- i32 0,
- %struct.anon* bitcast (%llvm.dbg.compositetype.type* @llvm.dbg.compositetype12 to %struct.anon*),
- %struct.anon* bitcast ([1 x %struct.anon*]* @llvm.dbg.array25 to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.compositetype.type*> [#uses=1]
-@llvm.dbg.compositetype12 = internal constant %llvm.dbg.compositetype.type {
- i32 393235,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* getelementptr ([5 x i8]* @.str13, i32 0, i32 0),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 1,
- i64 0,
- i64 8,
- i64 0,
- i32 0,
- %struct.anon* null,
- %struct.anon* bitcast ([2 x %struct.anon*]* @llvm.dbg.array23 to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.compositetype.type*> [#uses=1]
-@.str13 = internal constant [5 x i8] c"S271\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype14 = internal constant %llvm.dbg.derivedtype.type {
- i32 393229,
- %struct.anon* null,
- i8* getelementptr ([2 x i8]* @.str15, i32 0, i32 0),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 1,
- i64 0,
- i64 8,
- i64 0,
- i32 0,
- %struct.anon* bitcast (%llvm.dbg.compositetype.type* @llvm.dbg.compositetype16 to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str15 = internal constant [2 x i8] c"a\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.compositetype16 = internal constant %llvm.dbg.compositetype.type {
- i32 393217,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* null,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 0,
- i64 0,
- i64 8,
- i64 0,
- i32 0,
- %struct.anon* bitcast (%llvm.dbg.compositetype.type* @llvm.dbg.compositetype17 to %struct.anon*),
- %struct.anon* bitcast ([1 x %struct.anon*]* @llvm.dbg.array18 to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.compositetype.type*> [#uses=1]
-@llvm.dbg.compositetype17 = internal constant %llvm.dbg.compositetype.type {
- i32 393235,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* null,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 1,
- i64 0,
- i64 8,
- i64 0,
- i32 0,
- %struct.anon* null,
- %struct.anon* bitcast ([0 x %struct.anon*]* @llvm.dbg.array to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.compositetype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [0 x %struct.anon*] zeroinitializer, section "llvm.metadata" ; <[0 x %struct.anon*]*> [#uses=1]
-@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type {
- i32 393249,
- i64 0,
- i64 4 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1]
-@llvm.dbg.array18 = internal constant [1 x %struct.anon*] [ %struct.anon* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange to %struct.anon*) ], section "llvm.metadata" ; <[1 x %struct.anon*]*> [#uses=1]
-@llvm.dbg.derivedtype19 = internal constant %llvm.dbg.derivedtype.type {
- i32 393229,
- %struct.anon* null,
- i8* getelementptr ([2 x i8]* @.str20, i32 0, i32 0),
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 1,
- i64 0,
- i64 8,
- i64 0,
- i32 0,
- %struct.anon* bitcast (%llvm.dbg.compositetype.type* @llvm.dbg.compositetype21 to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str20 = internal constant [2 x i8] c"b\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.compositetype21 = internal constant %llvm.dbg.compositetype.type {
- i32 393235,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i8* null,
- %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*),
- i32 1,
- i64 0,
- i64 8,
- i64 0,
- i32 0,
- %struct.anon* null,
- %struct.anon* bitcast ([0 x %struct.anon*]* @llvm.dbg.array22 to %struct.anon*) }, section "llvm.metadata" ; <%llvm.dbg.compositetype.type*> [#uses=1]
-@llvm.dbg.array22 = internal constant [0 x %struct.anon*] zeroinitializer, section "llvm.metadata" ; <[0 x %struct.anon*]*> [#uses=1]
-@llvm.dbg.array23 = internal constant [2 x %struct.anon*] [ %struct.anon* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype14 to %struct.anon*), %struct.anon* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to %struct.anon*) ], section "llvm.metadata" ; <[2 x %struct.anon*]*> [#uses=1]
-@llvm.dbg.subrange24 = internal constant %llvm.dbg.subrange.type {
- i32 393249,
- i64 0,
- i64 4 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1]
-@llvm.dbg.array25 = internal constant [1 x %struct.anon*] [ %struct.anon* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange24 to %struct.anon*) ], section "llvm.metadata" ; <[1 x %struct.anon*]*> [#uses=1]
-
-define i8* @var() {
-entry:
- %retval = alloca i8* ; <i8**> [#uses=3]
- %tmp = alloca i8* ; <i8**> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start( %struct.anon* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %struct.anon*) )
- call void @llvm.dbg.stoppoint( i32 2, i32 0, %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*) )
- %retval1 = bitcast i8** %retval to %struct.anon* ; <%struct.anon*> [#uses=1]
- call void @llvm.dbg.declare( %struct.anon* %retval1, %struct.anon* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to %struct.anon*) )
- bitcast %struct.S271* getelementptr ([0 x %struct.S271]* @a271, i32 0, i32 0) to i8* ; <i8*>:0 [#uses=0]
- store i8* bitcast ([0 x %struct.S271]* @a271 to i8*), i8** %tmp, align 4
- %tmp2 = load i8** %tmp, align 4 ; <i8*> [#uses=1]
- store i8* %tmp2, i8** %retval, align 4
- br label %return
-
-return: ; preds = %entry
- %retval3 = load i8** %retval ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint( i32 2, i32 0, %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*) )
- call void @llvm.dbg.region.end( %struct.anon* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %struct.anon*) )
- ret i8* %retval3
-}
-
-declare void @llvm.dbg.func.start(%struct.anon*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, %struct.anon*) nounwind
-
-declare void @llvm.dbg.declare(%struct.anon*, %struct.anon*) nounwind
-
-declare void @llvm.dbg.region.end(%struct.anon*) nounwind
-
-define i32 @main() {
-entry:
- %retval = alloca i32 ; <i32*> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start( %struct.anon* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram6 to %struct.anon*) )
- call void @llvm.dbg.stoppoint( i32 3, i32 0, %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*) )
- %retval1 = bitcast i32* %retval to %struct.anon* ; <%struct.anon*> [#uses=1]
- call void @llvm.dbg.declare( %struct.anon* %retval1, %struct.anon* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable10 to %struct.anon*) )
- br label %return
-
-return: ; preds = %entry
- %retval2 = load i32* %retval ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint( i32 3, i32 0, %struct.anon* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %struct.anon*) )
- call void @llvm.dbg.region.end( %struct.anon* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram6 to %struct.anon*) )
- ret i32 %retval2
-}
diff --git a/test/DebugInfo/inheritance.ll b/test/DebugInfo/inheritance.ll
new file mode 100644
index 0000000..a689cb2
--- /dev/null
+++ b/test/DebugInfo/inheritance.ll
@@ -0,0 +1,151 @@
+; RUN: llc %s -o /dev/null
+; PR 2613.
+
+%struct.__class_type_info_pseudo = type { %struct.__type_info_pseudo }
+%struct.__type_info_pseudo = type { i8*, i8* }
+%struct.test1 = type { i32 (...)** }
+
+@_ZTV5test1 = weak_odr constant [4 x i32 (...)*] [i32 (...)* null, i32 (...)* bitcast (%struct.__class_type_info_pseudo* @_ZTI5test1 to i32 (...)*), i32 (...)* bitcast (void (%struct.test1*)* @_ZN5test1D1Ev to i32 (...)*), i32 (...)* bitcast (void (%struct.test1*)* @_ZN5test1D0Ev to i32 (...)*)], align 32 ; <[4 x i32 (...)*]*> [#uses=1]
+@_ZTI5test1 = weak_odr constant %struct.__class_type_info_pseudo { %struct.__type_info_pseudo { i8* inttoptr (i64 add (i64 ptrtoint ([0 x i32 (...)*]* @_ZTVN10__cxxabiv117__class_type_infoE to i64), i64 16) to i8*), i8* getelementptr inbounds ([7 x i8]* @_ZTS5test1, i64 0, i64 0) } }, align 16 ; <%struct.__class_type_info_pseudo*> [#uses=1]
+@_ZTVN10__cxxabiv117__class_type_infoE = external constant [0 x i32 (...)*] ; <[0 x i32 (...)*]*> [#uses=1]
+@_ZTS5test1 = weak_odr constant [7 x i8] c"5test1\00" ; <[7 x i8]*> [#uses=2]
+
+define i32 @main() nounwind ssp {
+entry:
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %0 = alloca i32 ; <i32*> [#uses=2]
+ %tst = alloca %struct.test1 ; <%struct.test1*> [#uses=1]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.declare(metadata !{%struct.test1* %tst}, metadata !0), !dbg !21
+ call void @_ZN5test1C1Ev(%struct.test1* %tst) nounwind, !dbg !22
+ store i32 0, i32* %0, align 4, !dbg !23
+ %1 = load i32* %0, align 4, !dbg !23 ; <i32> [#uses=1]
+ store i32 %1, i32* %retval, align 4, !dbg !23
+ br label %return, !dbg !23
+
+return: ; preds = %entry
+ %retval1 = load i32* %retval, !dbg !23 ; <i32> [#uses=1]
+ ret i32 %retval1, !dbg !23
+}
+
+define linkonce_odr void @_ZN5test1C1Ev(%struct.test1* %this) nounwind ssp align 2 {
+entry:
+ %this_addr = alloca %struct.test1* ; <%struct.test1**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.declare(metadata !{%struct.test1** %this_addr}, metadata !24), !dbg !28
+ store %struct.test1* %this, %struct.test1** %this_addr
+ %0 = load %struct.test1** %this_addr, align 8, !dbg !28 ; <%struct.test1*> [#uses=1]
+ %1 = getelementptr inbounds %struct.test1* %0, i32 0, i32 0, !dbg !28 ; <i32 (...)***> [#uses=1]
+ store i32 (...)** getelementptr inbounds ([4 x i32 (...)*]* @_ZTV5test1, i64 0, i64 2), i32 (...)*** %1, align 8, !dbg !28
+ br label %return, !dbg !28
+
+return: ; preds = %entry
+ ret void, !dbg !29
+}
+
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+define linkonce_odr void @_ZN5test1D1Ev(%struct.test1* %this) nounwind ssp align 2 {
+entry:
+ %this_addr = alloca %struct.test1* ; <%struct.test1**> [#uses=3]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.declare(metadata !{%struct.test1** %this_addr}, metadata !32), !dbg !34
+ store %struct.test1* %this, %struct.test1** %this_addr
+ %0 = load %struct.test1** %this_addr, align 8, !dbg !35 ; <%struct.test1*> [#uses=1]
+ %1 = getelementptr inbounds %struct.test1* %0, i32 0, i32 0, !dbg !35 ; <i32 (...)***> [#uses=1]
+ store i32 (...)** getelementptr inbounds ([4 x i32 (...)*]* @_ZTV5test1, i64 0, i64 2), i32 (...)*** %1, align 8, !dbg !35
+ br label %bb, !dbg !37
+
+bb: ; preds = %entry
+ %2 = trunc i32 0 to i8, !dbg !37 ; <i8> [#uses=1]
+ %toBool = icmp ne i8 %2, 0, !dbg !37 ; <i1> [#uses=1]
+ br i1 %toBool, label %bb1, label %bb2, !dbg !37
+
+bb1: ; preds = %bb
+ %3 = load %struct.test1** %this_addr, align 8, !dbg !37 ; <%struct.test1*> [#uses=1]
+ %4 = bitcast %struct.test1* %3 to i8*, !dbg !37 ; <i8*> [#uses=1]
+ call void @_ZdlPv(i8* %4) nounwind, !dbg !37
+ br label %bb2, !dbg !37
+
+bb2: ; preds = %bb1, %bb
+ br label %return, !dbg !37
+
+return: ; preds = %bb2
+ ret void, !dbg !37
+}
+
+define linkonce_odr void @_ZN5test1D0Ev(%struct.test1* %this) nounwind ssp align 2 {
+entry:
+ %this_addr = alloca %struct.test1* ; <%struct.test1**> [#uses=3]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.declare(metadata !{%struct.test1** %this_addr}, metadata !38), !dbg !40
+ store %struct.test1* %this, %struct.test1** %this_addr
+ %0 = load %struct.test1** %this_addr, align 8, !dbg !41 ; <%struct.test1*> [#uses=1]
+ %1 = getelementptr inbounds %struct.test1* %0, i32 0, i32 0, !dbg !41 ; <i32 (...)***> [#uses=1]
+ store i32 (...)** getelementptr inbounds ([4 x i32 (...)*]* @_ZTV5test1, i64 0, i64 2), i32 (...)*** %1, align 8, !dbg !41
+ br label %bb, !dbg !43
+
+bb: ; preds = %entry
+ %2 = trunc i32 1 to i8, !dbg !43 ; <i8> [#uses=1]
+ %toBool = icmp ne i8 %2, 0, !dbg !43 ; <i1> [#uses=1]
+ br i1 %toBool, label %bb1, label %bb2, !dbg !43
+
+bb1: ; preds = %bb
+ %3 = load %struct.test1** %this_addr, align 8, !dbg !43 ; <%struct.test1*> [#uses=1]
+ %4 = bitcast %struct.test1* %3 to i8*, !dbg !43 ; <i8*> [#uses=1]
+ call void @_ZdlPv(i8* %4) nounwind, !dbg !43
+ br label %bb2, !dbg !43
+
+bb2: ; preds = %bb1, %bb
+ br label %return, !dbg !43
+
+return: ; preds = %bb2
+ ret void, !dbg !43
+}
+
+declare void @_ZdlPv(i8*) nounwind
+
+!0 = metadata !{i32 459008, metadata !1, metadata !"tst", metadata !4, i32 13, metadata !8} ; [ DW_TAG_auto_variable ]
+!1 = metadata !{i32 458763, metadata !2, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!2 = metadata !{i32 458763, metadata !3, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!3 = metadata !{i32 458798, i32 0, metadata !4, metadata !"main", metadata !"main", metadata !"main", metadata !4, i32 11, metadata !5, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
+!4 = metadata !{i32 458769, i32 0, i32 4, metadata !"inheritance.cpp", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!5 = metadata !{i32 458773, metadata !4, metadata !"", metadata !4, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !6, i32 0, null} ; [ DW_TAG_subroutine_type ]
+!6 = metadata !{metadata !7}
+!7 = metadata !{i32 458788, metadata !4, metadata !"int", metadata !4, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+!8 = metadata !{i32 458771, metadata !4, metadata !"test1", metadata !4, i32 1, i64 64, i64 64, i64 0, i32 0, null, metadata !9, i32 0, metadata !8} ; [ DW_TAG_structure_type ]
+!9 = metadata !{metadata !10, metadata !14, metadata !18}
+!10 = metadata !{i32 458765, metadata !8, metadata !"_vptr$test1", metadata !4, i32 1, i64 64, i64 64, i64 0, i32 0, metadata !11} ; [ DW_TAG_member ]
+!11 = metadata !{i32 458767, metadata !4, metadata !"", metadata !4, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !12} ; [ DW_TAG_pointer_type ]
+!12 = metadata !{i32 458767, metadata !4, metadata !"__vtbl_ptr_type", metadata !13, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ]
+!13 = metadata !{i32 458769, i32 0, i32 4, metadata !"<built-in>", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 false, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!14 = metadata !{i32 458798, i32 0, metadata !8, metadata !"test1", metadata !"test1", metadata !"", metadata !4, i32 1, metadata !15, i1 false, i1 false, i32 0, i32 0, null, i1 true} ; [ DW_TAG_subprogram ]
+!15 = metadata !{i32 458773, metadata !4, metadata !"", metadata !4, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !16, i32 0, null} ; [ DW_TAG_subroutine_type ]
+!16 = metadata !{null, metadata !17}
+!17 = metadata !{i32 458767, metadata !4, metadata !"", metadata !4, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !8} ; [ DW_TAG_pointer_type ]
+!18 = metadata !{i32 458798, i32 0, metadata !8, metadata !"~test1", metadata !"~test1", metadata !"", metadata !4, i32 4, metadata !19, i1 false, i1 false, i32 1, i32 0, metadata !8, i1 false} ; [ DW_TAG_subprogram ]
+!19 = metadata !{i32 458773, metadata !4, metadata !"", metadata !4, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !20, i32 0, null} ; [ DW_TAG_subroutine_type ]
+!20 = metadata !{null, metadata !17, metadata !7}
+!21 = metadata !{i32 11, i32 0, metadata !1, null}
+!22 = metadata !{i32 13, i32 0, metadata !1, null}
+!23 = metadata !{i32 14, i32 0, metadata !1, null}
+!24 = metadata !{i32 459009, metadata !25, metadata !"this", metadata !4, i32 13, metadata !26} ; [ DW_TAG_arg_variable ]
+!25 = metadata !{i32 458798, i32 0, metadata !4, metadata !"test1", metadata !"test1", metadata !"_ZN5test1C1Ev", metadata !4, i32 1, metadata !15, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
+!26 = metadata !{i32 458790, metadata !4, metadata !"", metadata !4, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !27} ; [ DW_TAG_const_type ]
+!27 = metadata !{i32 458767, metadata !4, metadata !"", metadata !4, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !8} ; [ DW_TAG_pointer_type ]
+!28 = metadata !{i32 1, i32 0, metadata !25, null}
+!29 = metadata !{i32 1, i32 0, metadata !30, null}
+!30 = metadata !{i32 458763, metadata !31, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!31 = metadata !{i32 458763, metadata !25, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!32 = metadata !{i32 459009, metadata !33, metadata !"this", metadata !4, i32 4, metadata !26} ; [ DW_TAG_arg_variable ]
+!33 = metadata !{i32 458798, i32 0, metadata !8, metadata !"~test1", metadata !"~test1", metadata !"_ZN5test1D1Ev", metadata !4, i32 4, metadata !15, i1 false, i1 true, i32 1, i32 0, metadata !8, i1 false} ; [ DW_TAG_subprogram ]
+!34 = metadata !{i32 4, i32 0, metadata !33, null}
+!35 = metadata !{i32 5, i32 0, metadata !36, null}
+!36 = metadata !{i32 458763, metadata !33, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!37 = metadata !{i32 6, i32 0, metadata !36, null}
+!38 = metadata !{i32 459009, metadata !39, metadata !"this", metadata !4, i32 4, metadata !26} ; [ DW_TAG_arg_variable ]
+!39 = metadata !{i32 458798, i32 0, metadata !8, metadata !"~test1", metadata !"~test1", metadata !"_ZN5test1D0Ev", metadata !4, i32 4, metadata !15, i1 false, i1 true, i32 1, i32 1, metadata !8, i1 false} ; [ DW_TAG_subprogram ]
+!40 = metadata !{i32 4, i32 0, metadata !39, null}
+!41 = metadata !{i32 5, i32 0, metadata !42, null}
+!42 = metadata !{i32 458763, metadata !39, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!43 = metadata !{i32 6, i32 0, metadata !42, null}
diff --git a/test/ExecutionEngine/2010-01-15-UndefValue.ll b/test/ExecutionEngine/2010-01-15-UndefValue.ll
index 7d646eb..33ca63a 100644
--- a/test/ExecutionEngine/2010-01-15-UndefValue.ll
+++ b/test/ExecutionEngine/2010-01-15-UndefValue.ll
@@ -3,7 +3,7 @@
define i32 @main() {
%a = add i32 0, undef
- %b = add float 0.0, undef
- %c = add double 0.0, undef
+ %b = fadd float 0.0, undef
+ %c = fadd double 0.0, undef
ret i32 0
}
diff --git a/test/Feature/alignment.ll b/test/Feature/alignment.ll
index 409efeb..ef35a13 100644
--- a/test/Feature/alignment.ll
+++ b/test/Feature/alignment.ll
@@ -19,3 +19,7 @@ define i32* @test2() {
ret i32* %X
}
+define void @test3() alignstack(16) {
+ ret void
+}
+
diff --git a/test/Feature/unions.ll b/test/Feature/unions.ll
new file mode 100644
index 0000000..9d6c36b
--- /dev/null
+++ b/test/Feature/unions.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llvm-dis > %t1.ll
+; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
+; RUN: diff %t1.ll %t2.ll
+
+%union.anon = type union { i8, i32, float }
+
+@union1 = constant union { i32, i8 } { i32 4 }
+@union2 = constant union { i32, i8 } insertvalue(union { i32, i8 } undef, i32 4, 0)
+
+define void @"Unions" () {
+ ret void
+}
diff --git a/test/FrontendC++/2010-02-08-NamespaceVar.cpp b/test/FrontendC++/2010-02-08-NamespaceVar.cpp
deleted file mode 100644
index cd8247a..0000000
--- a/test/FrontendC++/2010-02-08-NamespaceVar.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %llvmgxx -S %s -o - | grep cX
-
-namespace C {
- int c = 1;
- namespace {
- int cX = 6;
- void marker2() {
- cX;
- }
- }
-}
-
-int main() {
- C::marker2();
- return 0;
-}
diff --git a/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp b/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp
new file mode 100644
index 0000000..4c8e0e5
--- /dev/null
+++ b/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp
@@ -0,0 +1,14 @@
+// RUN: %llvmgcc -g -S %s -o - | grep DW_TAG_pointer_type | grep "i32 458767, metadata .., metadata ..., metadata .., i32 ., i64 .., i64 .., i64 0, i32 64, metadata ..."
+// Here, second to last argument "i32 64" indicates that artificial type is set.
+// Test to artificial attribute attahed to "this" pointer type.
+// Radar 7655792 and 7655002
+
+class A {
+public:
+ int fn1(int i) const { return i + 2; };
+};
+
+int foo() {
+ A a;
+ return a.fn1(1);
+}
diff --git a/test/FrontendC/2003-12-14-ExternInlineSupport.c b/test/FrontendC/2003-12-14-ExternInlineSupport.c
index 510d1f8..fb92ec7 100644
--- a/test/FrontendC/2003-12-14-ExternInlineSupport.c
+++ b/test/FrontendC/2003-12-14-ExternInlineSupport.c
@@ -1,3 +1,3 @@
-// RUN: %llvmgcc -Os -xc %s -c -o - | llvm-dis | not grep dead_function
+// RUN: %llvmgcc -xc %s -c -o - | llvm-dis | not grep dead_function
extern __inline__ void dead_function() {}
diff --git a/test/FrontendC/2007-02-16-WritableStrings.c b/test/FrontendC/2007-02-16-WritableStrings.c
index 811e330..0f281ce 100644
--- a/test/FrontendC/2007-02-16-WritableStrings.c
+++ b/test/FrontendC/2007-02-16-WritableStrings.c
@@ -1,7 +1,7 @@
// Test the -fwritable-strings option.
// RUN: %llvmgcc -O3 -S -o - -emit-llvm -fwritable-strings %s | \
-// RUN: grep {private global}
+// RUN: grep {internal global}
// RUN: %llvmgcc -O3 -S -o - -emit-llvm %s | grep {private constant}
char *X = "foo";
diff --git a/test/FrontendC/2007-09-17-WeakRef.c b/test/FrontendC/2007-09-17-WeakRef.c
index 3cdd47e..6c420ea 100644
--- a/test/FrontendC/2007-09-17-WeakRef.c
+++ b/test/FrontendC/2007-09-17-WeakRef.c
@@ -1,6 +1,6 @@
// RUN: %llvmgcc -O1 -S %s -o - | grep icmp
// PR1678
-// XFAIL: llvmgcc4.0.1
+
extern void B (void);
static __typeof(B) A __attribute__ ((__weakref__("B")));
int active (void)
diff --git a/test/FrontendC/2010-02-10-PointerName.c b/test/FrontendC/2010-02-10-PointerName.c
new file mode 100644
index 0000000..7880fa8
--- /dev/null
+++ b/test/FrontendC/2010-02-10-PointerName.c
@@ -0,0 +1,7 @@
+// RUN: %llvmgcc %s -S -g -o - | grep DW_TAG_pointer_type | grep -v char
+
+char i = 1;
+void foo() {
+ char *cp = &i;
+}
+
diff --git a/test/FrontendC/2010-02-15-DbgStaticVar.c b/test/FrontendC/2010-02-15-DbgStaticVar.c
new file mode 100644
index 0000000..7827d96
--- /dev/null
+++ b/test/FrontendC/2010-02-15-DbgStaticVar.c
@@ -0,0 +1,13 @@
+// RUN: %llvmgcc -g -S %s -o - | grep "metadata ..b., metadata ..b., metadata ...,"
+// Test to check intentionally empty linkage name for a static variable.
+// Radar 7651244.
+static int foo(int a)
+{
+ static int b = 1;
+ return b+a;
+}
+
+int main() {
+ int j = foo(1);
+ return 0;
+}
diff --git a/test/FrontendC/2010-02-16-DbgVarScope.c b/test/FrontendC/2010-02-16-DbgVarScope.c
new file mode 100644
index 0000000..1d912d0
--- /dev/null
+++ b/test/FrontendC/2010-02-16-DbgVarScope.c
@@ -0,0 +1,30 @@
+// RUN: %llvmgcc -S -O0 -g %s -o - | \
+// RUN: llc --disable-fp-elim -o %t.s -O0 -relocation-model=pic
+// RUN: %compile_c %t.s -o %t.o
+// RUN: %link %t.o -o %t.exe
+// RUN: echo {break 24\nrun\np loc\n} > %t.in
+// RN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | \
+// RN: grep {$1 = 1}
+
+int g1 = 1;
+int g2 = 2;
+
+int __attribute__((always_inline)) bar() {
+ return g2 - g1;
+}
+void foobar() {}
+
+void foo(int s) {
+ unsigned loc = 0;
+ if (s) {
+ loc = 1;
+ foobar();
+ } else {
+ loc = bar();
+ foobar();
+ }
+}
+
+int main() {
+ foo(0);
+}
diff --git a/test/FrontendC/2010-02-18-Dbg-VectorType.c b/test/FrontendC/2010-02-18-Dbg-VectorType.c
new file mode 100644
index 0000000..d34031f
--- /dev/null
+++ b/test/FrontendC/2010-02-18-Dbg-VectorType.c
@@ -0,0 +1,9 @@
+// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_typedef | grep float4
+typedef float float4 __attribute__((vector_size(16)));
+
+int main(){
+ volatile float4 x = (float4) { 0.0f, 1.0f, 2.0f, 3.0f };
+ x += x;
+ return 0;
+}
+
diff --git a/test/FrontendC/2010-03-5-LexicalScope.c b/test/FrontendC/2010-03-5-LexicalScope.c
new file mode 100644
index 0000000..93a841a
--- /dev/null
+++ b/test/FrontendC/2010-03-5-LexicalScope.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_lexical_block | count 3
+int foo(int i) {
+ if (i) {
+ int j = 2;
+ }
+ else {
+ int j = 3;
+ }
+ return i;
+}
diff --git a/test/FrontendObjC/2010-02-11-fwritable-stringsBug.m b/test/FrontendObjC/2010-02-11-fwritable-stringsBug.m
new file mode 100644
index 0000000..13e1631
--- /dev/null
+++ b/test/FrontendObjC/2010-02-11-fwritable-stringsBug.m
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -x objective-c -fwritable-strings -S %s -o - | FileCheck %s
+// CHECK: @.str = private constant
+// CHECK: @.str1 = internal global
+
+// rdar://7634471
+
+@class NSString;
+
+@interface A
+- (void)foo:(NSString*)msg;
+- (void)bar:(const char*)msg;
+@end
+
+void func(A *a) {
+ [a foo:@"Hello world!"];
+ [a bar:"Goodbye world!"];
+}
diff --git a/test/FrontendObjC/2010-02-23-DbgInheritance.m b/test/FrontendObjC/2010-02-23-DbgInheritance.m
new file mode 100644
index 0000000..7e1cf67
--- /dev/null
+++ b/test/FrontendObjC/2010-02-23-DbgInheritance.m
@@ -0,0 +1,9 @@
+// RUN: %llvmgcc %s -S -g -o - | grep -v DW_TAG_member
+// Interface P should not be a member of interface I in debug info.
+@interface P
+@end
+
+@interface I : P
+@end
+
+void fn(I *iptr) {}
diff --git a/test/LLVMC/AppendCmdHook.td b/test/LLVMC/AppendCmdHook.td
index 4a9d391..539a93f 100644
--- a/test/LLVMC/AppendCmdHook.td
+++ b/test/LLVMC/AppendCmdHook.td
@@ -13,14 +13,14 @@ def OptList : OptionList<[
]>;
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy_lang"),
(out_language "dummy_lang"),
(actions (case
- // CHECK: push_back("-arg1")
- // CHECK: push_back("-arg2")
+ // CHECK: , "-arg1"));
+ // CHECK: , "-arg2"));
(switch_on "dummy1"), (append_cmd "-arg1 -arg2"),
- // CHECK: push_back("-arg3")
+ // CHECK: , "-arg3"));
// CHECK: hooks::MyHook()
(switch_on "dummy2"), (append_cmd "-arg3 $CALL(MyHook)")))
]>;
diff --git a/test/LLVMC/EnvParentheses.td b/test/LLVMC/EnvParentheses.td
index 77aab95..c563171 100644
--- a/test/LLVMC/EnvParentheses.td
+++ b/test/LLVMC/EnvParentheses.td
@@ -1,13 +1,13 @@
// Check the fix for PR4157.
// http://llvm.org/bugs/show_bug.cgi?id=4157
// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t
-// RUN: not grep {)));} %t
+// RUN: not grep {FOO")));} %t
// RUN: %compile_cxx -fexceptions -x c++ %t
include "llvm/CompilerDriver/Common.td"
def dummy_tool : Tool<[
-(cmd_line "gcc -o $OUTFILE $INFILE $ENV(FOO)/bar"),
+(command "gcc $ENV(FOO)/bar"),
(in_language "dummy"),
(out_language "dummy")
]>;
diff --git a/test/LLVMC/ExternOptions.td b/test/LLVMC/ExternOptions.td
index a05f2ca..77cb4bf 100644
--- a/test/LLVMC/ExternOptions.td
+++ b/test/LLVMC/ExternOptions.td
@@ -13,7 +13,7 @@ def OptList : OptionList<[(switch_option "Wall", (extern)),
(prefix_list_option "L", (extern))]>;
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy"),
(out_language "dummy"),
(actions (case
diff --git a/test/LLVMC/ForwardAs.td b/test/LLVMC/ForwardAs.td
index ce6fbb0..7c3bd17 100644
--- a/test/LLVMC/ForwardAs.td
+++ b/test/LLVMC/ForwardAs.td
@@ -9,11 +9,11 @@ include "llvm/CompilerDriver/Common.td"
def OptList : OptionList<[(parameter_option "dummy", (extern))]>;
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy"),
(out_language "dummy"),
(actions (case
- // CHECK: vec.push_back("unique_name")
+ // CHECK: "unique_name"));
(not_empty "dummy"), (forward_as "dummy", "unique_name")))
]>;
diff --git a/test/LLVMC/ForwardTransformedValue.td b/test/LLVMC/ForwardTransformedValue.td
index e263453..2caef6c 100644
--- a/test/LLVMC/ForwardTransformedValue.td
+++ b/test/LLVMC/ForwardTransformedValue.td
@@ -13,7 +13,7 @@ def OptList : OptionList<[(parameter_option "a", (extern)),
// CHECK: std::string HookB
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy"),
(out_language "dummy"),
(actions (case
diff --git a/test/LLVMC/ForwardValue.td b/test/LLVMC/ForwardValue.td
index 31e395e..463235c 100644
--- a/test/LLVMC/ForwardValue.td
+++ b/test/LLVMC/ForwardValue.td
@@ -10,13 +10,13 @@ def OptList : OptionList<[(parameter_option "a", (extern)),
(prefix_list_option "b", (extern))]>;
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy"),
(out_language "dummy"),
(actions (case
- // CHECK: vec.push_back(AutoGeneratedParameter_a)
+ // CHECK: , AutoGeneratedParameter_a));
(not_empty "a"), (forward_value "a"),
- // CHECK: std::copy(AutoGeneratedList_b.begin()
+ // CHECK: B = AutoGeneratedList_b.begin()
(not_empty "b"), (forward_value "b")))
]>;
diff --git a/test/LLVMC/HookWithArguments.td b/test/LLVMC/HookWithArguments.td
index ba0bbe1..312fa9c 100644
--- a/test/LLVMC/HookWithArguments.td
+++ b/test/LLVMC/HookWithArguments.td
@@ -6,12 +6,12 @@
include "llvm/CompilerDriver/Common.td"
// CHECK: Hook(const char* Arg0, const char* Arg1, const char* Arg2);
+// CHECK: "/path"
// CHECK: std::getenv("VARIABLE")
// CHECK: "/2path"
-// CHECK: "/path"
def dummy_tool : Tool<[
-(cmd_line "$CALL(Hook, 'Arg1', 'Arg2', 'Arg3 Arg3Cont')/path arg1 $ENV(VARIABLE)/2path arg2 $INFILE"),
+(command "$CALL(Hook, 'Arg1', 'Arg2', 'Arg3 Arg3Cont')/path arg1 $ENV(VARIABLE)/2path arg2"),
(in_language "dummy"),
(out_language "dummy")
]>;
diff --git a/test/LLVMC/HookWithInFile.td b/test/LLVMC/HookWithInFile.td
index e15e43c..f58e3f4 100644
--- a/test/LLVMC/HookWithInFile.td
+++ b/test/LLVMC/HookWithInFile.td
@@ -7,7 +7,7 @@ include "llvm/CompilerDriver/Common.td"
def dummy_tool : Tool<[
// CHECK: Hook(inFile.c_str())
-(cmd_line "$CALL(Hook, '$INFILE')/path $INFILE"),
+(command "$CALL(Hook, '$INFILE')/path"),
(in_language "dummy"),
(out_language "dummy")
]>;
diff --git a/test/LLVMC/Init.td b/test/LLVMC/Init.td
index 355d83f..ff9a0d8 100644
--- a/test/LLVMC/Init.td
+++ b/test/LLVMC/Init.td
@@ -13,7 +13,7 @@ def OptList : OptionList<[
]>;
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy_lang"),
(out_language "dummy_lang"),
(actions (case
diff --git a/test/LLVMC/MultiValuedOption.td b/test/LLVMC/MultiValuedOption.td
index 8cb1878..b52af57 100644
--- a/test/LLVMC/MultiValuedOption.td
+++ b/test/LLVMC/MultiValuedOption.td
@@ -12,7 +12,7 @@ def OptList : OptionList<[
(parameter_list_option "baz", (multi_val 2), (extern))]>;
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy"),
(out_language "dummy"),
(actions (case
diff --git a/test/LLVMC/MultiplePluginPriorities.td b/test/LLVMC/MultiplePluginPriorities.td
index f108641..2fe0645 100644
--- a/test/LLVMC/MultiplePluginPriorities.td
+++ b/test/LLVMC/MultiplePluginPriorities.td
@@ -4,6 +4,10 @@
// Disable for Darwin PPC: <rdar://problem/7598390>
// XFAIL: powerpc-apple-darwin
+// Generally XFAIL'ed for now, this is (sometimes?) failing on x86_64-apple-darwin10.
+// RUN: false
+// XFAIL: *
+
include "llvm/CompilerDriver/Common.td"
def Graph : CompilationGraph<[]>;
diff --git a/test/LLVMC/NoActions.td b/test/LLVMC/NoActions.td
index 9c2d45a..015bfdd 100644
--- a/test/LLVMC/NoActions.td
+++ b/test/LLVMC/NoActions.td
@@ -7,7 +7,7 @@ include "llvm/CompilerDriver/Common.td"
// CHECK: class dummy_tool : public Tool {
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy"),
(out_language "dummy")
]>;
diff --git a/test/LLVMC/OneOrMore.td b/test/LLVMC/OneOrMore.td
index ddf7cd1..42ec693 100644
--- a/test/LLVMC/OneOrMore.td
+++ b/test/LLVMC/OneOrMore.td
@@ -13,7 +13,7 @@ def OptList : OptionList<[
(parameter_list_option "baz", (optional))]>;
def dummy_tool : Tool<[
-(cmd_line "dummy_cmd $INFILE"),
+(command "dummy_cmd"),
(in_language "dummy"),
(out_language "dummy"),
(actions (case
diff --git a/test/LLVMC/OptionPreprocessor.td b/test/LLVMC/OptionPreprocessor.td
index 8d748ee..8a31481 100644
--- a/test/LLVMC/OptionPreprocessor.td
+++ b/test/LLVMC/OptionPreprocessor.td
@@ -52,7 +52,7 @@ def dummy : Tool<
[(in_language "dummy"),
(out_language "dummy"),
(output_suffix "d"),
- (cmd_line "dummy $INFILE -o $OUTFILE"),
+ (command "dummy"),
(actions (case (switch_on "foo"), (error),
(switch_on "bar"), (error),
(switch_on "baz"), (error),
diff --git a/test/MC/AsmParser/X86/x86_32-bit_cat.s b/test/MC/AsmParser/X86/x86_32-bit_cat.s
index f610b13..f0c7804 100644
--- a/test/MC/AsmParser/X86/x86_32-bit_cat.s
+++ b/test/MC/AsmParser/X86/x86_32-bit_cat.s
@@ -1,7 +1,7 @@
// This is the current set of tests that can pass though llvm-mc as it were a
// logical cat(1) and then reassemble to the same instruction. All of these
// will not yet encode correctly. The subset that will encode correctly are in
-// the file x86_32-bit.s .
+// the file x86_32-encoding.s (and other tests that encode are in x86_32-bit.s).
// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
@@ -1104,6 +1104,48 @@
rcrb $0x7f,0x12345678
// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+ sall $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 69
+ sall $0,0x45
+
+// CHECK: shll $0, 32493
+ sall $0,0x7eed
+
+// CHECK: shll $0, 3133065982
+ sall $0,0xbabecafe
+
+// CHECK: shll $0, 305419896
+ sall $0,0x12345678
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+ salb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 69
+ salb $0x7f,0x45
+
+// CHECK: shlb $127, 32493
+ salb $0x7f,0x7eed
+
+// CHECK: shlb $127, 3133065982
+ salb $0x7f,0xbabecafe
+
+// CHECK: shlb $127, 305419896
+ salb $0x7f,0x12345678
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+ sall 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlw 32493
+ salw 0x7eed
+
+// CHECK: shll 3133065982
+ sall 0xbabecafe
+
+// CHECK: shll 305419896
+ sall 0x12345678
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
shll $0,0xdeadbeef(%ebx,%ecx,8)
// CHECK: shll $0, 69
@@ -1826,6 +1868,9 @@
// CHECK: verw 305419896
verw 0x12345678
+// CHECK: fld %st(2)
+ fld %st(2)
+
// CHECK: fldl 3735928559(%ebx,%ecx,8)
fldl 0xdeadbeef(%ebx,%ecx,8)
@@ -1835,6 +1880,9 @@
// CHECK: fldl 305419896
fldl 0x12345678
+// CHECK: fld %st(2)
+ fld %st(2)
+
// CHECK: fildl 3735928559(%ebx,%ecx,8)
fildl 0xdeadbeef(%ebx,%ecx,8)
@@ -1880,6 +1928,9 @@
// CHECK: fbld 305419896
fbld 0x12345678
+// CHECK: fst %st(2)
+ fst %st(2)
+
// CHECK: fstl 3735928559(%ebx,%ecx,8)
fstl 0xdeadbeef(%ebx,%ecx,8)
@@ -1889,6 +1940,9 @@
// CHECK: fstl 305419896
fstl 0x12345678
+// CHECK: fst %st(2)
+ fst %st(2)
+
// CHECK: fistl 3735928559(%ebx,%ecx,8)
fistl 0xdeadbeef(%ebx,%ecx,8)
@@ -1898,6 +1952,9 @@
// CHECK: fistl 305419896
fistl 0x12345678
+// CHECK: fstp %st(2)
+ fstp %st(2)
+
// CHECK: fstpl 3735928559(%ebx,%ecx,8)
fstpl 0xdeadbeef(%ebx,%ecx,8)
@@ -1907,6 +1964,9 @@
// CHECK: fstpl 305419896
fstpl 0x12345678
+// CHECK: fstp %st(2)
+ fstp %st(2)
+
// CHECK: fistpl 3735928559(%ebx,%ecx,8)
fistpl 0xdeadbeef(%ebx,%ecx,8)
@@ -1952,6 +2012,12 @@
// CHECK: fbstp 305419896
fbstp 0x12345678
+// CHECK: fxch %st(2)
+ fxch %st(2)
+
+// CHECK: fcom %st(2)
+ fcom %st(2)
+
// CHECK: fcoml 3735928559(%ebx,%ecx,8)
fcoml 0xdeadbeef(%ebx,%ecx,8)
@@ -1961,6 +2027,9 @@
// CHECK: fcoml 305419896
fcoml 0x12345678
+// CHECK: fcom %st(2)
+ fcom %st(2)
+
// CHECK: ficoml 3735928559(%ebx,%ecx,8)
ficoml 0xdeadbeef(%ebx,%ecx,8)
@@ -1970,6 +2039,9 @@
// CHECK: ficoml 305419896
ficoml 0x12345678
+// CHECK: fcomp %st(2)
+ fcomp %st(2)
+
// CHECK: fcompl 3735928559(%ebx,%ecx,8)
fcompl 0xdeadbeef(%ebx,%ecx,8)
@@ -1979,6 +2051,9 @@
// CHECK: fcompl 305419896
fcompl 0x12345678
+// CHECK: fcomp %st(2)
+ fcomp %st(2)
+
// CHECK: ficompl 3735928559(%ebx,%ecx,8)
ficompl 0xdeadbeef(%ebx,%ecx,8)
@@ -1991,6 +2066,12 @@
// CHECK: fcompp
fcompp
+// CHECK: fucom %st(2)
+ fucom %st(2)
+
+// CHECK: fucomp %st(2)
+ fucomp %st(2)
+
// CHECK: fucompp
fucompp
@@ -2021,6 +2102,9 @@
// CHECK: fldz
fldz
+// CHECK: fadd %st(2)
+ fadd %st(2)
+
// CHECK: faddl 3735928559(%ebx,%ecx,8)
faddl 0xdeadbeef(%ebx,%ecx,8)
@@ -2039,6 +2123,12 @@
// CHECK: fiaddl 305419896
fiaddl 0x12345678
+// CHECK: faddp %st(2)
+ faddp %st(2)
+
+// CHECK: fsub %st(2)
+ fsub %st(2)
+
// CHECK: fsubl 3735928559(%ebx,%ecx,8)
fsubl 0xdeadbeef(%ebx,%ecx,8)
@@ -2057,6 +2147,12 @@
// CHECK: fisubl 305419896
fisubl 0x12345678
+// CHECK: fsubp %st(2)
+ fsubp %st(2)
+
+// CHECK: fsubr %st(2)
+ fsubr %st(2)
+
// CHECK: fsubrl 3735928559(%ebx,%ecx,8)
fsubrl 0xdeadbeef(%ebx,%ecx,8)
@@ -2075,6 +2171,12 @@
// CHECK: fisubrl 305419896
fisubrl 0x12345678
+// CHECK: fsubrp %st(2)
+ fsubrp %st(2)
+
+// CHECK: fmul %st(2)
+ fmul %st(2)
+
// CHECK: fmull 3735928559(%ebx,%ecx,8)
fmull 0xdeadbeef(%ebx,%ecx,8)
@@ -2093,6 +2195,12 @@
// CHECK: fimull 305419896
fimull 0x12345678
+// CHECK: fmulp %st(2)
+ fmulp %st(2)
+
+// CHECK: fdiv %st(2)
+ fdiv %st(2)
+
// CHECK: fdivl 3735928559(%ebx,%ecx,8)
fdivl 0xdeadbeef(%ebx,%ecx,8)
@@ -2111,6 +2219,12 @@
// CHECK: fidivl 305419896
fidivl 0x12345678
+// CHECK: fdivp %st(2)
+ fdivp %st(2)
+
+// CHECK: fdivr %st(2)
+ fdivr %st(2)
+
// CHECK: fdivrl 3735928559(%ebx,%ecx,8)
fdivrl 0xdeadbeef(%ebx,%ecx,8)
@@ -2129,6 +2243,9 @@
// CHECK: fidivrl 305419896
fidivrl 0x12345678
+// CHECK: fdivrp %st(2)
+ fdivrp %st(2)
+
// CHECK: f2xm1
f2xm1
@@ -2228,6 +2345,9 @@
// CHECK: frstor 32493
frstor 0x7eed
+// CHECK: ffree %st(2)
+ ffree %st(2)
+
// CHECK: fnop
fnop
@@ -2297,6 +2417,42 @@
// CHECK: ud2
ud2
+// CHECK: fcmovb %st(2), %st(0)
+ fcmovb %st(2),%st
+
+// CHECK: fcmove %st(2), %st(0)
+ fcmove %st(2),%st
+
+// CHECK: fcmovbe %st(2), %st(0)
+ fcmovbe %st(2),%st
+
+// CHECK: fcmovu %st(2), %st(0)
+ fcmovu %st(2),%st
+
+// CHECK: fcmovnb %st(2), %st(0)
+ fcmovnb %st(2),%st
+
+// CHECK: fcmovne %st(2), %st(0)
+ fcmovne %st(2),%st
+
+// CHECK: fcmovnbe %st(2), %st(0)
+ fcmovnbe %st(2),%st
+
+// CHECK: fcmovnu %st(2), %st(0)
+ fcmovnu %st(2),%st
+
+// CHECK: fcomi %st(2), %st(0)
+ fcomi %st(2),%st
+
+// CHECK: fucomi %st(2), %st(0)
+ fucomi %st(2),%st
+
+// CHECK: fcomip %st(2), %st(0)
+ fcomip %st(2),%st
+
+// CHECK: fucomip %st(2), %st(0)
+ fucomip %st(2),%st
+
// CHECK: movnti %ecx, 3735928559(%ebx,%ecx,8)
movnti %ecx,0xdeadbeef(%ebx,%ecx,8)
diff --git a/test/MC/AsmParser/X86/x86_32-encoding.s b/test/MC/AsmParser/X86/x86_32-encoding.s
index e029ded..e325bdd 100644
--- a/test/MC/AsmParser/X86/x86_32-encoding.s
+++ b/test/MC/AsmParser/X86/x86_32-encoding.s
@@ -1,13 +1,9861 @@
-// RUN: llvm-mc -triple i386-unknown-unknown %s -show-encoding | FileCheck %s
+// RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck %s
-fisttpl 3735928559(%ebx,%ecx,8)
-# CHECK: encoding: [0xdb,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+// CHECK: movb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc6,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ movb $0x7f,0xdeadbeef(%ebx,%ecx,8)
-sbbb $0xfe,0xdeadbeef(%ebx,%ecx,8)
-# CHECK: encoding: [0x80,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+// CHECK: movb $127, 69
+// CHECK: encoding: [0xc6,0x05,0x45,0x00,0x00,0x00,0x7f]
+ movb $0x7f,0x45
-psllw 69, %mm3
-# CHECK: encoding: [0x0f,0xf1,0x1d,0x45,0x00,0x00,0x00]
+// CHECK: movb $127, 32493
+// CHECK: encoding: [0xc6,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ movb $0x7f,0x7eed
-movntdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
-# CHECK: encoding: [0x66,0x0f,0x38,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+// CHECK: movb $127, 3133065982
+// CHECK: encoding: [0xc6,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ movb $0x7f,0xbabecafe
+
+// CHECK: movb $127, 305419896
+// CHECK: encoding: [0xc6,0x05,0x78,0x56,0x34,0x12,0x7f]
+ movb $0x7f,0x12345678
+
+// CHECK: movw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0xc7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ movw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movw $31438, 69
+// CHECK: encoding: [0x66,0xc7,0x05,0x45,0x00,0x00,0x00,0xce,0x7a]
+ movw $0x7ace,0x45
+
+// CHECK: movw $31438, 32493
+// CHECK: encoding: [0x66,0xc7,0x05,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ movw $0x7ace,0x7eed
+
+// CHECK: movw $31438, 3133065982
+// CHECK: encoding: [0x66,0xc7,0x05,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ movw $0x7ace,0xbabecafe
+
+// CHECK: movw $31438, 305419896
+// CHECK: encoding: [0x66,0xc7,0x05,0x78,0x56,0x34,0x12,0xce,0x7a]
+ movw $0x7ace,0x12345678
+
+// CHECK: movl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $2063514302, 69
+// CHECK: encoding: [0xc7,0x05,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0x45
+
+// CHECK: movl $2063514302, 32493
+// CHECK: encoding: [0xc7,0x05,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0x7eed
+
+// CHECK: movl $2063514302, 3133065982
+// CHECK: encoding: [0xc7,0x05,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0xbabecafe
+
+// CHECK: movl $2063514302, 305419896
+// CHECK: encoding: [0xc7,0x05,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0x12345678
+
+// CHECK: movl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc7,0x84,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $324478056, 69
+// CHECK: encoding: [0xc7,0x05,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0x45
+
+// CHECK: movl $324478056, 32493
+// CHECK: encoding: [0xc7,0x05,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0x7eed
+
+// CHECK: movl $324478056, 3133065982
+// CHECK: encoding: [0xc7,0x05,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0xbabecafe
+
+// CHECK: movl $324478056, 305419896
+// CHECK: encoding: [0xc7,0x05,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0x12345678
+
+// CHECK: movsbl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xbe,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movsbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movsbl 69, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0x45,0x00,0x00,0x00]
+ movsbl 0x45,%ecx
+
+// CHECK: movsbl 32493, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0xed,0x7e,0x00,0x00]
+ movsbl 0x7eed,%ecx
+
+// CHECK: movsbl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0xfe,0xca,0xbe,0xba]
+ movsbl 0xbabecafe,%ecx
+
+// CHECK: movsbl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0x78,0x56,0x34,0x12]
+ movsbl 0x12345678,%ecx
+
+// CHECK: movsbw 3735928559(%ebx,%ecx,8), %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movsbw 0xdeadbeef(%ebx,%ecx,8),%bx
+
+// CHECK: movsbw 69, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0x45,0x00,0x00,0x00]
+ movsbw 0x45,%bx
+
+// CHECK: movsbw 32493, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0xed,0x7e,0x00,0x00]
+ movsbw 0x7eed,%bx
+
+// CHECK: movsbw 3133065982, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0xfe,0xca,0xbe,0xba]
+ movsbw 0xbabecafe,%bx
+
+// CHECK: movsbw 305419896, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0x78,0x56,0x34,0x12]
+ movsbw 0x12345678,%bx
+
+// CHECK: movswl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xbf,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movswl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movswl 69, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0x45,0x00,0x00,0x00]
+ movswl 0x45,%ecx
+
+// CHECK: movswl 32493, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0xed,0x7e,0x00,0x00]
+ movswl 0x7eed,%ecx
+
+// CHECK: movswl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0xfe,0xca,0xbe,0xba]
+ movswl 0xbabecafe,%ecx
+
+// CHECK: movswl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0x78,0x56,0x34,0x12]
+ movswl 0x12345678,%ecx
+
+// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xb6,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movzbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzbl 69, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0x45,0x00,0x00,0x00]
+ movzbl 0x45,%ecx
+
+// CHECK: movzbl 32493, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0xed,0x7e,0x00,0x00]
+ movzbl 0x7eed,%ecx
+
+// CHECK: movzbl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0xfe,0xca,0xbe,0xba]
+ movzbl 0xbabecafe,%ecx
+
+// CHECK: movzbl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0x78,0x56,0x34,0x12]
+ movzbl 0x12345678,%ecx
+
+// CHECK: movzbw 3735928559(%ebx,%ecx,8), %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movzbw 0xdeadbeef(%ebx,%ecx,8),%bx
+
+// CHECK: movzbw 69, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0x45,0x00,0x00,0x00]
+ movzbw 0x45,%bx
+
+// CHECK: movzbw 32493, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0xed,0x7e,0x00,0x00]
+ movzbw 0x7eed,%bx
+
+// CHECK: movzbw 3133065982, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0xfe,0xca,0xbe,0xba]
+ movzbw 0xbabecafe,%bx
+
+// CHECK: movzbw 305419896, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0x78,0x56,0x34,0x12]
+ movzbw 0x12345678,%bx
+
+// CHECK: movzwl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xb7,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movzwl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzwl 69, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0x45,0x00,0x00,0x00]
+ movzwl 0x45,%ecx
+
+// CHECK: movzwl 32493, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0xed,0x7e,0x00,0x00]
+ movzwl 0x7eed,%ecx
+
+// CHECK: movzwl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0xfe,0xca,0xbe,0xba]
+ movzwl 0xbabecafe,%ecx
+
+// CHECK: movzwl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0x78,0x56,0x34,0x12]
+ movzwl 0x12345678,%ecx
+
+// CHECK: pushl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ pushl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: pushw 32493
+// CHECK: encoding: [0x66,0xff,0x35,0xed,0x7e,0x00,0x00]
+ pushw 0x7eed
+
+// CHECK: pushl 3133065982
+// CHECK: encoding: [0xff,0x35,0xfe,0xca,0xbe,0xba]
+ pushl 0xbabecafe
+
+// CHECK: pushl 305419896
+// CHECK: encoding: [0xff,0x35,0x78,0x56,0x34,0x12]
+ pushl 0x12345678
+
+// CHECK: popl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x8f,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ popl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: popw 32493
+// CHECK: encoding: [0x66,0x8f,0x05,0xed,0x7e,0x00,0x00]
+ popw 0x7eed
+
+// CHECK: popl 3133065982
+// CHECK: encoding: [0x8f,0x05,0xfe,0xca,0xbe,0xba]
+ popl 0xbabecafe
+
+// CHECK: popl 305419896
+// CHECK: encoding: [0x8f,0x05,0x78,0x56,0x34,0x12]
+ popl 0x12345678
+
+// CHECK: clc
+// CHECK: encoding: [0xf8]
+ clc
+
+// CHECK: cld
+// CHECK: encoding: [0xfc]
+ cld
+
+// CHECK: cli
+// CHECK: encoding: [0xfa]
+ cli
+
+// CHECK: clts
+// CHECK: encoding: [0x0f,0x06]
+ clts
+
+// CHECK: cmc
+// CHECK: encoding: [0xf5]
+ cmc
+
+// CHECK: lahf
+// CHECK: encoding: [0x9f]
+ lahf
+
+// CHECK: sahf
+// CHECK: encoding: [0x9e]
+ sahf
+
+// CHECK: stc
+// CHECK: encoding: [0xf9]
+ stc
+
+// CHECK: std
+// CHECK: encoding: [0xfd]
+ std
+
+// CHECK: sti
+// CHECK: encoding: [0xfb]
+ sti
+
+// CHECK: addb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x84,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ addb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addb $254, 69
+// CHECK: encoding: [0x80,0x05,0x45,0x00,0x00,0x00,0xfe]
+ addb $0xfe,0x45
+
+// CHECK: addb $254, 32493
+// CHECK: encoding: [0x80,0x05,0xed,0x7e,0x00,0x00,0xfe]
+ addb $0xfe,0x7eed
+
+// CHECK: addb $254, 3133065982
+// CHECK: encoding: [0x80,0x05,0xfe,0xca,0xbe,0xba,0xfe]
+ addb $0xfe,0xbabecafe
+
+// CHECK: addb $254, 305419896
+// CHECK: encoding: [0x80,0x05,0x78,0x56,0x34,0x12,0xfe]
+ addb $0xfe,0x12345678
+
+// CHECK: addb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ addb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addb $127, 69
+// CHECK: encoding: [0x80,0x05,0x45,0x00,0x00,0x00,0x7f]
+ addb $0x7f,0x45
+
+// CHECK: addb $127, 32493
+// CHECK: encoding: [0x80,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ addb $0x7f,0x7eed
+
+// CHECK: addb $127, 3133065982
+// CHECK: encoding: [0x80,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ addb $0x7f,0xbabecafe
+
+// CHECK: addb $127, 305419896
+// CHECK: encoding: [0x80,0x05,0x78,0x56,0x34,0x12,0x7f]
+ addb $0x7f,0x12345678
+
+// CHECK: addw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x84,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ addw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x05,0x45,0x00,0x00,0x00,0xce,0x7a]
+ addw $0x7ace,0x45
+
+// CHECK: addw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x05,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ addw $0x7ace,0x7eed
+
+// CHECK: addw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x05,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ addw $0x7ace,0xbabecafe
+
+// CHECK: addw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x05,0x78,0x56,0x34,0x12,0xce,0x7a]
+ addw $0x7ace,0x12345678
+
+// CHECK: addl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x84,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $2063514302, 69
+// CHECK: encoding: [0x81,0x05,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0x45
+
+// CHECK: addl $2063514302, 32493
+// CHECK: encoding: [0x81,0x05,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0x7eed
+
+// CHECK: addl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x05,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0xbabecafe
+
+// CHECK: addl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x05,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0x12345678
+
+// CHECK: addl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x84,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $324478056, 69
+// CHECK: encoding: [0x81,0x05,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0x45
+
+// CHECK: addl $324478056, 32493
+// CHECK: encoding: [0x81,0x05,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0x7eed
+
+// CHECK: addl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x05,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0xbabecafe
+
+// CHECK: addl $324478056, 305419896
+// CHECK: encoding: [0x81,0x05,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0x12345678
+
+// CHECK: incl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ incl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: incw 32493
+// CHECK: encoding: [0x66,0xff,0x05,0xed,0x7e,0x00,0x00]
+ incw 0x7eed
+
+// CHECK: incl 3133065982
+// CHECK: encoding: [0xff,0x05,0xfe,0xca,0xbe,0xba]
+ incl 0xbabecafe
+
+// CHECK: incl 305419896
+// CHECK: encoding: [0xff,0x05,0x78,0x56,0x34,0x12]
+ incl 0x12345678
+
+// CHECK: subb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xac,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ subb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $254, 69
+// CHECK: encoding: [0x80,0x2d,0x45,0x00,0x00,0x00,0xfe]
+ subb $0xfe,0x45
+
+// CHECK: subb $254, 32493
+// CHECK: encoding: [0x80,0x2d,0xed,0x7e,0x00,0x00,0xfe]
+ subb $0xfe,0x7eed
+
+// CHECK: subb $254, 3133065982
+// CHECK: encoding: [0x80,0x2d,0xfe,0xca,0xbe,0xba,0xfe]
+ subb $0xfe,0xbabecafe
+
+// CHECK: subb $254, 305419896
+// CHECK: encoding: [0x80,0x2d,0x78,0x56,0x34,0x12,0xfe]
+ subb $0xfe,0x12345678
+
+// CHECK: subb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xac,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ subb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $127, 69
+// CHECK: encoding: [0x80,0x2d,0x45,0x00,0x00,0x00,0x7f]
+ subb $0x7f,0x45
+
+// CHECK: subb $127, 32493
+// CHECK: encoding: [0x80,0x2d,0xed,0x7e,0x00,0x00,0x7f]
+ subb $0x7f,0x7eed
+
+// CHECK: subb $127, 3133065982
+// CHECK: encoding: [0x80,0x2d,0xfe,0xca,0xbe,0xba,0x7f]
+ subb $0x7f,0xbabecafe
+
+// CHECK: subb $127, 305419896
+// CHECK: encoding: [0x80,0x2d,0x78,0x56,0x34,0x12,0x7f]
+ subb $0x7f,0x12345678
+
+// CHECK: subw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xac,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ subw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x2d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ subw $0x7ace,0x45
+
+// CHECK: subw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x2d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ subw $0x7ace,0x7eed
+
+// CHECK: subw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x2d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ subw $0x7ace,0xbabecafe
+
+// CHECK: subw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x2d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ subw $0x7ace,0x12345678
+
+// CHECK: subl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xac,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $2063514302, 69
+// CHECK: encoding: [0x81,0x2d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0x45
+
+// CHECK: subl $2063514302, 32493
+// CHECK: encoding: [0x81,0x2d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0x7eed
+
+// CHECK: subl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x2d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0xbabecafe
+
+// CHECK: subl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x2d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0x12345678
+
+// CHECK: subl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xac,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $324478056, 69
+// CHECK: encoding: [0x81,0x2d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0x45
+
+// CHECK: subl $324478056, 32493
+// CHECK: encoding: [0x81,0x2d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0x7eed
+
+// CHECK: subl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x2d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0xbabecafe
+
+// CHECK: subl $324478056, 305419896
+// CHECK: encoding: [0x81,0x2d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0x12345678
+
+// CHECK: decl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ decl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: decw 32493
+// CHECK: encoding: [0x66,0xff,0x0d,0xed,0x7e,0x00,0x00]
+ decw 0x7eed
+
+// CHECK: decl 3133065982
+// CHECK: encoding: [0xff,0x0d,0xfe,0xca,0xbe,0xba]
+ decl 0xbabecafe
+
+// CHECK: decl 305419896
+// CHECK: encoding: [0xff,0x0d,0x78,0x56,0x34,0x12]
+ decl 0x12345678
+
+// CHECK: sbbb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ sbbb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbb $254, 69
+// CHECK: encoding: [0x80,0x1d,0x45,0x00,0x00,0x00,0xfe]
+ sbbb $0xfe,0x45
+
+// CHECK: sbbb $254, 32493
+// CHECK: encoding: [0x80,0x1d,0xed,0x7e,0x00,0x00,0xfe]
+ sbbb $0xfe,0x7eed
+
+// CHECK: sbbb $254, 3133065982
+// CHECK: encoding: [0x80,0x1d,0xfe,0xca,0xbe,0xba,0xfe]
+ sbbb $0xfe,0xbabecafe
+
+// CHECK: sbbb $254, 305419896
+// CHECK: encoding: [0x80,0x1d,0x78,0x56,0x34,0x12,0xfe]
+ sbbb $0xfe,0x12345678
+
+// CHECK: sbbb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x9c,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ sbbb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbb $127, 69
+// CHECK: encoding: [0x80,0x1d,0x45,0x00,0x00,0x00,0x7f]
+ sbbb $0x7f,0x45
+
+// CHECK: sbbb $127, 32493
+// CHECK: encoding: [0x80,0x1d,0xed,0x7e,0x00,0x00,0x7f]
+ sbbb $0x7f,0x7eed
+
+// CHECK: sbbb $127, 3133065982
+// CHECK: encoding: [0x80,0x1d,0xfe,0xca,0xbe,0xba,0x7f]
+ sbbb $0x7f,0xbabecafe
+
+// CHECK: sbbb $127, 305419896
+// CHECK: encoding: [0x80,0x1d,0x78,0x56,0x34,0x12,0x7f]
+ sbbb $0x7f,0x12345678
+
+// CHECK: sbbw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ sbbw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x1d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ sbbw $0x7ace,0x45
+
+// CHECK: sbbw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x1d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ sbbw $0x7ace,0x7eed
+
+// CHECK: sbbw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x1d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ sbbw $0x7ace,0xbabecafe
+
+// CHECK: sbbw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x1d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ sbbw $0x7ace,0x12345678
+
+// CHECK: sbbl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $2063514302, 69
+// CHECK: encoding: [0x81,0x1d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0x45
+
+// CHECK: sbbl $2063514302, 32493
+// CHECK: encoding: [0x81,0x1d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0x7eed
+
+// CHECK: sbbl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x1d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0xbabecafe
+
+// CHECK: sbbl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x1d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0x12345678
+
+// CHECK: sbbl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x9c,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $324478056, 69
+// CHECK: encoding: [0x81,0x1d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0x45
+
+// CHECK: sbbl $324478056, 32493
+// CHECK: encoding: [0x81,0x1d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0x7eed
+
+// CHECK: sbbl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x1d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0xbabecafe
+
+// CHECK: sbbl $324478056, 305419896
+// CHECK: encoding: [0x81,0x1d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0x12345678
+
+// CHECK: cmpb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xbc,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ cmpb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $254, 69
+// CHECK: encoding: [0x80,0x3d,0x45,0x00,0x00,0x00,0xfe]
+ cmpb $0xfe,0x45
+
+// CHECK: cmpb $254, 32493
+// CHECK: encoding: [0x80,0x3d,0xed,0x7e,0x00,0x00,0xfe]
+ cmpb $0xfe,0x7eed
+
+// CHECK: cmpb $254, 3133065982
+// CHECK: encoding: [0x80,0x3d,0xfe,0xca,0xbe,0xba,0xfe]
+ cmpb $0xfe,0xbabecafe
+
+// CHECK: cmpb $254, 305419896
+// CHECK: encoding: [0x80,0x3d,0x78,0x56,0x34,0x12,0xfe]
+ cmpb $0xfe,0x12345678
+
+// CHECK: cmpb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ cmpb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $127, 69
+// CHECK: encoding: [0x80,0x3d,0x45,0x00,0x00,0x00,0x7f]
+ cmpb $0x7f,0x45
+
+// CHECK: cmpb $127, 32493
+// CHECK: encoding: [0x80,0x3d,0xed,0x7e,0x00,0x00,0x7f]
+ cmpb $0x7f,0x7eed
+
+// CHECK: cmpb $127, 3133065982
+// CHECK: encoding: [0x80,0x3d,0xfe,0xca,0xbe,0xba,0x7f]
+ cmpb $0x7f,0xbabecafe
+
+// CHECK: cmpb $127, 305419896
+// CHECK: encoding: [0x80,0x3d,0x78,0x56,0x34,0x12,0x7f]
+ cmpb $0x7f,0x12345678
+
+// CHECK: cmpw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xbc,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ cmpw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x3d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ cmpw $0x7ace,0x45
+
+// CHECK: cmpw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x3d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ cmpw $0x7ace,0x7eed
+
+// CHECK: cmpw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x3d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ cmpw $0x7ace,0xbabecafe
+
+// CHECK: cmpw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x3d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ cmpw $0x7ace,0x12345678
+
+// CHECK: cmpl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xbc,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $2063514302, 69
+// CHECK: encoding: [0x81,0x3d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0x45
+
+// CHECK: cmpl $2063514302, 32493
+// CHECK: encoding: [0x81,0x3d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0x7eed
+
+// CHECK: cmpl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x3d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0xbabecafe
+
+// CHECK: cmpl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x3d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0x12345678
+
+// CHECK: cmpl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $324478056, 69
+// CHECK: encoding: [0x81,0x3d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0x45
+
+// CHECK: cmpl $324478056, 32493
+// CHECK: encoding: [0x81,0x3d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0x7eed
+
+// CHECK: cmpl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x3d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0xbabecafe
+
+// CHECK: cmpl $324478056, 305419896
+// CHECK: encoding: [0x81,0x3d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0x12345678
+
+// CHECK: testb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf6,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ testb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testb $127, 69
+// CHECK: encoding: [0xf6,0x05,0x45,0x00,0x00,0x00,0x7f]
+ testb $0x7f,0x45
+
+// CHECK: testb $127, 32493
+// CHECK: encoding: [0xf6,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ testb $0x7f,0x7eed
+
+// CHECK: testb $127, 3133065982
+// CHECK: encoding: [0xf6,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ testb $0x7f,0xbabecafe
+
+// CHECK: testb $127, 305419896
+// CHECK: encoding: [0xf6,0x05,0x78,0x56,0x34,0x12,0x7f]
+ testb $0x7f,0x12345678
+
+// CHECK: testw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0xf7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ testw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testw $31438, 69
+// CHECK: encoding: [0x66,0xf7,0x05,0x45,0x00,0x00,0x00,0xce,0x7a]
+ testw $0x7ace,0x45
+
+// CHECK: testw $31438, 32493
+// CHECK: encoding: [0x66,0xf7,0x05,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ testw $0x7ace,0x7eed
+
+// CHECK: testw $31438, 3133065982
+// CHECK: encoding: [0x66,0xf7,0x05,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ testw $0x7ace,0xbabecafe
+
+// CHECK: testw $31438, 305419896
+// CHECK: encoding: [0x66,0xf7,0x05,0x78,0x56,0x34,0x12,0xce,0x7a]
+ testw $0x7ace,0x12345678
+
+// CHECK: testl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $2063514302, 69
+// CHECK: encoding: [0xf7,0x05,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0x45
+
+// CHECK: testl $2063514302, 32493
+// CHECK: encoding: [0xf7,0x05,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0x7eed
+
+// CHECK: testl $2063514302, 3133065982
+// CHECK: encoding: [0xf7,0x05,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0xbabecafe
+
+// CHECK: testl $2063514302, 305419896
+// CHECK: encoding: [0xf7,0x05,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0x12345678
+
+// CHECK: testl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x84,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $324478056, 69
+// CHECK: encoding: [0xf7,0x05,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0x45
+
+// CHECK: testl $324478056, 32493
+// CHECK: encoding: [0xf7,0x05,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0x7eed
+
+// CHECK: testl $324478056, 3133065982
+// CHECK: encoding: [0xf7,0x05,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0xbabecafe
+
+// CHECK: testl $324478056, 305419896
+// CHECK: encoding: [0xf7,0x05,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0x12345678
+
+// CHECK: andb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xa4,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ andb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $254, 69
+// CHECK: encoding: [0x80,0x25,0x45,0x00,0x00,0x00,0xfe]
+ andb $0xfe,0x45
+
+// CHECK: andb $254, 32493
+// CHECK: encoding: [0x80,0x25,0xed,0x7e,0x00,0x00,0xfe]
+ andb $0xfe,0x7eed
+
+// CHECK: andb $254, 3133065982
+// CHECK: encoding: [0x80,0x25,0xfe,0xca,0xbe,0xba,0xfe]
+ andb $0xfe,0xbabecafe
+
+// CHECK: andb $254, 305419896
+// CHECK: encoding: [0x80,0x25,0x78,0x56,0x34,0x12,0xfe]
+ andb $0xfe,0x12345678
+
+// CHECK: andb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ andb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $127, 69
+// CHECK: encoding: [0x80,0x25,0x45,0x00,0x00,0x00,0x7f]
+ andb $0x7f,0x45
+
+// CHECK: andb $127, 32493
+// CHECK: encoding: [0x80,0x25,0xed,0x7e,0x00,0x00,0x7f]
+ andb $0x7f,0x7eed
+
+// CHECK: andb $127, 3133065982
+// CHECK: encoding: [0x80,0x25,0xfe,0xca,0xbe,0xba,0x7f]
+ andb $0x7f,0xbabecafe
+
+// CHECK: andb $127, 305419896
+// CHECK: encoding: [0x80,0x25,0x78,0x56,0x34,0x12,0x7f]
+ andb $0x7f,0x12345678
+
+// CHECK: andw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xa4,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ andw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x25,0x45,0x00,0x00,0x00,0xce,0x7a]
+ andw $0x7ace,0x45
+
+// CHECK: andw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x25,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ andw $0x7ace,0x7eed
+
+// CHECK: andw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x25,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ andw $0x7ace,0xbabecafe
+
+// CHECK: andw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x25,0x78,0x56,0x34,0x12,0xce,0x7a]
+ andw $0x7ace,0x12345678
+
+// CHECK: andl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xa4,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $2063514302, 69
+// CHECK: encoding: [0x81,0x25,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0x45
+
+// CHECK: andl $2063514302, 32493
+// CHECK: encoding: [0x81,0x25,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0x7eed
+
+// CHECK: andl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x25,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0xbabecafe
+
+// CHECK: andl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x25,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0x12345678
+
+// CHECK: andl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $324478056, 69
+// CHECK: encoding: [0x81,0x25,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0x45
+
+// CHECK: andl $324478056, 32493
+// CHECK: encoding: [0x81,0x25,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0x7eed
+
+// CHECK: andl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x25,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0xbabecafe
+
+// CHECK: andl $324478056, 305419896
+// CHECK: encoding: [0x81,0x25,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0x12345678
+
+// CHECK: orb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x8c,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ orb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $254, 69
+// CHECK: encoding: [0x80,0x0d,0x45,0x00,0x00,0x00,0xfe]
+ orb $0xfe,0x45
+
+// CHECK: orb $254, 32493
+// CHECK: encoding: [0x80,0x0d,0xed,0x7e,0x00,0x00,0xfe]
+ orb $0xfe,0x7eed
+
+// CHECK: orb $254, 3133065982
+// CHECK: encoding: [0x80,0x0d,0xfe,0xca,0xbe,0xba,0xfe]
+ orb $0xfe,0xbabecafe
+
+// CHECK: orb $254, 305419896
+// CHECK: encoding: [0x80,0x0d,0x78,0x56,0x34,0x12,0xfe]
+ orb $0xfe,0x12345678
+
+// CHECK: orb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ orb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $127, 69
+// CHECK: encoding: [0x80,0x0d,0x45,0x00,0x00,0x00,0x7f]
+ orb $0x7f,0x45
+
+// CHECK: orb $127, 32493
+// CHECK: encoding: [0x80,0x0d,0xed,0x7e,0x00,0x00,0x7f]
+ orb $0x7f,0x7eed
+
+// CHECK: orb $127, 3133065982
+// CHECK: encoding: [0x80,0x0d,0xfe,0xca,0xbe,0xba,0x7f]
+ orb $0x7f,0xbabecafe
+
+// CHECK: orb $127, 305419896
+// CHECK: encoding: [0x80,0x0d,0x78,0x56,0x34,0x12,0x7f]
+ orb $0x7f,0x12345678
+
+// CHECK: orw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x8c,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ orw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x0d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ orw $0x7ace,0x45
+
+// CHECK: orw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x0d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ orw $0x7ace,0x7eed
+
+// CHECK: orw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x0d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ orw $0x7ace,0xbabecafe
+
+// CHECK: orw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x0d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ orw $0x7ace,0x12345678
+
+// CHECK: orl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x8c,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $2063514302, 69
+// CHECK: encoding: [0x81,0x0d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0x45
+
+// CHECK: orl $2063514302, 32493
+// CHECK: encoding: [0x81,0x0d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0x7eed
+
+// CHECK: orl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x0d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0xbabecafe
+
+// CHECK: orl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x0d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0x12345678
+
+// CHECK: orl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $324478056, 69
+// CHECK: encoding: [0x81,0x0d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0x45
+
+// CHECK: orl $324478056, 32493
+// CHECK: encoding: [0x81,0x0d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0x7eed
+
+// CHECK: orl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x0d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0xbabecafe
+
+// CHECK: orl $324478056, 305419896
+// CHECK: encoding: [0x81,0x0d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0x12345678
+
+// CHECK: xorb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xb4,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ xorb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $254, 69
+// CHECK: encoding: [0x80,0x35,0x45,0x00,0x00,0x00,0xfe]
+ xorb $0xfe,0x45
+
+// CHECK: xorb $254, 32493
+// CHECK: encoding: [0x80,0x35,0xed,0x7e,0x00,0x00,0xfe]
+ xorb $0xfe,0x7eed
+
+// CHECK: xorb $254, 3133065982
+// CHECK: encoding: [0x80,0x35,0xfe,0xca,0xbe,0xba,0xfe]
+ xorb $0xfe,0xbabecafe
+
+// CHECK: xorb $254, 305419896
+// CHECK: encoding: [0x80,0x35,0x78,0x56,0x34,0x12,0xfe]
+ xorb $0xfe,0x12345678
+
+// CHECK: xorb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xb4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ xorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $127, 69
+// CHECK: encoding: [0x80,0x35,0x45,0x00,0x00,0x00,0x7f]
+ xorb $0x7f,0x45
+
+// CHECK: xorb $127, 32493
+// CHECK: encoding: [0x80,0x35,0xed,0x7e,0x00,0x00,0x7f]
+ xorb $0x7f,0x7eed
+
+// CHECK: xorb $127, 3133065982
+// CHECK: encoding: [0x80,0x35,0xfe,0xca,0xbe,0xba,0x7f]
+ xorb $0x7f,0xbabecafe
+
+// CHECK: xorb $127, 305419896
+// CHECK: encoding: [0x80,0x35,0x78,0x56,0x34,0x12,0x7f]
+ xorb $0x7f,0x12345678
+
+// CHECK: xorw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xb4,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ xorw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x35,0x45,0x00,0x00,0x00,0xce,0x7a]
+ xorw $0x7ace,0x45
+
+// CHECK: xorw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x35,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ xorw $0x7ace,0x7eed
+
+// CHECK: xorw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x35,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ xorw $0x7ace,0xbabecafe
+
+// CHECK: xorw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x35,0x78,0x56,0x34,0x12,0xce,0x7a]
+ xorw $0x7ace,0x12345678
+
+// CHECK: xorl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xb4,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $2063514302, 69
+// CHECK: encoding: [0x81,0x35,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0x45
+
+// CHECK: xorl $2063514302, 32493
+// CHECK: encoding: [0x81,0x35,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0x7eed
+
+// CHECK: xorl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x35,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0xbabecafe
+
+// CHECK: xorl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x35,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0x12345678
+
+// CHECK: xorl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xb4,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $324478056, 69
+// CHECK: encoding: [0x81,0x35,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0x45
+
+// CHECK: xorl $324478056, 32493
+// CHECK: encoding: [0x81,0x35,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0x7eed
+
+// CHECK: xorl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x35,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0xbabecafe
+
+// CHECK: xorl $324478056, 305419896
+// CHECK: encoding: [0x81,0x35,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0x12345678
+
+// CHECK: adcb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x94,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ adcb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $254, 69
+// CHECK: encoding: [0x80,0x15,0x45,0x00,0x00,0x00,0xfe]
+ adcb $0xfe,0x45
+
+// CHECK: adcb $254, 32493
+// CHECK: encoding: [0x80,0x15,0xed,0x7e,0x00,0x00,0xfe]
+ adcb $0xfe,0x7eed
+
+// CHECK: adcb $254, 3133065982
+// CHECK: encoding: [0x80,0x15,0xfe,0xca,0xbe,0xba,0xfe]
+ adcb $0xfe,0xbabecafe
+
+// CHECK: adcb $254, 305419896
+// CHECK: encoding: [0x80,0x15,0x78,0x56,0x34,0x12,0xfe]
+ adcb $0xfe,0x12345678
+
+// CHECK: adcb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x94,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ adcb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $127, 69
+// CHECK: encoding: [0x80,0x15,0x45,0x00,0x00,0x00,0x7f]
+ adcb $0x7f,0x45
+
+// CHECK: adcb $127, 32493
+// CHECK: encoding: [0x80,0x15,0xed,0x7e,0x00,0x00,0x7f]
+ adcb $0x7f,0x7eed
+
+// CHECK: adcb $127, 3133065982
+// CHECK: encoding: [0x80,0x15,0xfe,0xca,0xbe,0xba,0x7f]
+ adcb $0x7f,0xbabecafe
+
+// CHECK: adcb $127, 305419896
+// CHECK: encoding: [0x80,0x15,0x78,0x56,0x34,0x12,0x7f]
+ adcb $0x7f,0x12345678
+
+// CHECK: adcw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x94,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ adcw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x15,0x45,0x00,0x00,0x00,0xce,0x7a]
+ adcw $0x7ace,0x45
+
+// CHECK: adcw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x15,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ adcw $0x7ace,0x7eed
+
+// CHECK: adcw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x15,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ adcw $0x7ace,0xbabecafe
+
+// CHECK: adcw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x15,0x78,0x56,0x34,0x12,0xce,0x7a]
+ adcw $0x7ace,0x12345678
+
+// CHECK: adcl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x94,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $2063514302, 69
+// CHECK: encoding: [0x81,0x15,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0x45
+
+// CHECK: adcl $2063514302, 32493
+// CHECK: encoding: [0x81,0x15,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0x7eed
+
+// CHECK: adcl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x15,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0xbabecafe
+
+// CHECK: adcl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x15,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0x12345678
+
+// CHECK: adcl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x94,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $324478056, 69
+// CHECK: encoding: [0x81,0x15,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0x45
+
+// CHECK: adcl $324478056, 32493
+// CHECK: encoding: [0x81,0x15,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0x7eed
+
+// CHECK: adcl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x15,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0xbabecafe
+
+// CHECK: adcl $324478056, 305419896
+// CHECK: encoding: [0x81,0x15,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0x12345678
+
+// CHECK: negl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ negl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: negw 32493
+// CHECK: encoding: [0x66,0xf7,0x1d,0xed,0x7e,0x00,0x00]
+ negw 0x7eed
+
+// CHECK: negl 3133065982
+// CHECK: encoding: [0xf7,0x1d,0xfe,0xca,0xbe,0xba]
+ negl 0xbabecafe
+
+// CHECK: negl 305419896
+// CHECK: encoding: [0xf7,0x1d,0x78,0x56,0x34,0x12]
+ negl 0x12345678
+
+// CHECK: notl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ notl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: notw 32493
+// CHECK: encoding: [0x66,0xf7,0x15,0xed,0x7e,0x00,0x00]
+ notw 0x7eed
+
+// CHECK: notl 3133065982
+// CHECK: encoding: [0xf7,0x15,0xfe,0xca,0xbe,0xba]
+ notl 0xbabecafe
+
+// CHECK: notl 305419896
+// CHECK: encoding: [0xf7,0x15,0x78,0x56,0x34,0x12]
+ notl 0x12345678
+
+// CHECK: cbtw
+// CHECK: encoding: [0x66,0x98]
+ cbtw
+
+// CHECK: cwtl
+// CHECK: encoding: [0x98]
+ cwtl
+
+// CHECK: cwtd
+// CHECK: encoding: [0x66,0x99]
+ cwtd
+
+// CHECK: cltd
+// CHECK: encoding: [0x99]
+ cltd
+
+// CHECK: mull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ mull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: mulw 32493
+// CHECK: encoding: [0x66,0xf7,0x25,0xed,0x7e,0x00,0x00]
+ mulw 0x7eed
+
+// CHECK: mull 3133065982
+// CHECK: encoding: [0xf7,0x25,0xfe,0xca,0xbe,0xba]
+ mull 0xbabecafe
+
+// CHECK: mull 305419896
+// CHECK: encoding: [0xf7,0x25,0x78,0x56,0x34,0x12]
+ mull 0x12345678
+
+// CHECK: imull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ imull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: imulw 32493
+// CHECK: encoding: [0x66,0xf7,0x2d,0xed,0x7e,0x00,0x00]
+ imulw 0x7eed
+
+// CHECK: imull 3133065982
+// CHECK: encoding: [0xf7,0x2d,0xfe,0xca,0xbe,0xba]
+ imull 0xbabecafe
+
+// CHECK: imull 305419896
+// CHECK: encoding: [0xf7,0x2d,0x78,0x56,0x34,0x12]
+ imull 0x12345678
+
+// CHECK: divl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ divl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: divw 32493
+// CHECK: encoding: [0x66,0xf7,0x35,0xed,0x7e,0x00,0x00]
+ divw 0x7eed
+
+// CHECK: divl 3133065982
+// CHECK: encoding: [0xf7,0x35,0xfe,0xca,0xbe,0xba]
+ divl 0xbabecafe
+
+// CHECK: divl 305419896
+// CHECK: encoding: [0xf7,0x35,0x78,0x56,0x34,0x12]
+ divl 0x12345678
+
+// CHECK: idivl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ idivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: idivw 32493
+// CHECK: encoding: [0x66,0xf7,0x3d,0xed,0x7e,0x00,0x00]
+ idivw 0x7eed
+
+// CHECK: idivl 3133065982
+// CHECK: encoding: [0xf7,0x3d,0xfe,0xca,0xbe,0xba]
+ idivl 0xbabecafe
+
+// CHECK: idivl 305419896
+// CHECK: encoding: [0xf7,0x3d,0x78,0x56,0x34,0x12]
+ idivl 0x12345678
+
+// CHECK: roll $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0x84,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ roll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: roll $0, 69
+// CHECK: encoding: [0xc1,0x05,0x45,0x00,0x00,0x00,0x00]
+ roll $0,0x45
+
+// CHECK: roll $0, 32493
+// CHECK: encoding: [0xc1,0x05,0xed,0x7e,0x00,0x00,0x00]
+ roll $0,0x7eed
+
+// CHECK: roll $0, 3133065982
+// CHECK: encoding: [0xc1,0x05,0xfe,0xca,0xbe,0xba,0x00]
+ roll $0,0xbabecafe
+
+// CHECK: roll $0, 305419896
+// CHECK: encoding: [0xc1,0x05,0x78,0x56,0x34,0x12,0x00]
+ roll $0,0x12345678
+
+// CHECK: rolb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ rolb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rolb $127, 69
+// CHECK: encoding: [0xc0,0x05,0x45,0x00,0x00,0x00,0x7f]
+ rolb $0x7f,0x45
+
+// CHECK: rolb $127, 32493
+// CHECK: encoding: [0xc0,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ rolb $0x7f,0x7eed
+
+// CHECK: rolb $127, 3133065982
+// CHECK: encoding: [0xc0,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ rolb $0x7f,0xbabecafe
+
+// CHECK: rolb $127, 305419896
+// CHECK: encoding: [0xc0,0x05,0x78,0x56,0x34,0x12,0x7f]
+ rolb $0x7f,0x12345678
+
+// CHECK: roll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ roll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rolw 32493
+// CHECK: encoding: [0x66,0xd1,0x05,0xed,0x7e,0x00,0x00]
+ rolw 0x7eed
+
+// CHECK: roll 3133065982
+// CHECK: encoding: [0xd1,0x05,0xfe,0xca,0xbe,0xba]
+ roll 0xbabecafe
+
+// CHECK: roll 305419896
+// CHECK: encoding: [0xd1,0x05,0x78,0x56,0x34,0x12]
+ roll 0x12345678
+
+// CHECK: rorl $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ rorl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorl $0, 69
+// CHECK: encoding: [0xc1,0x0d,0x45,0x00,0x00,0x00,0x00]
+ rorl $0,0x45
+
+// CHECK: rorl $0, 32493
+// CHECK: encoding: [0xc1,0x0d,0xed,0x7e,0x00,0x00,0x00]
+ rorl $0,0x7eed
+
+// CHECK: rorl $0, 3133065982
+// CHECK: encoding: [0xc1,0x0d,0xfe,0xca,0xbe,0xba,0x00]
+ rorl $0,0xbabecafe
+
+// CHECK: rorl $0, 305419896
+// CHECK: encoding: [0xc1,0x0d,0x78,0x56,0x34,0x12,0x00]
+ rorl $0,0x12345678
+
+// CHECK: rorb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ rorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorb $127, 69
+// CHECK: encoding: [0xc0,0x0d,0x45,0x00,0x00,0x00,0x7f]
+ rorb $0x7f,0x45
+
+// CHECK: rorb $127, 32493
+// CHECK: encoding: [0xc0,0x0d,0xed,0x7e,0x00,0x00,0x7f]
+ rorb $0x7f,0x7eed
+
+// CHECK: rorb $127, 3133065982
+// CHECK: encoding: [0xc0,0x0d,0xfe,0xca,0xbe,0xba,0x7f]
+ rorb $0x7f,0xbabecafe
+
+// CHECK: rorb $127, 305419896
+// CHECK: encoding: [0xc0,0x0d,0x78,0x56,0x34,0x12,0x7f]
+ rorb $0x7f,0x12345678
+
+// CHECK: rorl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ rorl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorw 32493
+// CHECK: encoding: [0x66,0xd1,0x0d,0xed,0x7e,0x00,0x00]
+ rorw 0x7eed
+
+// CHECK: rorl 3133065982
+// CHECK: encoding: [0xd1,0x0d,0xfe,0xca,0xbe,0xba]
+ rorl 0xbabecafe
+
+// CHECK: rorl 305419896
+// CHECK: encoding: [0xd1,0x0d,0x78,0x56,0x34,0x12]
+ rorl 0x12345678
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ sall $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 69
+// CHECK: encoding: [0xc1,0x25,0x45,0x00,0x00,0x00,0x00]
+ sall $0,0x45
+
+// CHECK: shll $0, 32493
+// CHECK: encoding: [0xc1,0x25,0xed,0x7e,0x00,0x00,0x00]
+ sall $0,0x7eed
+
+// CHECK: shll $0, 3133065982
+// CHECK: encoding: [0xc1,0x25,0xfe,0xca,0xbe,0xba,0x00]
+ sall $0,0xbabecafe
+
+// CHECK: shll $0, 305419896
+// CHECK: encoding: [0xc1,0x25,0x78,0x56,0x34,0x12,0x00]
+ sall $0,0x12345678
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ salb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 69
+// CHECK: encoding: [0xc0,0x25,0x45,0x00,0x00,0x00,0x7f]
+ salb $0x7f,0x45
+
+// CHECK: shlb $127, 32493
+// CHECK: encoding: [0xc0,0x25,0xed,0x7e,0x00,0x00,0x7f]
+ salb $0x7f,0x7eed
+
+// CHECK: shlb $127, 3133065982
+// CHECK: encoding: [0xc0,0x25,0xfe,0xca,0xbe,0xba,0x7f]
+ salb $0x7f,0xbabecafe
+
+// CHECK: shlb $127, 305419896
+// CHECK: encoding: [0xc0,0x25,0x78,0x56,0x34,0x12,0x7f]
+ salb $0x7f,0x12345678
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ sall 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlw 32493
+// CHECK: encoding: [0x66,0xd1,0x25,0xed,0x7e,0x00,0x00]
+ salw 0x7eed
+
+// CHECK: shll 3133065982
+// CHECK: encoding: [0xd1,0x25,0xfe,0xca,0xbe,0xba]
+ sall 0xbabecafe
+
+// CHECK: shll 305419896
+// CHECK: encoding: [0xd1,0x25,0x78,0x56,0x34,0x12]
+ sall 0x12345678
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ shll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 69
+// CHECK: encoding: [0xc1,0x25,0x45,0x00,0x00,0x00,0x00]
+ shll $0,0x45
+
+// CHECK: shll $0, 32493
+// CHECK: encoding: [0xc1,0x25,0xed,0x7e,0x00,0x00,0x00]
+ shll $0,0x7eed
+
+// CHECK: shll $0, 3133065982
+// CHECK: encoding: [0xc1,0x25,0xfe,0xca,0xbe,0xba,0x00]
+ shll $0,0xbabecafe
+
+// CHECK: shll $0, 305419896
+// CHECK: encoding: [0xc1,0x25,0x78,0x56,0x34,0x12,0x00]
+ shll $0,0x12345678
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ shlb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 69
+// CHECK: encoding: [0xc0,0x25,0x45,0x00,0x00,0x00,0x7f]
+ shlb $0x7f,0x45
+
+// CHECK: shlb $127, 32493
+// CHECK: encoding: [0xc0,0x25,0xed,0x7e,0x00,0x00,0x7f]
+ shlb $0x7f,0x7eed
+
+// CHECK: shlb $127, 3133065982
+// CHECK: encoding: [0xc0,0x25,0xfe,0xca,0xbe,0xba,0x7f]
+ shlb $0x7f,0xbabecafe
+
+// CHECK: shlb $127, 305419896
+// CHECK: encoding: [0xc0,0x25,0x78,0x56,0x34,0x12,0x7f]
+ shlb $0x7f,0x12345678
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ shll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlw 32493
+// CHECK: encoding: [0x66,0xd1,0x25,0xed,0x7e,0x00,0x00]
+ shlw 0x7eed
+
+// CHECK: shll 3133065982
+// CHECK: encoding: [0xd1,0x25,0xfe,0xca,0xbe,0xba]
+ shll 0xbabecafe
+
+// CHECK: shll 305419896
+// CHECK: encoding: [0xd1,0x25,0x78,0x56,0x34,0x12]
+ shll 0x12345678
+
+// CHECK: shrl $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xac,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ shrl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrl $0, 69
+// CHECK: encoding: [0xc1,0x2d,0x45,0x00,0x00,0x00,0x00]
+ shrl $0,0x45
+
+// CHECK: shrl $0, 32493
+// CHECK: encoding: [0xc1,0x2d,0xed,0x7e,0x00,0x00,0x00]
+ shrl $0,0x7eed
+
+// CHECK: shrl $0, 3133065982
+// CHECK: encoding: [0xc1,0x2d,0xfe,0xca,0xbe,0xba,0x00]
+ shrl $0,0xbabecafe
+
+// CHECK: shrl $0, 305419896
+// CHECK: encoding: [0xc1,0x2d,0x78,0x56,0x34,0x12,0x00]
+ shrl $0,0x12345678
+
+// CHECK: shrb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xac,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ shrb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrb $127, 69
+// CHECK: encoding: [0xc0,0x2d,0x45,0x00,0x00,0x00,0x7f]
+ shrb $0x7f,0x45
+
+// CHECK: shrb $127, 32493
+// CHECK: encoding: [0xc0,0x2d,0xed,0x7e,0x00,0x00,0x7f]
+ shrb $0x7f,0x7eed
+
+// CHECK: shrb $127, 3133065982
+// CHECK: encoding: [0xc0,0x2d,0xfe,0xca,0xbe,0xba,0x7f]
+ shrb $0x7f,0xbabecafe
+
+// CHECK: shrb $127, 305419896
+// CHECK: encoding: [0xc0,0x2d,0x78,0x56,0x34,0x12,0x7f]
+ shrb $0x7f,0x12345678
+
+// CHECK: shrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ shrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrw 32493
+// CHECK: encoding: [0x66,0xd1,0x2d,0xed,0x7e,0x00,0x00]
+ shrw 0x7eed
+
+// CHECK: shrl 3133065982
+// CHECK: encoding: [0xd1,0x2d,0xfe,0xca,0xbe,0xba]
+ shrl 0xbabecafe
+
+// CHECK: shrl 305419896
+// CHECK: encoding: [0xd1,0x2d,0x78,0x56,0x34,0x12]
+ shrl 0x12345678
+
+// CHECK: sarl $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ sarl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarl $0, 69
+// CHECK: encoding: [0xc1,0x3d,0x45,0x00,0x00,0x00,0x00]
+ sarl $0,0x45
+
+// CHECK: sarl $0, 32493
+// CHECK: encoding: [0xc1,0x3d,0xed,0x7e,0x00,0x00,0x00]
+ sarl $0,0x7eed
+
+// CHECK: sarl $0, 3133065982
+// CHECK: encoding: [0xc1,0x3d,0xfe,0xca,0xbe,0xba,0x00]
+ sarl $0,0xbabecafe
+
+// CHECK: sarl $0, 305419896
+// CHECK: encoding: [0xc1,0x3d,0x78,0x56,0x34,0x12,0x00]
+ sarl $0,0x12345678
+
+// CHECK: sarb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ sarb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarb $127, 69
+// CHECK: encoding: [0xc0,0x3d,0x45,0x00,0x00,0x00,0x7f]
+ sarb $0x7f,0x45
+
+// CHECK: sarb $127, 32493
+// CHECK: encoding: [0xc0,0x3d,0xed,0x7e,0x00,0x00,0x7f]
+ sarb $0x7f,0x7eed
+
+// CHECK: sarb $127, 3133065982
+// CHECK: encoding: [0xc0,0x3d,0xfe,0xca,0xbe,0xba,0x7f]
+ sarb $0x7f,0xbabecafe
+
+// CHECK: sarb $127, 305419896
+// CHECK: encoding: [0xc0,0x3d,0x78,0x56,0x34,0x12,0x7f]
+ sarb $0x7f,0x12345678
+
+// CHECK: sarl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ sarl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarw 32493
+// CHECK: encoding: [0x66,0xd1,0x3d,0xed,0x7e,0x00,0x00]
+ sarw 0x7eed
+
+// CHECK: sarl 3133065982
+// CHECK: encoding: [0xd1,0x3d,0xfe,0xca,0xbe,0xba]
+ sarl 0xbabecafe
+
+// CHECK: sarl 305419896
+// CHECK: encoding: [0xd1,0x3d,0x78,0x56,0x34,0x12]
+ sarl 0x12345678
+
+// CHECK: call *%ecx
+// CHECK: encoding: [0xff,0xd1]
+ call *%ecx
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call *3135175374
+// CHECK: encoding: [0xff,0x15,0xce,0xfa,0xde,0xba]
+ call *0xbadeface
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call *3135175374
+// CHECK: encoding: [0xff,0x15,0xce,0xfa,0xde,0xba]
+ call *0xbadeface
+
+// CHECK: lcallw *32493
+// CHECK: encoding: [0x66,0xff,0x1d,0xed,0x7e,0x00,0x00]
+ lcallw *0x7eed
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp *3135175374
+// CHECK: encoding: [0xff,0x25,0xce,0xfa,0xde,0xba]
+ jmp *0xbadeface
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp *3135175374
+// CHECK: encoding: [0xff,0x25,0xce,0xfa,0xde,0xba]
+ jmp *0xbadeface
+
+// CHECK: ljmpl *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ljmpl *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ljmpw *32493
+// CHECK: encoding: [0x66,0xff,0x2d,0xed,0x7e,0x00,0x00]
+ ljmpw *0x7eed
+
+// CHECK: ljmpl *3133065982
+// CHECK: encoding: [0xff,0x2d,0xfe,0xca,0xbe,0xba]
+ ljmpl *0xbabecafe
+
+// CHECK: ljmpl *305419896
+// CHECK: encoding: [0xff,0x2d,0x78,0x56,0x34,0x12]
+ ljmpl *0x12345678
+
+// CHECK: ret
+// CHECK: encoding: [0xc3]
+ ret
+
+// CHECK: lret
+// CHECK: encoding: [0xcb]
+ lret
+
+// CHECK: leave
+// CHECK: encoding: [0xc9]
+ leave
+
+// CHECK: seto %bl
+// CHECK: encoding: [0x0f,0x90,0xc3]
+ seto %bl
+
+// CHECK: seto 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x90,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ seto 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: seto 32493
+// CHECK: encoding: [0x0f,0x90,0x05,0xed,0x7e,0x00,0x00]
+ seto 0x7eed
+
+// CHECK: seto 3133065982
+// CHECK: encoding: [0x0f,0x90,0x05,0xfe,0xca,0xbe,0xba]
+ seto 0xbabecafe
+
+// CHECK: seto 305419896
+// CHECK: encoding: [0x0f,0x90,0x05,0x78,0x56,0x34,0x12]
+ seto 0x12345678
+
+// CHECK: setno %bl
+// CHECK: encoding: [0x0f,0x91,0xc3]
+ setno %bl
+
+// CHECK: setno 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x91,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setno 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setno 32493
+// CHECK: encoding: [0x0f,0x91,0x05,0xed,0x7e,0x00,0x00]
+ setno 0x7eed
+
+// CHECK: setno 3133065982
+// CHECK: encoding: [0x0f,0x91,0x05,0xfe,0xca,0xbe,0xba]
+ setno 0xbabecafe
+
+// CHECK: setno 305419896
+// CHECK: encoding: [0x0f,0x91,0x05,0x78,0x56,0x34,0x12]
+ setno 0x12345678
+
+// CHECK: setb %bl
+// CHECK: encoding: [0x0f,0x92,0xc3]
+ setb %bl
+
+// CHECK: setb 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x92,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setb 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setb 32493
+// CHECK: encoding: [0x0f,0x92,0x05,0xed,0x7e,0x00,0x00]
+ setb 0x7eed
+
+// CHECK: setb 3133065982
+// CHECK: encoding: [0x0f,0x92,0x05,0xfe,0xca,0xbe,0xba]
+ setb 0xbabecafe
+
+// CHECK: setb 305419896
+// CHECK: encoding: [0x0f,0x92,0x05,0x78,0x56,0x34,0x12]
+ setb 0x12345678
+
+// CHECK: setae %bl
+// CHECK: encoding: [0x0f,0x93,0xc3]
+ setae %bl
+
+// CHECK: setae 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x93,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setae 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setae 32493
+// CHECK: encoding: [0x0f,0x93,0x05,0xed,0x7e,0x00,0x00]
+ setae 0x7eed
+
+// CHECK: setae 3133065982
+// CHECK: encoding: [0x0f,0x93,0x05,0xfe,0xca,0xbe,0xba]
+ setae 0xbabecafe
+
+// CHECK: setae 305419896
+// CHECK: encoding: [0x0f,0x93,0x05,0x78,0x56,0x34,0x12]
+ setae 0x12345678
+
+// CHECK: sete %bl
+// CHECK: encoding: [0x0f,0x94,0xc3]
+ sete %bl
+
+// CHECK: sete 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x94,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ sete 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sete 32493
+// CHECK: encoding: [0x0f,0x94,0x05,0xed,0x7e,0x00,0x00]
+ sete 0x7eed
+
+// CHECK: sete 3133065982
+// CHECK: encoding: [0x0f,0x94,0x05,0xfe,0xca,0xbe,0xba]
+ sete 0xbabecafe
+
+// CHECK: sete 305419896
+// CHECK: encoding: [0x0f,0x94,0x05,0x78,0x56,0x34,0x12]
+ sete 0x12345678
+
+// CHECK: setne %bl
+// CHECK: encoding: [0x0f,0x95,0xc3]
+ setne %bl
+
+// CHECK: setne 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x95,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setne 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setne 32493
+// CHECK: encoding: [0x0f,0x95,0x05,0xed,0x7e,0x00,0x00]
+ setne 0x7eed
+
+// CHECK: setne 3133065982
+// CHECK: encoding: [0x0f,0x95,0x05,0xfe,0xca,0xbe,0xba]
+ setne 0xbabecafe
+
+// CHECK: setne 305419896
+// CHECK: encoding: [0x0f,0x95,0x05,0x78,0x56,0x34,0x12]
+ setne 0x12345678
+
+// CHECK: setbe %bl
+// CHECK: encoding: [0x0f,0x96,0xc3]
+ setbe %bl
+
+// CHECK: setbe 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x96,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setbe 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setbe 32493
+// CHECK: encoding: [0x0f,0x96,0x05,0xed,0x7e,0x00,0x00]
+ setbe 0x7eed
+
+// CHECK: setbe 3133065982
+// CHECK: encoding: [0x0f,0x96,0x05,0xfe,0xca,0xbe,0xba]
+ setbe 0xbabecafe
+
+// CHECK: setbe 305419896
+// CHECK: encoding: [0x0f,0x96,0x05,0x78,0x56,0x34,0x12]
+ setbe 0x12345678
+
+// CHECK: seta %bl
+// CHECK: encoding: [0x0f,0x97,0xc3]
+ seta %bl
+
+// CHECK: seta 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x97,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ seta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: seta 32493
+// CHECK: encoding: [0x0f,0x97,0x05,0xed,0x7e,0x00,0x00]
+ seta 0x7eed
+
+// CHECK: seta 3133065982
+// CHECK: encoding: [0x0f,0x97,0x05,0xfe,0xca,0xbe,0xba]
+ seta 0xbabecafe
+
+// CHECK: seta 305419896
+// CHECK: encoding: [0x0f,0x97,0x05,0x78,0x56,0x34,0x12]
+ seta 0x12345678
+
+// CHECK: sets %bl
+// CHECK: encoding: [0x0f,0x98,0xc3]
+ sets %bl
+
+// CHECK: sets 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x98,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ sets 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sets 32493
+// CHECK: encoding: [0x0f,0x98,0x05,0xed,0x7e,0x00,0x00]
+ sets 0x7eed
+
+// CHECK: sets 3133065982
+// CHECK: encoding: [0x0f,0x98,0x05,0xfe,0xca,0xbe,0xba]
+ sets 0xbabecafe
+
+// CHECK: sets 305419896
+// CHECK: encoding: [0x0f,0x98,0x05,0x78,0x56,0x34,0x12]
+ sets 0x12345678
+
+// CHECK: setns %bl
+// CHECK: encoding: [0x0f,0x99,0xc3]
+ setns %bl
+
+// CHECK: setns 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x99,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setns 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setns 32493
+// CHECK: encoding: [0x0f,0x99,0x05,0xed,0x7e,0x00,0x00]
+ setns 0x7eed
+
+// CHECK: setns 3133065982
+// CHECK: encoding: [0x0f,0x99,0x05,0xfe,0xca,0xbe,0xba]
+ setns 0xbabecafe
+
+// CHECK: setns 305419896
+// CHECK: encoding: [0x0f,0x99,0x05,0x78,0x56,0x34,0x12]
+ setns 0x12345678
+
+// CHECK: setp %bl
+// CHECK: encoding: [0x0f,0x9a,0xc3]
+ setp %bl
+
+// CHECK: setp 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9a,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setp 32493
+// CHECK: encoding: [0x0f,0x9a,0x05,0xed,0x7e,0x00,0x00]
+ setp 0x7eed
+
+// CHECK: setp 3133065982
+// CHECK: encoding: [0x0f,0x9a,0x05,0xfe,0xca,0xbe,0xba]
+ setp 0xbabecafe
+
+// CHECK: setp 305419896
+// CHECK: encoding: [0x0f,0x9a,0x05,0x78,0x56,0x34,0x12]
+ setp 0x12345678
+
+// CHECK: setnp %bl
+// CHECK: encoding: [0x0f,0x9b,0xc3]
+ setnp %bl
+
+// CHECK: setnp 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9b,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setnp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setnp 32493
+// CHECK: encoding: [0x0f,0x9b,0x05,0xed,0x7e,0x00,0x00]
+ setnp 0x7eed
+
+// CHECK: setnp 3133065982
+// CHECK: encoding: [0x0f,0x9b,0x05,0xfe,0xca,0xbe,0xba]
+ setnp 0xbabecafe
+
+// CHECK: setnp 305419896
+// CHECK: encoding: [0x0f,0x9b,0x05,0x78,0x56,0x34,0x12]
+ setnp 0x12345678
+
+// CHECK: setl %bl
+// CHECK: encoding: [0x0f,0x9c,0xc3]
+ setl %bl
+
+// CHECK: setl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9c,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setl 32493
+// CHECK: encoding: [0x0f,0x9c,0x05,0xed,0x7e,0x00,0x00]
+ setl 0x7eed
+
+// CHECK: setl 3133065982
+// CHECK: encoding: [0x0f,0x9c,0x05,0xfe,0xca,0xbe,0xba]
+ setl 0xbabecafe
+
+// CHECK: setl 305419896
+// CHECK: encoding: [0x0f,0x9c,0x05,0x78,0x56,0x34,0x12]
+ setl 0x12345678
+
+// CHECK: setge %bl
+// CHECK: encoding: [0x0f,0x9d,0xc3]
+ setge %bl
+
+// CHECK: setge 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9d,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setge 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setge 32493
+// CHECK: encoding: [0x0f,0x9d,0x05,0xed,0x7e,0x00,0x00]
+ setge 0x7eed
+
+// CHECK: setge 3133065982
+// CHECK: encoding: [0x0f,0x9d,0x05,0xfe,0xca,0xbe,0xba]
+ setge 0xbabecafe
+
+// CHECK: setge 305419896
+// CHECK: encoding: [0x0f,0x9d,0x05,0x78,0x56,0x34,0x12]
+ setge 0x12345678
+
+// CHECK: setle %bl
+// CHECK: encoding: [0x0f,0x9e,0xc3]
+ setle %bl
+
+// CHECK: setle 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9e,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setle 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setle 32493
+// CHECK: encoding: [0x0f,0x9e,0x05,0xed,0x7e,0x00,0x00]
+ setle 0x7eed
+
+// CHECK: setle 3133065982
+// CHECK: encoding: [0x0f,0x9e,0x05,0xfe,0xca,0xbe,0xba]
+ setle 0xbabecafe
+
+// CHECK: setle 305419896
+// CHECK: encoding: [0x0f,0x9e,0x05,0x78,0x56,0x34,0x12]
+ setle 0x12345678
+
+// CHECK: setg %bl
+// CHECK: encoding: [0x0f,0x9f,0xc3]
+ setg %bl
+
+// CHECK: setg 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9f,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setg 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setg 32493
+// CHECK: encoding: [0x0f,0x9f,0x05,0xed,0x7e,0x00,0x00]
+ setg 0x7eed
+
+// CHECK: setg 3133065982
+// CHECK: encoding: [0x0f,0x9f,0x05,0xfe,0xca,0xbe,0xba]
+ setg 0xbabecafe
+
+// CHECK: setg 305419896
+// CHECK: encoding: [0x0f,0x9f,0x05,0x78,0x56,0x34,0x12]
+ setg 0x12345678
+
+// CHECK: rsm
+// CHECK: encoding: [0x0f,0xaa]
+ rsm
+
+// CHECK: hlt
+// CHECK: encoding: [0xf4]
+ hlt
+
+// CHECK: nopl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x1f,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ nopl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: nopw 32493
+// CHECK: encoding: [0x66,0x0f,0x1f,0x05,0xed,0x7e,0x00,0x00]
+ nopw 0x7eed
+
+// CHECK: nopl 3133065982
+// CHECK: encoding: [0x0f,0x1f,0x05,0xfe,0xca,0xbe,0xba]
+ nopl 0xbabecafe
+
+// CHECK: nopl 305419896
+// CHECK: encoding: [0x0f,0x1f,0x05,0x78,0x56,0x34,0x12]
+ nopl 0x12345678
+
+// CHECK: nop
+// CHECK: encoding: [0x90]
+ nop
+
+// CHECK: lldtw 32493
+// CHECK: encoding: [0x0f,0x00,0x15,0xed,0x7e,0x00,0x00]
+ lldtw 0x7eed
+
+// CHECK: lmsww 32493
+// CHECK: encoding: [0x0f,0x01,0x35,0xed,0x7e,0x00,0x00]
+ lmsww 0x7eed
+
+// CHECK: ltrw 32493
+// CHECK: encoding: [0x0f,0x00,0x1d,0xed,0x7e,0x00,0x00]
+ ltrw 0x7eed
+
+// CHECK: sldtw 32493
+// CHECK: encoding: [0x0f,0x00,0x05,0xed,0x7e,0x00,0x00]
+ sldtw 0x7eed
+
+// CHECK: smsww 32493
+// CHECK: encoding: [0x0f,0x01,0x25,0xed,0x7e,0x00,0x00]
+ smsww 0x7eed
+
+// CHECK: strw 32493
+// CHECK: encoding: [0x0f,0x00,0x0d,0xed,0x7e,0x00,0x00]
+ strw 0x7eed
+
+// CHECK: verr %bx
+// CHECK: encoding: [0x0f,0x00,0xe3]
+ verr %bx
+
+// CHECK: verr 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x00,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ verr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: verr 3133065982
+// CHECK: encoding: [0x0f,0x00,0x25,0xfe,0xca,0xbe,0xba]
+ verr 0xbabecafe
+
+// CHECK: verr 305419896
+// CHECK: encoding: [0x0f,0x00,0x25,0x78,0x56,0x34,0x12]
+ verr 0x12345678
+
+// CHECK: verw %bx
+// CHECK: encoding: [0x0f,0x00,0xeb]
+ verw %bx
+
+// CHECK: verw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x00,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ verw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: verw 3133065982
+// CHECK: encoding: [0x0f,0x00,0x2d,0xfe,0xca,0xbe,0xba]
+ verw 0xbabecafe
+
+// CHECK: verw 305419896
+// CHECK: encoding: [0x0f,0x00,0x2d,0x78,0x56,0x34,0x12]
+ verw 0x12345678
+
+// CHECK: fld %st(2)
+// CHECK: encoding: [0xd9,0xc2]
+ fld %st(2)
+
+// CHECK: fldl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fldl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldl 3133065982
+// CHECK: encoding: [0xdd,0x05,0xfe,0xca,0xbe,0xba]
+ fldl 0xbabecafe
+
+// CHECK: fldl 305419896
+// CHECK: encoding: [0xdd,0x05,0x78,0x56,0x34,0x12]
+ fldl 0x12345678
+
+// CHECK: fld %st(2)
+// CHECK: encoding: [0xd9,0xc2]
+ fld %st(2)
+
+// CHECK: fildl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fildl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildl 3133065982
+// CHECK: encoding: [0xdb,0x05,0xfe,0xca,0xbe,0xba]
+ fildl 0xbabecafe
+
+// CHECK: fildl 305419896
+// CHECK: encoding: [0xdb,0x05,0x78,0x56,0x34,0x12]
+ fildl 0x12345678
+
+// CHECK: fildll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fildll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildll 32493
+// CHECK: encoding: [0xdf,0x2d,0xed,0x7e,0x00,0x00]
+ fildll 0x7eed
+
+// CHECK: fildll 3133065982
+// CHECK: encoding: [0xdf,0x2d,0xfe,0xca,0xbe,0xba]
+ fildll 0xbabecafe
+
+// CHECK: fildll 305419896
+// CHECK: encoding: [0xdf,0x2d,0x78,0x56,0x34,0x12]
+ fildll 0x12345678
+
+// CHECK: fldt 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fldt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldt 32493
+// CHECK: encoding: [0xdb,0x2d,0xed,0x7e,0x00,0x00]
+ fldt 0x7eed
+
+// CHECK: fldt 3133065982
+// CHECK: encoding: [0xdb,0x2d,0xfe,0xca,0xbe,0xba]
+ fldt 0xbabecafe
+
+// CHECK: fldt 305419896
+// CHECK: encoding: [0xdb,0x2d,0x78,0x56,0x34,0x12]
+ fldt 0x12345678
+
+// CHECK: fbld 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ fbld 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbld 32493
+// CHECK: encoding: [0xdf,0x25,0xed,0x7e,0x00,0x00]
+ fbld 0x7eed
+
+// CHECK: fbld 3133065982
+// CHECK: encoding: [0xdf,0x25,0xfe,0xca,0xbe,0xba]
+ fbld 0xbabecafe
+
+// CHECK: fbld 305419896
+// CHECK: encoding: [0xdf,0x25,0x78,0x56,0x34,0x12]
+ fbld 0x12345678
+
+// CHECK: fst %st(2)
+// CHECK: encoding: [0xdd,0xd2]
+ fst %st(2)
+
+// CHECK: fstl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ fstl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstl 3133065982
+// CHECK: encoding: [0xdd,0x15,0xfe,0xca,0xbe,0xba]
+ fstl 0xbabecafe
+
+// CHECK: fstl 305419896
+// CHECK: encoding: [0xdd,0x15,0x78,0x56,0x34,0x12]
+ fstl 0x12345678
+
+// CHECK: fst %st(2)
+// CHECK: encoding: [0xdd,0xd2]
+ fst %st(2)
+
+// CHECK: fistl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ fistl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistl 3133065982
+// CHECK: encoding: [0xdb,0x15,0xfe,0xca,0xbe,0xba]
+ fistl 0xbabecafe
+
+// CHECK: fistl 305419896
+// CHECK: encoding: [0xdb,0x15,0x78,0x56,0x34,0x12]
+ fistl 0x12345678
+
+// CHECK: fstp %st(2)
+// CHECK: encoding: [0xdd,0xda]
+ fstp %st(2)
+
+// CHECK: fstpl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ fstpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpl 3133065982
+// CHECK: encoding: [0xdd,0x1d,0xfe,0xca,0xbe,0xba]
+ fstpl 0xbabecafe
+
+// CHECK: fstpl 305419896
+// CHECK: encoding: [0xdd,0x1d,0x78,0x56,0x34,0x12]
+ fstpl 0x12345678
+
+// CHECK: fstp %st(2)
+// CHECK: encoding: [0xdd,0xda]
+ fstp %st(2)
+
+// CHECK: fistpl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ fistpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpl 3133065982
+// CHECK: encoding: [0xdb,0x1d,0xfe,0xca,0xbe,0xba]
+ fistpl 0xbabecafe
+
+// CHECK: fistpl 305419896
+// CHECK: encoding: [0xdb,0x1d,0x78,0x56,0x34,0x12]
+ fistpl 0x12345678
+
+// CHECK: fistpll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fistpll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpll 32493
+// CHECK: encoding: [0xdf,0x3d,0xed,0x7e,0x00,0x00]
+ fistpll 0x7eed
+
+// CHECK: fistpll 3133065982
+// CHECK: encoding: [0xdf,0x3d,0xfe,0xca,0xbe,0xba]
+ fistpll 0xbabecafe
+
+// CHECK: fistpll 305419896
+// CHECK: encoding: [0xdf,0x3d,0x78,0x56,0x34,0x12]
+ fistpll 0x12345678
+
+// CHECK: fstpt 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fstpt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpt 32493
+// CHECK: encoding: [0xdb,0x3d,0xed,0x7e,0x00,0x00]
+ fstpt 0x7eed
+
+// CHECK: fstpt 3133065982
+// CHECK: encoding: [0xdb,0x3d,0xfe,0xca,0xbe,0xba]
+ fstpt 0xbabecafe
+
+// CHECK: fstpt 305419896
+// CHECK: encoding: [0xdb,0x3d,0x78,0x56,0x34,0x12]
+ fstpt 0x12345678
+
+// CHECK: fbstp 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ fbstp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbstp 32493
+// CHECK: encoding: [0xdf,0x35,0xed,0x7e,0x00,0x00]
+ fbstp 0x7eed
+
+// CHECK: fbstp 3133065982
+// CHECK: encoding: [0xdf,0x35,0xfe,0xca,0xbe,0xba]
+ fbstp 0xbabecafe
+
+// CHECK: fbstp 305419896
+// CHECK: encoding: [0xdf,0x35,0x78,0x56,0x34,0x12]
+ fbstp 0x12345678
+
+// CHECK: fxch %st(2)
+// CHECK: encoding: [0xd9,0xca]
+ fxch %st(2)
+
+// CHECK: fcom %st(2)
+// CHECK: encoding: [0xd8,0xd2]
+ fcom %st(2)
+
+// CHECK: fcom %st(2)
+// CHECK: encoding: [0xd8,0xd2]
+ fcom %st(2)
+
+// CHECK: ficoml 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ ficoml 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficoml 3133065982
+// CHECK: encoding: [0xda,0x15,0xfe,0xca,0xbe,0xba]
+ ficoml 0xbabecafe
+
+// CHECK: ficoml 305419896
+// CHECK: encoding: [0xda,0x15,0x78,0x56,0x34,0x12]
+ ficoml 0x12345678
+
+// CHECK: fcomp %st(2)
+// CHECK: encoding: [0xd8,0xda]
+ fcomp %st(2)
+
+// CHECK: fcomp %st(2)
+// CHECK: encoding: [0xd8,0xda]
+ fcomp %st(2)
+
+// CHECK: ficompl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ ficompl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficompl 3133065982
+// CHECK: encoding: [0xda,0x1d,0xfe,0xca,0xbe,0xba]
+ ficompl 0xbabecafe
+
+// CHECK: ficompl 305419896
+// CHECK: encoding: [0xda,0x1d,0x78,0x56,0x34,0x12]
+ ficompl 0x12345678
+
+// CHECK: fcompp
+// CHECK: encoding: [0xde,0xd9]
+ fcompp
+
+// CHECK: fucom %st(2)
+// CHECK: encoding: [0xdd,0xe2]
+ fucom %st(2)
+
+// CHECK: fucomp %st(2)
+// CHECK: encoding: [0xdd,0xea]
+ fucomp %st(2)
+
+// CHECK: fucompp
+// CHECK: encoding: [0xda,0xe9]
+ fucompp
+
+// CHECK: ftst
+// CHECK: encoding: [0xd9,0xe4]
+ ftst
+
+// CHECK: fxam
+// CHECK: encoding: [0xd9,0xe5]
+ fxam
+
+// CHECK: fld1
+// CHECK: encoding: [0xd9,0xe8]
+ fld1
+
+// CHECK: fldl2t
+// CHECK: encoding: [0xd9,0xe9]
+ fldl2t
+
+// CHECK: fldl2e
+// CHECK: encoding: [0xd9,0xea]
+ fldl2e
+
+// CHECK: fldpi
+// CHECK: encoding: [0xd9,0xeb]
+ fldpi
+
+// CHECK: fldlg2
+// CHECK: encoding: [0xd9,0xec]
+ fldlg2
+
+// CHECK: fldln2
+// CHECK: encoding: [0xd9,0xed]
+ fldln2
+
+// CHECK: fldz
+// CHECK: encoding: [0xd9,0xee]
+ fldz
+
+// CHECK: fadd %st(2)
+// CHECK: encoding: [0xd8,0xc2]
+ fadd %st(2)
+
+// CHECK: faddl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ faddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: faddl 3133065982
+// CHECK: encoding: [0xdc,0x05,0xfe,0xca,0xbe,0xba]
+ faddl 0xbabecafe
+
+// CHECK: faddl 305419896
+// CHECK: encoding: [0xdc,0x05,0x78,0x56,0x34,0x12]
+ faddl 0x12345678
+
+// CHECK: fiaddl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fiaddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fiaddl 3133065982
+// CHECK: encoding: [0xda,0x05,0xfe,0xca,0xbe,0xba]
+ fiaddl 0xbabecafe
+
+// CHECK: fiaddl 305419896
+// CHECK: encoding: [0xda,0x05,0x78,0x56,0x34,0x12]
+ fiaddl 0x12345678
+
+// CHECK: faddp %st(2)
+// CHECK: encoding: [0xde,0xc2]
+ faddp %st(2)
+
+// CHECK: fsub %st(2)
+// CHECK: encoding: [0xd8,0xe2]
+ fsub %st(2)
+
+// CHECK: fsubl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ fsubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubl 3133065982
+// CHECK: encoding: [0xdc,0x25,0xfe,0xca,0xbe,0xba]
+ fsubl 0xbabecafe
+
+// CHECK: fsubl 305419896
+// CHECK: encoding: [0xdc,0x25,0x78,0x56,0x34,0x12]
+ fsubl 0x12345678
+
+// CHECK: fisubl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ fisubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubl 3133065982
+// CHECK: encoding: [0xda,0x25,0xfe,0xca,0xbe,0xba]
+ fisubl 0xbabecafe
+
+// CHECK: fisubl 305419896
+// CHECK: encoding: [0xda,0x25,0x78,0x56,0x34,0x12]
+ fisubl 0x12345678
+
+// CHECK: fsubp %st(2)
+// CHECK: encoding: [0xde,0xe2]
+ fsubp %st(2)
+
+// CHECK: fsubr %st(2)
+// CHECK: encoding: [0xd8,0xea]
+ fsubr %st(2)
+
+// CHECK: fsubrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fsubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubrl 3133065982
+// CHECK: encoding: [0xdc,0x2d,0xfe,0xca,0xbe,0xba]
+ fsubrl 0xbabecafe
+
+// CHECK: fsubrl 305419896
+// CHECK: encoding: [0xdc,0x2d,0x78,0x56,0x34,0x12]
+ fsubrl 0x12345678
+
+// CHECK: fisubrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fisubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubrl 3133065982
+// CHECK: encoding: [0xda,0x2d,0xfe,0xca,0xbe,0xba]
+ fisubrl 0xbabecafe
+
+// CHECK: fisubrl 305419896
+// CHECK: encoding: [0xda,0x2d,0x78,0x56,0x34,0x12]
+ fisubrl 0x12345678
+
+// CHECK: fsubrp %st(2)
+// CHECK: encoding: [0xde,0xea]
+ fsubrp %st(2)
+
+// CHECK: fmul %st(2)
+// CHECK: encoding: [0xd8,0xca]
+ fmul %st(2)
+
+// CHECK: fmull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fmull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fmull 3133065982
+// CHECK: encoding: [0xdc,0x0d,0xfe,0xca,0xbe,0xba]
+ fmull 0xbabecafe
+
+// CHECK: fmull 305419896
+// CHECK: encoding: [0xdc,0x0d,0x78,0x56,0x34,0x12]
+ fmull 0x12345678
+
+// CHECK: fimull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fimull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fimull 3133065982
+// CHECK: encoding: [0xda,0x0d,0xfe,0xca,0xbe,0xba]
+ fimull 0xbabecafe
+
+// CHECK: fimull 305419896
+// CHECK: encoding: [0xda,0x0d,0x78,0x56,0x34,0x12]
+ fimull 0x12345678
+
+// CHECK: fmulp %st(2)
+// CHECK: encoding: [0xde,0xca]
+ fmulp %st(2)
+
+// CHECK: fdiv %st(2)
+// CHECK: encoding: [0xd8,0xf2]
+ fdiv %st(2)
+
+// CHECK: fdivl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ fdivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivl 3133065982
+// CHECK: encoding: [0xdc,0x35,0xfe,0xca,0xbe,0xba]
+ fdivl 0xbabecafe
+
+// CHECK: fdivl 305419896
+// CHECK: encoding: [0xdc,0x35,0x78,0x56,0x34,0x12]
+ fdivl 0x12345678
+
+// CHECK: fidivl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ fidivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivl 3133065982
+// CHECK: encoding: [0xda,0x35,0xfe,0xca,0xbe,0xba]
+ fidivl 0xbabecafe
+
+// CHECK: fidivl 305419896
+// CHECK: encoding: [0xda,0x35,0x78,0x56,0x34,0x12]
+ fidivl 0x12345678
+
+// CHECK: fdivp %st(2)
+// CHECK: encoding: [0xde,0xf2]
+ fdivp %st(2)
+
+// CHECK: fdivr %st(2)
+// CHECK: encoding: [0xd8,0xfa]
+ fdivr %st(2)
+
+// CHECK: fdivrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fdivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivrl 3133065982
+// CHECK: encoding: [0xdc,0x3d,0xfe,0xca,0xbe,0xba]
+ fdivrl 0xbabecafe
+
+// CHECK: fdivrl 305419896
+// CHECK: encoding: [0xdc,0x3d,0x78,0x56,0x34,0x12]
+ fdivrl 0x12345678
+
+// CHECK: fidivrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fidivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivrl 3133065982
+// CHECK: encoding: [0xda,0x3d,0xfe,0xca,0xbe,0xba]
+ fidivrl 0xbabecafe
+
+// CHECK: fidivrl 305419896
+// CHECK: encoding: [0xda,0x3d,0x78,0x56,0x34,0x12]
+ fidivrl 0x12345678
+
+// CHECK: fdivrp %st(2)
+// CHECK: encoding: [0xde,0xfa]
+ fdivrp %st(2)
+
+// CHECK: f2xm1
+// CHECK: encoding: [0xd9,0xf0]
+ f2xm1
+
+// CHECK: fyl2x
+// CHECK: encoding: [0xd9,0xf1]
+ fyl2x
+
+// CHECK: fptan
+// CHECK: encoding: [0xd9,0xf2]
+ fptan
+
+// CHECK: fpatan
+// CHECK: encoding: [0xd9,0xf3]
+ fpatan
+
+// CHECK: fxtract
+// CHECK: encoding: [0xd9,0xf4]
+ fxtract
+
+// CHECK: fprem1
+// CHECK: encoding: [0xd9,0xf5]
+ fprem1
+
+// CHECK: fdecstp
+// CHECK: encoding: [0xd9,0xf6]
+ fdecstp
+
+// CHECK: fincstp
+// CHECK: encoding: [0xd9,0xf7]
+ fincstp
+
+// CHECK: fprem
+// CHECK: encoding: [0xd9,0xf8]
+ fprem
+
+// CHECK: fyl2xp1
+// CHECK: encoding: [0xd9,0xf9]
+ fyl2xp1
+
+// CHECK: fsqrt
+// CHECK: encoding: [0xd9,0xfa]
+ fsqrt
+
+// CHECK: fsincos
+// CHECK: encoding: [0xd9,0xfb]
+ fsincos
+
+// CHECK: frndint
+// CHECK: encoding: [0xd9,0xfc]
+ frndint
+
+// CHECK: fscale
+// CHECK: encoding: [0xd9,0xfd]
+ fscale
+
+// CHECK: fsin
+// CHECK: encoding: [0xd9,0xfe]
+ fsin
+
+// CHECK: fcos
+// CHECK: encoding: [0xd9,0xff]
+ fcos
+
+// CHECK: fchs
+// CHECK: encoding: [0xd9,0xe0]
+ fchs
+
+// CHECK: fabs
+// CHECK: encoding: [0xd9,0xe1]
+ fabs
+
+// CHECK: fninit
+// CHECK: encoding: [0xdb,0xe3]
+ fninit
+
+// CHECK: fldcw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fldcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldcw 3133065982
+// CHECK: encoding: [0xd9,0x2d,0xfe,0xca,0xbe,0xba]
+ fldcw 0xbabecafe
+
+// CHECK: fldcw 305419896
+// CHECK: encoding: [0xd9,0x2d,0x78,0x56,0x34,0x12]
+ fldcw 0x12345678
+
+// CHECK: fnstcw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd9,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fnstcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fnstcw 3133065982
+// CHECK: encoding: [0xd9,0x3d,0xfe,0xca,0xbe,0xba]
+ fnstcw 0xbabecafe
+
+// CHECK: fnstcw 305419896
+// CHECK: encoding: [0xd9,0x3d,0x78,0x56,0x34,0x12]
+ fnstcw 0x12345678
+
+// CHECK: fnstsw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fnstsw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fnstsw 3133065982
+// CHECK: encoding: [0xdd,0x3d,0xfe,0xca,0xbe,0xba]
+ fnstsw 0xbabecafe
+
+// CHECK: fnstsw 305419896
+// CHECK: encoding: [0xdd,0x3d,0x78,0x56,0x34,0x12]
+ fnstsw 0x12345678
+
+// CHECK: fnclex
+// CHECK: encoding: [0xdb,0xe2]
+ fnclex
+
+// CHECK: fnstenv 32493
+// CHECK: encoding: [0xd9,0x35,0xed,0x7e,0x00,0x00]
+ fnstenv 0x7eed
+
+// CHECK: fldenv 32493
+// CHECK: encoding: [0xd9,0x25,0xed,0x7e,0x00,0x00]
+ fldenv 0x7eed
+
+// CHECK: fnsave 32493
+// CHECK: encoding: [0xdd,0x35,0xed,0x7e,0x00,0x00]
+ fnsave 0x7eed
+
+// CHECK: frstor 32493
+// CHECK: encoding: [0xdd,0x25,0xed,0x7e,0x00,0x00]
+ frstor 0x7eed
+
+// CHECK: ffree %st(2)
+// CHECK: encoding: [0xdd,0xc2]
+ ffree %st(2)
+
+// CHECK: fnop
+// CHECK: encoding: [0xd9,0xd0]
+ fnop
+
+// CHECK: invd
+// CHECK: encoding: [0x0f,0x08]
+ invd
+
+// CHECK: wbinvd
+// CHECK: encoding: [0x0f,0x09]
+ wbinvd
+
+// CHECK: cpuid
+// CHECK: encoding: [0x0f,0xa2]
+ cpuid
+
+// CHECK: wrmsr
+// CHECK: encoding: [0x0f,0x30]
+ wrmsr
+
+// CHECK: rdtsc
+// CHECK: encoding: [0x0f,0x31]
+ rdtsc
+
+// CHECK: rdmsr
+// CHECK: encoding: [0x0f,0x32]
+ rdmsr
+
+// CHECK: cmpxchg8b 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc7,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ cmpxchg8b 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpxchg8b 32493
+// CHECK: encoding: [0x0f,0xc7,0x0d,0xed,0x7e,0x00,0x00]
+ cmpxchg8b 0x7eed
+
+// CHECK: cmpxchg8b 3133065982
+// CHECK: encoding: [0x0f,0xc7,0x0d,0xfe,0xca,0xbe,0xba]
+ cmpxchg8b 0xbabecafe
+
+// CHECK: cmpxchg8b 305419896
+// CHECK: encoding: [0x0f,0xc7,0x0d,0x78,0x56,0x34,0x12]
+ cmpxchg8b 0x12345678
+
+// CHECK: sysenter
+// CHECK: encoding: [0x0f,0x34]
+ sysenter
+
+// CHECK: sysexit
+// CHECK: encoding: [0x0f,0x35]
+ sysexit
+
+// CHECK: fxsave 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fxsave 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fxsave 32493
+// CHECK: encoding: [0x0f,0xae,0x05,0xed,0x7e,0x00,0x00]
+ fxsave 0x7eed
+
+// CHECK: fxsave 3133065982
+// CHECK: encoding: [0x0f,0xae,0x05,0xfe,0xca,0xbe,0xba]
+ fxsave 0xbabecafe
+
+// CHECK: fxsave 305419896
+// CHECK: encoding: [0x0f,0xae,0x05,0x78,0x56,0x34,0x12]
+ fxsave 0x12345678
+
+// CHECK: fxrstor 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fxrstor 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fxrstor 32493
+// CHECK: encoding: [0x0f,0xae,0x0d,0xed,0x7e,0x00,0x00]
+ fxrstor 0x7eed
+
+// CHECK: fxrstor 3133065982
+// CHECK: encoding: [0x0f,0xae,0x0d,0xfe,0xca,0xbe,0xba]
+ fxrstor 0xbabecafe
+
+// CHECK: fxrstor 305419896
+// CHECK: encoding: [0x0f,0xae,0x0d,0x78,0x56,0x34,0x12]
+ fxrstor 0x12345678
+
+// CHECK: rdpmc
+// CHECK: encoding: [0x0f,0x33]
+ rdpmc
+
+// CHECK: ud2
+// CHECK: encoding: [0x0f,0x0b]
+ ud2
+
+// CHECK: fcmovb %st(2), %st(0)
+// CHECK: encoding: [0xda,0xc2]
+ fcmovb %st(2),%st
+
+// CHECK: fcmove %st(2), %st(0)
+// CHECK: encoding: [0xda,0xca]
+ fcmove %st(2),%st
+
+// CHECK: fcmovbe %st(2), %st(0)
+// CHECK: encoding: [0xda,0xd2]
+ fcmovbe %st(2),%st
+
+// CHECK: fcmovu %st(2), %st(0)
+// CHECK: encoding: [0xda,0xda]
+ fcmovu %st(2),%st
+
+// CHECK: fcmovnb %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xc2]
+ fcmovnb %st(2),%st
+
+// CHECK: fcmovne %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xca]
+ fcmovne %st(2),%st
+
+// CHECK: fcmovnbe %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xd2]
+ fcmovnbe %st(2),%st
+
+// CHECK: fcmovnu %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xda]
+ fcmovnu %st(2),%st
+
+// CHECK: fcomi %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xf2]
+ fcomi %st(2),%st
+
+// CHECK: fucomi %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xea]
+ fucomi %st(2),%st
+
+// CHECK: fcomip %st(2), %st(0)
+// CHECK: encoding: [0xdf,0xf2]
+ fcomip %st(2),%st
+
+// CHECK: fucomip %st(2), %st(0)
+// CHECK: encoding: [0xdf,0xea]
+ fucomip %st(2),%st
+
+// CHECK: movnti %ecx, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc3,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movnti %ecx,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movnti %ecx, 69
+// CHECK: encoding: [0x0f,0xc3,0x0d,0x45,0x00,0x00,0x00]
+ movnti %ecx,0x45
+
+// CHECK: movnti %ecx, 32493
+// CHECK: encoding: [0x0f,0xc3,0x0d,0xed,0x7e,0x00,0x00]
+ movnti %ecx,0x7eed
+
+// CHECK: movnti %ecx, 3133065982
+// CHECK: encoding: [0x0f,0xc3,0x0d,0xfe,0xca,0xbe,0xba]
+ movnti %ecx,0xbabecafe
+
+// CHECK: movnti %ecx, 305419896
+// CHECK: encoding: [0x0f,0xc3,0x0d,0x78,0x56,0x34,0x12]
+ movnti %ecx,0x12345678
+
+// CHECK: clflush 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ clflush 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: clflush 32493
+// CHECK: encoding: [0x0f,0xae,0x3d,0xed,0x7e,0x00,0x00]
+ clflush 0x7eed
+
+// CHECK: clflush 3133065982
+// CHECK: encoding: [0x0f,0xae,0x3d,0xfe,0xca,0xbe,0xba]
+ clflush 0xbabecafe
+
+// CHECK: clflush 305419896
+// CHECK: encoding: [0x0f,0xae,0x3d,0x78,0x56,0x34,0x12]
+ clflush 0x12345678
+
+// CHECK: emms
+// CHECK: encoding: [0x0f,0x77]
+ emms
+
+// CHECK: movd %ecx, %mm3
+// CHECK: encoding: [0x0f,0x6e,0xd9]
+ movd %ecx,%mm3
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6e,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movd 69, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0x45,0x00,0x00,0x00]
+ movd 0x45,%mm3
+
+// CHECK: movd 32493, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0xed,0x7e,0x00,0x00]
+ movd 0x7eed,%mm3
+
+// CHECK: movd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0xfe,0xca,0xbe,0xba]
+ movd 0xbabecafe,%mm3
+
+// CHECK: movd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0x78,0x56,0x34,0x12]
+ movd 0x12345678,%mm3
+
+// CHECK: movd %mm3, %ecx
+// CHECK: encoding: [0x0f,0x7e,0xd9]
+ movd %mm3,%ecx
+
+// CHECK: movd %mm3, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x7e,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movd %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movd %mm3, 69
+// CHECK: encoding: [0x0f,0x7e,0x1d,0x45,0x00,0x00,0x00]
+ movd %mm3,0x45
+
+// CHECK: movd %mm3, 32493
+// CHECK: encoding: [0x0f,0x7e,0x1d,0xed,0x7e,0x00,0x00]
+ movd %mm3,0x7eed
+
+// CHECK: movd %mm3, 3133065982
+// CHECK: encoding: [0x0f,0x7e,0x1d,0xfe,0xca,0xbe,0xba]
+ movd %mm3,0xbabecafe
+
+// CHECK: movd %mm3, 305419896
+// CHECK: encoding: [0x0f,0x7e,0x1d,0x78,0x56,0x34,0x12]
+ movd %mm3,0x12345678
+
+// CHECK: movd %ecx, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0xe9]
+ movd %ecx,%xmm5
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0x45,0x00,0x00,0x00]
+ movd 0x45,%xmm5
+
+// CHECK: movd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0xed,0x7e,0x00,0x00]
+ movd 0x7eed,%xmm5
+
+// CHECK: movd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0xfe,0xca,0xbe,0xba]
+ movd 0xbabecafe,%xmm5
+
+// CHECK: movd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0x78,0x56,0x34,0x12]
+ movd 0x12345678,%xmm5
+
+// CHECK: movd %xmm5, %ecx
+// CHECK: encoding: [0x66,0x0f,0x7e,0xe9]
+ movd %xmm5,%ecx
+
+// CHECK: movd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x7e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0x45,0x00,0x00,0x00]
+ movd %xmm5,0x45
+
+// CHECK: movd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0xed,0x7e,0x00,0x00]
+ movd %xmm5,0x7eed
+
+// CHECK: movd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0xfe,0xca,0xbe,0xba]
+ movd %xmm5,0xbabecafe
+
+// CHECK: movd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0x78,0x56,0x34,0x12]
+ movd %xmm5,0x12345678
+
+// CHECK: movq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6f,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movq 69, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0x45,0x00,0x00,0x00]
+ movq 0x45,%mm3
+
+// CHECK: movq 32493, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0xed,0x7e,0x00,0x00]
+ movq 0x7eed,%mm3
+
+// CHECK: movq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0xfe,0xca,0xbe,0xba]
+ movq 0xbabecafe,%mm3
+
+// CHECK: movq 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0x78,0x56,0x34,0x12]
+ movq 0x12345678,%mm3
+
+// CHECK: movq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6f,0xdb]
+ movq %mm3,%mm3
+
+// CHECK: movq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6f,0xdb]
+ movq %mm3,%mm3
+
+// CHECK: movq %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x7e,0xed]
+ movq %xmm5,%xmm5
+
+// CHECK: movq %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0xd6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movq %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0x45,0x00,0x00,0x00]
+ movq %xmm5,0x45
+
+// CHECK: movq %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0xed,0x7e,0x00,0x00]
+ movq %xmm5,0x7eed
+
+// CHECK: movq %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0xfe,0xca,0xbe,0xba]
+ movq %xmm5,0xbabecafe
+
+// CHECK: movq %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0x78,0x56,0x34,0x12]
+ movq %xmm5,0x12345678
+
+// CHECK: movq %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x7e,0xed]
+ movq %xmm5,%xmm5
+
+// CHECK: packssdw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6b,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ packssdw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packssdw 69, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0x45,0x00,0x00,0x00]
+ packssdw 0x45,%mm3
+
+// CHECK: packssdw 32493, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0xed,0x7e,0x00,0x00]
+ packssdw 0x7eed,%mm3
+
+// CHECK: packssdw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0xfe,0xca,0xbe,0xba]
+ packssdw 0xbabecafe,%mm3
+
+// CHECK: packssdw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0x78,0x56,0x34,0x12]
+ packssdw 0x12345678,%mm3
+
+// CHECK: packssdw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6b,0xdb]
+ packssdw %mm3,%mm3
+
+// CHECK: packssdw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packssdw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packssdw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0x45,0x00,0x00,0x00]
+ packssdw 0x45,%xmm5
+
+// CHECK: packssdw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0xed,0x7e,0x00,0x00]
+ packssdw 0x7eed,%xmm5
+
+// CHECK: packssdw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0xfe,0xca,0xbe,0xba]
+ packssdw 0xbabecafe,%xmm5
+
+// CHECK: packssdw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0x78,0x56,0x34,0x12]
+ packssdw 0x12345678,%xmm5
+
+// CHECK: packssdw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0xed]
+ packssdw %xmm5,%xmm5
+
+// CHECK: packsswb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x63,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ packsswb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packsswb 69, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0x45,0x00,0x00,0x00]
+ packsswb 0x45,%mm3
+
+// CHECK: packsswb 32493, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0xed,0x7e,0x00,0x00]
+ packsswb 0x7eed,%mm3
+
+// CHECK: packsswb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0xfe,0xca,0xbe,0xba]
+ packsswb 0xbabecafe,%mm3
+
+// CHECK: packsswb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0x78,0x56,0x34,0x12]
+ packsswb 0x12345678,%mm3
+
+// CHECK: packsswb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x63,0xdb]
+ packsswb %mm3,%mm3
+
+// CHECK: packsswb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packsswb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packsswb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0x45,0x00,0x00,0x00]
+ packsswb 0x45,%xmm5
+
+// CHECK: packsswb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0xed,0x7e,0x00,0x00]
+ packsswb 0x7eed,%xmm5
+
+// CHECK: packsswb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0xfe,0xca,0xbe,0xba]
+ packsswb 0xbabecafe,%xmm5
+
+// CHECK: packsswb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0x78,0x56,0x34,0x12]
+ packsswb 0x12345678,%xmm5
+
+// CHECK: packsswb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0xed]
+ packsswb %xmm5,%xmm5
+
+// CHECK: packuswb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x67,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ packuswb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packuswb 69, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0x45,0x00,0x00,0x00]
+ packuswb 0x45,%mm3
+
+// CHECK: packuswb 32493, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0xed,0x7e,0x00,0x00]
+ packuswb 0x7eed,%mm3
+
+// CHECK: packuswb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0xfe,0xca,0xbe,0xba]
+ packuswb 0xbabecafe,%mm3
+
+// CHECK: packuswb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0x78,0x56,0x34,0x12]
+ packuswb 0x12345678,%mm3
+
+// CHECK: packuswb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x67,0xdb]
+ packuswb %mm3,%mm3
+
+// CHECK: packuswb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packuswb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packuswb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0x45,0x00,0x00,0x00]
+ packuswb 0x45,%xmm5
+
+// CHECK: packuswb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0xed,0x7e,0x00,0x00]
+ packuswb 0x7eed,%xmm5
+
+// CHECK: packuswb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0xfe,0xca,0xbe,0xba]
+ packuswb 0xbabecafe,%xmm5
+
+// CHECK: packuswb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0x78,0x56,0x34,0x12]
+ packuswb 0x12345678,%xmm5
+
+// CHECK: packuswb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0xed]
+ packuswb %xmm5,%xmm5
+
+// CHECK: paddb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfc,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddb 69, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0x45,0x00,0x00,0x00]
+ paddb 0x45,%mm3
+
+// CHECK: paddb 32493, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0xed,0x7e,0x00,0x00]
+ paddb 0x7eed,%mm3
+
+// CHECK: paddb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0xfe,0xca,0xbe,0xba]
+ paddb 0xbabecafe,%mm3
+
+// CHECK: paddb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0x78,0x56,0x34,0x12]
+ paddb 0x12345678,%mm3
+
+// CHECK: paddb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfc,0xdb]
+ paddb %mm3,%mm3
+
+// CHECK: paddb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0x45,0x00,0x00,0x00]
+ paddb 0x45,%xmm5
+
+// CHECK: paddb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0xed,0x7e,0x00,0x00]
+ paddb 0x7eed,%xmm5
+
+// CHECK: paddb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0xfe,0xca,0xbe,0xba]
+ paddb 0xbabecafe,%xmm5
+
+// CHECK: paddb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0x78,0x56,0x34,0x12]
+ paddb 0x12345678,%xmm5
+
+// CHECK: paddb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0xed]
+ paddb %xmm5,%xmm5
+
+// CHECK: paddw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfd,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddw 69, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0x45,0x00,0x00,0x00]
+ paddw 0x45,%mm3
+
+// CHECK: paddw 32493, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0xed,0x7e,0x00,0x00]
+ paddw 0x7eed,%mm3
+
+// CHECK: paddw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0xfe,0xca,0xbe,0xba]
+ paddw 0xbabecafe,%mm3
+
+// CHECK: paddw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0x78,0x56,0x34,0x12]
+ paddw 0x12345678,%mm3
+
+// CHECK: paddw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfd,0xdb]
+ paddw %mm3,%mm3
+
+// CHECK: paddw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0x45,0x00,0x00,0x00]
+ paddw 0x45,%xmm5
+
+// CHECK: paddw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0xed,0x7e,0x00,0x00]
+ paddw 0x7eed,%xmm5
+
+// CHECK: paddw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0xfe,0xca,0xbe,0xba]
+ paddw 0xbabecafe,%xmm5
+
+// CHECK: paddw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0x78,0x56,0x34,0x12]
+ paddw 0x12345678,%xmm5
+
+// CHECK: paddw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0xed]
+ paddw %xmm5,%xmm5
+
+// CHECK: paddd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfe,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddd 69, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0x45,0x00,0x00,0x00]
+ paddd 0x45,%mm3
+
+// CHECK: paddd 32493, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0xed,0x7e,0x00,0x00]
+ paddd 0x7eed,%mm3
+
+// CHECK: paddd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0xfe,0xca,0xbe,0xba]
+ paddd 0xbabecafe,%mm3
+
+// CHECK: paddd 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0x78,0x56,0x34,0x12]
+ paddd 0x12345678,%mm3
+
+// CHECK: paddd %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfe,0xdb]
+ paddd %mm3,%mm3
+
+// CHECK: paddd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0x45,0x00,0x00,0x00]
+ paddd 0x45,%xmm5
+
+// CHECK: paddd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0xed,0x7e,0x00,0x00]
+ paddd 0x7eed,%xmm5
+
+// CHECK: paddd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0xfe,0xca,0xbe,0xba]
+ paddd 0xbabecafe,%xmm5
+
+// CHECK: paddd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0x78,0x56,0x34,0x12]
+ paddd 0x12345678,%xmm5
+
+// CHECK: paddd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0xed]
+ paddd %xmm5,%xmm5
+
+// CHECK: paddq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd4,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddq 69, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0x45,0x00,0x00,0x00]
+ paddq 0x45,%mm3
+
+// CHECK: paddq 32493, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0xed,0x7e,0x00,0x00]
+ paddq 0x7eed,%mm3
+
+// CHECK: paddq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0xfe,0xca,0xbe,0xba]
+ paddq 0xbabecafe,%mm3
+
+// CHECK: paddq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0x78,0x56,0x34,0x12]
+ paddq 0x12345678,%mm3
+
+// CHECK: paddq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd4,0xdb]
+ paddq %mm3,%mm3
+
+// CHECK: paddq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0x45,0x00,0x00,0x00]
+ paddq 0x45,%xmm5
+
+// CHECK: paddq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0xed,0x7e,0x00,0x00]
+ paddq 0x7eed,%xmm5
+
+// CHECK: paddq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0xfe,0xca,0xbe,0xba]
+ paddq 0xbabecafe,%xmm5
+
+// CHECK: paddq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0x78,0x56,0x34,0x12]
+ paddq 0x12345678,%xmm5
+
+// CHECK: paddq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0xed]
+ paddq %xmm5,%xmm5
+
+// CHECK: paddsb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xec,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddsb 69, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0x45,0x00,0x00,0x00]
+ paddsb 0x45,%mm3
+
+// CHECK: paddsb 32493, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0xed,0x7e,0x00,0x00]
+ paddsb 0x7eed,%mm3
+
+// CHECK: paddsb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0xfe,0xca,0xbe,0xba]
+ paddsb 0xbabecafe,%mm3
+
+// CHECK: paddsb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0x78,0x56,0x34,0x12]
+ paddsb 0x12345678,%mm3
+
+// CHECK: paddsb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xec,0xdb]
+ paddsb %mm3,%mm3
+
+// CHECK: paddsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0x45,0x00,0x00,0x00]
+ paddsb 0x45,%xmm5
+
+// CHECK: paddsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0xed,0x7e,0x00,0x00]
+ paddsb 0x7eed,%xmm5
+
+// CHECK: paddsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0xfe,0xca,0xbe,0xba]
+ paddsb 0xbabecafe,%xmm5
+
+// CHECK: paddsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0x78,0x56,0x34,0x12]
+ paddsb 0x12345678,%xmm5
+
+// CHECK: paddsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0xed]
+ paddsb %xmm5,%xmm5
+
+// CHECK: paddsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xed,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddsw 69, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0x45,0x00,0x00,0x00]
+ paddsw 0x45,%mm3
+
+// CHECK: paddsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0xed,0x7e,0x00,0x00]
+ paddsw 0x7eed,%mm3
+
+// CHECK: paddsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0xfe,0xca,0xbe,0xba]
+ paddsw 0xbabecafe,%mm3
+
+// CHECK: paddsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0x78,0x56,0x34,0x12]
+ paddsw 0x12345678,%mm3
+
+// CHECK: paddsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xed,0xdb]
+ paddsw %mm3,%mm3
+
+// CHECK: paddsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0x45,0x00,0x00,0x00]
+ paddsw 0x45,%xmm5
+
+// CHECK: paddsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0xed,0x7e,0x00,0x00]
+ paddsw 0x7eed,%xmm5
+
+// CHECK: paddsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0xfe,0xca,0xbe,0xba]
+ paddsw 0xbabecafe,%xmm5
+
+// CHECK: paddsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0x78,0x56,0x34,0x12]
+ paddsw 0x12345678,%xmm5
+
+// CHECK: paddsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0xed]
+ paddsw %xmm5,%xmm5
+
+// CHECK: paddusb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdc,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddusb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddusb 69, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0x45,0x00,0x00,0x00]
+ paddusb 0x45,%mm3
+
+// CHECK: paddusb 32493, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0xed,0x7e,0x00,0x00]
+ paddusb 0x7eed,%mm3
+
+// CHECK: paddusb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0xfe,0xca,0xbe,0xba]
+ paddusb 0xbabecafe,%mm3
+
+// CHECK: paddusb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0x78,0x56,0x34,0x12]
+ paddusb 0x12345678,%mm3
+
+// CHECK: paddusb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdc,0xdb]
+ paddusb %mm3,%mm3
+
+// CHECK: paddusb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddusb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddusb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0x45,0x00,0x00,0x00]
+ paddusb 0x45,%xmm5
+
+// CHECK: paddusb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0xed,0x7e,0x00,0x00]
+ paddusb 0x7eed,%xmm5
+
+// CHECK: paddusb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0xfe,0xca,0xbe,0xba]
+ paddusb 0xbabecafe,%xmm5
+
+// CHECK: paddusb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0x78,0x56,0x34,0x12]
+ paddusb 0x12345678,%xmm5
+
+// CHECK: paddusb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0xed]
+ paddusb %xmm5,%xmm5
+
+// CHECK: paddusw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdd,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddusw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddusw 69, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0x45,0x00,0x00,0x00]
+ paddusw 0x45,%mm3
+
+// CHECK: paddusw 32493, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0xed,0x7e,0x00,0x00]
+ paddusw 0x7eed,%mm3
+
+// CHECK: paddusw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0xfe,0xca,0xbe,0xba]
+ paddusw 0xbabecafe,%mm3
+
+// CHECK: paddusw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0x78,0x56,0x34,0x12]
+ paddusw 0x12345678,%mm3
+
+// CHECK: paddusw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdd,0xdb]
+ paddusw %mm3,%mm3
+
+// CHECK: paddusw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddusw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddusw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0x45,0x00,0x00,0x00]
+ paddusw 0x45,%xmm5
+
+// CHECK: paddusw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0xed,0x7e,0x00,0x00]
+ paddusw 0x7eed,%xmm5
+
+// CHECK: paddusw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0xfe,0xca,0xbe,0xba]
+ paddusw 0xbabecafe,%xmm5
+
+// CHECK: paddusw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0x78,0x56,0x34,0x12]
+ paddusw 0x12345678,%xmm5
+
+// CHECK: paddusw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0xed]
+ paddusw %xmm5,%xmm5
+
+// CHECK: pand 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pand 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pand 69, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0x45,0x00,0x00,0x00]
+ pand 0x45,%mm3
+
+// CHECK: pand 32493, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0xed,0x7e,0x00,0x00]
+ pand 0x7eed,%mm3
+
+// CHECK: pand 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0xfe,0xca,0xbe,0xba]
+ pand 0xbabecafe,%mm3
+
+// CHECK: pand 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0x78,0x56,0x34,0x12]
+ pand 0x12345678,%mm3
+
+// CHECK: pand %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdb,0xdb]
+ pand %mm3,%mm3
+
+// CHECK: pand 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pand 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pand 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0x45,0x00,0x00,0x00]
+ pand 0x45,%xmm5
+
+// CHECK: pand 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0xed,0x7e,0x00,0x00]
+ pand 0x7eed,%xmm5
+
+// CHECK: pand 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0xfe,0xca,0xbe,0xba]
+ pand 0xbabecafe,%xmm5
+
+// CHECK: pand 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0x78,0x56,0x34,0x12]
+ pand 0x12345678,%xmm5
+
+// CHECK: pand %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0xed]
+ pand %xmm5,%xmm5
+
+// CHECK: pandn 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdf,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pandn 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pandn 69, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0x45,0x00,0x00,0x00]
+ pandn 0x45,%mm3
+
+// CHECK: pandn 32493, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0xed,0x7e,0x00,0x00]
+ pandn 0x7eed,%mm3
+
+// CHECK: pandn 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0xfe,0xca,0xbe,0xba]
+ pandn 0xbabecafe,%mm3
+
+// CHECK: pandn 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0x78,0x56,0x34,0x12]
+ pandn 0x12345678,%mm3
+
+// CHECK: pandn %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdf,0xdb]
+ pandn %mm3,%mm3
+
+// CHECK: pandn 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pandn 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pandn 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0x45,0x00,0x00,0x00]
+ pandn 0x45,%xmm5
+
+// CHECK: pandn 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0xed,0x7e,0x00,0x00]
+ pandn 0x7eed,%xmm5
+
+// CHECK: pandn 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0xfe,0xca,0xbe,0xba]
+ pandn 0xbabecafe,%xmm5
+
+// CHECK: pandn 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0x78,0x56,0x34,0x12]
+ pandn 0x12345678,%xmm5
+
+// CHECK: pandn %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0xed]
+ pandn %xmm5,%xmm5
+
+// CHECK: pcmpeqb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x74,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqb 69, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0x45,0x00,0x00,0x00]
+ pcmpeqb 0x45,%mm3
+
+// CHECK: pcmpeqb 32493, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpeqb 0x7eed,%mm3
+
+// CHECK: pcmpeqb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpeqb 0xbabecafe,%mm3
+
+// CHECK: pcmpeqb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0x78,0x56,0x34,0x12]
+ pcmpeqb 0x12345678,%mm3
+
+// CHECK: pcmpeqb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x74,0xdb]
+ pcmpeqb %mm3,%mm3
+
+// CHECK: pcmpeqb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqb 0x45,%xmm5
+
+// CHECK: pcmpeqb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqb 0x7eed,%xmm5
+
+// CHECK: pcmpeqb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqb 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqb 0x12345678,%xmm5
+
+// CHECK: pcmpeqb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0xed]
+ pcmpeqb %xmm5,%xmm5
+
+// CHECK: pcmpeqw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x75,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqw 69, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0x45,0x00,0x00,0x00]
+ pcmpeqw 0x45,%mm3
+
+// CHECK: pcmpeqw 32493, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpeqw 0x7eed,%mm3
+
+// CHECK: pcmpeqw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpeqw 0xbabecafe,%mm3
+
+// CHECK: pcmpeqw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0x78,0x56,0x34,0x12]
+ pcmpeqw 0x12345678,%mm3
+
+// CHECK: pcmpeqw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x75,0xdb]
+ pcmpeqw %mm3,%mm3
+
+// CHECK: pcmpeqw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqw 0x45,%xmm5
+
+// CHECK: pcmpeqw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqw 0x7eed,%xmm5
+
+// CHECK: pcmpeqw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqw 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqw 0x12345678,%xmm5
+
+// CHECK: pcmpeqw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0xed]
+ pcmpeqw %xmm5,%xmm5
+
+// CHECK: pcmpeqd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x76,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqd 69, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0x45,0x00,0x00,0x00]
+ pcmpeqd 0x45,%mm3
+
+// CHECK: pcmpeqd 32493, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpeqd 0x7eed,%mm3
+
+// CHECK: pcmpeqd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpeqd 0xbabecafe,%mm3
+
+// CHECK: pcmpeqd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0x78,0x56,0x34,0x12]
+ pcmpeqd 0x12345678,%mm3
+
+// CHECK: pcmpeqd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x76,0xdb]
+ pcmpeqd %mm3,%mm3
+
+// CHECK: pcmpeqd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqd 0x45,%xmm5
+
+// CHECK: pcmpeqd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqd 0x7eed,%xmm5
+
+// CHECK: pcmpeqd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqd 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqd 0x12345678,%xmm5
+
+// CHECK: pcmpeqd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0xed]
+ pcmpeqd %xmm5,%xmm5
+
+// CHECK: pcmpgtb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x64,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtb 69, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0x45,0x00,0x00,0x00]
+ pcmpgtb 0x45,%mm3
+
+// CHECK: pcmpgtb 32493, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpgtb 0x7eed,%mm3
+
+// CHECK: pcmpgtb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpgtb 0xbabecafe,%mm3
+
+// CHECK: pcmpgtb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0x78,0x56,0x34,0x12]
+ pcmpgtb 0x12345678,%mm3
+
+// CHECK: pcmpgtb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x64,0xdb]
+ pcmpgtb %mm3,%mm3
+
+// CHECK: pcmpgtb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtb 0x45,%xmm5
+
+// CHECK: pcmpgtb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtb 0x7eed,%xmm5
+
+// CHECK: pcmpgtb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtb 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtb 0x12345678,%xmm5
+
+// CHECK: pcmpgtb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0xed]
+ pcmpgtb %xmm5,%xmm5
+
+// CHECK: pcmpgtw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x65,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtw 69, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0x45,0x00,0x00,0x00]
+ pcmpgtw 0x45,%mm3
+
+// CHECK: pcmpgtw 32493, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpgtw 0x7eed,%mm3
+
+// CHECK: pcmpgtw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpgtw 0xbabecafe,%mm3
+
+// CHECK: pcmpgtw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0x78,0x56,0x34,0x12]
+ pcmpgtw 0x12345678,%mm3
+
+// CHECK: pcmpgtw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x65,0xdb]
+ pcmpgtw %mm3,%mm3
+
+// CHECK: pcmpgtw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtw 0x45,%xmm5
+
+// CHECK: pcmpgtw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtw 0x7eed,%xmm5
+
+// CHECK: pcmpgtw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtw 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtw 0x12345678,%xmm5
+
+// CHECK: pcmpgtw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0xed]
+ pcmpgtw %xmm5,%xmm5
+
+// CHECK: pcmpgtd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x66,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtd 69, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0x45,0x00,0x00,0x00]
+ pcmpgtd 0x45,%mm3
+
+// CHECK: pcmpgtd 32493, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpgtd 0x7eed,%mm3
+
+// CHECK: pcmpgtd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpgtd 0xbabecafe,%mm3
+
+// CHECK: pcmpgtd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0x78,0x56,0x34,0x12]
+ pcmpgtd 0x12345678,%mm3
+
+// CHECK: pcmpgtd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x66,0xdb]
+ pcmpgtd %mm3,%mm3
+
+// CHECK: pcmpgtd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtd 0x45,%xmm5
+
+// CHECK: pcmpgtd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtd 0x7eed,%xmm5
+
+// CHECK: pcmpgtd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtd 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtd 0x12345678,%xmm5
+
+// CHECK: pcmpgtd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0xed]
+ pcmpgtd %xmm5,%xmm5
+
+// CHECK: pmaddwd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf5,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaddwd 69, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0x45,0x00,0x00,0x00]
+ pmaddwd 0x45,%mm3
+
+// CHECK: pmaddwd 32493, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0xed,0x7e,0x00,0x00]
+ pmaddwd 0x7eed,%mm3
+
+// CHECK: pmaddwd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaddwd 0xbabecafe,%mm3
+
+// CHECK: pmaddwd 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0x78,0x56,0x34,0x12]
+ pmaddwd 0x12345678,%mm3
+
+// CHECK: pmaddwd %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf5,0xdb]
+ pmaddwd %mm3,%mm3
+
+// CHECK: pmaddwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaddwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0x45,0x00,0x00,0x00]
+ pmaddwd 0x45,%xmm5
+
+// CHECK: pmaddwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0xed,0x7e,0x00,0x00]
+ pmaddwd 0x7eed,%xmm5
+
+// CHECK: pmaddwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaddwd 0xbabecafe,%xmm5
+
+// CHECK: pmaddwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0x78,0x56,0x34,0x12]
+ pmaddwd 0x12345678,%xmm5
+
+// CHECK: pmaddwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0xed]
+ pmaddwd %xmm5,%xmm5
+
+// CHECK: pmulhw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe5,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhw 69, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0x45,0x00,0x00,0x00]
+ pmulhw 0x45,%mm3
+
+// CHECK: pmulhw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0xed,0x7e,0x00,0x00]
+ pmulhw 0x7eed,%mm3
+
+// CHECK: pmulhw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0xfe,0xca,0xbe,0xba]
+ pmulhw 0xbabecafe,%mm3
+
+// CHECK: pmulhw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0x78,0x56,0x34,0x12]
+ pmulhw 0x12345678,%mm3
+
+// CHECK: pmulhw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe5,0xdb]
+ pmulhw %mm3,%mm3
+
+// CHECK: pmulhw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0x45,0x00,0x00,0x00]
+ pmulhw 0x45,%xmm5
+
+// CHECK: pmulhw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0xed,0x7e,0x00,0x00]
+ pmulhw 0x7eed,%xmm5
+
+// CHECK: pmulhw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulhw 0xbabecafe,%xmm5
+
+// CHECK: pmulhw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0x78,0x56,0x34,0x12]
+ pmulhw 0x12345678,%xmm5
+
+// CHECK: pmulhw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0xed]
+ pmulhw %xmm5,%xmm5
+
+// CHECK: pmullw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd5,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmullw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmullw 69, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0x45,0x00,0x00,0x00]
+ pmullw 0x45,%mm3
+
+// CHECK: pmullw 32493, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0xed,0x7e,0x00,0x00]
+ pmullw 0x7eed,%mm3
+
+// CHECK: pmullw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0xfe,0xca,0xbe,0xba]
+ pmullw 0xbabecafe,%mm3
+
+// CHECK: pmullw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0x78,0x56,0x34,0x12]
+ pmullw 0x12345678,%mm3
+
+// CHECK: pmullw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd5,0xdb]
+ pmullw %mm3,%mm3
+
+// CHECK: pmullw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmullw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmullw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0x45,0x00,0x00,0x00]
+ pmullw 0x45,%xmm5
+
+// CHECK: pmullw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0xed,0x7e,0x00,0x00]
+ pmullw 0x7eed,%xmm5
+
+// CHECK: pmullw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0xfe,0xca,0xbe,0xba]
+ pmullw 0xbabecafe,%xmm5
+
+// CHECK: pmullw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0x78,0x56,0x34,0x12]
+ pmullw 0x12345678,%xmm5
+
+// CHECK: pmullw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0xed]
+ pmullw %xmm5,%xmm5
+
+// CHECK: por 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xeb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ por 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: por 69, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0x45,0x00,0x00,0x00]
+ por 0x45,%mm3
+
+// CHECK: por 32493, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0xed,0x7e,0x00,0x00]
+ por 0x7eed,%mm3
+
+// CHECK: por 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0xfe,0xca,0xbe,0xba]
+ por 0xbabecafe,%mm3
+
+// CHECK: por 305419896, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0x78,0x56,0x34,0x12]
+ por 0x12345678,%mm3
+
+// CHECK: por %mm3, %mm3
+// CHECK: encoding: [0x0f,0xeb,0xdb]
+ por %mm3,%mm3
+
+// CHECK: por 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ por 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: por 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0x45,0x00,0x00,0x00]
+ por 0x45,%xmm5
+
+// CHECK: por 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0xed,0x7e,0x00,0x00]
+ por 0x7eed,%xmm5
+
+// CHECK: por 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0xfe,0xca,0xbe,0xba]
+ por 0xbabecafe,%xmm5
+
+// CHECK: por 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0x78,0x56,0x34,0x12]
+ por 0x12345678,%xmm5
+
+// CHECK: por %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0xed]
+ por %xmm5,%xmm5
+
+// CHECK: psllw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf1,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psllw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psllw 69, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0x45,0x00,0x00,0x00]
+ psllw 0x45,%mm3
+
+// CHECK: psllw 32493, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0xed,0x7e,0x00,0x00]
+ psllw 0x7eed,%mm3
+
+// CHECK: psllw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0xfe,0xca,0xbe,0xba]
+ psllw 0xbabecafe,%mm3
+
+// CHECK: psllw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0x78,0x56,0x34,0x12]
+ psllw 0x12345678,%mm3
+
+// CHECK: psllw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf1,0xdb]
+ psllw %mm3,%mm3
+
+// CHECK: psllw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psllw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psllw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0x45,0x00,0x00,0x00]
+ psllw 0x45,%xmm5
+
+// CHECK: psllw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0xed,0x7e,0x00,0x00]
+ psllw 0x7eed,%xmm5
+
+// CHECK: psllw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0xfe,0xca,0xbe,0xba]
+ psllw 0xbabecafe,%xmm5
+
+// CHECK: psllw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0x78,0x56,0x34,0x12]
+ psllw 0x12345678,%xmm5
+
+// CHECK: psllw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0xed]
+ psllw %xmm5,%xmm5
+
+// CHECK: psllw $127, %mm3
+// CHECK: encoding: [0x0f,0x71,0xf3,0x7f]
+ psllw $0x7f,%mm3
+
+// CHECK: psllw $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x71,0xf5,0x7f]
+ psllw $0x7f,%xmm5
+
+// CHECK: pslld 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf2,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pslld 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pslld 69, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0x45,0x00,0x00,0x00]
+ pslld 0x45,%mm3
+
+// CHECK: pslld 32493, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0xed,0x7e,0x00,0x00]
+ pslld 0x7eed,%mm3
+
+// CHECK: pslld 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0xfe,0xca,0xbe,0xba]
+ pslld 0xbabecafe,%mm3
+
+// CHECK: pslld 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0x78,0x56,0x34,0x12]
+ pslld 0x12345678,%mm3
+
+// CHECK: pslld %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf2,0xdb]
+ pslld %mm3,%mm3
+
+// CHECK: pslld 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pslld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pslld 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0x45,0x00,0x00,0x00]
+ pslld 0x45,%xmm5
+
+// CHECK: pslld 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0xed,0x7e,0x00,0x00]
+ pslld 0x7eed,%xmm5
+
+// CHECK: pslld 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0xfe,0xca,0xbe,0xba]
+ pslld 0xbabecafe,%xmm5
+
+// CHECK: pslld 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0x78,0x56,0x34,0x12]
+ pslld 0x12345678,%xmm5
+
+// CHECK: pslld %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0xed]
+ pslld %xmm5,%xmm5
+
+// CHECK: pslld $127, %mm3
+// CHECK: encoding: [0x0f,0x72,0xf3,0x7f]
+ pslld $0x7f,%mm3
+
+// CHECK: pslld $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x72,0xf5,0x7f]
+ pslld $0x7f,%xmm5
+
+// CHECK: psllq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf3,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psllq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psllq 69, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0x45,0x00,0x00,0x00]
+ psllq 0x45,%mm3
+
+// CHECK: psllq 32493, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0xed,0x7e,0x00,0x00]
+ psllq 0x7eed,%mm3
+
+// CHECK: psllq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0xfe,0xca,0xbe,0xba]
+ psllq 0xbabecafe,%mm3
+
+// CHECK: psllq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0x78,0x56,0x34,0x12]
+ psllq 0x12345678,%mm3
+
+// CHECK: psllq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf3,0xdb]
+ psllq %mm3,%mm3
+
+// CHECK: psllq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psllq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psllq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0x45,0x00,0x00,0x00]
+ psllq 0x45,%xmm5
+
+// CHECK: psllq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0xed,0x7e,0x00,0x00]
+ psllq 0x7eed,%xmm5
+
+// CHECK: psllq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0xfe,0xca,0xbe,0xba]
+ psllq 0xbabecafe,%xmm5
+
+// CHECK: psllq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0x78,0x56,0x34,0x12]
+ psllq 0x12345678,%xmm5
+
+// CHECK: psllq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0xed]
+ psllq %xmm5,%xmm5
+
+// CHECK: psllq $127, %mm3
+// CHECK: encoding: [0x0f,0x73,0xf3,0x7f]
+ psllq $0x7f,%mm3
+
+// CHECK: psllq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xf5,0x7f]
+ psllq $0x7f,%xmm5
+
+// CHECK: psraw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe1,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psraw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psraw 69, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0x45,0x00,0x00,0x00]
+ psraw 0x45,%mm3
+
+// CHECK: psraw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0xed,0x7e,0x00,0x00]
+ psraw 0x7eed,%mm3
+
+// CHECK: psraw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0xfe,0xca,0xbe,0xba]
+ psraw 0xbabecafe,%mm3
+
+// CHECK: psraw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0x78,0x56,0x34,0x12]
+ psraw 0x12345678,%mm3
+
+// CHECK: psraw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe1,0xdb]
+ psraw %mm3,%mm3
+
+// CHECK: psraw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psraw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psraw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0x45,0x00,0x00,0x00]
+ psraw 0x45,%xmm5
+
+// CHECK: psraw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0xed,0x7e,0x00,0x00]
+ psraw 0x7eed,%xmm5
+
+// CHECK: psraw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0xfe,0xca,0xbe,0xba]
+ psraw 0xbabecafe,%xmm5
+
+// CHECK: psraw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0x78,0x56,0x34,0x12]
+ psraw 0x12345678,%xmm5
+
+// CHECK: psraw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0xed]
+ psraw %xmm5,%xmm5
+
+// CHECK: psraw $127, %mm3
+// CHECK: encoding: [0x0f,0x71,0xe3,0x7f]
+ psraw $0x7f,%mm3
+
+// CHECK: psraw $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x71,0xe5,0x7f]
+ psraw $0x7f,%xmm5
+
+// CHECK: psrad 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe2,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrad 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrad 69, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0x45,0x00,0x00,0x00]
+ psrad 0x45,%mm3
+
+// CHECK: psrad 32493, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0xed,0x7e,0x00,0x00]
+ psrad 0x7eed,%mm3
+
+// CHECK: psrad 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0xfe,0xca,0xbe,0xba]
+ psrad 0xbabecafe,%mm3
+
+// CHECK: psrad 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0x78,0x56,0x34,0x12]
+ psrad 0x12345678,%mm3
+
+// CHECK: psrad %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe2,0xdb]
+ psrad %mm3,%mm3
+
+// CHECK: psrad 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrad 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrad 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0x45,0x00,0x00,0x00]
+ psrad 0x45,%xmm5
+
+// CHECK: psrad 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0xed,0x7e,0x00,0x00]
+ psrad 0x7eed,%xmm5
+
+// CHECK: psrad 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0xfe,0xca,0xbe,0xba]
+ psrad 0xbabecafe,%xmm5
+
+// CHECK: psrad 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0x78,0x56,0x34,0x12]
+ psrad 0x12345678,%xmm5
+
+// CHECK: psrad %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0xed]
+ psrad %xmm5,%xmm5
+
+// CHECK: psrad $127, %mm3
+// CHECK: encoding: [0x0f,0x72,0xe3,0x7f]
+ psrad $0x7f,%mm3
+
+// CHECK: psrad $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x72,0xe5,0x7f]
+ psrad $0x7f,%xmm5
+
+// CHECK: psrlw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd1,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrlw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrlw 69, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0x45,0x00,0x00,0x00]
+ psrlw 0x45,%mm3
+
+// CHECK: psrlw 32493, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0xed,0x7e,0x00,0x00]
+ psrlw 0x7eed,%mm3
+
+// CHECK: psrlw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0xfe,0xca,0xbe,0xba]
+ psrlw 0xbabecafe,%mm3
+
+// CHECK: psrlw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0x78,0x56,0x34,0x12]
+ psrlw 0x12345678,%mm3
+
+// CHECK: psrlw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd1,0xdb]
+ psrlw %mm3,%mm3
+
+// CHECK: psrlw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrlw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrlw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0x45,0x00,0x00,0x00]
+ psrlw 0x45,%xmm5
+
+// CHECK: psrlw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0xed,0x7e,0x00,0x00]
+ psrlw 0x7eed,%xmm5
+
+// CHECK: psrlw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0xfe,0xca,0xbe,0xba]
+ psrlw 0xbabecafe,%xmm5
+
+// CHECK: psrlw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0x78,0x56,0x34,0x12]
+ psrlw 0x12345678,%xmm5
+
+// CHECK: psrlw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0xed]
+ psrlw %xmm5,%xmm5
+
+// CHECK: psrlw $127, %mm3
+// CHECK: encoding: [0x0f,0x71,0xd3,0x7f]
+ psrlw $0x7f,%mm3
+
+// CHECK: psrlw $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x71,0xd5,0x7f]
+ psrlw $0x7f,%xmm5
+
+// CHECK: psrld 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd2,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrld 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrld 69, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0x45,0x00,0x00,0x00]
+ psrld 0x45,%mm3
+
+// CHECK: psrld 32493, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0xed,0x7e,0x00,0x00]
+ psrld 0x7eed,%mm3
+
+// CHECK: psrld 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0xfe,0xca,0xbe,0xba]
+ psrld 0xbabecafe,%mm3
+
+// CHECK: psrld 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0x78,0x56,0x34,0x12]
+ psrld 0x12345678,%mm3
+
+// CHECK: psrld %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd2,0xdb]
+ psrld %mm3,%mm3
+
+// CHECK: psrld 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrld 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0x45,0x00,0x00,0x00]
+ psrld 0x45,%xmm5
+
+// CHECK: psrld 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0xed,0x7e,0x00,0x00]
+ psrld 0x7eed,%xmm5
+
+// CHECK: psrld 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0xfe,0xca,0xbe,0xba]
+ psrld 0xbabecafe,%xmm5
+
+// CHECK: psrld 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0x78,0x56,0x34,0x12]
+ psrld 0x12345678,%xmm5
+
+// CHECK: psrld %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0xed]
+ psrld %xmm5,%xmm5
+
+// CHECK: psrld $127, %mm3
+// CHECK: encoding: [0x0f,0x72,0xd3,0x7f]
+ psrld $0x7f,%mm3
+
+// CHECK: psrld $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x72,0xd5,0x7f]
+ psrld $0x7f,%xmm5
+
+// CHECK: psrlq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd3,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrlq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrlq 69, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0x45,0x00,0x00,0x00]
+ psrlq 0x45,%mm3
+
+// CHECK: psrlq 32493, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0xed,0x7e,0x00,0x00]
+ psrlq 0x7eed,%mm3
+
+// CHECK: psrlq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0xfe,0xca,0xbe,0xba]
+ psrlq 0xbabecafe,%mm3
+
+// CHECK: psrlq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0x78,0x56,0x34,0x12]
+ psrlq 0x12345678,%mm3
+
+// CHECK: psrlq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd3,0xdb]
+ psrlq %mm3,%mm3
+
+// CHECK: psrlq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrlq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrlq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0x45,0x00,0x00,0x00]
+ psrlq 0x45,%xmm5
+
+// CHECK: psrlq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0xed,0x7e,0x00,0x00]
+ psrlq 0x7eed,%xmm5
+
+// CHECK: psrlq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0xfe,0xca,0xbe,0xba]
+ psrlq 0xbabecafe,%xmm5
+
+// CHECK: psrlq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0x78,0x56,0x34,0x12]
+ psrlq 0x12345678,%xmm5
+
+// CHECK: psrlq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0xed]
+ psrlq %xmm5,%xmm5
+
+// CHECK: psrlq $127, %mm3
+// CHECK: encoding: [0x0f,0x73,0xd3,0x7f]
+ psrlq $0x7f,%mm3
+
+// CHECK: psrlq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xd5,0x7f]
+ psrlq $0x7f,%xmm5
+
+// CHECK: psubb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf8,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubb 69, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0x45,0x00,0x00,0x00]
+ psubb 0x45,%mm3
+
+// CHECK: psubb 32493, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0xed,0x7e,0x00,0x00]
+ psubb 0x7eed,%mm3
+
+// CHECK: psubb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0xfe,0xca,0xbe,0xba]
+ psubb 0xbabecafe,%mm3
+
+// CHECK: psubb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0x78,0x56,0x34,0x12]
+ psubb 0x12345678,%mm3
+
+// CHECK: psubb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf8,0xdb]
+ psubb %mm3,%mm3
+
+// CHECK: psubb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0x45,0x00,0x00,0x00]
+ psubb 0x45,%xmm5
+
+// CHECK: psubb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0xed,0x7e,0x00,0x00]
+ psubb 0x7eed,%xmm5
+
+// CHECK: psubb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0xfe,0xca,0xbe,0xba]
+ psubb 0xbabecafe,%xmm5
+
+// CHECK: psubb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0x78,0x56,0x34,0x12]
+ psubb 0x12345678,%xmm5
+
+// CHECK: psubb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0xed]
+ psubb %xmm5,%xmm5
+
+// CHECK: psubw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf9,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubw 69, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0x45,0x00,0x00,0x00]
+ psubw 0x45,%mm3
+
+// CHECK: psubw 32493, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0xed,0x7e,0x00,0x00]
+ psubw 0x7eed,%mm3
+
+// CHECK: psubw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0xfe,0xca,0xbe,0xba]
+ psubw 0xbabecafe,%mm3
+
+// CHECK: psubw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0x78,0x56,0x34,0x12]
+ psubw 0x12345678,%mm3
+
+// CHECK: psubw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf9,0xdb]
+ psubw %mm3,%mm3
+
+// CHECK: psubw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0x45,0x00,0x00,0x00]
+ psubw 0x45,%xmm5
+
+// CHECK: psubw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0xed,0x7e,0x00,0x00]
+ psubw 0x7eed,%xmm5
+
+// CHECK: psubw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0xfe,0xca,0xbe,0xba]
+ psubw 0xbabecafe,%xmm5
+
+// CHECK: psubw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0x78,0x56,0x34,0x12]
+ psubw 0x12345678,%xmm5
+
+// CHECK: psubw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0xed]
+ psubw %xmm5,%xmm5
+
+// CHECK: psubd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfa,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubd 69, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0x45,0x00,0x00,0x00]
+ psubd 0x45,%mm3
+
+// CHECK: psubd 32493, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0xed,0x7e,0x00,0x00]
+ psubd 0x7eed,%mm3
+
+// CHECK: psubd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0xfe,0xca,0xbe,0xba]
+ psubd 0xbabecafe,%mm3
+
+// CHECK: psubd 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0x78,0x56,0x34,0x12]
+ psubd 0x12345678,%mm3
+
+// CHECK: psubd %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfa,0xdb]
+ psubd %mm3,%mm3
+
+// CHECK: psubd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0x45,0x00,0x00,0x00]
+ psubd 0x45,%xmm5
+
+// CHECK: psubd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0xed,0x7e,0x00,0x00]
+ psubd 0x7eed,%xmm5
+
+// CHECK: psubd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0xfe,0xca,0xbe,0xba]
+ psubd 0xbabecafe,%xmm5
+
+// CHECK: psubd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0x78,0x56,0x34,0x12]
+ psubd 0x12345678,%xmm5
+
+// CHECK: psubd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0xed]
+ psubd %xmm5,%xmm5
+
+// CHECK: psubq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubq 69, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0x45,0x00,0x00,0x00]
+ psubq 0x45,%mm3
+
+// CHECK: psubq 32493, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0xed,0x7e,0x00,0x00]
+ psubq 0x7eed,%mm3
+
+// CHECK: psubq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0xfe,0xca,0xbe,0xba]
+ psubq 0xbabecafe,%mm3
+
+// CHECK: psubq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0x78,0x56,0x34,0x12]
+ psubq 0x12345678,%mm3
+
+// CHECK: psubq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfb,0xdb]
+ psubq %mm3,%mm3
+
+// CHECK: psubq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0x45,0x00,0x00,0x00]
+ psubq 0x45,%xmm5
+
+// CHECK: psubq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0xed,0x7e,0x00,0x00]
+ psubq 0x7eed,%xmm5
+
+// CHECK: psubq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0xfe,0xca,0xbe,0xba]
+ psubq 0xbabecafe,%xmm5
+
+// CHECK: psubq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0x78,0x56,0x34,0x12]
+ psubq 0x12345678,%xmm5
+
+// CHECK: psubq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0xed]
+ psubq %xmm5,%xmm5
+
+// CHECK: psubsb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe8,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubsb 69, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0x45,0x00,0x00,0x00]
+ psubsb 0x45,%mm3
+
+// CHECK: psubsb 32493, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0xed,0x7e,0x00,0x00]
+ psubsb 0x7eed,%mm3
+
+// CHECK: psubsb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0xfe,0xca,0xbe,0xba]
+ psubsb 0xbabecafe,%mm3
+
+// CHECK: psubsb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0x78,0x56,0x34,0x12]
+ psubsb 0x12345678,%mm3
+
+// CHECK: psubsb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe8,0xdb]
+ psubsb %mm3,%mm3
+
+// CHECK: psubsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0x45,0x00,0x00,0x00]
+ psubsb 0x45,%xmm5
+
+// CHECK: psubsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0xed,0x7e,0x00,0x00]
+ psubsb 0x7eed,%xmm5
+
+// CHECK: psubsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0xfe,0xca,0xbe,0xba]
+ psubsb 0xbabecafe,%xmm5
+
+// CHECK: psubsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0x78,0x56,0x34,0x12]
+ psubsb 0x12345678,%xmm5
+
+// CHECK: psubsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0xed]
+ psubsb %xmm5,%xmm5
+
+// CHECK: psubsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe9,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubsw 69, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0x45,0x00,0x00,0x00]
+ psubsw 0x45,%mm3
+
+// CHECK: psubsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0xed,0x7e,0x00,0x00]
+ psubsw 0x7eed,%mm3
+
+// CHECK: psubsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0xfe,0xca,0xbe,0xba]
+ psubsw 0xbabecafe,%mm3
+
+// CHECK: psubsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0x78,0x56,0x34,0x12]
+ psubsw 0x12345678,%mm3
+
+// CHECK: psubsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe9,0xdb]
+ psubsw %mm3,%mm3
+
+// CHECK: psubsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0x45,0x00,0x00,0x00]
+ psubsw 0x45,%xmm5
+
+// CHECK: psubsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0xed,0x7e,0x00,0x00]
+ psubsw 0x7eed,%xmm5
+
+// CHECK: psubsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0xfe,0xca,0xbe,0xba]
+ psubsw 0xbabecafe,%xmm5
+
+// CHECK: psubsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0x78,0x56,0x34,0x12]
+ psubsw 0x12345678,%xmm5
+
+// CHECK: psubsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0xed]
+ psubsw %xmm5,%xmm5
+
+// CHECK: psubusb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd8,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubusb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubusb 69, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0x45,0x00,0x00,0x00]
+ psubusb 0x45,%mm3
+
+// CHECK: psubusb 32493, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0xed,0x7e,0x00,0x00]
+ psubusb 0x7eed,%mm3
+
+// CHECK: psubusb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0xfe,0xca,0xbe,0xba]
+ psubusb 0xbabecafe,%mm3
+
+// CHECK: psubusb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0x78,0x56,0x34,0x12]
+ psubusb 0x12345678,%mm3
+
+// CHECK: psubusb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd8,0xdb]
+ psubusb %mm3,%mm3
+
+// CHECK: psubusb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubusb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubusb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0x45,0x00,0x00,0x00]
+ psubusb 0x45,%xmm5
+
+// CHECK: psubusb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0xed,0x7e,0x00,0x00]
+ psubusb 0x7eed,%xmm5
+
+// CHECK: psubusb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0xfe,0xca,0xbe,0xba]
+ psubusb 0xbabecafe,%xmm5
+
+// CHECK: psubusb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0x78,0x56,0x34,0x12]
+ psubusb 0x12345678,%xmm5
+
+// CHECK: psubusb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0xed]
+ psubusb %xmm5,%xmm5
+
+// CHECK: psubusw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd9,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubusw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubusw 69, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0x45,0x00,0x00,0x00]
+ psubusw 0x45,%mm3
+
+// CHECK: psubusw 32493, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0xed,0x7e,0x00,0x00]
+ psubusw 0x7eed,%mm3
+
+// CHECK: psubusw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0xfe,0xca,0xbe,0xba]
+ psubusw 0xbabecafe,%mm3
+
+// CHECK: psubusw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0x78,0x56,0x34,0x12]
+ psubusw 0x12345678,%mm3
+
+// CHECK: psubusw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd9,0xdb]
+ psubusw %mm3,%mm3
+
+// CHECK: psubusw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubusw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubusw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0x45,0x00,0x00,0x00]
+ psubusw 0x45,%xmm5
+
+// CHECK: psubusw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0xed,0x7e,0x00,0x00]
+ psubusw 0x7eed,%xmm5
+
+// CHECK: psubusw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0xfe,0xca,0xbe,0xba]
+ psubusw 0xbabecafe,%xmm5
+
+// CHECK: psubusw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0x78,0x56,0x34,0x12]
+ psubusw 0x12345678,%xmm5
+
+// CHECK: psubusw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0xed]
+ psubusw %xmm5,%xmm5
+
+// CHECK: punpckhbw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x68,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhbw 69, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0x45,0x00,0x00,0x00]
+ punpckhbw 0x45,%mm3
+
+// CHECK: punpckhbw 32493, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0xed,0x7e,0x00,0x00]
+ punpckhbw 0x7eed,%mm3
+
+// CHECK: punpckhbw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckhbw 0xbabecafe,%mm3
+
+// CHECK: punpckhbw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0x78,0x56,0x34,0x12]
+ punpckhbw 0x12345678,%mm3
+
+// CHECK: punpckhbw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x68,0xdb]
+ punpckhbw %mm3,%mm3
+
+// CHECK: punpckhbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0x45,0x00,0x00,0x00]
+ punpckhbw 0x45,%xmm5
+
+// CHECK: punpckhbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhbw 0x7eed,%xmm5
+
+// CHECK: punpckhbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhbw 0xbabecafe,%xmm5
+
+// CHECK: punpckhbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0x78,0x56,0x34,0x12]
+ punpckhbw 0x12345678,%xmm5
+
+// CHECK: punpckhbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0xed]
+ punpckhbw %xmm5,%xmm5
+
+// CHECK: punpckhwd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x69,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhwd 69, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0x45,0x00,0x00,0x00]
+ punpckhwd 0x45,%mm3
+
+// CHECK: punpckhwd 32493, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0xed,0x7e,0x00,0x00]
+ punpckhwd 0x7eed,%mm3
+
+// CHECK: punpckhwd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckhwd 0xbabecafe,%mm3
+
+// CHECK: punpckhwd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0x78,0x56,0x34,0x12]
+ punpckhwd 0x12345678,%mm3
+
+// CHECK: punpckhwd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x69,0xdb]
+ punpckhwd %mm3,%mm3
+
+// CHECK: punpckhwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0x45,0x00,0x00,0x00]
+ punpckhwd 0x45,%xmm5
+
+// CHECK: punpckhwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhwd 0x7eed,%xmm5
+
+// CHECK: punpckhwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhwd 0xbabecafe,%xmm5
+
+// CHECK: punpckhwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0x78,0x56,0x34,0x12]
+ punpckhwd 0x12345678,%xmm5
+
+// CHECK: punpckhwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0xed]
+ punpckhwd %xmm5,%xmm5
+
+// CHECK: punpckhdq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6a,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhdq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhdq 69, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0x45,0x00,0x00,0x00]
+ punpckhdq 0x45,%mm3
+
+// CHECK: punpckhdq 32493, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0xed,0x7e,0x00,0x00]
+ punpckhdq 0x7eed,%mm3
+
+// CHECK: punpckhdq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckhdq 0xbabecafe,%mm3
+
+// CHECK: punpckhdq 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0x78,0x56,0x34,0x12]
+ punpckhdq 0x12345678,%mm3
+
+// CHECK: punpckhdq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6a,0xdb]
+ punpckhdq %mm3,%mm3
+
+// CHECK: punpckhdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0x45,0x00,0x00,0x00]
+ punpckhdq 0x45,%xmm5
+
+// CHECK: punpckhdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhdq 0x7eed,%xmm5
+
+// CHECK: punpckhdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhdq 0xbabecafe,%xmm5
+
+// CHECK: punpckhdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0x78,0x56,0x34,0x12]
+ punpckhdq 0x12345678,%xmm5
+
+// CHECK: punpckhdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0xed]
+ punpckhdq %xmm5,%xmm5
+
+// CHECK: punpcklbw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x60,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpcklbw 69, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0x45,0x00,0x00,0x00]
+ punpcklbw 0x45,%mm3
+
+// CHECK: punpcklbw 32493, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0xed,0x7e,0x00,0x00]
+ punpcklbw 0x7eed,%mm3
+
+// CHECK: punpcklbw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0xfe,0xca,0xbe,0xba]
+ punpcklbw 0xbabecafe,%mm3
+
+// CHECK: punpcklbw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0x78,0x56,0x34,0x12]
+ punpcklbw 0x12345678,%mm3
+
+// CHECK: punpcklbw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x60,0xdb]
+ punpcklbw %mm3,%mm3
+
+// CHECK: punpcklbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0x45,0x00,0x00,0x00]
+ punpcklbw 0x45,%xmm5
+
+// CHECK: punpcklbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0xed,0x7e,0x00,0x00]
+ punpcklbw 0x7eed,%xmm5
+
+// CHECK: punpcklbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0xfe,0xca,0xbe,0xba]
+ punpcklbw 0xbabecafe,%xmm5
+
+// CHECK: punpcklbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0x78,0x56,0x34,0x12]
+ punpcklbw 0x12345678,%xmm5
+
+// CHECK: punpcklbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0xed]
+ punpcklbw %xmm5,%xmm5
+
+// CHECK: punpcklwd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x61,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpcklwd 69, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0x45,0x00,0x00,0x00]
+ punpcklwd 0x45,%mm3
+
+// CHECK: punpcklwd 32493, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0xed,0x7e,0x00,0x00]
+ punpcklwd 0x7eed,%mm3
+
+// CHECK: punpcklwd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0xfe,0xca,0xbe,0xba]
+ punpcklwd 0xbabecafe,%mm3
+
+// CHECK: punpcklwd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0x78,0x56,0x34,0x12]
+ punpcklwd 0x12345678,%mm3
+
+// CHECK: punpcklwd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x61,0xdb]
+ punpcklwd %mm3,%mm3
+
+// CHECK: punpcklwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0x45,0x00,0x00,0x00]
+ punpcklwd 0x45,%xmm5
+
+// CHECK: punpcklwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0xed,0x7e,0x00,0x00]
+ punpcklwd 0x7eed,%xmm5
+
+// CHECK: punpcklwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0xfe,0xca,0xbe,0xba]
+ punpcklwd 0xbabecafe,%xmm5
+
+// CHECK: punpcklwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0x78,0x56,0x34,0x12]
+ punpcklwd 0x12345678,%xmm5
+
+// CHECK: punpcklwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0xed]
+ punpcklwd %xmm5,%xmm5
+
+// CHECK: punpckldq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x62,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckldq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckldq 69, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0x45,0x00,0x00,0x00]
+ punpckldq 0x45,%mm3
+
+// CHECK: punpckldq 32493, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0xed,0x7e,0x00,0x00]
+ punpckldq 0x7eed,%mm3
+
+// CHECK: punpckldq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckldq 0xbabecafe,%mm3
+
+// CHECK: punpckldq 305419896, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0x78,0x56,0x34,0x12]
+ punpckldq 0x12345678,%mm3
+
+// CHECK: punpckldq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x62,0xdb]
+ punpckldq %mm3,%mm3
+
+// CHECK: punpckldq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckldq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckldq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0x45,0x00,0x00,0x00]
+ punpckldq 0x45,%xmm5
+
+// CHECK: punpckldq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0xed,0x7e,0x00,0x00]
+ punpckldq 0x7eed,%xmm5
+
+// CHECK: punpckldq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckldq 0xbabecafe,%xmm5
+
+// CHECK: punpckldq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0x78,0x56,0x34,0x12]
+ punpckldq 0x12345678,%xmm5
+
+// CHECK: punpckldq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0xed]
+ punpckldq %xmm5,%xmm5
+
+// CHECK: pxor 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xef,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pxor 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pxor 69, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0x45,0x00,0x00,0x00]
+ pxor 0x45,%mm3
+
+// CHECK: pxor 32493, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0xed,0x7e,0x00,0x00]
+ pxor 0x7eed,%mm3
+
+// CHECK: pxor 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0xfe,0xca,0xbe,0xba]
+ pxor 0xbabecafe,%mm3
+
+// CHECK: pxor 305419896, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0x78,0x56,0x34,0x12]
+ pxor 0x12345678,%mm3
+
+// CHECK: pxor %mm3, %mm3
+// CHECK: encoding: [0x0f,0xef,0xdb]
+ pxor %mm3,%mm3
+
+// CHECK: pxor 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pxor 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pxor 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0x45,0x00,0x00,0x00]
+ pxor 0x45,%xmm5
+
+// CHECK: pxor 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0xed,0x7e,0x00,0x00]
+ pxor 0x7eed,%xmm5
+
+// CHECK: pxor 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0xfe,0xca,0xbe,0xba]
+ pxor 0xbabecafe,%xmm5
+
+// CHECK: pxor 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0x78,0x56,0x34,0x12]
+ pxor 0x12345678,%xmm5
+
+// CHECK: pxor %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0xed]
+ pxor %xmm5,%xmm5
+
+// CHECK: addps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addps 69, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addps 0x45,%xmm5
+
+// CHECK: addps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addps 0x7eed,%xmm5
+
+// CHECK: addps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addps 0xbabecafe,%xmm5
+
+// CHECK: addps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addps 0x12345678,%xmm5
+
+// CHECK: addps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x58,0xed]
+ addps %xmm5,%xmm5
+
+// CHECK: addss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addss 0x45,%xmm5
+
+// CHECK: addss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addss 0x7eed,%xmm5
+
+// CHECK: addss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addss 0xbabecafe,%xmm5
+
+// CHECK: addss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addss 0x12345678,%xmm5
+
+// CHECK: addss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0xed]
+ addss %xmm5,%xmm5
+
+// CHECK: andnps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x55,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andnps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andnps 69, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0x45,0x00,0x00,0x00]
+ andnps 0x45,%xmm5
+
+// CHECK: andnps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0xed,0x7e,0x00,0x00]
+ andnps 0x7eed,%xmm5
+
+// CHECK: andnps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0xfe,0xca,0xbe,0xba]
+ andnps 0xbabecafe,%xmm5
+
+// CHECK: andnps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0x78,0x56,0x34,0x12]
+ andnps 0x12345678,%xmm5
+
+// CHECK: andnps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x55,0xed]
+ andnps %xmm5,%xmm5
+
+// CHECK: andps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x54,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andps 69, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0x45,0x00,0x00,0x00]
+ andps 0x45,%xmm5
+
+// CHECK: andps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0xed,0x7e,0x00,0x00]
+ andps 0x7eed,%xmm5
+
+// CHECK: andps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0xfe,0xca,0xbe,0xba]
+ andps 0xbabecafe,%xmm5
+
+// CHECK: andps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0x78,0x56,0x34,0x12]
+ andps 0x12345678,%xmm5
+
+// CHECK: andps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x54,0xed]
+ andps %xmm5,%xmm5
+
+// CHECK: comiss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x2f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ comiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: comiss 69, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0x45,0x00,0x00,0x00]
+ comiss 0x45,%xmm5
+
+// CHECK: comiss 32493, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0xed,0x7e,0x00,0x00]
+ comiss 0x7eed,%xmm5
+
+// CHECK: comiss 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0xfe,0xca,0xbe,0xba]
+ comiss 0xbabecafe,%xmm5
+
+// CHECK: comiss 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0x78,0x56,0x34,0x12]
+ comiss 0x12345678,%xmm5
+
+// CHECK: comiss %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0xed]
+ comiss %xmm5,%xmm5
+
+// CHECK: cvtpi2ps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpi2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2ps 69, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtpi2ps 0x45,%xmm5
+
+// CHECK: cvtpi2ps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpi2ps 0x7eed,%xmm5
+
+// CHECK: cvtpi2ps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpi2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtpi2ps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtpi2ps 0x12345678,%xmm5
+
+// CHECK: cvtpi2ps %mm3, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0xeb]
+ cvtpi2ps %mm3,%xmm5
+
+// CHECK: cvtps2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x2d,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvtps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtps2pi 69, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0x45,0x00,0x00,0x00]
+ cvtps2pi 0x45,%mm3
+
+// CHECK: cvtps2pi 32493, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0xed,0x7e,0x00,0x00]
+ cvtps2pi 0x7eed,%mm3
+
+// CHECK: cvtps2pi 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0xfe,0xca,0xbe,0xba]
+ cvtps2pi 0xbabecafe,%mm3
+
+// CHECK: cvtps2pi 305419896, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0x78,0x56,0x34,0x12]
+ cvtps2pi 0x12345678,%mm3
+
+// CHECK: cvtps2pi %xmm5, %mm3
+// CHECK: encoding: [0x0f,0x2d,0xdd]
+ cvtps2pi %xmm5,%mm3
+
+// CHECK: cvtsi2ss %ecx, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0xe9]
+ cvtsi2ss %ecx,%xmm5
+
+// CHECK: cvtsi2ss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtsi2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsi2ss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtsi2ss 0x45,%xmm5
+
+// CHECK: cvtsi2ss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtsi2ss 0x7eed,%xmm5
+
+// CHECK: cvtsi2ss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtsi2ss 0xbabecafe,%xmm5
+
+// CHECK: cvtsi2ss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtsi2ss 0x12345678,%xmm5
+
+// CHECK: cvttps2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x2c,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttps2pi 69, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0x45,0x00,0x00,0x00]
+ cvttps2pi 0x45,%mm3
+
+// CHECK: cvttps2pi 32493, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0xed,0x7e,0x00,0x00]
+ cvttps2pi 0x7eed,%mm3
+
+// CHECK: cvttps2pi 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0xfe,0xca,0xbe,0xba]
+ cvttps2pi 0xbabecafe,%mm3
+
+// CHECK: cvttps2pi 305419896, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0x78,0x56,0x34,0x12]
+ cvttps2pi 0x12345678,%mm3
+
+// CHECK: cvttps2pi %xmm5, %mm3
+// CHECK: encoding: [0x0f,0x2c,0xdd]
+ cvttps2pi %xmm5,%mm3
+
+// CHECK: cvttss2si 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttss2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttss2si 69, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0x45,0x00,0x00,0x00]
+ cvttss2si 0x45,%ecx
+
+// CHECK: cvttss2si 32493, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0xed,0x7e,0x00,0x00]
+ cvttss2si 0x7eed,%ecx
+
+// CHECK: cvttss2si 3133065982, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0xfe,0xca,0xbe,0xba]
+ cvttss2si 0xbabecafe,%ecx
+
+// CHECK: cvttss2si 305419896, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0x78,0x56,0x34,0x12]
+ cvttss2si 0x12345678,%ecx
+
+// CHECK: cvttss2si %xmm5, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0xcd]
+ cvttss2si %xmm5,%ecx
+
+// CHECK: divps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divps 0x45,%xmm5
+
+// CHECK: divps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divps 0x7eed,%xmm5
+
+// CHECK: divps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divps 0xbabecafe,%xmm5
+
+// CHECK: divps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divps 0x12345678,%xmm5
+
+// CHECK: divps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0xed]
+ divps %xmm5,%xmm5
+
+// CHECK: divss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divss 0x45,%xmm5
+
+// CHECK: divss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divss 0x7eed,%xmm5
+
+// CHECK: divss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divss 0xbabecafe,%xmm5
+
+// CHECK: divss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divss 0x12345678,%xmm5
+
+// CHECK: divss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0xed]
+ divss %xmm5,%xmm5
+
+// CHECK: ldmxcsr 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ ldmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ldmxcsr 32493
+// CHECK: encoding: [0x0f,0xae,0x15,0xed,0x7e,0x00,0x00]
+ ldmxcsr 0x7eed
+
+// CHECK: ldmxcsr 3133065982
+// CHECK: encoding: [0x0f,0xae,0x15,0xfe,0xca,0xbe,0xba]
+ ldmxcsr 0xbabecafe
+
+// CHECK: ldmxcsr 305419896
+// CHECK: encoding: [0x0f,0xae,0x15,0x78,0x56,0x34,0x12]
+ ldmxcsr 0x12345678
+
+// CHECK: maskmovq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf7,0xdb]
+ maskmovq %mm3,%mm3
+
+// CHECK: maxps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxps 0x45,%xmm5
+
+// CHECK: maxps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxps 0x7eed,%xmm5
+
+// CHECK: maxps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxps 0xbabecafe,%xmm5
+
+// CHECK: maxps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxps 0x12345678,%xmm5
+
+// CHECK: maxps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0xed]
+ maxps %xmm5,%xmm5
+
+// CHECK: maxss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxss 0x45,%xmm5
+
+// CHECK: maxss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxss 0x7eed,%xmm5
+
+// CHECK: maxss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxss 0xbabecafe,%xmm5
+
+// CHECK: maxss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxss 0x12345678,%xmm5
+
+// CHECK: maxss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0xed]
+ maxss %xmm5,%xmm5
+
+// CHECK: minps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minps 0x45,%xmm5
+
+// CHECK: minps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minps 0x7eed,%xmm5
+
+// CHECK: minps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minps 0xbabecafe,%xmm5
+
+// CHECK: minps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minps 0x12345678,%xmm5
+
+// CHECK: minps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0xed]
+ minps %xmm5,%xmm5
+
+// CHECK: minss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minss 0x45,%xmm5
+
+// CHECK: minss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minss 0x7eed,%xmm5
+
+// CHECK: minss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minss 0xbabecafe,%xmm5
+
+// CHECK: minss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minss 0x12345678,%xmm5
+
+// CHECK: minss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0xed]
+ minss %xmm5,%xmm5
+
+// CHECK: movaps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x28,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movaps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movaps 69, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0x45,0x00,0x00,0x00]
+ movaps 0x45,%xmm5
+
+// CHECK: movaps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0xed,0x7e,0x00,0x00]
+ movaps 0x7eed,%xmm5
+
+// CHECK: movaps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0xfe,0xca,0xbe,0xba]
+ movaps 0xbabecafe,%xmm5
+
+// CHECK: movaps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0x78,0x56,0x34,0x12]
+ movaps 0x12345678,%xmm5
+
+// CHECK: movaps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x28,0xed]
+ movaps %xmm5,%xmm5
+
+// CHECK: movaps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x29,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movaps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movaps %xmm5, 69
+// CHECK: encoding: [0x0f,0x29,0x2d,0x45,0x00,0x00,0x00]
+ movaps %xmm5,0x45
+
+// CHECK: movaps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x29,0x2d,0xed,0x7e,0x00,0x00]
+ movaps %xmm5,0x7eed
+
+// CHECK: movaps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x29,0x2d,0xfe,0xca,0xbe,0xba]
+ movaps %xmm5,0xbabecafe
+
+// CHECK: movaps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x29,0x2d,0x78,0x56,0x34,0x12]
+ movaps %xmm5,0x12345678
+
+// CHECK: movaps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x28,0xed]
+ movaps %xmm5,%xmm5
+
+// CHECK: movhlps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x12,0xed]
+ movhlps %xmm5,%xmm5
+
+// CHECK: movhps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x16,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movhps 69, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0x45,0x00,0x00,0x00]
+ movhps 0x45,%xmm5
+
+// CHECK: movhps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0xed,0x7e,0x00,0x00]
+ movhps 0x7eed,%xmm5
+
+// CHECK: movhps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0xfe,0xca,0xbe,0xba]
+ movhps 0xbabecafe,%xmm5
+
+// CHECK: movhps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0x78,0x56,0x34,0x12]
+ movhps 0x12345678,%xmm5
+
+// CHECK: movhps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x17,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movhps %xmm5, 69
+// CHECK: encoding: [0x0f,0x17,0x2d,0x45,0x00,0x00,0x00]
+ movhps %xmm5,0x45
+
+// CHECK: movhps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x17,0x2d,0xed,0x7e,0x00,0x00]
+ movhps %xmm5,0x7eed
+
+// CHECK: movhps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x17,0x2d,0xfe,0xca,0xbe,0xba]
+ movhps %xmm5,0xbabecafe
+
+// CHECK: movhps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x17,0x2d,0x78,0x56,0x34,0x12]
+ movhps %xmm5,0x12345678
+
+// CHECK: movlhps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x16,0xed]
+ movlhps %xmm5,%xmm5
+
+// CHECK: movlps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movlps 69, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movlps 0x45,%xmm5
+
+// CHECK: movlps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movlps 0x7eed,%xmm5
+
+// CHECK: movlps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movlps 0xbabecafe,%xmm5
+
+// CHECK: movlps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movlps 0x12345678,%xmm5
+
+// CHECK: movlps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x13,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlps %xmm5, 69
+// CHECK: encoding: [0x0f,0x13,0x2d,0x45,0x00,0x00,0x00]
+ movlps %xmm5,0x45
+
+// CHECK: movlps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x13,0x2d,0xed,0x7e,0x00,0x00]
+ movlps %xmm5,0x7eed
+
+// CHECK: movlps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x13,0x2d,0xfe,0xca,0xbe,0xba]
+ movlps %xmm5,0xbabecafe
+
+// CHECK: movlps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x13,0x2d,0x78,0x56,0x34,0x12]
+ movlps %xmm5,0x12345678
+
+// CHECK: movmskps %xmm5, %ecx
+// CHECK: encoding: [0x0f,0x50,0xcd]
+ movmskps %xmm5,%ecx
+
+// CHECK: movntps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x2b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntps %xmm5, 69
+// CHECK: encoding: [0x0f,0x2b,0x2d,0x45,0x00,0x00,0x00]
+ movntps %xmm5,0x45
+
+// CHECK: movntps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x2b,0x2d,0xed,0x7e,0x00,0x00]
+ movntps %xmm5,0x7eed
+
+// CHECK: movntps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x2b,0x2d,0xfe,0xca,0xbe,0xba]
+ movntps %xmm5,0xbabecafe
+
+// CHECK: movntps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x2b,0x2d,0x78,0x56,0x34,0x12]
+ movntps %xmm5,0x12345678
+
+// CHECK: movntq %mm3, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xe7,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movntq %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntq %mm3, 69
+// CHECK: encoding: [0x0f,0xe7,0x1d,0x45,0x00,0x00,0x00]
+ movntq %mm3,0x45
+
+// CHECK: movntq %mm3, 32493
+// CHECK: encoding: [0x0f,0xe7,0x1d,0xed,0x7e,0x00,0x00]
+ movntq %mm3,0x7eed
+
+// CHECK: movntq %mm3, 3133065982
+// CHECK: encoding: [0x0f,0xe7,0x1d,0xfe,0xca,0xbe,0xba]
+ movntq %mm3,0xbabecafe
+
+// CHECK: movntq %mm3, 305419896
+// CHECK: encoding: [0x0f,0xe7,0x1d,0x78,0x56,0x34,0x12]
+ movntq %mm3,0x12345678
+
+// CHECK: movntdq %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0xe7,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntdq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntdq %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0x45,0x00,0x00,0x00]
+ movntdq %xmm5,0x45
+
+// CHECK: movntdq %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0xed,0x7e,0x00,0x00]
+ movntdq %xmm5,0x7eed
+
+// CHECK: movntdq %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0xfe,0xca,0xbe,0xba]
+ movntdq %xmm5,0xbabecafe
+
+// CHECK: movntdq %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0x78,0x56,0x34,0x12]
+ movntdq %xmm5,0x12345678
+
+// CHECK: movss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movss 0x45,%xmm5
+
+// CHECK: movss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movss 0x7eed,%xmm5
+
+// CHECK: movss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movss 0xbabecafe,%xmm5
+
+// CHECK: movss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movss 0x12345678,%xmm5
+
+// CHECK: movss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0xed]
+ movss %xmm5,%xmm5
+
+// CHECK: movss %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf3,0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movss %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movss %xmm5, 69
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movss %xmm5,0x45
+
+// CHECK: movss %xmm5, 32493
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movss %xmm5,0x7eed
+
+// CHECK: movss %xmm5, 3133065982
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movss %xmm5,0xbabecafe
+
+// CHECK: movss %xmm5, 305419896
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movss %xmm5,0x12345678
+
+// CHECK: movss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0xed]
+ movss %xmm5,%xmm5
+
+// CHECK: movups 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movups 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movups 69, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movups 0x45,%xmm5
+
+// CHECK: movups 32493, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movups 0x7eed,%xmm5
+
+// CHECK: movups 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movups 0xbabecafe,%xmm5
+
+// CHECK: movups 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movups 0x12345678,%xmm5
+
+// CHECK: movups %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x10,0xed]
+ movups %xmm5,%xmm5
+
+// CHECK: movups %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movups %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movups %xmm5, 69
+// CHECK: encoding: [0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movups %xmm5,0x45
+
+// CHECK: movups %xmm5, 32493
+// CHECK: encoding: [0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movups %xmm5,0x7eed
+
+// CHECK: movups %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movups %xmm5,0xbabecafe
+
+// CHECK: movups %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movups %xmm5,0x12345678
+
+// CHECK: movups %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x10,0xed]
+ movups %xmm5,%xmm5
+
+// CHECK: mulps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulps 69, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulps 0x45,%xmm5
+
+// CHECK: mulps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulps 0x7eed,%xmm5
+
+// CHECK: mulps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulps 0xbabecafe,%xmm5
+
+// CHECK: mulps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulps 0x12345678,%xmm5
+
+// CHECK: mulps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x59,0xed]
+ mulps %xmm5,%xmm5
+
+// CHECK: mulss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulss 0x45,%xmm5
+
+// CHECK: mulss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulss 0x7eed,%xmm5
+
+// CHECK: mulss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulss 0xbabecafe,%xmm5
+
+// CHECK: mulss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulss 0x12345678,%xmm5
+
+// CHECK: mulss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0xed]
+ mulss %xmm5,%xmm5
+
+// CHECK: orps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x56,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ orps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: orps 69, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0x45,0x00,0x00,0x00]
+ orps 0x45,%xmm5
+
+// CHECK: orps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0xed,0x7e,0x00,0x00]
+ orps 0x7eed,%xmm5
+
+// CHECK: orps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0xfe,0xca,0xbe,0xba]
+ orps 0xbabecafe,%xmm5
+
+// CHECK: orps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0x78,0x56,0x34,0x12]
+ orps 0x12345678,%xmm5
+
+// CHECK: orps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x56,0xed]
+ orps %xmm5,%xmm5
+
+// CHECK: pavgb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe0,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pavgb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pavgb 69, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0x45,0x00,0x00,0x00]
+ pavgb 0x45,%mm3
+
+// CHECK: pavgb 32493, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0xed,0x7e,0x00,0x00]
+ pavgb 0x7eed,%mm3
+
+// CHECK: pavgb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0xfe,0xca,0xbe,0xba]
+ pavgb 0xbabecafe,%mm3
+
+// CHECK: pavgb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0x78,0x56,0x34,0x12]
+ pavgb 0x12345678,%mm3
+
+// CHECK: pavgb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe0,0xdb]
+ pavgb %mm3,%mm3
+
+// CHECK: pavgb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pavgb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pavgb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0x45,0x00,0x00,0x00]
+ pavgb 0x45,%xmm5
+
+// CHECK: pavgb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0xed,0x7e,0x00,0x00]
+ pavgb 0x7eed,%xmm5
+
+// CHECK: pavgb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0xfe,0xca,0xbe,0xba]
+ pavgb 0xbabecafe,%xmm5
+
+// CHECK: pavgb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0x78,0x56,0x34,0x12]
+ pavgb 0x12345678,%xmm5
+
+// CHECK: pavgb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0xed]
+ pavgb %xmm5,%xmm5
+
+// CHECK: pavgw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe3,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pavgw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pavgw 69, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0x45,0x00,0x00,0x00]
+ pavgw 0x45,%mm3
+
+// CHECK: pavgw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0xed,0x7e,0x00,0x00]
+ pavgw 0x7eed,%mm3
+
+// CHECK: pavgw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0xfe,0xca,0xbe,0xba]
+ pavgw 0xbabecafe,%mm3
+
+// CHECK: pavgw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0x78,0x56,0x34,0x12]
+ pavgw 0x12345678,%mm3
+
+// CHECK: pavgw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe3,0xdb]
+ pavgw %mm3,%mm3
+
+// CHECK: pavgw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pavgw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pavgw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0x45,0x00,0x00,0x00]
+ pavgw 0x45,%xmm5
+
+// CHECK: pavgw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0xed,0x7e,0x00,0x00]
+ pavgw 0x7eed,%xmm5
+
+// CHECK: pavgw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0xfe,0xca,0xbe,0xba]
+ pavgw 0xbabecafe,%xmm5
+
+// CHECK: pavgw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0x78,0x56,0x34,0x12]
+ pavgw 0x12345678,%xmm5
+
+// CHECK: pavgw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0xed]
+ pavgw %xmm5,%xmm5
+
+// CHECK: pmaxsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xee,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaxsw 69, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0x45,0x00,0x00,0x00]
+ pmaxsw 0x45,%mm3
+
+// CHECK: pmaxsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0xed,0x7e,0x00,0x00]
+ pmaxsw 0x7eed,%mm3
+
+// CHECK: pmaxsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaxsw 0xbabecafe,%mm3
+
+// CHECK: pmaxsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0x78,0x56,0x34,0x12]
+ pmaxsw 0x12345678,%mm3
+
+// CHECK: pmaxsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xee,0xdb]
+ pmaxsw %mm3,%mm3
+
+// CHECK: pmaxsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0x45,0x00,0x00,0x00]
+ pmaxsw 0x45,%xmm5
+
+// CHECK: pmaxsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxsw 0x7eed,%xmm5
+
+// CHECK: pmaxsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxsw 0xbabecafe,%xmm5
+
+// CHECK: pmaxsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0x78,0x56,0x34,0x12]
+ pmaxsw 0x12345678,%xmm5
+
+// CHECK: pmaxsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0xed]
+ pmaxsw %xmm5,%xmm5
+
+// CHECK: pmaxub 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xde,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxub 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaxub 69, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0x45,0x00,0x00,0x00]
+ pmaxub 0x45,%mm3
+
+// CHECK: pmaxub 32493, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0xed,0x7e,0x00,0x00]
+ pmaxub 0x7eed,%mm3
+
+// CHECK: pmaxub 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaxub 0xbabecafe,%mm3
+
+// CHECK: pmaxub 305419896, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0x78,0x56,0x34,0x12]
+ pmaxub 0x12345678,%mm3
+
+// CHECK: pmaxub %mm3, %mm3
+// CHECK: encoding: [0x0f,0xde,0xdb]
+ pmaxub %mm3,%mm3
+
+// CHECK: pmaxub 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxub 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxub 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0x45,0x00,0x00,0x00]
+ pmaxub 0x45,%xmm5
+
+// CHECK: pmaxub 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxub 0x7eed,%xmm5
+
+// CHECK: pmaxub 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxub 0xbabecafe,%xmm5
+
+// CHECK: pmaxub 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0x78,0x56,0x34,0x12]
+ pmaxub 0x12345678,%xmm5
+
+// CHECK: pmaxub %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0xed]
+ pmaxub %xmm5,%xmm5
+
+// CHECK: pminsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xea,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pminsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pminsw 69, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0x45,0x00,0x00,0x00]
+ pminsw 0x45,%mm3
+
+// CHECK: pminsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0xed,0x7e,0x00,0x00]
+ pminsw 0x7eed,%mm3
+
+// CHECK: pminsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0xfe,0xca,0xbe,0xba]
+ pminsw 0xbabecafe,%mm3
+
+// CHECK: pminsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0x78,0x56,0x34,0x12]
+ pminsw 0x12345678,%mm3
+
+// CHECK: pminsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xea,0xdb]
+ pminsw %mm3,%mm3
+
+// CHECK: pminsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0x45,0x00,0x00,0x00]
+ pminsw 0x45,%xmm5
+
+// CHECK: pminsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0xed,0x7e,0x00,0x00]
+ pminsw 0x7eed,%xmm5
+
+// CHECK: pminsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0xfe,0xca,0xbe,0xba]
+ pminsw 0xbabecafe,%xmm5
+
+// CHECK: pminsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0x78,0x56,0x34,0x12]
+ pminsw 0x12345678,%xmm5
+
+// CHECK: pminsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0xed]
+ pminsw %xmm5,%xmm5
+
+// CHECK: pminub 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xda,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pminub 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pminub 69, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0x45,0x00,0x00,0x00]
+ pminub 0x45,%mm3
+
+// CHECK: pminub 32493, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0xed,0x7e,0x00,0x00]
+ pminub 0x7eed,%mm3
+
+// CHECK: pminub 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0xfe,0xca,0xbe,0xba]
+ pminub 0xbabecafe,%mm3
+
+// CHECK: pminub 305419896, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0x78,0x56,0x34,0x12]
+ pminub 0x12345678,%mm3
+
+// CHECK: pminub %mm3, %mm3
+// CHECK: encoding: [0x0f,0xda,0xdb]
+ pminub %mm3,%mm3
+
+// CHECK: pminub 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminub 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminub 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0x45,0x00,0x00,0x00]
+ pminub 0x45,%xmm5
+
+// CHECK: pminub 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0xed,0x7e,0x00,0x00]
+ pminub 0x7eed,%xmm5
+
+// CHECK: pminub 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0xfe,0xca,0xbe,0xba]
+ pminub 0xbabecafe,%xmm5
+
+// CHECK: pminub 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0x78,0x56,0x34,0x12]
+ pminub 0x12345678,%xmm5
+
+// CHECK: pminub %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0xed]
+ pminub %xmm5,%xmm5
+
+// CHECK: pmovmskb %mm3, %ecx
+// CHECK: encoding: [0x0f,0xd7,0xcb]
+ pmovmskb %mm3,%ecx
+
+// CHECK: pmovmskb %xmm5, %ecx
+// CHECK: encoding: [0x66,0x0f,0xd7,0xcd]
+ pmovmskb %xmm5,%ecx
+
+// CHECK: pmulhuw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe4,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhuw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhuw 69, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0x45,0x00,0x00,0x00]
+ pmulhuw 0x45,%mm3
+
+// CHECK: pmulhuw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0xed,0x7e,0x00,0x00]
+ pmulhuw 0x7eed,%mm3
+
+// CHECK: pmulhuw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0xfe,0xca,0xbe,0xba]
+ pmulhuw 0xbabecafe,%mm3
+
+// CHECK: pmulhuw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0x78,0x56,0x34,0x12]
+ pmulhuw 0x12345678,%mm3
+
+// CHECK: pmulhuw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe4,0xdb]
+ pmulhuw %mm3,%mm3
+
+// CHECK: pmulhuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0x45,0x00,0x00,0x00]
+ pmulhuw 0x45,%xmm5
+
+// CHECK: pmulhuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0xed,0x7e,0x00,0x00]
+ pmulhuw 0x7eed,%xmm5
+
+// CHECK: pmulhuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulhuw 0xbabecafe,%xmm5
+
+// CHECK: pmulhuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0x78,0x56,0x34,0x12]
+ pmulhuw 0x12345678,%xmm5
+
+// CHECK: pmulhuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0xed]
+ pmulhuw %xmm5,%xmm5
+
+// CHECK: prefetchnta 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ prefetchnta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetchnta 32493
+// CHECK: encoding: [0x0f,0x18,0x05,0xed,0x7e,0x00,0x00]
+ prefetchnta 0x7eed
+
+// CHECK: prefetchnta 3133065982
+// CHECK: encoding: [0x0f,0x18,0x05,0xfe,0xca,0xbe,0xba]
+ prefetchnta 0xbabecafe
+
+// CHECK: prefetchnta 305419896
+// CHECK: encoding: [0x0f,0x18,0x05,0x78,0x56,0x34,0x12]
+ prefetchnta 0x12345678
+
+// CHECK: prefetcht0 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ prefetcht0 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht0 32493
+// CHECK: encoding: [0x0f,0x18,0x0d,0xed,0x7e,0x00,0x00]
+ prefetcht0 0x7eed
+
+// CHECK: prefetcht0 3133065982
+// CHECK: encoding: [0x0f,0x18,0x0d,0xfe,0xca,0xbe,0xba]
+ prefetcht0 0xbabecafe
+
+// CHECK: prefetcht0 305419896
+// CHECK: encoding: [0x0f,0x18,0x0d,0x78,0x56,0x34,0x12]
+ prefetcht0 0x12345678
+
+// CHECK: prefetcht1 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ prefetcht1 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht1 32493
+// CHECK: encoding: [0x0f,0x18,0x15,0xed,0x7e,0x00,0x00]
+ prefetcht1 0x7eed
+
+// CHECK: prefetcht1 3133065982
+// CHECK: encoding: [0x0f,0x18,0x15,0xfe,0xca,0xbe,0xba]
+ prefetcht1 0xbabecafe
+
+// CHECK: prefetcht1 305419896
+// CHECK: encoding: [0x0f,0x18,0x15,0x78,0x56,0x34,0x12]
+ prefetcht1 0x12345678
+
+// CHECK: prefetcht2 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ prefetcht2 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht2 32493
+// CHECK: encoding: [0x0f,0x18,0x1d,0xed,0x7e,0x00,0x00]
+ prefetcht2 0x7eed
+
+// CHECK: prefetcht2 3133065982
+// CHECK: encoding: [0x0f,0x18,0x1d,0xfe,0xca,0xbe,0xba]
+ prefetcht2 0xbabecafe
+
+// CHECK: prefetcht2 305419896
+// CHECK: encoding: [0x0f,0x18,0x1d,0x78,0x56,0x34,0x12]
+ prefetcht2 0x12345678
+
+// CHECK: psadbw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf6,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psadbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psadbw 69, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0x45,0x00,0x00,0x00]
+ psadbw 0x45,%mm3
+
+// CHECK: psadbw 32493, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0xed,0x7e,0x00,0x00]
+ psadbw 0x7eed,%mm3
+
+// CHECK: psadbw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0xfe,0xca,0xbe,0xba]
+ psadbw 0xbabecafe,%mm3
+
+// CHECK: psadbw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0x78,0x56,0x34,0x12]
+ psadbw 0x12345678,%mm3
+
+// CHECK: psadbw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf6,0xdb]
+ psadbw %mm3,%mm3
+
+// CHECK: psadbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psadbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psadbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0x45,0x00,0x00,0x00]
+ psadbw 0x45,%xmm5
+
+// CHECK: psadbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0xed,0x7e,0x00,0x00]
+ psadbw 0x7eed,%xmm5
+
+// CHECK: psadbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0xfe,0xca,0xbe,0xba]
+ psadbw 0xbabecafe,%xmm5
+
+// CHECK: psadbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0x78,0x56,0x34,0x12]
+ psadbw 0x12345678,%xmm5
+
+// CHECK: psadbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0xed]
+ psadbw %xmm5,%xmm5
+
+// CHECK: rcpps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x53,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rcpps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpps 69, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0x45,0x00,0x00,0x00]
+ rcpps 0x45,%xmm5
+
+// CHECK: rcpps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0xed,0x7e,0x00,0x00]
+ rcpps 0x7eed,%xmm5
+
+// CHECK: rcpps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0xfe,0xca,0xbe,0xba]
+ rcpps 0xbabecafe,%xmm5
+
+// CHECK: rcpps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0x78,0x56,0x34,0x12]
+ rcpps 0x12345678,%xmm5
+
+// CHECK: rcpps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x53,0xed]
+ rcpps %xmm5,%xmm5
+
+// CHECK: rcpss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rcpss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0x45,0x00,0x00,0x00]
+ rcpss 0x45,%xmm5
+
+// CHECK: rcpss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0xed,0x7e,0x00,0x00]
+ rcpss 0x7eed,%xmm5
+
+// CHECK: rcpss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0xfe,0xca,0xbe,0xba]
+ rcpss 0xbabecafe,%xmm5
+
+// CHECK: rcpss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0x78,0x56,0x34,0x12]
+ rcpss 0x12345678,%xmm5
+
+// CHECK: rcpss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0xed]
+ rcpss %xmm5,%xmm5
+
+// CHECK: rsqrtps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x52,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rsqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtps 69, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0x45,0x00,0x00,0x00]
+ rsqrtps 0x45,%xmm5
+
+// CHECK: rsqrtps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0xed,0x7e,0x00,0x00]
+ rsqrtps 0x7eed,%xmm5
+
+// CHECK: rsqrtps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0xfe,0xca,0xbe,0xba]
+ rsqrtps 0xbabecafe,%xmm5
+
+// CHECK: rsqrtps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0x78,0x56,0x34,0x12]
+ rsqrtps 0x12345678,%xmm5
+
+// CHECK: rsqrtps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x52,0xed]
+ rsqrtps %xmm5,%xmm5
+
+// CHECK: rsqrtss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rsqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0x45,0x00,0x00,0x00]
+ rsqrtss 0x45,%xmm5
+
+// CHECK: rsqrtss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0xed,0x7e,0x00,0x00]
+ rsqrtss 0x7eed,%xmm5
+
+// CHECK: rsqrtss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0xfe,0xca,0xbe,0xba]
+ rsqrtss 0xbabecafe,%xmm5
+
+// CHECK: rsqrtss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0x78,0x56,0x34,0x12]
+ rsqrtss 0x12345678,%xmm5
+
+// CHECK: rsqrtss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0xed]
+ rsqrtss %xmm5,%xmm5
+
+// CHECK: sqrtps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtps 69, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtps 0x45,%xmm5
+
+// CHECK: sqrtps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtps 0x7eed,%xmm5
+
+// CHECK: sqrtps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtps 0xbabecafe,%xmm5
+
+// CHECK: sqrtps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtps 0x12345678,%xmm5
+
+// CHECK: sqrtps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x51,0xed]
+ sqrtps %xmm5,%xmm5
+
+// CHECK: sqrtss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtss 0x45,%xmm5
+
+// CHECK: sqrtss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtss 0x7eed,%xmm5
+
+// CHECK: sqrtss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtss 0xbabecafe,%xmm5
+
+// CHECK: sqrtss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtss 0x12345678,%xmm5
+
+// CHECK: sqrtss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0xed]
+ sqrtss %xmm5,%xmm5
+
+// CHECK: stmxcsr 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ stmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: stmxcsr 32493
+// CHECK: encoding: [0x0f,0xae,0x1d,0xed,0x7e,0x00,0x00]
+ stmxcsr 0x7eed
+
+// CHECK: stmxcsr 3133065982
+// CHECK: encoding: [0x0f,0xae,0x1d,0xfe,0xca,0xbe,0xba]
+ stmxcsr 0xbabecafe
+
+// CHECK: stmxcsr 305419896
+// CHECK: encoding: [0x0f,0xae,0x1d,0x78,0x56,0x34,0x12]
+ stmxcsr 0x12345678
+
+// CHECK: subps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subps 0x45,%xmm5
+
+// CHECK: subps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subps 0x7eed,%xmm5
+
+// CHECK: subps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subps 0xbabecafe,%xmm5
+
+// CHECK: subps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subps 0x12345678,%xmm5
+
+// CHECK: subps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0xed]
+ subps %xmm5,%xmm5
+
+// CHECK: subss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subss 0x45,%xmm5
+
+// CHECK: subss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subss 0x7eed,%xmm5
+
+// CHECK: subss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subss 0xbabecafe,%xmm5
+
+// CHECK: subss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subss 0x12345678,%xmm5
+
+// CHECK: subss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0xed]
+ subss %xmm5,%xmm5
+
+// CHECK: ucomiss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x2e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ucomiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomiss 69, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0x45,0x00,0x00,0x00]
+ ucomiss 0x45,%xmm5
+
+// CHECK: ucomiss 32493, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0xed,0x7e,0x00,0x00]
+ ucomiss 0x7eed,%xmm5
+
+// CHECK: ucomiss 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0xfe,0xca,0xbe,0xba]
+ ucomiss 0xbabecafe,%xmm5
+
+// CHECK: ucomiss 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0x78,0x56,0x34,0x12]
+ ucomiss 0x12345678,%xmm5
+
+// CHECK: ucomiss %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0xed]
+ ucomiss %xmm5,%xmm5
+
+// CHECK: unpckhps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x15,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpckhps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpckhps 69, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0x45,0x00,0x00,0x00]
+ unpckhps 0x45,%xmm5
+
+// CHECK: unpckhps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0xed,0x7e,0x00,0x00]
+ unpckhps 0x7eed,%xmm5
+
+// CHECK: unpckhps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0xfe,0xca,0xbe,0xba]
+ unpckhps 0xbabecafe,%xmm5
+
+// CHECK: unpckhps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0x78,0x56,0x34,0x12]
+ unpckhps 0x12345678,%xmm5
+
+// CHECK: unpckhps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x15,0xed]
+ unpckhps %xmm5,%xmm5
+
+// CHECK: unpcklps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x14,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpcklps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpcklps 69, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0x45,0x00,0x00,0x00]
+ unpcklps 0x45,%xmm5
+
+// CHECK: unpcklps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0xed,0x7e,0x00,0x00]
+ unpcklps 0x7eed,%xmm5
+
+// CHECK: unpcklps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0xfe,0xca,0xbe,0xba]
+ unpcklps 0xbabecafe,%xmm5
+
+// CHECK: unpcklps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0x78,0x56,0x34,0x12]
+ unpcklps 0x12345678,%xmm5
+
+// CHECK: unpcklps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x14,0xed]
+ unpcklps %xmm5,%xmm5
+
+// CHECK: xorps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x57,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ xorps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: xorps 69, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0x45,0x00,0x00,0x00]
+ xorps 0x45,%xmm5
+
+// CHECK: xorps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0xed,0x7e,0x00,0x00]
+ xorps 0x7eed,%xmm5
+
+// CHECK: xorps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0xfe,0xca,0xbe,0xba]
+ xorps 0xbabecafe,%xmm5
+
+// CHECK: xorps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0x78,0x56,0x34,0x12]
+ xorps 0x12345678,%xmm5
+
+// CHECK: xorps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x57,0xed]
+ xorps %xmm5,%xmm5
+
+// CHECK: addpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addpd 0x45,%xmm5
+
+// CHECK: addpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addpd 0x7eed,%xmm5
+
+// CHECK: addpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addpd 0xbabecafe,%xmm5
+
+// CHECK: addpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addpd 0x12345678,%xmm5
+
+// CHECK: addpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0xed]
+ addpd %xmm5,%xmm5
+
+// CHECK: addsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addsd 0x45,%xmm5
+
+// CHECK: addsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addsd 0x7eed,%xmm5
+
+// CHECK: addsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addsd 0xbabecafe,%xmm5
+
+// CHECK: addsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addsd 0x12345678,%xmm5
+
+// CHECK: addsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0xed]
+ addsd %xmm5,%xmm5
+
+// CHECK: andnpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andnpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andnpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0x45,0x00,0x00,0x00]
+ andnpd 0x45,%xmm5
+
+// CHECK: andnpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0xed,0x7e,0x00,0x00]
+ andnpd 0x7eed,%xmm5
+
+// CHECK: andnpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0xfe,0xca,0xbe,0xba]
+ andnpd 0xbabecafe,%xmm5
+
+// CHECK: andnpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0x78,0x56,0x34,0x12]
+ andnpd 0x12345678,%xmm5
+
+// CHECK: andnpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0xed]
+ andnpd %xmm5,%xmm5
+
+// CHECK: andpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0x45,0x00,0x00,0x00]
+ andpd 0x45,%xmm5
+
+// CHECK: andpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0xed,0x7e,0x00,0x00]
+ andpd 0x7eed,%xmm5
+
+// CHECK: andpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0xfe,0xca,0xbe,0xba]
+ andpd 0xbabecafe,%xmm5
+
+// CHECK: andpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0x78,0x56,0x34,0x12]
+ andpd 0x12345678,%xmm5
+
+// CHECK: andpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0xed]
+ andpd %xmm5,%xmm5
+
+// CHECK: comisd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ comisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: comisd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0x45,0x00,0x00,0x00]
+ comisd 0x45,%xmm5
+
+// CHECK: comisd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0xed,0x7e,0x00,0x00]
+ comisd 0x7eed,%xmm5
+
+// CHECK: comisd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0xfe,0xca,0xbe,0xba]
+ comisd 0xbabecafe,%xmm5
+
+// CHECK: comisd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0x78,0x56,0x34,0x12]
+ comisd 0x12345678,%xmm5
+
+// CHECK: comisd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0xed]
+ comisd %xmm5,%xmm5
+
+// CHECK: cvtpi2pd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpi2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2pd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtpi2pd 0x45,%xmm5
+
+// CHECK: cvtpi2pd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpi2pd 0x7eed,%xmm5
+
+// CHECK: cvtpi2pd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpi2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtpi2pd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtpi2pd 0x12345678,%xmm5
+
+// CHECK: cvtpi2pd %mm3, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0xeb]
+ cvtpi2pd %mm3,%xmm5
+
+// CHECK: cvtsi2sd %ecx, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0xe9]
+ cvtsi2sd %ecx,%xmm5
+
+// CHECK: cvtsi2sd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtsi2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsi2sd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtsi2sd 0x45,%xmm5
+
+// CHECK: cvtsi2sd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtsi2sd 0x7eed,%xmm5
+
+// CHECK: cvtsi2sd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtsi2sd 0xbabecafe,%xmm5
+
+// CHECK: cvtsi2sd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtsi2sd 0x12345678,%xmm5
+
+// CHECK: divpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divpd 0x45,%xmm5
+
+// CHECK: divpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divpd 0x7eed,%xmm5
+
+// CHECK: divpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divpd 0xbabecafe,%xmm5
+
+// CHECK: divpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divpd 0x12345678,%xmm5
+
+// CHECK: divpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0xed]
+ divpd %xmm5,%xmm5
+
+// CHECK: divsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divsd 0x45,%xmm5
+
+// CHECK: divsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divsd 0x7eed,%xmm5
+
+// CHECK: divsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divsd 0xbabecafe,%xmm5
+
+// CHECK: divsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divsd 0x12345678,%xmm5
+
+// CHECK: divsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0xed]
+ divsd %xmm5,%xmm5
+
+// CHECK: maxpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxpd 0x45,%xmm5
+
+// CHECK: maxpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxpd 0x7eed,%xmm5
+
+// CHECK: maxpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxpd 0xbabecafe,%xmm5
+
+// CHECK: maxpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxpd 0x12345678,%xmm5
+
+// CHECK: maxpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0xed]
+ maxpd %xmm5,%xmm5
+
+// CHECK: maxsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxsd 0x45,%xmm5
+
+// CHECK: maxsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxsd 0x7eed,%xmm5
+
+// CHECK: maxsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxsd 0xbabecafe,%xmm5
+
+// CHECK: maxsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxsd 0x12345678,%xmm5
+
+// CHECK: maxsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0xed]
+ maxsd %xmm5,%xmm5
+
+// CHECK: minpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minpd 0x45,%xmm5
+
+// CHECK: minpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minpd 0x7eed,%xmm5
+
+// CHECK: minpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minpd 0xbabecafe,%xmm5
+
+// CHECK: minpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minpd 0x12345678,%xmm5
+
+// CHECK: minpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0xed]
+ minpd %xmm5,%xmm5
+
+// CHECK: minsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minsd 0x45,%xmm5
+
+// CHECK: minsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minsd 0x7eed,%xmm5
+
+// CHECK: minsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minsd 0xbabecafe,%xmm5
+
+// CHECK: minsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minsd 0x12345678,%xmm5
+
+// CHECK: minsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0xed]
+ minsd %xmm5,%xmm5
+
+// CHECK: movapd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movapd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movapd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0x45,0x00,0x00,0x00]
+ movapd 0x45,%xmm5
+
+// CHECK: movapd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0xed,0x7e,0x00,0x00]
+ movapd 0x7eed,%xmm5
+
+// CHECK: movapd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0xfe,0xca,0xbe,0xba]
+ movapd 0xbabecafe,%xmm5
+
+// CHECK: movapd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0x78,0x56,0x34,0x12]
+ movapd 0x12345678,%xmm5
+
+// CHECK: movapd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0xed]
+ movapd %xmm5,%xmm5
+
+// CHECK: movapd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x29,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movapd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movapd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0x45,0x00,0x00,0x00]
+ movapd %xmm5,0x45
+
+// CHECK: movapd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0xed,0x7e,0x00,0x00]
+ movapd %xmm5,0x7eed
+
+// CHECK: movapd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0xfe,0xca,0xbe,0xba]
+ movapd %xmm5,0xbabecafe
+
+// CHECK: movapd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0x78,0x56,0x34,0x12]
+ movapd %xmm5,0x12345678
+
+// CHECK: movapd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0xed]
+ movapd %xmm5,%xmm5
+
+// CHECK: movhpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movhpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0x45,0x00,0x00,0x00]
+ movhpd 0x45,%xmm5
+
+// CHECK: movhpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0xed,0x7e,0x00,0x00]
+ movhpd 0x7eed,%xmm5
+
+// CHECK: movhpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0xfe,0xca,0xbe,0xba]
+ movhpd 0xbabecafe,%xmm5
+
+// CHECK: movhpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0x78,0x56,0x34,0x12]
+ movhpd 0x12345678,%xmm5
+
+// CHECK: movhpd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x17,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movhpd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0x45,0x00,0x00,0x00]
+ movhpd %xmm5,0x45
+
+// CHECK: movhpd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0xed,0x7e,0x00,0x00]
+ movhpd %xmm5,0x7eed
+
+// CHECK: movhpd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0xfe,0xca,0xbe,0xba]
+ movhpd %xmm5,0xbabecafe
+
+// CHECK: movhpd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0x78,0x56,0x34,0x12]
+ movhpd %xmm5,0x12345678
+
+// CHECK: movlpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movlpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movlpd 0x45,%xmm5
+
+// CHECK: movlpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movlpd 0x7eed,%xmm5
+
+// CHECK: movlpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movlpd 0xbabecafe,%xmm5
+
+// CHECK: movlpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movlpd 0x12345678,%xmm5
+
+// CHECK: movlpd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x13,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlpd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0x45,0x00,0x00,0x00]
+ movlpd %xmm5,0x45
+
+// CHECK: movlpd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0xed,0x7e,0x00,0x00]
+ movlpd %xmm5,0x7eed
+
+// CHECK: movlpd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0xfe,0xca,0xbe,0xba]
+ movlpd %xmm5,0xbabecafe
+
+// CHECK: movlpd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0x78,0x56,0x34,0x12]
+ movlpd %xmm5,0x12345678
+
+// CHECK: movmskpd %xmm5, %ecx
+// CHECK: encoding: [0x66,0x0f,0x50,0xcd]
+ movmskpd %xmm5,%ecx
+
+// CHECK: movntpd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x2b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntpd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0x45,0x00,0x00,0x00]
+ movntpd %xmm5,0x45
+
+// CHECK: movntpd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0xed,0x7e,0x00,0x00]
+ movntpd %xmm5,0x7eed
+
+// CHECK: movntpd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0xfe,0xca,0xbe,0xba]
+ movntpd %xmm5,0xbabecafe
+
+// CHECK: movntpd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0x78,0x56,0x34,0x12]
+ movntpd %xmm5,0x12345678
+
+// CHECK: movsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movsd 0x45,%xmm5
+
+// CHECK: movsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movsd 0x7eed,%xmm5
+
+// CHECK: movsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movsd 0xbabecafe,%xmm5
+
+// CHECK: movsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movsd 0x12345678,%xmm5
+
+// CHECK: movsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0xed]
+ movsd %xmm5,%xmm5
+
+// CHECK: movsd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf2,0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movsd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movsd %xmm5, 69
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movsd %xmm5,0x45
+
+// CHECK: movsd %xmm5, 32493
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movsd %xmm5,0x7eed
+
+// CHECK: movsd %xmm5, 3133065982
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movsd %xmm5,0xbabecafe
+
+// CHECK: movsd %xmm5, 305419896
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movsd %xmm5,0x12345678
+
+// CHECK: movsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0xed]
+ movsd %xmm5,%xmm5
+
+// CHECK: movupd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movupd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movupd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movupd 0x45,%xmm5
+
+// CHECK: movupd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movupd 0x7eed,%xmm5
+
+// CHECK: movupd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movupd 0xbabecafe,%xmm5
+
+// CHECK: movupd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movupd 0x12345678,%xmm5
+
+// CHECK: movupd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0xed]
+ movupd %xmm5,%xmm5
+
+// CHECK: movupd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movupd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movupd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movupd %xmm5,0x45
+
+// CHECK: movupd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movupd %xmm5,0x7eed
+
+// CHECK: movupd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movupd %xmm5,0xbabecafe
+
+// CHECK: movupd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movupd %xmm5,0x12345678
+
+// CHECK: movupd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0xed]
+ movupd %xmm5,%xmm5
+
+// CHECK: mulpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulpd 0x45,%xmm5
+
+// CHECK: mulpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulpd 0x7eed,%xmm5
+
+// CHECK: mulpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulpd 0xbabecafe,%xmm5
+
+// CHECK: mulpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulpd 0x12345678,%xmm5
+
+// CHECK: mulpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0xed]
+ mulpd %xmm5,%xmm5
+
+// CHECK: mulsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulsd 0x45,%xmm5
+
+// CHECK: mulsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulsd 0x7eed,%xmm5
+
+// CHECK: mulsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulsd 0xbabecafe,%xmm5
+
+// CHECK: mulsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulsd 0x12345678,%xmm5
+
+// CHECK: mulsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0xed]
+ mulsd %xmm5,%xmm5
+
+// CHECK: orpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ orpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: orpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0x45,0x00,0x00,0x00]
+ orpd 0x45,%xmm5
+
+// CHECK: orpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0xed,0x7e,0x00,0x00]
+ orpd 0x7eed,%xmm5
+
+// CHECK: orpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0xfe,0xca,0xbe,0xba]
+ orpd 0xbabecafe,%xmm5
+
+// CHECK: orpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0x78,0x56,0x34,0x12]
+ orpd 0x12345678,%xmm5
+
+// CHECK: orpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0xed]
+ orpd %xmm5,%xmm5
+
+// CHECK: sqrtpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtpd 0x45,%xmm5
+
+// CHECK: sqrtpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtpd 0x7eed,%xmm5
+
+// CHECK: sqrtpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtpd 0xbabecafe,%xmm5
+
+// CHECK: sqrtpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtpd 0x12345678,%xmm5
+
+// CHECK: sqrtpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0xed]
+ sqrtpd %xmm5,%xmm5
+
+// CHECK: sqrtsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtsd 0x45,%xmm5
+
+// CHECK: sqrtsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtsd 0x7eed,%xmm5
+
+// CHECK: sqrtsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtsd 0xbabecafe,%xmm5
+
+// CHECK: sqrtsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtsd 0x12345678,%xmm5
+
+// CHECK: sqrtsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0xed]
+ sqrtsd %xmm5,%xmm5
+
+// CHECK: subpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subpd 0x45,%xmm5
+
+// CHECK: subpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subpd 0x7eed,%xmm5
+
+// CHECK: subpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subpd 0xbabecafe,%xmm5
+
+// CHECK: subpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subpd 0x12345678,%xmm5
+
+// CHECK: subpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0xed]
+ subpd %xmm5,%xmm5
+
+// CHECK: subsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subsd 0x45,%xmm5
+
+// CHECK: subsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subsd 0x7eed,%xmm5
+
+// CHECK: subsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subsd 0xbabecafe,%xmm5
+
+// CHECK: subsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subsd 0x12345678,%xmm5
+
+// CHECK: subsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0xed]
+ subsd %xmm5,%xmm5
+
+// CHECK: ucomisd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ucomisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomisd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0x45,0x00,0x00,0x00]
+ ucomisd 0x45,%xmm5
+
+// CHECK: ucomisd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0xed,0x7e,0x00,0x00]
+ ucomisd 0x7eed,%xmm5
+
+// CHECK: ucomisd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0xfe,0xca,0xbe,0xba]
+ ucomisd 0xbabecafe,%xmm5
+
+// CHECK: ucomisd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0x78,0x56,0x34,0x12]
+ ucomisd 0x12345678,%xmm5
+
+// CHECK: ucomisd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0xed]
+ ucomisd %xmm5,%xmm5
+
+// CHECK: unpckhpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpckhpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpckhpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0x45,0x00,0x00,0x00]
+ unpckhpd 0x45,%xmm5
+
+// CHECK: unpckhpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0xed,0x7e,0x00,0x00]
+ unpckhpd 0x7eed,%xmm5
+
+// CHECK: unpckhpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0xfe,0xca,0xbe,0xba]
+ unpckhpd 0xbabecafe,%xmm5
+
+// CHECK: unpckhpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0x78,0x56,0x34,0x12]
+ unpckhpd 0x12345678,%xmm5
+
+// CHECK: unpckhpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0xed]
+ unpckhpd %xmm5,%xmm5
+
+// CHECK: unpcklpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpcklpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpcklpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0x45,0x00,0x00,0x00]
+ unpcklpd 0x45,%xmm5
+
+// CHECK: unpcklpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0xed,0x7e,0x00,0x00]
+ unpcklpd 0x7eed,%xmm5
+
+// CHECK: unpcklpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0xfe,0xca,0xbe,0xba]
+ unpcklpd 0xbabecafe,%xmm5
+
+// CHECK: unpcklpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0x78,0x56,0x34,0x12]
+ unpcklpd 0x12345678,%xmm5
+
+// CHECK: unpcklpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0xed]
+ unpcklpd %xmm5,%xmm5
+
+// CHECK: xorpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ xorpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: xorpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0x45,0x00,0x00,0x00]
+ xorpd 0x45,%xmm5
+
+// CHECK: xorpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0xed,0x7e,0x00,0x00]
+ xorpd 0x7eed,%xmm5
+
+// CHECK: xorpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0xfe,0xca,0xbe,0xba]
+ xorpd 0xbabecafe,%xmm5
+
+// CHECK: xorpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0x78,0x56,0x34,0x12]
+ xorpd 0x12345678,%xmm5
+
+// CHECK: xorpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0xed]
+ xorpd %xmm5,%xmm5
+
+// CHECK: cvtdq2pd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtdq2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2pd 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0x45,0x00,0x00,0x00]
+ cvtdq2pd 0x45,%xmm5
+
+// CHECK: cvtdq2pd 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0xed,0x7e,0x00,0x00]
+ cvtdq2pd 0x7eed,%xmm5
+
+// CHECK: cvtdq2pd 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtdq2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtdq2pd 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0x78,0x56,0x34,0x12]
+ cvtdq2pd 0x12345678,%xmm5
+
+// CHECK: cvtdq2pd %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0xed]
+ cvtdq2pd %xmm5,%xmm5
+
+// CHECK: cvtpd2dq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpd2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpd2dq 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0x45,0x00,0x00,0x00]
+ cvtpd2dq 0x45,%xmm5
+
+// CHECK: cvtpd2dq 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpd2dq 0x7eed,%xmm5
+
+// CHECK: cvtpd2dq 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpd2dq 0xbabecafe,%xmm5
+
+// CHECK: cvtpd2dq 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0x78,0x56,0x34,0x12]
+ cvtpd2dq 0x12345678,%xmm5
+
+// CHECK: cvtpd2dq %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0xed]
+ cvtpd2dq %xmm5,%xmm5
+
+// CHECK: cvtdq2ps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtdq2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2ps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0x45,0x00,0x00,0x00]
+ cvtdq2ps 0x45,%xmm5
+
+// CHECK: cvtdq2ps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0xed,0x7e,0x00,0x00]
+ cvtdq2ps 0x7eed,%xmm5
+
+// CHECK: cvtdq2ps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtdq2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtdq2ps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0x78,0x56,0x34,0x12]
+ cvtdq2ps 0x12345678,%xmm5
+
+// CHECK: cvtdq2ps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0xed]
+ cvtdq2ps %xmm5,%xmm5
+
+// CHECK: cvtpd2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtpd2pi 69, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0x45,0x00,0x00,0x00]
+ cvtpd2pi 0x45,%mm3
+
+// CHECK: cvtpd2pi 32493, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0xed,0x7e,0x00,0x00]
+ cvtpd2pi 0x7eed,%mm3
+
+// CHECK: cvtpd2pi 3133065982, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0xfe,0xca,0xbe,0xba]
+ cvtpd2pi 0xbabecafe,%mm3
+
+// CHECK: cvtpd2pi 305419896, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0x78,0x56,0x34,0x12]
+ cvtpd2pi 0x12345678,%mm3
+
+// CHECK: cvtpd2pi %xmm5, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0xdd]
+ cvtpd2pi %xmm5,%mm3
+
+// CHECK: cvtpd2ps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpd2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpd2ps 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtpd2ps 0x45,%xmm5
+
+// CHECK: cvtpd2ps 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpd2ps 0x7eed,%xmm5
+
+// CHECK: cvtpd2ps 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpd2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtpd2ps 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtpd2ps 0x12345678,%xmm5
+
+// CHECK: cvtpd2ps %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0xed]
+ cvtpd2ps %xmm5,%xmm5
+
+// CHECK: cvtps2pd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtps2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtps2pd 69, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtps2pd 0x45,%xmm5
+
+// CHECK: cvtps2pd 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtps2pd 0x7eed,%xmm5
+
+// CHECK: cvtps2pd 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtps2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtps2pd 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtps2pd 0x12345678,%xmm5
+
+// CHECK: cvtps2pd %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0xed]
+ cvtps2pd %xmm5,%xmm5
+
+// CHECK: cvtps2dq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtps2dq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0x45,0x00,0x00,0x00]
+ cvtps2dq 0x45,%xmm5
+
+// CHECK: cvtps2dq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0xed,0x7e,0x00,0x00]
+ cvtps2dq 0x7eed,%xmm5
+
+// CHECK: cvtps2dq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtps2dq 0xbabecafe,%xmm5
+
+// CHECK: cvtps2dq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0x78,0x56,0x34,0x12]
+ cvtps2dq 0x12345678,%xmm5
+
+// CHECK: cvtps2dq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0xed]
+ cvtps2dq %xmm5,%xmm5
+
+// CHECK: cvtsd2ss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtsd2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsd2ss 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtsd2ss 0x45,%xmm5
+
+// CHECK: cvtsd2ss 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtsd2ss 0x7eed,%xmm5
+
+// CHECK: cvtsd2ss 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtsd2ss 0xbabecafe,%xmm5
+
+// CHECK: cvtsd2ss 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtsd2ss 0x12345678,%xmm5
+
+// CHECK: cvtsd2ss %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0xed]
+ cvtsd2ss %xmm5,%xmm5
+
+// CHECK: cvtss2sd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtss2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtss2sd 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtss2sd 0x45,%xmm5
+
+// CHECK: cvtss2sd 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtss2sd 0x7eed,%xmm5
+
+// CHECK: cvtss2sd 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtss2sd 0xbabecafe,%xmm5
+
+// CHECK: cvtss2sd 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtss2sd 0x12345678,%xmm5
+
+// CHECK: cvtss2sd %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0xed]
+ cvtss2sd %xmm5,%xmm5
+
+// CHECK: cvttpd2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttpd2pi 69, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0x45,0x00,0x00,0x00]
+ cvttpd2pi 0x45,%mm3
+
+// CHECK: cvttpd2pi 32493, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0xed,0x7e,0x00,0x00]
+ cvttpd2pi 0x7eed,%mm3
+
+// CHECK: cvttpd2pi 3133065982, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0xfe,0xca,0xbe,0xba]
+ cvttpd2pi 0xbabecafe,%mm3
+
+// CHECK: cvttpd2pi 305419896, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0x78,0x56,0x34,0x12]
+ cvttpd2pi 0x12345678,%mm3
+
+// CHECK: cvttpd2pi %xmm5, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0xdd]
+ cvttpd2pi %xmm5,%mm3
+
+// CHECK: cvttsd2si 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttsd2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttsd2si 69, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0x45,0x00,0x00,0x00]
+ cvttsd2si 0x45,%ecx
+
+// CHECK: cvttsd2si 32493, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0xed,0x7e,0x00,0x00]
+ cvttsd2si 0x7eed,%ecx
+
+// CHECK: cvttsd2si 3133065982, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0xfe,0xca,0xbe,0xba]
+ cvttsd2si 0xbabecafe,%ecx
+
+// CHECK: cvttsd2si 305419896, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0x78,0x56,0x34,0x12]
+ cvttsd2si 0x12345678,%ecx
+
+// CHECK: cvttsd2si %xmm5, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0xcd]
+ cvttsd2si %xmm5,%ecx
+
+// CHECK: cvttps2dq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvttps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvttps2dq 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0x45,0x00,0x00,0x00]
+ cvttps2dq 0x45,%xmm5
+
+// CHECK: cvttps2dq 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0xed,0x7e,0x00,0x00]
+ cvttps2dq 0x7eed,%xmm5
+
+// CHECK: cvttps2dq 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0xfe,0xca,0xbe,0xba]
+ cvttps2dq 0xbabecafe,%xmm5
+
+// CHECK: cvttps2dq 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0x78,0x56,0x34,0x12]
+ cvttps2dq 0x12345678,%xmm5
+
+// CHECK: cvttps2dq %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0xed]
+ cvttps2dq %xmm5,%xmm5
+
+// CHECK: maskmovdqu %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf7,0xed]
+ maskmovdqu %xmm5,%xmm5
+
+// CHECK: movdqa 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqa 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0x45,0x00,0x00,0x00]
+ movdqa 0x45,%xmm5
+
+// CHECK: movdqa 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqa 0x7eed,%xmm5
+
+// CHECK: movdqa 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqa 0xbabecafe,%xmm5
+
+// CHECK: movdqa 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0x78,0x56,0x34,0x12]
+ movdqa 0x12345678,%xmm5
+
+// CHECK: movdqa %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0xed]
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqa %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x7f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqa %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdqa %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0x45,0x00,0x00,0x00]
+ movdqa %xmm5,0x45
+
+// CHECK: movdqa %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqa %xmm5,0x7eed
+
+// CHECK: movdqa %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqa %xmm5,0xbabecafe
+
+// CHECK: movdqa %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0x78,0x56,0x34,0x12]
+ movdqa %xmm5,0x12345678
+
+// CHECK: movdqa %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0xed]
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqu 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqu 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0x45,0x00,0x00,0x00]
+ movdqu 0x45,%xmm5
+
+// CHECK: movdqu 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqu 0x7eed,%xmm5
+
+// CHECK: movdqu 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqu 0xbabecafe,%xmm5
+
+// CHECK: movdqu 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0x78,0x56,0x34,0x12]
+ movdqu 0x12345678,%xmm5
+
+// CHECK: movdqu %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf3,0x0f,0x7f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqu %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdqu %xmm5, 69
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0x45,0x00,0x00,0x00]
+ movdqu %xmm5,0x45
+
+// CHECK: movdqu %xmm5, 32493
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqu %xmm5,0x7eed
+
+// CHECK: movdqu %xmm5, 3133065982
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqu %xmm5,0xbabecafe
+
+// CHECK: movdqu %xmm5, 305419896
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0x78,0x56,0x34,0x12]
+ movdqu %xmm5,0x12345678
+
+// CHECK: movdq2q %xmm5, %mm3
+// CHECK: encoding: [0xf2,0x0f,0xd6,0xdd]
+ movdq2q %xmm5,%mm3
+
+// CHECK: movq2dq %mm3, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xd6,0xeb]
+ movq2dq %mm3,%xmm5
+
+// CHECK: pmuludq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf4,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmuludq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmuludq 69, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0x45,0x00,0x00,0x00]
+ pmuludq 0x45,%mm3
+
+// CHECK: pmuludq 32493, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0xed,0x7e,0x00,0x00]
+ pmuludq 0x7eed,%mm3
+
+// CHECK: pmuludq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0xfe,0xca,0xbe,0xba]
+ pmuludq 0xbabecafe,%mm3
+
+// CHECK: pmuludq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0x78,0x56,0x34,0x12]
+ pmuludq 0x12345678,%mm3
+
+// CHECK: pmuludq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf4,0xdb]
+ pmuludq %mm3,%mm3
+
+// CHECK: pmuludq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmuludq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmuludq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0x45,0x00,0x00,0x00]
+ pmuludq 0x45,%xmm5
+
+// CHECK: pmuludq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0xed,0x7e,0x00,0x00]
+ pmuludq 0x7eed,%xmm5
+
+// CHECK: pmuludq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0xfe,0xca,0xbe,0xba]
+ pmuludq 0xbabecafe,%xmm5
+
+// CHECK: pmuludq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0x78,0x56,0x34,0x12]
+ pmuludq 0x12345678,%xmm5
+
+// CHECK: pmuludq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0xed]
+ pmuludq %xmm5,%xmm5
+
+// CHECK: pslldq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xfd,0x7f]
+ pslldq $0x7f,%xmm5
+
+// CHECK: psrldq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xdd,0x7f]
+ psrldq $0x7f,%xmm5
+
+// CHECK: punpckhqdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhqdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhqdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0x45,0x00,0x00,0x00]
+ punpckhqdq 0x45,%xmm5
+
+// CHECK: punpckhqdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhqdq 0x7eed,%xmm5
+
+// CHECK: punpckhqdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhqdq 0xbabecafe,%xmm5
+
+// CHECK: punpckhqdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0x78,0x56,0x34,0x12]
+ punpckhqdq 0x12345678,%xmm5
+
+// CHECK: punpckhqdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0xed]
+ punpckhqdq %xmm5,%xmm5
+
+// CHECK: punpcklqdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklqdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklqdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0x45,0x00,0x00,0x00]
+ punpcklqdq 0x45,%xmm5
+
+// CHECK: punpcklqdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0xed,0x7e,0x00,0x00]
+ punpcklqdq 0x7eed,%xmm5
+
+// CHECK: punpcklqdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0xfe,0xca,0xbe,0xba]
+ punpcklqdq 0xbabecafe,%xmm5
+
+// CHECK: punpcklqdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0x78,0x56,0x34,0x12]
+ punpcklqdq 0x12345678,%xmm5
+
+// CHECK: punpcklqdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0xed]
+ punpcklqdq %xmm5,%xmm5
+
+// CHECK: addsubpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addsubpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsubpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0x45,0x00,0x00,0x00]
+ addsubpd 0x45,%xmm5
+
+// CHECK: addsubpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0xed,0x7e,0x00,0x00]
+ addsubpd 0x7eed,%xmm5
+
+// CHECK: addsubpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0xfe,0xca,0xbe,0xba]
+ addsubpd 0xbabecafe,%xmm5
+
+// CHECK: addsubpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0x78,0x56,0x34,0x12]
+ addsubpd 0x12345678,%xmm5
+
+// CHECK: addsubpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0xed]
+ addsubpd %xmm5,%xmm5
+
+// CHECK: addsubps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addsubps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsubps 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0x45,0x00,0x00,0x00]
+ addsubps 0x45,%xmm5
+
+// CHECK: addsubps 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0xed,0x7e,0x00,0x00]
+ addsubps 0x7eed,%xmm5
+
+// CHECK: addsubps 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0xfe,0xca,0xbe,0xba]
+ addsubps 0xbabecafe,%xmm5
+
+// CHECK: addsubps 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0x78,0x56,0x34,0x12]
+ addsubps 0x12345678,%xmm5
+
+// CHECK: addsubps %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0xed]
+ addsubps %xmm5,%xmm5
+
+// CHECK: fisttpl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fisttpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisttpl 3133065982
+// CHECK: encoding: [0xdb,0x0d,0xfe,0xca,0xbe,0xba]
+ fisttpl 0xbabecafe
+
+// CHECK: fisttpl 305419896
+// CHECK: encoding: [0xdb,0x0d,0x78,0x56,0x34,0x12]
+ fisttpl 0x12345678
+
+// CHECK: haddpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ haddpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: haddpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0x45,0x00,0x00,0x00]
+ haddpd 0x45,%xmm5
+
+// CHECK: haddpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0xed,0x7e,0x00,0x00]
+ haddpd 0x7eed,%xmm5
+
+// CHECK: haddpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0xfe,0xca,0xbe,0xba]
+ haddpd 0xbabecafe,%xmm5
+
+// CHECK: haddpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0x78,0x56,0x34,0x12]
+ haddpd 0x12345678,%xmm5
+
+// CHECK: haddpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0xed]
+ haddpd %xmm5,%xmm5
+
+// CHECK: haddps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ haddps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: haddps 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0x45,0x00,0x00,0x00]
+ haddps 0x45,%xmm5
+
+// CHECK: haddps 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0xed,0x7e,0x00,0x00]
+ haddps 0x7eed,%xmm5
+
+// CHECK: haddps 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0xfe,0xca,0xbe,0xba]
+ haddps 0xbabecafe,%xmm5
+
+// CHECK: haddps 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0x78,0x56,0x34,0x12]
+ haddps 0x12345678,%xmm5
+
+// CHECK: haddps %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0xed]
+ haddps %xmm5,%xmm5
+
+// CHECK: hsubpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ hsubpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: hsubpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0x45,0x00,0x00,0x00]
+ hsubpd 0x45,%xmm5
+
+// CHECK: hsubpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0xed,0x7e,0x00,0x00]
+ hsubpd 0x7eed,%xmm5
+
+// CHECK: hsubpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0xfe,0xca,0xbe,0xba]
+ hsubpd 0xbabecafe,%xmm5
+
+// CHECK: hsubpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0x78,0x56,0x34,0x12]
+ hsubpd 0x12345678,%xmm5
+
+// CHECK: hsubpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0xed]
+ hsubpd %xmm5,%xmm5
+
+// CHECK: hsubps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ hsubps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: hsubps 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0x45,0x00,0x00,0x00]
+ hsubps 0x45,%xmm5
+
+// CHECK: hsubps 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0xed,0x7e,0x00,0x00]
+ hsubps 0x7eed,%xmm5
+
+// CHECK: hsubps 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0xfe,0xca,0xbe,0xba]
+ hsubps 0xbabecafe,%xmm5
+
+// CHECK: hsubps 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0x78,0x56,0x34,0x12]
+ hsubps 0x12345678,%xmm5
+
+// CHECK: hsubps %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0xed]
+ hsubps %xmm5,%xmm5
+
+// CHECK: lddqu 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ lddqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: lddqu 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0x45,0x00,0x00,0x00]
+ lddqu 0x45,%xmm5
+
+// CHECK: lddqu 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0xed,0x7e,0x00,0x00]
+ lddqu 0x7eed,%xmm5
+
+// CHECK: lddqu 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0xfe,0xca,0xbe,0xba]
+ lddqu 0xbabecafe,%xmm5
+
+// CHECK: lddqu 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0x78,0x56,0x34,0x12]
+ lddqu 0x12345678,%xmm5
+
+// CHECK: movddup 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movddup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movddup 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movddup 0x45,%xmm5
+
+// CHECK: movddup 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movddup 0x7eed,%xmm5
+
+// CHECK: movddup 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movddup 0xbabecafe,%xmm5
+
+// CHECK: movddup 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movddup 0x12345678,%xmm5
+
+// CHECK: movddup %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0xed]
+ movddup %xmm5,%xmm5
+
+// CHECK: movshdup 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movshdup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movshdup 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0x45,0x00,0x00,0x00]
+ movshdup 0x45,%xmm5
+
+// CHECK: movshdup 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0xed,0x7e,0x00,0x00]
+ movshdup 0x7eed,%xmm5
+
+// CHECK: movshdup 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0xfe,0xca,0xbe,0xba]
+ movshdup 0xbabecafe,%xmm5
+
+// CHECK: movshdup 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0x78,0x56,0x34,0x12]
+ movshdup 0x12345678,%xmm5
+
+// CHECK: movshdup %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0xed]
+ movshdup %xmm5,%xmm5
+
+// CHECK: movsldup 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movsldup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsldup 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movsldup 0x45,%xmm5
+
+// CHECK: movsldup 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movsldup 0x7eed,%xmm5
+
+// CHECK: movsldup 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movsldup 0xbabecafe,%xmm5
+
+// CHECK: movsldup 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movsldup 0x12345678,%xmm5
+
+// CHECK: movsldup %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0xed]
+ movsldup %xmm5,%xmm5
+
+// CHECK: vmclear 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0xc7,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ vmclear 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmclear 32493
+// CHECK: encoding: [0x66,0x0f,0xc7,0x35,0xed,0x7e,0x00,0x00]
+ vmclear 0x7eed
+
+// CHECK: vmclear 3133065982
+// CHECK: encoding: [0x66,0x0f,0xc7,0x35,0xfe,0xca,0xbe,0xba]
+ vmclear 0xbabecafe
+
+// CHECK: vmclear 305419896
+// CHECK: encoding: [0x66,0x0f,0xc7,0x35,0x78,0x56,0x34,0x12]
+ vmclear 0x12345678
+
+// CHECK: vmptrld 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc7,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ vmptrld 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmptrld 32493
+// CHECK: encoding: [0x0f,0xc7,0x35,0xed,0x7e,0x00,0x00]
+ vmptrld 0x7eed
+
+// CHECK: vmptrld 3133065982
+// CHECK: encoding: [0x0f,0xc7,0x35,0xfe,0xca,0xbe,0xba]
+ vmptrld 0xbabecafe
+
+// CHECK: vmptrld 305419896
+// CHECK: encoding: [0x0f,0xc7,0x35,0x78,0x56,0x34,0x12]
+ vmptrld 0x12345678
+
+// CHECK: vmptrst 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc7,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ vmptrst 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmptrst 32493
+// CHECK: encoding: [0x0f,0xc7,0x3d,0xed,0x7e,0x00,0x00]
+ vmptrst 0x7eed
+
+// CHECK: vmptrst 3133065982
+// CHECK: encoding: [0x0f,0xc7,0x3d,0xfe,0xca,0xbe,0xba]
+ vmptrst 0xbabecafe
+
+// CHECK: vmptrst 305419896
+// CHECK: encoding: [0x0f,0xc7,0x3d,0x78,0x56,0x34,0x12]
+ vmptrst 0x12345678
+
+// CHECK: phaddw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phaddw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0x45,0x00,0x00,0x00]
+ phaddw 0x45,%mm3
+
+// CHECK: phaddw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0xed,0x7e,0x00,0x00]
+ phaddw 0x7eed,%mm3
+
+// CHECK: phaddw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0xfe,0xca,0xbe,0xba]
+ phaddw 0xbabecafe,%mm3
+
+// CHECK: phaddw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0x78,0x56,0x34,0x12]
+ phaddw 0x12345678,%mm3
+
+// CHECK: phaddw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0xdb]
+ phaddw %mm3,%mm3
+
+// CHECK: phaddw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phaddw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0x45,0x00,0x00,0x00]
+ phaddw 0x45,%xmm5
+
+// CHECK: phaddw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0xed,0x7e,0x00,0x00]
+ phaddw 0x7eed,%xmm5
+
+// CHECK: phaddw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0xfe,0xca,0xbe,0xba]
+ phaddw 0xbabecafe,%xmm5
+
+// CHECK: phaddw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0x78,0x56,0x34,0x12]
+ phaddw 0x12345678,%xmm5
+
+// CHECK: phaddw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0xed]
+ phaddw %xmm5,%xmm5
+
+// CHECK: phaddd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phaddd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0x45,0x00,0x00,0x00]
+ phaddd 0x45,%mm3
+
+// CHECK: phaddd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0xed,0x7e,0x00,0x00]
+ phaddd 0x7eed,%mm3
+
+// CHECK: phaddd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0xfe,0xca,0xbe,0xba]
+ phaddd 0xbabecafe,%mm3
+
+// CHECK: phaddd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0x78,0x56,0x34,0x12]
+ phaddd 0x12345678,%mm3
+
+// CHECK: phaddd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0xdb]
+ phaddd %mm3,%mm3
+
+// CHECK: phaddd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phaddd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0x45,0x00,0x00,0x00]
+ phaddd 0x45,%xmm5
+
+// CHECK: phaddd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0xed,0x7e,0x00,0x00]
+ phaddd 0x7eed,%xmm5
+
+// CHECK: phaddd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0xfe,0xca,0xbe,0xba]
+ phaddd 0xbabecafe,%xmm5
+
+// CHECK: phaddd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0x78,0x56,0x34,0x12]
+ phaddd 0x12345678,%xmm5
+
+// CHECK: phaddd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0xed]
+ phaddd %xmm5,%xmm5
+
+// CHECK: phaddsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phaddsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0x45,0x00,0x00,0x00]
+ phaddsw 0x45,%mm3
+
+// CHECK: phaddsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0xed,0x7e,0x00,0x00]
+ phaddsw 0x7eed,%mm3
+
+// CHECK: phaddsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0xfe,0xca,0xbe,0xba]
+ phaddsw 0xbabecafe,%mm3
+
+// CHECK: phaddsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0x78,0x56,0x34,0x12]
+ phaddsw 0x12345678,%mm3
+
+// CHECK: phaddsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0xdb]
+ phaddsw %mm3,%mm3
+
+// CHECK: phaddsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phaddsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0x45,0x00,0x00,0x00]
+ phaddsw 0x45,%xmm5
+
+// CHECK: phaddsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0xed,0x7e,0x00,0x00]
+ phaddsw 0x7eed,%xmm5
+
+// CHECK: phaddsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0xfe,0xca,0xbe,0xba]
+ phaddsw 0xbabecafe,%xmm5
+
+// CHECK: phaddsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0x78,0x56,0x34,0x12]
+ phaddsw 0x12345678,%xmm5
+
+// CHECK: phaddsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0xed]
+ phaddsw %xmm5,%xmm5
+
+// CHECK: phsubw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phsubw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0x45,0x00,0x00,0x00]
+ phsubw 0x45,%mm3
+
+// CHECK: phsubw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0xed,0x7e,0x00,0x00]
+ phsubw 0x7eed,%mm3
+
+// CHECK: phsubw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0xfe,0xca,0xbe,0xba]
+ phsubw 0xbabecafe,%mm3
+
+// CHECK: phsubw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0x78,0x56,0x34,0x12]
+ phsubw 0x12345678,%mm3
+
+// CHECK: phsubw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0xdb]
+ phsubw %mm3,%mm3
+
+// CHECK: phsubw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phsubw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0x45,0x00,0x00,0x00]
+ phsubw 0x45,%xmm5
+
+// CHECK: phsubw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0xed,0x7e,0x00,0x00]
+ phsubw 0x7eed,%xmm5
+
+// CHECK: phsubw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0xfe,0xca,0xbe,0xba]
+ phsubw 0xbabecafe,%xmm5
+
+// CHECK: phsubw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0x78,0x56,0x34,0x12]
+ phsubw 0x12345678,%xmm5
+
+// CHECK: phsubw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0xed]
+ phsubw %xmm5,%xmm5
+
+// CHECK: phsubd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phsubd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0x45,0x00,0x00,0x00]
+ phsubd 0x45,%mm3
+
+// CHECK: phsubd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0xed,0x7e,0x00,0x00]
+ phsubd 0x7eed,%mm3
+
+// CHECK: phsubd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0xfe,0xca,0xbe,0xba]
+ phsubd 0xbabecafe,%mm3
+
+// CHECK: phsubd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0x78,0x56,0x34,0x12]
+ phsubd 0x12345678,%mm3
+
+// CHECK: phsubd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0xdb]
+ phsubd %mm3,%mm3
+
+// CHECK: phsubd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phsubd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0x45,0x00,0x00,0x00]
+ phsubd 0x45,%xmm5
+
+// CHECK: phsubd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0xed,0x7e,0x00,0x00]
+ phsubd 0x7eed,%xmm5
+
+// CHECK: phsubd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0xfe,0xca,0xbe,0xba]
+ phsubd 0xbabecafe,%xmm5
+
+// CHECK: phsubd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0x78,0x56,0x34,0x12]
+ phsubd 0x12345678,%xmm5
+
+// CHECK: phsubd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0xed]
+ phsubd %xmm5,%xmm5
+
+// CHECK: phsubsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phsubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0x45,0x00,0x00,0x00]
+ phsubsw 0x45,%mm3
+
+// CHECK: phsubsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0xed,0x7e,0x00,0x00]
+ phsubsw 0x7eed,%mm3
+
+// CHECK: phsubsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0xfe,0xca,0xbe,0xba]
+ phsubsw 0xbabecafe,%mm3
+
+// CHECK: phsubsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0x78,0x56,0x34,0x12]
+ phsubsw 0x12345678,%mm3
+
+// CHECK: phsubsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0xdb]
+ phsubsw %mm3,%mm3
+
+// CHECK: phsubsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phsubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0x45,0x00,0x00,0x00]
+ phsubsw 0x45,%xmm5
+
+// CHECK: phsubsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0xed,0x7e,0x00,0x00]
+ phsubsw 0x7eed,%xmm5
+
+// CHECK: phsubsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0xfe,0xca,0xbe,0xba]
+ phsubsw 0xbabecafe,%xmm5
+
+// CHECK: phsubsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0x78,0x56,0x34,0x12]
+ phsubsw 0x12345678,%xmm5
+
+// CHECK: phsubsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0xed]
+ phsubsw %xmm5,%xmm5
+
+// CHECK: pmaddubsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaddubsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0x45,0x00,0x00,0x00]
+ pmaddubsw 0x45,%mm3
+
+// CHECK: pmaddubsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0xed,0x7e,0x00,0x00]
+ pmaddubsw 0x7eed,%mm3
+
+// CHECK: pmaddubsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaddubsw 0xbabecafe,%mm3
+
+// CHECK: pmaddubsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0x78,0x56,0x34,0x12]
+ pmaddubsw 0x12345678,%mm3
+
+// CHECK: pmaddubsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0xdb]
+ pmaddubsw %mm3,%mm3
+
+// CHECK: pmaddubsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaddubsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0x45,0x00,0x00,0x00]
+ pmaddubsw 0x45,%xmm5
+
+// CHECK: pmaddubsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0xed,0x7e,0x00,0x00]
+ pmaddubsw 0x7eed,%xmm5
+
+// CHECK: pmaddubsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaddubsw 0xbabecafe,%xmm5
+
+// CHECK: pmaddubsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0x78,0x56,0x34,0x12]
+ pmaddubsw 0x12345678,%xmm5
+
+// CHECK: pmaddubsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0xed]
+ pmaddubsw %xmm5,%xmm5
+
+// CHECK: pmulhrsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhrsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhrsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0x45,0x00,0x00,0x00]
+ pmulhrsw 0x45,%mm3
+
+// CHECK: pmulhrsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0xed,0x7e,0x00,0x00]
+ pmulhrsw 0x7eed,%mm3
+
+// CHECK: pmulhrsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0xfe,0xca,0xbe,0xba]
+ pmulhrsw 0xbabecafe,%mm3
+
+// CHECK: pmulhrsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0x78,0x56,0x34,0x12]
+ pmulhrsw 0x12345678,%mm3
+
+// CHECK: pmulhrsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0xdb]
+ pmulhrsw %mm3,%mm3
+
+// CHECK: pmulhrsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhrsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhrsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0x45,0x00,0x00,0x00]
+ pmulhrsw 0x45,%xmm5
+
+// CHECK: pmulhrsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0xed,0x7e,0x00,0x00]
+ pmulhrsw 0x7eed,%xmm5
+
+// CHECK: pmulhrsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulhrsw 0xbabecafe,%xmm5
+
+// CHECK: pmulhrsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0x78,0x56,0x34,0x12]
+ pmulhrsw 0x12345678,%xmm5
+
+// CHECK: pmulhrsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0xed]
+ pmulhrsw %xmm5,%xmm5
+
+// CHECK: pshufb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pshufb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pshufb 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0x45,0x00,0x00,0x00]
+ pshufb 0x45,%mm3
+
+// CHECK: pshufb 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0xed,0x7e,0x00,0x00]
+ pshufb 0x7eed,%mm3
+
+// CHECK: pshufb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0xfe,0xca,0xbe,0xba]
+ pshufb 0xbabecafe,%mm3
+
+// CHECK: pshufb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0x78,0x56,0x34,0x12]
+ pshufb 0x12345678,%mm3
+
+// CHECK: pshufb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0xdb]
+ pshufb %mm3,%mm3
+
+// CHECK: pshufb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pshufb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pshufb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0x45,0x00,0x00,0x00]
+ pshufb 0x45,%xmm5
+
+// CHECK: pshufb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0xed,0x7e,0x00,0x00]
+ pshufb 0x7eed,%xmm5
+
+// CHECK: pshufb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0xfe,0xca,0xbe,0xba]
+ pshufb 0xbabecafe,%xmm5
+
+// CHECK: pshufb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0x78,0x56,0x34,0x12]
+ pshufb 0x12345678,%xmm5
+
+// CHECK: pshufb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0xed]
+ pshufb %xmm5,%xmm5
+
+// CHECK: psignb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psignb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignb 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0x45,0x00,0x00,0x00]
+ psignb 0x45,%mm3
+
+// CHECK: psignb 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0xed,0x7e,0x00,0x00]
+ psignb 0x7eed,%mm3
+
+// CHECK: psignb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0xfe,0xca,0xbe,0xba]
+ psignb 0xbabecafe,%mm3
+
+// CHECK: psignb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0x78,0x56,0x34,0x12]
+ psignb 0x12345678,%mm3
+
+// CHECK: psignb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0xdb]
+ psignb %mm3,%mm3
+
+// CHECK: psignb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psignb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0x45,0x00,0x00,0x00]
+ psignb 0x45,%xmm5
+
+// CHECK: psignb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0xed,0x7e,0x00,0x00]
+ psignb 0x7eed,%xmm5
+
+// CHECK: psignb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0xfe,0xca,0xbe,0xba]
+ psignb 0xbabecafe,%xmm5
+
+// CHECK: psignb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0x78,0x56,0x34,0x12]
+ psignb 0x12345678,%xmm5
+
+// CHECK: psignb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0xed]
+ psignb %xmm5,%xmm5
+
+// CHECK: psignw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psignw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0x45,0x00,0x00,0x00]
+ psignw 0x45,%mm3
+
+// CHECK: psignw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0xed,0x7e,0x00,0x00]
+ psignw 0x7eed,%mm3
+
+// CHECK: psignw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0xfe,0xca,0xbe,0xba]
+ psignw 0xbabecafe,%mm3
+
+// CHECK: psignw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0x78,0x56,0x34,0x12]
+ psignw 0x12345678,%mm3
+
+// CHECK: psignw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0xdb]
+ psignw %mm3,%mm3
+
+// CHECK: psignw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psignw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0x45,0x00,0x00,0x00]
+ psignw 0x45,%xmm5
+
+// CHECK: psignw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0xed,0x7e,0x00,0x00]
+ psignw 0x7eed,%xmm5
+
+// CHECK: psignw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0xfe,0xca,0xbe,0xba]
+ psignw 0xbabecafe,%xmm5
+
+// CHECK: psignw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0x78,0x56,0x34,0x12]
+ psignw 0x12345678,%xmm5
+
+// CHECK: psignw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0xed]
+ psignw %xmm5,%xmm5
+
+// CHECK: psignd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psignd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0x45,0x00,0x00,0x00]
+ psignd 0x45,%mm3
+
+// CHECK: psignd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0xed,0x7e,0x00,0x00]
+ psignd 0x7eed,%mm3
+
+// CHECK: psignd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0xfe,0xca,0xbe,0xba]
+ psignd 0xbabecafe,%mm3
+
+// CHECK: psignd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0x78,0x56,0x34,0x12]
+ psignd 0x12345678,%mm3
+
+// CHECK: psignd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0xdb]
+ psignd %mm3,%mm3
+
+// CHECK: psignd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psignd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0x45,0x00,0x00,0x00]
+ psignd 0x45,%xmm5
+
+// CHECK: psignd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0xed,0x7e,0x00,0x00]
+ psignd 0x7eed,%xmm5
+
+// CHECK: psignd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0xfe,0xca,0xbe,0xba]
+ psignd 0xbabecafe,%xmm5
+
+// CHECK: psignd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0x78,0x56,0x34,0x12]
+ psignd 0x12345678,%xmm5
+
+// CHECK: psignd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0xed]
+ psignd %xmm5,%xmm5
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsb 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0x45,0x00,0x00,0x00]
+ pabsb 0x45,%mm3
+
+// CHECK: pabsb 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0xed,0x7e,0x00,0x00]
+ pabsb 0x7eed,%mm3
+
+// CHECK: pabsb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0xfe,0xca,0xbe,0xba]
+ pabsb 0xbabecafe,%mm3
+
+// CHECK: pabsb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0x78,0x56,0x34,0x12]
+ pabsb 0x12345678,%mm3
+
+// CHECK: pabsb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0xdb]
+ pabsb %mm3,%mm3
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0x45,0x00,0x00,0x00]
+ pabsb 0x45,%xmm5
+
+// CHECK: pabsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0xed,0x7e,0x00,0x00]
+ pabsb 0x7eed,%xmm5
+
+// CHECK: pabsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0xfe,0xca,0xbe,0xba]
+ pabsb 0xbabecafe,%xmm5
+
+// CHECK: pabsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0x78,0x56,0x34,0x12]
+ pabsb 0x12345678,%xmm5
+
+// CHECK: pabsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0xed]
+ pabsb %xmm5,%xmm5
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0x45,0x00,0x00,0x00]
+ pabsw 0x45,%mm3
+
+// CHECK: pabsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0xed,0x7e,0x00,0x00]
+ pabsw 0x7eed,%mm3
+
+// CHECK: pabsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0xfe,0xca,0xbe,0xba]
+ pabsw 0xbabecafe,%mm3
+
+// CHECK: pabsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0x78,0x56,0x34,0x12]
+ pabsw 0x12345678,%mm3
+
+// CHECK: pabsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0xdb]
+ pabsw %mm3,%mm3
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0x45,0x00,0x00,0x00]
+ pabsw 0x45,%xmm5
+
+// CHECK: pabsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0xed,0x7e,0x00,0x00]
+ pabsw 0x7eed,%xmm5
+
+// CHECK: pabsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0xfe,0xca,0xbe,0xba]
+ pabsw 0xbabecafe,%xmm5
+
+// CHECK: pabsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0x78,0x56,0x34,0x12]
+ pabsw 0x12345678,%xmm5
+
+// CHECK: pabsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0xed]
+ pabsw %xmm5,%xmm5
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0x45,0x00,0x00,0x00]
+ pabsd 0x45,%mm3
+
+// CHECK: pabsd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0xed,0x7e,0x00,0x00]
+ pabsd 0x7eed,%mm3
+
+// CHECK: pabsd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0xfe,0xca,0xbe,0xba]
+ pabsd 0xbabecafe,%mm3
+
+// CHECK: pabsd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0x78,0x56,0x34,0x12]
+ pabsd 0x12345678,%mm3
+
+// CHECK: pabsd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0xdb]
+ pabsd %mm3,%mm3
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0x45,0x00,0x00,0x00]
+ pabsd 0x45,%xmm5
+
+// CHECK: pabsd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0xed,0x7e,0x00,0x00]
+ pabsd 0x7eed,%xmm5
+
+// CHECK: pabsd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0xfe,0xca,0xbe,0xba]
+ pabsd 0xbabecafe,%xmm5
+
+// CHECK: pabsd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0x78,0x56,0x34,0x12]
+ pabsd 0x12345678,%xmm5
+
+// CHECK: pabsd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0xed]
+ pabsd %xmm5,%xmm5
+
+// CHECK: femms
+// CHECK: encoding: [0x0f,0x0e]
+ femms
+
+// CHECK: movntdqa 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movntdqa 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ movntdqa 0x45,%xmm5
+
+// CHECK: movntdqa 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ movntdqa 0x7eed,%xmm5
+
+// CHECK: movntdqa 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ movntdqa 0xbabecafe,%xmm5
+
+// CHECK: movntdqa 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ movntdqa 0x12345678,%xmm5
+
+// CHECK: packusdw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packusdw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packusdw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0x45,0x00,0x00,0x00]
+ packusdw 0x45,%xmm5
+
+// CHECK: packusdw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0xed,0x7e,0x00,0x00]
+ packusdw 0x7eed,%xmm5
+
+// CHECK: packusdw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0xfe,0xca,0xbe,0xba]
+ packusdw 0xbabecafe,%xmm5
+
+// CHECK: packusdw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0x78,0x56,0x34,0x12]
+ packusdw 0x12345678,%xmm5
+
+// CHECK: packusdw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0xed]
+ packusdw %xmm5,%xmm5
+
+// CHECK: pcmpeqq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqq 0x45,%xmm5
+
+// CHECK: pcmpeqq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqq 0x7eed,%xmm5
+
+// CHECK: pcmpeqq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqq 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqq 0x12345678,%xmm5
+
+// CHECK: pcmpeqq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0xed]
+ pcmpeqq %xmm5,%xmm5
+
+// CHECK: phminposuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phminposuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phminposuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0x45,0x00,0x00,0x00]
+ phminposuw 0x45,%xmm5
+
+// CHECK: phminposuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0xed,0x7e,0x00,0x00]
+ phminposuw 0x7eed,%xmm5
+
+// CHECK: phminposuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0xfe,0xca,0xbe,0xba]
+ phminposuw 0xbabecafe,%xmm5
+
+// CHECK: phminposuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0x78,0x56,0x34,0x12]
+ phminposuw 0x12345678,%xmm5
+
+// CHECK: phminposuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0xed]
+ phminposuw %xmm5,%xmm5
+
+// CHECK: pmaxsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0x45,0x00,0x00,0x00]
+ pmaxsb 0x45,%xmm5
+
+// CHECK: pmaxsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxsb 0x7eed,%xmm5
+
+// CHECK: pmaxsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxsb 0xbabecafe,%xmm5
+
+// CHECK: pmaxsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0x78,0x56,0x34,0x12]
+ pmaxsb 0x12345678,%xmm5
+
+// CHECK: pmaxsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0xed]
+ pmaxsb %xmm5,%xmm5
+
+// CHECK: pmaxsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0x45,0x00,0x00,0x00]
+ pmaxsd 0x45,%xmm5
+
+// CHECK: pmaxsd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxsd 0x7eed,%xmm5
+
+// CHECK: pmaxsd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxsd 0xbabecafe,%xmm5
+
+// CHECK: pmaxsd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0x78,0x56,0x34,0x12]
+ pmaxsd 0x12345678,%xmm5
+
+// CHECK: pmaxsd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0xed]
+ pmaxsd %xmm5,%xmm5
+
+// CHECK: pmaxud 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxud 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxud 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0x45,0x00,0x00,0x00]
+ pmaxud 0x45,%xmm5
+
+// CHECK: pmaxud 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxud 0x7eed,%xmm5
+
+// CHECK: pmaxud 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxud 0xbabecafe,%xmm5
+
+// CHECK: pmaxud 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0x78,0x56,0x34,0x12]
+ pmaxud 0x12345678,%xmm5
+
+// CHECK: pmaxud %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0xed]
+ pmaxud %xmm5,%xmm5
+
+// CHECK: pmaxuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0x45,0x00,0x00,0x00]
+ pmaxuw 0x45,%xmm5
+
+// CHECK: pmaxuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxuw 0x7eed,%xmm5
+
+// CHECK: pmaxuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxuw 0xbabecafe,%xmm5
+
+// CHECK: pmaxuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0x78,0x56,0x34,0x12]
+ pmaxuw 0x12345678,%xmm5
+
+// CHECK: pmaxuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0xed]
+ pmaxuw %xmm5,%xmm5
+
+// CHECK: pminsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0x45,0x00,0x00,0x00]
+ pminsb 0x45,%xmm5
+
+// CHECK: pminsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0xed,0x7e,0x00,0x00]
+ pminsb 0x7eed,%xmm5
+
+// CHECK: pminsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0xfe,0xca,0xbe,0xba]
+ pminsb 0xbabecafe,%xmm5
+
+// CHECK: pminsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0x78,0x56,0x34,0x12]
+ pminsb 0x12345678,%xmm5
+
+// CHECK: pminsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0xed]
+ pminsb %xmm5,%xmm5
+
+// CHECK: pminsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0x45,0x00,0x00,0x00]
+ pminsd 0x45,%xmm5
+
+// CHECK: pminsd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0xed,0x7e,0x00,0x00]
+ pminsd 0x7eed,%xmm5
+
+// CHECK: pminsd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0xfe,0xca,0xbe,0xba]
+ pminsd 0xbabecafe,%xmm5
+
+// CHECK: pminsd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0x78,0x56,0x34,0x12]
+ pminsd 0x12345678,%xmm5
+
+// CHECK: pminsd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0xed]
+ pminsd %xmm5,%xmm5
+
+// CHECK: pminud 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminud 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminud 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0x45,0x00,0x00,0x00]
+ pminud 0x45,%xmm5
+
+// CHECK: pminud 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0xed,0x7e,0x00,0x00]
+ pminud 0x7eed,%xmm5
+
+// CHECK: pminud 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0xfe,0xca,0xbe,0xba]
+ pminud 0xbabecafe,%xmm5
+
+// CHECK: pminud 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0x78,0x56,0x34,0x12]
+ pminud 0x12345678,%xmm5
+
+// CHECK: pminud %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0xed]
+ pminud %xmm5,%xmm5
+
+// CHECK: pminuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0x45,0x00,0x00,0x00]
+ pminuw 0x45,%xmm5
+
+// CHECK: pminuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0xed,0x7e,0x00,0x00]
+ pminuw 0x7eed,%xmm5
+
+// CHECK: pminuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0xfe,0xca,0xbe,0xba]
+ pminuw 0xbabecafe,%xmm5
+
+// CHECK: pminuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0x78,0x56,0x34,0x12]
+ pminuw 0x12345678,%xmm5
+
+// CHECK: pminuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0xed]
+ pminuw %xmm5,%xmm5
+
+// CHECK: pmovsxbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxbw 0x45,%xmm5
+
+// CHECK: pmovsxbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxbw 0x7eed,%xmm5
+
+// CHECK: pmovsxbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxbw 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxbw 0x12345678,%xmm5
+
+// CHECK: pmovsxbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0xed]
+ pmovsxbw %xmm5,%xmm5
+
+// CHECK: pmovsxbd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxbd 0x45,%xmm5
+
+// CHECK: pmovsxbd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxbd 0x7eed,%xmm5
+
+// CHECK: pmovsxbd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxbd 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxbd 0x12345678,%xmm5
+
+// CHECK: pmovsxbd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0xed]
+ pmovsxbd %xmm5,%xmm5
+
+// CHECK: pmovsxbq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxbq 0x45,%xmm5
+
+// CHECK: pmovsxbq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxbq 0x7eed,%xmm5
+
+// CHECK: pmovsxbq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxbq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxbq 0x12345678,%xmm5
+
+// CHECK: pmovsxbq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0xed]
+ pmovsxbq %xmm5,%xmm5
+
+// CHECK: pmovsxwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxwd 0x45,%xmm5
+
+// CHECK: pmovsxwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxwd 0x7eed,%xmm5
+
+// CHECK: pmovsxwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxwd 0xbabecafe,%xmm5
+
+// CHECK: pmovsxwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxwd 0x12345678,%xmm5
+
+// CHECK: pmovsxwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0xed]
+ pmovsxwd %xmm5,%xmm5
+
+// CHECK: pmovsxwq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxwq 0x45,%xmm5
+
+// CHECK: pmovsxwq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxwq 0x7eed,%xmm5
+
+// CHECK: pmovsxwq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxwq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxwq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxwq 0x12345678,%xmm5
+
+// CHECK: pmovsxwq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0xed]
+ pmovsxwq %xmm5,%xmm5
+
+// CHECK: pmovsxdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxdq 0x45,%xmm5
+
+// CHECK: pmovsxdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxdq 0x7eed,%xmm5
+
+// CHECK: pmovsxdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxdq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxdq 0x12345678,%xmm5
+
+// CHECK: pmovsxdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0xed]
+ pmovsxdq %xmm5,%xmm5
+
+// CHECK: pmovzxbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxbw 0x45,%xmm5
+
+// CHECK: pmovzxbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxbw 0x7eed,%xmm5
+
+// CHECK: pmovzxbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxbw 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxbw 0x12345678,%xmm5
+
+// CHECK: pmovzxbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0xed]
+ pmovzxbw %xmm5,%xmm5
+
+// CHECK: pmovzxbd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxbd 0x45,%xmm5
+
+// CHECK: pmovzxbd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxbd 0x7eed,%xmm5
+
+// CHECK: pmovzxbd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxbd 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxbd 0x12345678,%xmm5
+
+// CHECK: pmovzxbd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0xed]
+ pmovzxbd %xmm5,%xmm5
+
+// CHECK: pmovzxbq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxbq 0x45,%xmm5
+
+// CHECK: pmovzxbq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxbq 0x7eed,%xmm5
+
+// CHECK: pmovzxbq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxbq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxbq 0x12345678,%xmm5
+
+// CHECK: pmovzxbq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0xed]
+ pmovzxbq %xmm5,%xmm5
+
+// CHECK: pmovzxwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxwd 0x45,%xmm5
+
+// CHECK: pmovzxwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxwd 0x7eed,%xmm5
+
+// CHECK: pmovzxwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxwd 0xbabecafe,%xmm5
+
+// CHECK: pmovzxwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxwd 0x12345678,%xmm5
+
+// CHECK: pmovzxwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0xed]
+ pmovzxwd %xmm5,%xmm5
+
+// CHECK: pmovzxwq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxwq 0x45,%xmm5
+
+// CHECK: pmovzxwq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxwq 0x7eed,%xmm5
+
+// CHECK: pmovzxwq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxwq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxwq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxwq 0x12345678,%xmm5
+
+// CHECK: pmovzxwq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0xed]
+ pmovzxwq %xmm5,%xmm5
+
+// CHECK: pmovzxdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxdq 0x45,%xmm5
+
+// CHECK: pmovzxdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxdq 0x7eed,%xmm5
+
+// CHECK: pmovzxdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxdq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxdq 0x12345678,%xmm5
+
+// CHECK: pmovzxdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0xed]
+ pmovzxdq %xmm5,%xmm5
+
+// CHECK: pmuldq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmuldq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmuldq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0x45,0x00,0x00,0x00]
+ pmuldq 0x45,%xmm5
+
+// CHECK: pmuldq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0xed,0x7e,0x00,0x00]
+ pmuldq 0x7eed,%xmm5
+
+// CHECK: pmuldq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0xfe,0xca,0xbe,0xba]
+ pmuldq 0xbabecafe,%xmm5
+
+// CHECK: pmuldq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0x78,0x56,0x34,0x12]
+ pmuldq 0x12345678,%xmm5
+
+// CHECK: pmuldq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0xed]
+ pmuldq %xmm5,%xmm5
+
+// CHECK: pmulld 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulld 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0x45,0x00,0x00,0x00]
+ pmulld 0x45,%xmm5
+
+// CHECK: pmulld 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0xed,0x7e,0x00,0x00]
+ pmulld 0x7eed,%xmm5
+
+// CHECK: pmulld 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulld 0xbabecafe,%xmm5
+
+// CHECK: pmulld 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0x78,0x56,0x34,0x12]
+ pmulld 0x12345678,%xmm5
+
+// CHECK: pmulld %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0xed]
+ pmulld %xmm5,%xmm5
+
+// CHECK: ptest 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ptest 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ptest 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0x45,0x00,0x00,0x00]
+ ptest 0x45,%xmm5
+
+// CHECK: ptest 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0xed,0x7e,0x00,0x00]
+ ptest 0x7eed,%xmm5
+
+// CHECK: ptest 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0xfe,0xca,0xbe,0xba]
+ ptest 0xbabecafe,%xmm5
+
+// CHECK: ptest 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0x78,0x56,0x34,0x12]
+ ptest 0x12345678,%xmm5
+
+// CHECK: ptest %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0xed]
+ ptest %xmm5,%xmm5
+
+// CHECK: pcmpgtq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtq 0x45,%xmm5
+
+// CHECK: pcmpgtq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtq 0x7eed,%xmm5
+
+// CHECK: pcmpgtq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtq 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtq 0x12345678,%xmm5
+
+// CHECK: pcmpgtq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0xed]
+ pcmpgtq %xmm5,%xmm5
diff --git a/test/MC/AsmParser/X86/x86_32-new-encoder.s b/test/MC/AsmParser/X86/x86_32-new-encoder.s
new file mode 100644
index 0000000..6fd0cbb
--- /dev/null
+++ b/test/MC/AsmParser/X86/x86_32-new-encoder.s
@@ -0,0 +1,41 @@
+// RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck %s
+
+ lfence
+// CHECK: lfence
+// CHECK: encoding: [0x0f,0xae,0xe8]
+ mfence
+// CHECK: mfence
+// CHECK: encoding: [0x0f,0xae,0xf0]
+ monitor
+// CHECK: monitor
+// CHECK: encoding: [0x0f,0x01,0xc8]
+ mwait
+// CHECK: mwait
+// CHECK: encoding: [0x0f,0x01,0xc9]
+
+ vmcall
+// CHECK: vmcall
+// CHECK: encoding: [0x0f,0x01,0xc1]
+ vmlaunch
+// CHECK: vmlaunch
+// CHECK: encoding: [0x0f,0x01,0xc2]
+ vmresume
+// CHECK: vmresume
+// CHECK: encoding: [0x0f,0x01,0xc3]
+ vmxoff
+// CHECK: vmxoff
+// CHECK: encoding: [0x0f,0x01,0xc4]
+ swapgs
+// CHECK: swapgs
+// CHECK: encoding: [0x0f,0x01,0xf8]
+
+rdtscp
+// CHECK: rdtscp
+// CHECK: encoding: [0x0f,0x01,0xf9]
+
+
+// CHECK: movl %eax, 16(%ebp) # encoding: [0x89,0x45,0x10]
+ movl %eax, 16(%ebp)
+// CHECK: movl %eax, -16(%ebp) # encoding: [0x89,0x45,0xf0]
+ movl %eax, -16(%ebp)
+
diff --git a/test/MC/AsmParser/X86/x86_64-new-encoder.s b/test/MC/AsmParser/X86/x86_64-new-encoder.s
new file mode 100644
index 0000000..56ec0b3
--- /dev/null
+++ b/test/MC/AsmParser/X86/x86_64-new-encoder.s
@@ -0,0 +1,26 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding %s | FileCheck %s
+
+movl foo(%rip), %eax
+// CHECK: movl foo(%rip), %eax
+// CHECK: encoding: [0x8b,0x05,A,A,A,A]
+// CHECK: fixup A - offset: 2, value: foo-4, kind: reloc_riprel_4byte
+
+movb $12, foo(%rip)
+// CHECK: movb $12, foo(%rip)
+// CHECK: encoding: [0xc6,0x05,A,A,A,A,0x0c]
+// CHECK: fixup A - offset: 2, value: foo-5, kind: reloc_riprel_4byte
+
+movw $12, foo(%rip)
+// CHECK: movw $12, foo(%rip)
+// CHECK: encoding: [0x66,0xc7,0x05,A,A,A,A,0x0c,0x00]
+// CHECK: fixup A - offset: 3, value: foo-6, kind: reloc_riprel_4byte
+
+movl $12, foo(%rip)
+// CHECK: movl $12, foo(%rip)
+// CHECK: encoding: [0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
+// CHECK: fixup A - offset: 2, value: foo-8, kind: reloc_riprel_4byte
+
+movq $12, foo(%rip)
+// CHECK: movq $12, foo(%rip)
+// CHECK: encoding: [0x48,0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
+// CHECK: fixup A - offset: 3, value: foo-8, kind: reloc_riprel_4byte
diff --git a/test/MC/AsmParser/X86/x86_instructions.s b/test/MC/AsmParser/X86/x86_instructions.s
index a74dcd2..b558c2e 100644
--- a/test/MC/AsmParser/X86/x86_instructions.s
+++ b/test/MC/AsmParser/X86/x86_instructions.s
@@ -109,31 +109,31 @@
repne;scasb
// CHECK: lock
-// CHECK: cmpxchgb %al, 0(%ebx)
+// CHECK: cmpxchgb %al, (%ebx)
lock;cmpxchgb %al, 0(%ebx)
// CHECK: cs
-// CHECK: movb 0(%eax), %al
+// CHECK: movb (%eax), %al
cs;movb 0(%eax), %al
// CHECK: ss
-// CHECK: movb 0(%eax), %al
+// CHECK: movb (%eax), %al
ss;movb 0(%eax), %al
// CHECK: ds
-// CHECK: movb 0(%eax), %al
+// CHECK: movb (%eax), %al
ds;movb 0(%eax), %al
// CHECK: es
-// CHECK: movb 0(%eax), %al
+// CHECK: movb (%eax), %al
es;movb 0(%eax), %al
// CHECK: fs
-// CHECK: movb 0(%eax), %al
+// CHECK: movb (%eax), %al
fs;movb 0(%eax), %al
// CHECK: gs
-// CHECK: movb 0(%eax), %al
+// CHECK: movb (%eax), %al
gs;movb 0(%eax), %al
// CHECK: fadd %st(0)
diff --git a/test/MC/AsmParser/X86/x86_operands.s b/test/MC/AsmParser/X86/x86_operands.s
index 433c9bf..edddd1f 100644
--- a/test/MC/AsmParser/X86/x86_operands.s
+++ b/test/MC/AsmParser/X86/x86_operands.s
@@ -5,28 +5,28 @@
# Immediates
# CHECK: addl $1, %eax
addl $1, %eax
-# CHECK: addl $1+2, %eax
+# CHECK: addl $3, %eax
addl $(1+2), %eax
# CHECK: addl $a, %eax
addl $a, %eax
-# CHECK: addl $1+2, %eax
+# CHECK: addl $3, %eax
addl $1 + 2, %eax
# Disambiguation
- # FIXME: Add back when we can match this.
- #addl $1, 4+4
- # FIXME: Add back when we can match this.
- #addl $1, (4+4)
-# CHECK: addl $1, 4+4(%eax)
+# CHECK: addl $1, 8
+ addl $1, 4+4
+# CHECK: addl $1, 8
+ addl $1, (4+4)
+# CHECK: addl $1, 8(%eax)
addl $1, 4+4(%eax)
-# CHECK: addl $1, 4+4(%eax)
+# CHECK: addl $1, 8(%eax)
addl $1, (4+4)(%eax)
# CHECK: addl $1, 8(%eax)
addl $1, 8(%eax)
-# CHECK: addl $1, 0(%eax)
+# CHECK: addl $1, (%eax)
addl $1, (%eax)
-# CHECK: addl $1, 4+4(,%eax)
+# CHECK: addl $1, 8(,%eax)
addl $1, (4+4)(,%eax)
# Indirect Memory Operands
diff --git a/test/MC/AsmParser/conditional_asm.s b/test/MC/AsmParser/conditional_asm.s
index b8a514f..f619ef9 100644
--- a/test/MC/AsmParser/conditional_asm.s
+++ b/test/MC/AsmParser/conditional_asm.s
@@ -1,6 +1,6 @@
# RUN: llvm-mc -triple i386-unknown-unknown %s -I %p | FileCheck %s
-# CHECK: .byte 1+1
+# CHECK: .byte 2
.if 1+2
.if 1-1
.byte 1
diff --git a/test/MC/Disassembler/simple-tests.txt b/test/MC/Disassembler/simple-tests.txt
index 1e3249f..11c077d 100644
--- a/test/MC/Disassembler/simple-tests.txt
+++ b/test/MC/Disassembler/simple-tests.txt
@@ -13,3 +13,32 @@
# CHECK: callq -1234
0xe8 0x2e 0xfb 0xff 0xff
+# CHECK: lfence
+0x0f 0xae 0xe8
+
+# CHECK: mfence
+0x0f 0xae 0xf0
+
+# CHECK: monitor
+0x0f 0x01 0xc8
+
+# CHECK: mwait
+0x0f 0x01 0xc9
+
+# CHECK: vmcall
+0x0f 0x01 0xc1
+
+# CHECK: vmlaunch
+0x0f 0x01 0xc2
+
+# CHECK: vmresume
+0x0f 0x01 0xc3
+
+# CHECK: vmxoff
+0x0f 0x01 0xc4
+
+# CHECK: swapgs
+0x0f 0x01 0xf8
+
+# CHECK: rdtscp
+0x0f 0x01 0xf9 \ No newline at end of file
diff --git a/test/MC/MachO/Darwin/optimal_nop.s b/test/MC/MachO/Darwin/optimal_nop.s
new file mode 100644
index 0000000..29cb073
--- /dev/null
+++ b/test/MC/MachO/Darwin/optimal_nop.s
@@ -0,0 +1,156 @@
+// Validate that we can assemble this file exactly like the platform
+// assembler.
+//
+// RUN: llvm-mc -filetype=obj -triple i386-apple-darwin10 -o %t.mc.o %s
+// RUN: as -arch i386 -o %t.as.o %s
+// RUN: diff %t.mc.o %t.as.o
+
+# 1 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ # nop
+ # 0x90
+ .align 1, 0x90
+ ret
+# 2 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ # xchg %ax,%ax
+ # 0x66, 0x90
+ .align 2, 0x90
+ ret
+# 3 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ # nopl (%[re]ax)
+ # 0x0f, 0x1f, 0x00
+ .align 2, 0x90
+ ret
+# 4 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ ret
+ # nopl 0(%[re]ax)
+ # 0x0f, 0x1f, 0x40, 0x00
+ .align 3, 0x90
+ ret
+# 5 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ # nopl 0(%[re]ax,%[re]ax,1)
+ # 0x0f, 0x1f, 0x44, 0x00, 0x00
+ .align 3, 0x90
+ ret
+# 6 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ # nopw 0(%[re]ax,%[re]ax,1)
+ # 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
+ .align 3, 0x90
+ ret
+# 7 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ # nopl 0L(%[re]ax)
+ # 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00
+ .align 3, 0x90
+ ret
+# 8 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ # nopl 0L(%[re]ax,%[re]ax,1)
+ # 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
+ .align 3, 0x90
+ ret
+# 9 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ # nopw 0L(%[re]ax,%[re]ax,1)
+ # 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
+ .align 4, 0x90
+ ret
+# 10 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ # nopw %cs:0L(%[re]ax,%[re]ax,1)
+ # 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
+ .align 4, 0x90
+ ret
+# 11 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ ret
+ ret
+ # nopw %cs:0L(%[re]ax,%[re]ax,1)
+ # 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
+ .align 4, 0x90
+ ret
+# 12 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ ret
+ # nopw 0(%[re]ax,%[re]ax,1)
+ # nopw 0(%[re]ax,%[re]ax,1)
+ # 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
+ # 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
+ .align 4, 0x90
+ ret
+# 13 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ ret
+ # nopw 0(%[re]ax,%[re]ax,1)
+ # nopl 0L(%[re]ax)
+ # 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
+ # 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00
+ .align 4, 0x90
+ ret
+# 14 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ ret
+ # nopl 0L(%[re]ax)
+ # nopl 0L(%[re]ax)
+ # 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
+ # 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00
+ .align 4, 0x90
+ ret
+# 15 byte nop test
+ .align 4, 0 # start with 16 byte alignment filled with zeros
+ ret
+ # nopl 0L(%[re]ax)
+ # nopl 0L(%[re]ax,%[re]ax,1)
+ # 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
+ # 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
+ .align 4, 0x90
+ ret
diff --git a/test/Makefile b/test/Makefile
index e7776f8..3750fdb 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -155,7 +155,6 @@ site.exp: FORCE
@echo 'set target_triplet "$(TARGET_TRIPLE)"' >> site.tmp
@echo 'set TARGETS_TO_BUILD "$(TARGETS_TO_BUILD)"' >> site.tmp
@echo 'set llvmgcc_langs "$(LLVMGCC_LANGS)"' >> site.tmp
- @echo 'set llvmgcc_version "$(LLVMGCC_VERSION)"' >> site.tmp
@echo 'set llvmtoolsdir "$(ToolDir)"' >>site.tmp
@echo 'set llvmlibsdir "$(LibDir)"' >>site.tmp
@echo 'set llvm_bindings "$(BINDINGS_TO_BUILD)"' >> site.tmp
@@ -170,7 +169,6 @@ site.exp: FORCE
@echo 'set link "' $(CXX) $(CPP.Flags) $(CXX.Flags) $(TargetCommonOpts) $(CompileCommonOpts) $(LD.Flags) '"' >>site.tmp
@echo 'set llvmgcc "$(LLVMGCC) $(TargetCommonOpts) $(EXTRA_OPTIONS)"' >> site.tmp
@echo 'set llvmgxx "$(LLVMGCC) $(TargetCommonOpts) $(EXTRA_OPTIONS)"' >> site.tmp
- @echo 'set llvmgccmajvers "$(LLVMGCC_MAJVERS)"' >> site.tmp
@echo 'set bugpoint_topts $(BUGPOINT_TOPTS)' >> site.tmp
@echo 'set shlibext "$(SHLIBEXT)"' >> site.tmp
@echo 'set ocamlopt "$(OCAMLOPT) -cc \"$(CXX_FOR_OCAMLOPT)\" -I $(LibDir)/ocaml"' >> site.tmp
@@ -200,4 +198,6 @@ Unit/lit.site.cfg: $(PROJ_OBJ_DIR)/Unit/.dir FORCE
-e "s#@LLVM_TOOLS_DIR@#$(ToolDir)#g" \
-e "s#@LLVMGCCDIR@#$(LLVMGCCDIR)#g" \
-e "s#@LLVM_BUILD_MODE@#$(BuildMode)#g" \
+ -e "s#@ENABLE_SHARED@#$(ENABLE_SHARED)#g" \
+ -e "s#@SHLIBPATH_VAR@#$(SHLIBPATH_VAR)#g" \
$(PROJ_SRC_DIR)/Unit/lit.site.cfg.in > $@
diff --git a/test/Makefile.tests b/test/Makefile.tests
index 90e9f2c..aeb5871 100644
--- a/test/Makefile.tests
+++ b/test/Makefile.tests
@@ -49,15 +49,15 @@ clean::
# Compile from X.c to Output/X.ll
Output/%.ll: %.c $(LCC1) Output/.dir $(INCLUDES)
- -$(LLVMGCCWITHPATH) $(CPPFLAGS) $(LCCFLAGS) -S $< -o $@
+ -$(LLVMCC) $(CPPFLAGS) $(LCCFLAGS) -S $< -o $@
# Compile from X.cpp to Output/X.ll
Output/%.ll: %.cpp $(LCC1XX) Output/.dir $(INCLUDES)
- -$(LLVMGXXWITHPATH) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+ -$(LLVMCXX) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
# Compile from X.cc to Output/X.ll
Output/%.ll: %.cc $(LCC1XX) Output/.dir $(INCLUDES)
- -$(LLVMGXXWITHPATH) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+ -$(LLVMCXX) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
# LLVM Assemble from Output/X.ll to Output/X.bc. Output/X.ll must have come
# from GCC output, so use GCCAS.
diff --git a/test/Other/2008-03-19-PassManager.ll b/test/Other/2008-03-19-PassManager.ll
deleted file mode 100644
index e208222..0000000
--- a/test/Other/2008-03-19-PassManager.ll
+++ /dev/null
@@ -1,58 +0,0 @@
-; PR 2034
-; RUN: opt < %s -anders-aa -instcombine -gvn -disable-output
- %struct.FULL = type { i32, i32, [1000 x float*] }
-
-define i32 @sgesl(%struct.FULL* %a, i32* %ipvt, float* %b, i32 %job) {
-entry:
- %a_addr = alloca %struct.FULL* ; <%struct.FULL**> [#uses=1]
- %ipvt_addr = alloca i32* ; <i32**> [#uses=1]
- %b_addr = alloca float* ; <float**> [#uses=1]
- %job_addr = alloca i32 ; <i32*> [#uses=1]
- %akk = alloca float* ; <float**> [#uses=2]
- %k = alloca i32 ; <i32*> [#uses=1]
- %l = alloca i32 ; <i32*> [#uses=1]
- %n = alloca i32 ; <i32*> [#uses=1]
- %nm1 = alloca i32 ; <i32*> [#uses=1]
- %tmp5 = load i32* %job_addr, align 4 ; <i32> [#uses=1]
- %tmp6 = icmp eq i32 %tmp5, 0 ; <i1> [#uses=1]
- %tmp67 = zext i1 %tmp6 to i8 ; <i8> [#uses=1]
- %toBool = icmp ne i8 %tmp67, 0 ; <i1> [#uses=1]
- br i1 %toBool, label %cond_true, label %cond_next137
-
-cond_true: ; preds = %entry
- %tmp732 = load i32* %nm1, align 4 ; <i32> [#uses=1]
- %tmp743 = icmp slt i32 0, %tmp732 ; <i1> [#uses=1]
- %tmp74754 = zext i1 %tmp743 to i8 ; <i8> [#uses=1]
- %toBool765 = icmp ne i8 %tmp74754, 0 ; <i1> [#uses=1]
- br i1 %toBool765, label %bb, label %bb77
-
-bb: ; preds = %cond_true
- %tmp9 = load %struct.FULL** %a_addr, align 4 ; <%struct.FULL*> [#uses=1]
- %tmp10 = getelementptr %struct.FULL* %tmp9, i32 0, i32 2 ; <[1000 x float*]*> [#uses=1]
- %tmp11 = getelementptr [1000 x float*]* %tmp10, i32 0, i32 0 ; <float**> [#uses=1]
- %tmp12 = load float** %tmp11, align 4 ; <float*> [#uses=1]
- %tmp13 = load i32* %k, align 4 ; <i32> [#uses=1]
- %tmp14 = getelementptr float* %tmp12, i32 %tmp13 ; <float*> [#uses=1]
- store float* %tmp14, float** %akk, align 4
- %tmp17 = load float** %b_addr, align 4 ; <float*> [#uses=0]
- %tmp18 = load i32* %l, align 4 ; <i32> [#uses=0]
- ret i32 0
-
-bb77: ; preds = %cond_true
- ret i32 0
-
-cond_next137: ; preds = %entry
- %tmp18922 = load i32* %n, align 4 ; <i32> [#uses=1]
- %tmp19023 = icmp slt i32 0, %tmp18922 ; <i1> [#uses=1]
- %tmp19019124 = zext i1 %tmp19023 to i8 ; <i8> [#uses=1]
- %toBool19225 = icmp ne i8 %tmp19019124, 0 ; <i1> [#uses=1]
- br i1 %toBool19225, label %bb138, label %bb193
-
-bb138: ; preds = %cond_next137
- store float* null, float** %akk, align 4
- ret i32 0
-
-bb193: ; preds = %cond_next137
- %tmp196 = load i32** %ipvt_addr, align 4 ; <i32*> [#uses=0]
- ret i32 0
-}
diff --git a/test/Other/constant-fold-gep.ll b/test/Other/constant-fold-gep.ll
index 2888b3d..5358e1f 100644
--- a/test/Other/constant-fold-gep.ll
+++ b/test/Other/constant-fold-gep.ll
@@ -69,6 +69,8 @@
; PLAIN: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; PLAIN: @j = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; PLAIN: @k = constant i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
; OPT: @a = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
; OPT: @b = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; OPT: @c = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
@@ -78,6 +80,8 @@
; OPT: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
; OPT: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
; OPT: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; OPT: @j = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; OPT: @k = constant i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
; TO: @a = constant i64 18480
; TO: @b = constant i64 8
; TO: @c = constant i64 16
@@ -87,6 +91,8 @@
; TO: @g = constant i64 8
; TO: @h = constant i64 8
; TO: @i = constant i64 8
+; TO: @j = constant i64 8
+; TO: @k = constant i64 8
@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
@b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}* null, i64 0, i32 1) to i64)
@@ -97,6 +103,8 @@
@g = constant i64 ptrtoint ({double, double}* getelementptr ({i1, {double, double}}* null, i64 0, i32 1) to i64)
@h = constant i64 ptrtoint (double** getelementptr (double** null, i64 1) to i64)
@i = constant i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64)
+@j = constant i64 ptrtoint (union {double, double}* getelementptr ({i1, union {double, double}}* null, i64 0, i32 1) to i64)
+@k = constant i64 ptrtoint (union {double, double}* getelementptr (union {double, double}* null, i64 1) to i64)
; The target-dependent folder should cast GEP indices to integer-sized pointers.
@@ -244,15 +252,23 @@ define i1* @hoo1() nounwind {
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fg() nounwind {
-; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fh() nounwind {
-; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
+; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; PLAIN: define i64 @fi() nounwind {
-; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64) to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fj() nounwind {
+; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fk() nounwind {
+; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; OPT: define i64 @fa() nounwind {
@@ -282,6 +298,12 @@ define i1* @hoo1() nounwind {
; OPT: define i64 @fi() nounwind {
; OPT: ret i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
; OPT: }
+; OPT: define i64 @fj() nounwind {
+; OPT: ret i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; OPT: }
+; OPT: define i64 @fk() nounwind {
+; OPT: ret i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64)
+; OPT: }
; TO: define i64 @fa() nounwind {
; TO: ret i64 18480
; TO: }
@@ -309,6 +331,12 @@ define i1* @hoo1() nounwind {
; TO: define i64 @fi() nounwind {
; TO: ret i64 8
; TO: }
+; TO: define i64 @fj() nounwind {
+; TO: ret i64 8
+; TO: }
+; TO: define i64 @fk() nounwind {
+; TO: ret i64 8
+; TO: }
; SCEV: Classifying expressions for: @fa
; SCEV: %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310) to i64
; SCEV: --> (2310 * sizeof(double))
@@ -328,14 +356,20 @@ define i1* @hoo1() nounwind {
; SCEV: %t = bitcast i64 1 to i64
; SCEV: --> 1
; SCEV: Classifying expressions for: @fg
-; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
; SCEV: --> alignof(double)
; SCEV: Classifying expressions for: @fh
-; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
+; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64) to i64
; SCEV: --> sizeof(i1*)
; SCEV: Classifying expressions for: @fi
-; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64) to i64
; SCEV: --> alignof(i1*)
+; SCEV: Classifying expressions for: @fj
+; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
+; SCEV: --> alignof(double)
+; SCEV: Classifying expressions for: @fk
+; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64) to i64
+; SCEV: --> sizeof(double)
define i64 @fa() nounwind {
%t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5)) to i64
@@ -373,6 +407,14 @@ define i64 @fi() nounwind {
%t = bitcast i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64) to i64
ret i64 %t
}
+define i64 @fj() nounwind {
+ %t = bitcast i64 ptrtoint (union {double, double}* getelementptr ({i1, union {double, double}}* null, i64 0, i32 1) to i64) to i64
+ ret i64 %t
+}
+define i64 @fk() nounwind {
+ %t = bitcast i64 ptrtoint (union {double, double}* getelementptr (union {double, double}* null, i64 1) to i64) to i64
+ ret i64 %t
+}
; PLAIN: define i64* @fM() nounwind {
; PLAIN: %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
diff --git a/test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll b/test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll
deleted file mode 100644
index cea18a0..0000000
--- a/test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: opt < %s -constmerge -S | grep foo
-; RUN: opt < %s -constmerge -S | grep bar
-
-; Don't merge constants in different sections.
-
-@G1 = internal constant i32 1, section "foo" ; <i32*> [#uses=1]
-@G2 = internal constant i32 1, section "bar" ; <i32*> [#uses=1]
-@G3 = internal constant i32 1, section "bar" ; <i32*> [#uses=1]
-
-define void @test(i32** %P1, i32** %P2, i32** %P3) {
- store i32* @G1, i32** %P1
- store i32* @G2, i32** %P2
- store i32* @G3, i32** %P3
- ret void
-}
-
diff --git a/test/Transforms/ConstantMerge/dont-merge.ll b/test/Transforms/ConstantMerge/dont-merge.ll
new file mode 100644
index 0000000..877cf8d
--- /dev/null
+++ b/test/Transforms/ConstantMerge/dont-merge.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -constmerge -S | FileCheck %s
+
+; Don't merge constants with specified sections.
+
+@T1G1 = internal constant i32 1, section "foo"
+@T1G2 = internal constant i32 1, section "bar"
+@T1G3 = internal constant i32 1, section "bar"
+
+; CHECK: @T1G1
+; CHECK: @T1G2
+; CHECK: @T1G3
+
+define void @test1(i32** %P1, i32** %P2, i32** %P3) {
+ store i32* @T1G1, i32** %P1
+ store i32* @T1G2, i32** %P2
+ store i32* @T1G3, i32** %P3
+ ret void
+}
+
+@T2a = internal constant i32 224
+@T2b = internal addrspace(30) constant i32 224
+
+; CHECK: @T2a
+; CHECK: @T2b
+
+define void @test2(i32** %P1, i32 addrspace(30)** %P2) {
+ store i32* @T2a, i32** %P1
+ store i32 addrspace(30)* @T2b, i32 addrspace(30)** %P2
+ ret void
+}
diff --git a/test/Transforms/DeadStoreElimination/crash.ll b/test/Transforms/DeadStoreElimination/crash.ll
index f89f8f5..6d8ba71 100644
--- a/test/Transforms/DeadStoreElimination/crash.ll
+++ b/test/Transforms/DeadStoreElimination/crash.ll
@@ -41,3 +41,17 @@ bb14: ; preds = %bb4
}
declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
+
+
+; rdar://7635088
+define i32 @test3() {
+entry:
+ ret i32 0
+
+dead:
+ %P2 = getelementptr i32 *%P2, i32 52
+ %Q2 = getelementptr i32 *%Q2, i32 52
+ store i32 4, i32* %P2
+ store i32 4, i32* %Q2
+ br label %dead
+} \ No newline at end of file
diff --git a/test/Transforms/GVN/2008-02-13-NewPHI.ll b/test/Transforms/GVN/2008-02-13-NewPHI.ll
index 54998db..80b519d 100644
--- a/test/Transforms/GVN/2008-02-13-NewPHI.ll
+++ b/test/Transforms/GVN/2008-02-13-NewPHI.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -anders-aa -gvn
+; RUN: opt < %s -gvn
; PR2032
define i32 @sscal(i32 %n, double %sa1, float* %sx, i32 %incx) {
diff --git a/test/Transforms/GVN/2009-03-05-dbg.ll b/test/Transforms/GVN/2009-03-05-dbg.ll
deleted file mode 100644
index cad3312..0000000
--- a/test/Transforms/GVN/2009-03-05-dbg.ll
+++ /dev/null
@@ -1,66 +0,0 @@
-; RUN: opt < %s -gvn -disable-output
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
-@llvm.dbg.compile_unit298 = external constant %llvm.dbg.compile_unit.type ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-define i8* @__deregister_frame_info_bases(i8* %begin) {
-entry:
- br i1 false, label %bb17, label %bb
-
-bb: ; preds = %entry
- br i1 false, label %bb17, label %bb6.preheader
-
-bb6.preheader: ; preds = %bb
- br label %bb6
-
-bb3: ; preds = %bb6
- br i1 false, label %bb4, label %bb6
-
-bb4: ; preds = %bb3
- br label %out
-
-bb6: ; preds = %bb3, %bb6.preheader
- br i1 false, label %bb14.loopexit, label %bb3
-
-bb8: ; preds = %bb14
- br i1 false, label %bb9, label %bb11
-
-bb9: ; preds = %bb8
- br i1 false, label %bb10, label %bb13
-
-bb10: ; preds = %bb9
- br label %out
-
-bb11: ; preds = %bb8
- br i1 false, label %bb12, label %bb13
-
-bb12: ; preds = %bb11
- br label %out
-
-bb13: ; preds = %bb11, %bb9
- br label %bb14
-
-bb14.loopexit: ; preds = %bb6
- br label %bb14
-
-bb14: ; preds = %bb14.loopexit, %bb13
- br i1 false, label %bb15.loopexit, label %bb8
-
-out: ; preds = %bb12, %bb10, %bb4
- tail call void @llvm.dbg.stoppoint(i32 217, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit298 to { }*))
- br i1 false, label %bb15, label %bb16
-
-bb15.loopexit: ; preds = %bb14
- br label %bb15
-
-bb15: ; preds = %bb15.loopexit, %out
- tail call void @llvm.dbg.stoppoint(i32 217, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit298 to { }*))
- unreachable
-
-bb16: ; preds = %out
- ret i8* null
-
-bb17: ; preds = %bb, %entry
- ret i8* null
-}
diff --git a/test/Transforms/GVN/crash.ll b/test/Transforms/GVN/crash.ll
index 9167b6e..4a3aa1c 100644
--- a/test/Transforms/GVN/crash.ll
+++ b/test/Transforms/GVN/crash.ll
@@ -5,7 +5,7 @@
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"
target triple = "x86_64-apple-darwin10.0"
-define i32* @peel_to_type(i8* %name, i32 %namelen, i32* %o, i32 %expected_type) nounwind ssp {
+define i32* @test1(i8* %name, i32 %namelen, i32* %o, i32 %expected_type) nounwind ssp {
entry:
br i1 undef, label %if.end13, label %while.body.preheader
@@ -69,7 +69,7 @@ declare i32* @parse_object(i8*)
@attribute_tables = external global [4 x %struct.attribute_spec*] ; <[4 x %struct.attribute_spec*]*> [#uses=2]
-define void @decl_attributes() nounwind {
+define void @test2() nounwind {
entry:
br label %bb69.i
@@ -99,7 +99,7 @@ bb66.i: ; Unreachable
@g = external global i64, align 8
-define i32* @foo() {
+define i32* @test3() {
do.end17.i:
%tmp18.i = load i7** undef
%tmp1 = bitcast i7* %tmp18.i to i8*
@@ -135,3 +135,19 @@ do.body57.i:
declare i32 @foo2()
+
+
+define i32 @test4() {
+entry:
+ ret i32 0
+
+dead:
+ %P2 = getelementptr i32 *%P2, i32 52
+ %Q2 = getelementptr i32 *%Q2, i32 52
+ store i32 4, i32* %P2
+ %A = load i32* %Q2
+ br i1 true, label %dead, label %dead2
+
+dead2:
+ ret i32 %A
+}
diff --git a/test/Transforms/GVN/pre-load.ll b/test/Transforms/GVN/pre-load.ll
index 7047d4e..d40a467 100644
--- a/test/Transforms/GVN/pre-load.ll
+++ b/test/Transforms/GVN/pre-load.ll
@@ -362,3 +362,30 @@ bb:
return:
ret void
}
+
+; Test critical edge splitting.
+define i32 @test11(i32* %p, i1 %C, i32 %N) {
+; CHECK: @test11
+block1:
+ br i1 %C, label %block2, label %block3
+
+block2:
+ %cond = icmp sgt i32 %N, 1
+ br i1 %cond, label %block4, label %block5
+; CHECK: load i32* %p
+; CHECK-NEXT: br label %block4
+
+block3:
+ store i32 0, i32* %p
+ br label %block4
+
+block4:
+ %PRE = load i32* %p
+ br label %block5
+
+block5:
+ %ret = phi i32 [ 0, %block2 ], [ %PRE, %block4 ]
+ ret i32 %ret
+; CHECK: block4:
+; CHECK-NEXT: phi i32
+}
diff --git a/test/Transforms/GlobalOpt/2009-03-03-dbg.ll b/test/Transforms/GlobalOpt/2009-03-03-dbg.ll
deleted file mode 100644
index 070f89f..0000000
--- a/test/Transforms/GlobalOpt/2009-03-03-dbg.ll
+++ /dev/null
@@ -1,54 +0,0 @@
-; RUN: opt < %s -globalopt -S | not grep global_variable42
-; XFAIL: *
-
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i32 }
- %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
- %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.subrange.type = type { i32, i64, i64 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str2 = internal constant [57 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 2099)\00", section "llvm.metadata" ; <[57 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([57 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str4 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str5 = internal constant [6 x i8] c"i_ptr\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([6 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 5, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=0]
-@sillyArray.1433 = internal global [8 x i32] [ i32 2, i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19 ] ; <[8 x i32]*> [#uses=1]
-@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type { i32 458785, i64 0, i64 7 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1]
-@llvm.dbg.array6 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1]
-@llvm.dbg.composite7 = internal constant %llvm.dbg.composite.type { i32 458753, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 256, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast ([1 x { }*]* @llvm.dbg.array6 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str8 = internal constant [16 x i8] c"sillyArray.1433\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str9 = internal constant [11 x i8] c"sillyArray\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.global_variable42 = internal constant %llvm.dbg.global_variable.type { i32 458804, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([16 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str9, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite7 to { }*), i1 true, i1 true, { }* bitcast ([8 x i32]* @sillyArray.1433 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0]
-
-define i32 @main() nounwind {
-entry:
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.stoppoint(i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.stoppoint(i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- ret i32 0
-}
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.declare({ }*, { }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @llvm.dbg.region.end({ }*) nounwind
diff --git a/test/Transforms/GlobalOpt/2009-03-05-dbg.ll b/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
index a5f9ed3..3154856 100644
--- a/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
+++ b/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
@@ -1,67 +1,76 @@
; RUN: opt < %s -globalopt -stats -disable-output |& grep "1 globalopt - Number of global vars shrunk to booleans"
-; XFAIL: *
- type { } ; type %0
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, %0*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0*, %0*, i32 }
- %llvm.dbg.global_variable.type = type { i32, %0*, %0*, i8*, i8*, i8*, %0*, i32, %0*, i1, i1, %0* }
- %llvm.dbg.subprogram.type = type { i32, %0*, %0*, i8*, i8*, i8*, %0*, i32, %0*, i1, i1 }
- %llvm.dbg.variable.type = type { i32, %0*, i8*, %0*, i32, %0* }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [5 x i8] c"gs.c\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5641) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 1, i8* getelementptr ([5 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str4 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 4, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str5 = internal constant [2 x i8] c"i\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %0*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 4, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@Stop = internal global i32 0 ; <i32*> [#uses=4]
-@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str6 = internal constant [5 x i8] c"Stop\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type { i32 458804, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 2, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*), i1 true, i1 true, %0* bitcast (i32* @Stop to %0*) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0]
+@Stop = internal global i32 0 ; <i32*> [#uses=3]
-define i32 @foo(i32 %i) nounwind {
+define i32 @foo(i32 %i) nounwind ssp {
entry:
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %0*))
- call void @llvm.dbg.stoppoint(i32 5, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = load i32* @Stop, align 4 ; <i32> [#uses=1]
- %1 = icmp eq i32 %0, 1 ; <i1> [#uses=1]
- br i1 %1, label %bb, label %bb1
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !3)
+ %0 = icmp eq i32 %i, 1, !dbg !7 ; <i1> [#uses=1]
+ br i1 %0, label %bb, label %bb1, !dbg !7
-bb: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 6, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- store i32 0, i32* @Stop, align 4
- call void @llvm.dbg.stoppoint(i32 7, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %2 = mul i32 %i, 42 ; <i32> [#uses=1]
- br label %bb2
+bb: ; preds = %entry
+ store i32 0, i32* @Stop, align 4, !dbg !9
+ %1 = mul nsw i32 %i, 42, !dbg !10 ; <i32> [#uses=1]
+ call void @llvm.dbg.value(metadata !{i32 %1}, i64 0, metadata !3), !dbg !10
+ br label %bb2, !dbg !10
-bb1: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 9, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- store i32 1, i32* @Stop, align 4
- call void @llvm.dbg.stoppoint(i32 10, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb2
+bb1: ; preds = %entry
+ store i32 1, i32* @Stop, align 4, !dbg !11
+ br label %bb2, !dbg !11
-bb2: ; preds = %bb1, %bb
- %.0 = phi i32 [ %i, %bb1 ], [ %2, %bb ] ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 10, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.stoppoint(i32 10, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %0*))
- ret i32 %.0
+bb2: ; preds = %bb1, %bb
+ %i_addr.0 = phi i32 [ %1, %bb ], [ %i, %bb1 ] ; <i32> [#uses=1]
+ br label %return, !dbg !12
+
+return: ; preds = %bb2
+ ret i32 %i_addr.0, !dbg !12
}
-declare void @llvm.dbg.func.start(%0*) nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+define i32 @bar() nounwind ssp {
+entry:
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ %0 = load i32* @Stop, align 4, !dbg !13 ; <i32> [#uses=1]
+ %1 = icmp eq i32 %0, 1, !dbg !13 ; <i1> [#uses=1]
+ br i1 %1, label %bb, label %bb1, !dbg !13
+
+bb: ; preds = %entry
+ br label %bb2, !dbg !18
+
+bb1: ; preds = %entry
+ br label %bb2, !dbg !19
+
+bb2: ; preds = %bb1, %bb
+ %.0 = phi i32 [ 0, %bb ], [ 1, %bb1 ] ; <i32> [#uses=1]
+ br label %return, !dbg !19
+
+return: ; preds = %bb2
+ ret i32 %.0, !dbg !19
+}
-declare void @llvm.dbg.declare(%0*, %0*) nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
-declare void @llvm.dbg.stoppoint(i32, i32, %0*) nounwind readnone
+!llvm.dbg.gv = !{!0}
-declare void @llvm.dbg.region.end(%0*) nounwind readnone
+!0 = metadata !{i32 458804, i32 0, metadata !1, metadata !"Stop", metadata !"Stop", metadata !"", metadata !1, i32 2, metadata !2, i1 true, i1 true, i32* @Stop} ; [ DW_TAG_variable ]
+!1 = metadata !{i32 458769, i32 0, i32 1, metadata !"g.c", metadata !"/tmp", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!2 = metadata !{i32 458788, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+!3 = metadata !{i32 459009, metadata !4, metadata !"i", metadata !1, i32 4, metadata !2} ; [ DW_TAG_arg_variable ]
+!4 = metadata !{i32 458798, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 4, metadata !5, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
+!5 = metadata !{i32 458773, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !6, i32 0, null} ; [ DW_TAG_subroutine_type ]
+!6 = metadata !{metadata !2, metadata !2}
+!7 = metadata !{i32 5, i32 0, metadata !8, null}
+!8 = metadata !{i32 458763, metadata !4, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!9 = metadata !{i32 6, i32 0, metadata !8, null}
+!10 = metadata !{i32 7, i32 0, metadata !8, null}
+!11 = metadata !{i32 9, i32 0, metadata !8, null}
+!12 = metadata !{i32 11, i32 0, metadata !8, null}
+!13 = metadata !{i32 14, i32 0, metadata !14, null}
+!14 = metadata !{i32 458763, metadata !15, i32 0, i32 0} ; [ DW_TAG_lexical_block ]
+!15 = metadata !{i32 458798, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"bar", metadata !1, i32 13, metadata !16, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
+!16 = metadata !{i32 458773, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !17, i32 0, null} ; [ DW_TAG_subroutine_type ]
+!17 = metadata !{metadata !2}
+!18 = metadata !{i32 15, i32 0, metadata !14, null}
+!19 = metadata !{i32 16, i32 0, metadata !14, null}
diff --git a/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll b/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll
new file mode 100644
index 0000000..27352fa
--- /dev/null
+++ b/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll
@@ -0,0 +1,18 @@
+; PR6422
+; RUN: opt -globalopt -S %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"
+target triple = "x86_64-unknown-linux-gnu"
+
+@fixLRBT = internal global i32* null ; <i32**> [#uses=2]
+
+declare noalias i8* @malloc(i32)
+
+define i32 @parser() nounwind {
+bb918:
+ %malloccall.i10 = call i8* @malloc(i32 16) nounwind ; <i8*> [#uses=1]
+ %0 = bitcast i8* %malloccall.i10 to i32* ; <i32*> [#uses=1]
+ store i32* %0, i32** @fixLRBT, align 8
+ %1 = load i32** @fixLRBT, align 8 ; <i32*> [#uses=0]
+ %A = load i32* %1
+ ret i32 %A
+}
diff --git a/test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll b/test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll
new file mode 100644
index 0000000..6f1996a
--- /dev/null
+++ b/test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll
@@ -0,0 +1,27 @@
+; RUN: opt -globalopt -S %s
+; PR6435
+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"
+
+%struct.xyz = type { double, i32 }
+
+@Y = internal global %struct.xyz* null ; <%struct.xyz**> [#uses=2]
+@numf2s = external global i32 ; <i32*> [#uses=1]
+
+define fastcc void @init_net() nounwind {
+entry:
+ %0 = load i32* @numf2s, align 4 ; <i32> [#uses=1]
+ %mallocsize2 = shl i32 %0, 4 ; <i32> [#uses=1]
+ %malloccall3 = tail call i8* @malloc(i32 %mallocsize2) nounwind ; <i8*> [#uses=1]
+ %1 = bitcast i8* %malloccall3 to %struct.xyz* ; <%struct.xyz*> [#uses=1]
+ store %struct.xyz* %1, %struct.xyz** @Y, align 8
+ ret void
+}
+
+define fastcc void @load_train(i8* %trainfile, i32 %mode, i32 %objects) nounwind {
+entry:
+ %0 = load %struct.xyz** @Y, align 8 ; <%struct.xyz*> [#uses=0]
+ ret void
+}
+
+declare noalias i8* @malloc(i32)
diff --git a/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll b/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll
deleted file mode 100644
index f794e9f..0000000
--- a/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll
+++ /dev/null
@@ -1,98 +0,0 @@
-; RUN: opt < %s -globalopt -S | not grep CTOR
-@llvm.global_ctors = appending global [10 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR1 }, { i32, void ()* } { i32 65535, void ()* @CTOR1 }, { i32, void ()* } { i32 65535, void ()* @CTOR2 }, { i32, void ()* } { i32 65535, void ()* @CTOR3 }, { i32, void ()* } { i32 65535, void ()* @CTOR4 }, { i32, void ()* } { i32 65535, void ()* @CTOR5 }, { i32, void ()* } { i32 65535, void ()* @CTOR6 }, { i32, void ()* } { i32 65535, void ()* @CTOR7 }, { i32, void ()* } { i32 65535, void ()* @CTOR8 }, { i32, void ()* } { i32 2147483647, void ()* null } ] ; <[10 x { i32, void ()* }]*> [#uses=0]
-@G = global i32 0 ; <i32*> [#uses=1]
-@G2 = global i32 0 ; <i32*> [#uses=1]
-@G3 = global i32 -123 ; <i32*> [#uses=2]
-@X = global { i32, [2 x i32] } { i32 0, [2 x i32] [ i32 17, i32 21 ] } ; <{ i32, [2 x i32] }*> [#uses=2]
-@Y = global i32 -1 ; <i32*> [#uses=2]
-@Z = global i32 123 ; <i32*> [#uses=1]
-@D = global double 0.000000e+00 ; <double*> [#uses=1]
-@CTORGV = internal global i1 false ; <i1*> [#uses=2]
-
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
-
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"
-
-@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-define internal void @CTOR1() {
- ret void
-}
-
-define internal void @CTOR2() {
- %A = add i32 1, 23 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- store i32 %A, i32* @G
- store i1 true, i1* @CTORGV
- ret void
-}
-
-define internal void @CTOR3() {
- %X = or i1 true, false ; <i1> [#uses=1]
- br label %Cont
-
-Cont: ; preds = %0
- br i1 %X, label %S, label %T
-
-S: ; preds = %Cont
- store i32 24, i32* @G2
- ret void
-
-T: ; preds = %Cont
- ret void
-}
-
-define internal void @CTOR4() {
- %X = load i32* @G3 ; <i32> [#uses=1]
- %Y = add i32 %X, 123 ; <i32> [#uses=1]
- store i32 %Y, i32* @G3
- ret void
-}
-
-define internal void @CTOR5() {
- %X.2p = getelementptr inbounds { i32, [2 x i32] }* @X, i32 0, i32 1, i32 0 ; <i32*> [#uses=2]
- %X.2 = load i32* %X.2p ; <i32> [#uses=1]
- %X.1p = getelementptr inbounds { i32, [2 x i32] }* @X, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %X.2, i32* %X.1p
- store i32 42, i32* %X.2p
- ret void
-}
-
-define internal void @CTOR6() {
- %A = alloca i32 ; <i32*> [#uses=2]
- %y = load i32* @Y ; <i32> [#uses=1]
- store i32 %y, i32* %A
- %Av = load i32* %A ; <i32> [#uses=1]
- %Av1 = add i32 %Av, 1 ; <i32> [#uses=1]
- store i32 %Av1, i32* @Y
- ret void
-}
-
-define internal void @CTOR7() {
- call void @setto( i32* @Z, i32 0 )
- ret void
-}
-
-define void @setto(i32* %P, i32 %V) {
- store i32 %V, i32* %P
- ret void
-}
-
-declare double @cos(double)
-
-define internal void @CTOR8() {
- %X = call double @cos( double 1.000000e+00 ) ; <double> [#uses=1]
- store double %X, double* @D
- ret void
-}
-
-define i1 @accessor() {
- %V = load i1* @CTORGV ; <i1> [#uses=1]
- ret i1 %V
-}
diff --git a/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll b/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll
index 36d5006..ecd5086 100644
--- a/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll
+++ b/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll
@@ -7,7 +7,7 @@ define i32 @test() {
LoopHead: ; preds = %LoopHead, %0, %0
%A = phi i32 [ 7, %0 ], [ 7, %0 ], [ %B, %LoopHead ] ; <i32> [#uses=1]
%B = add i32 %A, 1 ; <i32> [#uses=2]
- br i1 false, label %LoopHead, label %Out
+ br i1 true, label %LoopHead, label %Out
Out: ; preds = %LoopHead
ret i32 %B
diff --git a/test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll b/test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll
index 70ea11e..7536331 100644
--- a/test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll
+++ b/test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll
@@ -10,7 +10,7 @@ no_exit: ; preds = %no_exit, %entry
%k.0.pn = phi i32 [ %inc.4, %no_exit ], [ 1, %entry ] ; <i32> [#uses=1]
%inc.3 = add i32 %j.0.pn, 1 ; <i32> [#uses=1]
%inc.4 = add i32 %k.0.pn, 1 ; <i32> [#uses=1]
- br i1 false, label %no_exit, label %loopexit
+ br i1 undef, label %no_exit, label %loopexit
loopexit: ; preds = %no_exit, %entry
ret void
diff --git a/test/Transforms/IndVarSimplify/2003-12-15-Crash.ll b/test/Transforms/IndVarSimplify/2003-12-15-Crash.ll
index 5aa2d90..662828c 100644
--- a/test/Transforms/IndVarSimplify/2003-12-15-Crash.ll
+++ b/test/Transforms/IndVarSimplify/2003-12-15-Crash.ll
@@ -8,7 +8,7 @@ cond_continue.3: ; preds = %entry
loopexit.14: ; preds = %entry
%tmp.738 = sub i32 0, 0 ; <i32> [#uses=1]
- br i1 false, label %no_exit.15.preheader, label %loopexit.15
+ br i1 undef, label %no_exit.15.preheader, label %loopexit.15
no_exit.15.preheader: ; preds = %loopexit.14
br label %no_exit.15
@@ -16,7 +16,7 @@ no_exit.15.preheader: ; preds = %loopexit.14
no_exit.15: ; preds = %no_exit.15, %no_exit.15.preheader
%highC.0 = phi i32 [ %tmp.738, %no_exit.15.preheader ], [ %dec.0, %no_exit.15 ] ; <i32> [#uses=1]
%dec.0 = add i32 %highC.0, -1 ; <i32> [#uses=1]
- br i1 false, label %no_exit.15, label %loopexit.15
+ br i1 undef, label %no_exit.15, label %loopexit.15
loopexit.15: ; preds = %no_exit.15, %loopexit.14
ret void
diff --git a/test/Transforms/IndVarSimplify/2005-11-18-Crash.ll b/test/Transforms/IndVarSimplify/2005-11-18-Crash.ll
index f9a3fe6..7202c7a 100644
--- a/test/Transforms/IndVarSimplify/2005-11-18-Crash.ll
+++ b/test/Transforms/IndVarSimplify/2005-11-18-Crash.ll
@@ -9,7 +9,7 @@ entry:
no_exit.0: ; preds = %no_exit.0, %entry
%p.0.0 = phi i32* [ getelementptr ([29 x [29 x [2 x i32]]]* @fixtab, i32 0, i32 0, i32 0, i32 0), %entry ], [ %inc.0, %no_exit.0 ] ; <i32*> [#uses=1]
%inc.0 = getelementptr i32* %p.0.0, i32 1 ; <i32*> [#uses=1]
- br i1 false, label %no_exit.0, label %no_exit.1
+ br i1 undef, label %no_exit.0, label %no_exit.1
no_exit.1: ; preds = %no_exit.0
ret void
diff --git a/test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll b/test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll
index 79ac1f0..80c9ebf 100644
--- a/test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll
+++ b/test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll
@@ -20,7 +20,7 @@ cond_next182.i: ; preds = %cond_next182.i, %cond_true52
%tmp194.i53 = bitcast i32 %decay.i.0 to float ; <float> [#uses=1]
%tmp195.i = fsub float %tmp194.i53, 8.000000e+00 ; <float> [#uses=1]
%tmp195.i.upgrd.1 = bitcast float %tmp195.i to i32 ; <i32> [#uses=1]
- br i1 false, label %cond_next182.i, label %bb418.i.preheader
+ br i1 undef, label %cond_next182.i, label %bb418.i.preheader
bb418.i.preheader: ; preds = %cond_next182.i
ret void
diff --git a/test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll b/test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll
index 9ad8691..d73eee8 100644
--- a/test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll
+++ b/test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll
@@ -12,7 +12,7 @@ bb.nph1.preheader: ; preds = %4
br label %bb.nph1
bb.nph1: ; preds = %.outer, %bb.nph1.preheader
- br i1 false, label %bb.nph3.preheader, label %.outer
+ br i1 undef, label %bb.nph3.preheader, label %.outer
bb.nph3.preheader: ; preds = %bb.nph1
br label %bb.nph3
@@ -31,7 +31,7 @@ bb.nph3: ; preds = %bb.nph3, %bb.nph3.preheader
br label %.outer
.outer: ; preds = %.outer.loopexit, %bb.nph1
- br i1 false, label %bb.nph1, label %.outer._crit_edge.loopexit
+ br i1 undef, label %bb.nph1, label %.outer._crit_edge.loopexit
.outer._crit_edge.loopexit: ; preds = %.outer
br label %.outer._crit_edge
diff --git a/test/Transforms/IndVarSimplify/addrec-gep.ll b/test/Transforms/IndVarSimplify/addrec-gep.ll
index 9e42734..345f666 100644
--- a/test/Transforms/IndVarSimplify/addrec-gep.ll
+++ b/test/Transforms/IndVarSimplify/addrec-gep.ll
@@ -25,7 +25,7 @@ bb1: ; preds = %bb2, %bb.nph
%j.01 = phi i64 [ %tmp9, %bb2 ], [ 0, %bb.nph ] ; <i64> [#uses=3]
%tmp3 = add i64 %j.01, %tmp1 ; <i64> [#uses=1]
%tmp4 = add i64 %j.01, %tmp2 ; <i64> [#uses=1]
- %z0 = add i64 %tmp4, 5203
+ %z0 = add i64 %tmp3, 5203
%tmp5 = getelementptr double* %p, i64 %z0 ; <double*> [#uses=1]
%tmp6 = load double* %tmp5, align 8 ; <double> [#uses=1]
%tmp7 = fdiv double %tmp6, 2.100000e+00 ; <double> [#uses=1]
diff --git a/test/Transforms/IndVarSimplify/avoid-i0.ll b/test/Transforms/IndVarSimplify/avoid-i0.ll
index d110a8a..59661fa 100644
--- a/test/Transforms/IndVarSimplify/avoid-i0.ll
+++ b/test/Transforms/IndVarSimplify/avoid-i0.ll
@@ -10,13 +10,13 @@ entry:
bb: ; preds = %bb6, %entry
%p_71_addr.0 = phi i8 [ %p_71, %entry ], [ %0, %bb6 ] ; <i8> [#uses=0]
- br i1 false, label %bb4, label %bb1
+ br i1 undef, label %bb4, label %bb1
bb1: ; preds = %bb
ret i32 0
bb4: ; preds = %bb4, %bb
- br i1 false, label %bb6, label %bb4
+ br i1 undef, label %bb6, label %bb4
bb6: ; preds = %bb4
%0 = and i8 0, 0 ; <i8> [#uses=1]
diff --git a/test/Transforms/IndVarSimplify/max-pointer.ll b/test/Transforms/IndVarSimplify/max-pointer.ll
index 71bc720..f18f968 100644
--- a/test/Transforms/IndVarSimplify/max-pointer.ll
+++ b/test/Transforms/IndVarSimplify/max-pointer.ll
@@ -16,7 +16,7 @@ bb2: ; preds = %bb2, %entry
%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ] ; <i8*> [#uses=1]
%1 = getelementptr i8* %str2Ptr_addr.1, i64 1 ; <i8*> [#uses=2]
%2 = icmp ult i8* %1, %inLastBytePtr ; <i1> [#uses=0]
- br i1 false, label %bb2, label %return
+ br i1 undef, label %bb2, label %return
return: ; preds = %bb2
ret void
@@ -32,7 +32,7 @@ bb2: ; preds = %bb2, %entry
%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ] ; <i8*> [#uses=1]
%1 = getelementptr i8* %str2Ptr_addr.1, i64 1 ; <i8*> [#uses=2]
%2 = icmp slt i8* %1, %inLastBytePtr ; <i1> [#uses=0]
- br i1 false, label %bb2, label %return
+ br i1 undef, label %bb2, label %return
return: ; preds = %bb2
ret void
diff --git a/test/Transforms/InstCombine/2006-12-08-ICmp-Combining.ll b/test/Transforms/InstCombine/2006-12-08-ICmp-Combining.ll
deleted file mode 100644
index 80ee3e2..0000000
--- a/test/Transforms/InstCombine/2006-12-08-ICmp-Combining.ll
+++ /dev/null
@@ -1,18 +0,0 @@
-; RUN: opt < %s -instcombine -S | \
-; RUN: grep {%bothcond =}
-
-define i1 @Doit_bb(i32 %i.0) {
-bb:
- %tmp = icmp sgt i32 %i.0, 0 ; <i1> [#uses=1]
- %tmp.not = xor i1 %tmp, true ; <i1> [#uses=1]
- %tmp2 = icmp sgt i32 %i.0, 8 ; <i1> [#uses=1]
- %bothcond = or i1 %tmp.not, %tmp2 ; <i1> [#uses=1]
- br i1 %bothcond, label %exitTrue, label %exitFalse
-
-exitTrue: ; preds = %bb
- ret i1 true
-
-exitFalse: ; preds = %bb
- ret i1 false
-}
-
diff --git a/test/Transforms/InstCombine/2009-01-19-fmod-constant-float-specials.ll b/test/Transforms/InstCombine/2009-01-19-fmod-constant-float-specials.ll
index 79a2f1f..1421347 100644
--- a/test/Transforms/InstCombine/2009-01-19-fmod-constant-float-specials.ll
+++ b/test/Transforms/InstCombine/2009-01-19-fmod-constant-float-specials.ll
@@ -1,5 +1,4 @@
-; RUN: opt < %s -simplifycfg -instcombine -S | grep 0x7FF8000000000000 | count 7
-; RUN: opt < %s -simplifycfg -instcombine -S | grep 0x7FF00000FFFFFFFF | count 5
+; RUN: opt < %s -simplifycfg -instcombine -S | grep 0x7FF8000000000000 | count 12
; RUN: opt < %s -simplifycfg -instcombine -S | grep {0\\.0} | count 3
; RUN: opt < %s -simplifycfg -instcombine -S | grep {3\\.5} | count 1
;
diff --git a/test/Transforms/InstCombine/2010-03-03-ExtElim.ll b/test/Transforms/InstCombine/2010-03-03-ExtElim.ll
new file mode 100644
index 0000000..2df12d6
--- /dev/null
+++ b/test/Transforms/InstCombine/2010-03-03-ExtElim.ll
@@ -0,0 +1,18 @@
+; RUN: opt -instcombine -S %s | FileCheck %s
+; PR6486
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-unknown-linux-gnu"
+
+@g_92 = common global [2 x i32*] zeroinitializer, align 4 ; <[2 x i32*]*> [#uses=1]
+@g_177 = constant i32** bitcast (i8* getelementptr (i8* bitcast ([2 x i32*]* @g_92 to i8*), i64 4) to i32**), align 4 ; <i32***> [#uses=1]
+
+define i1 @test() nounwind {
+; CHECK: @test
+ %tmp = load i32*** @g_177 ; <i32**> [#uses=1]
+ %cmp = icmp ne i32** null, %tmp ; <i1> [#uses=1]
+ %conv = zext i1 %cmp to i32 ; <i32> [#uses=1]
+ %cmp1 = icmp sle i32 0, %conv ; <i1> [#uses=1]
+ ret i1 %cmp1
+; CHECK: ret i1 true
+}
diff --git a/test/Transforms/InstCombine/JavaCompare.ll b/test/Transforms/InstCombine/JavaCompare.ll
index 7d0edb8..46b6c19 100644
--- a/test/Transforms/InstCombine/JavaCompare.ll
+++ b/test/Transforms/InstCombine/JavaCompare.ll
@@ -1,7 +1,7 @@
; This is the sequence of stuff that the Java front-end expands for a single
; <= comparison. Check to make sure we turn it into a <= (only)
-; RUN: opt < %s -instcombine -S | grep {%c3 = icmp sle i32 %A, %B}
+; RUN: opt < %s -instcombine -S | grep {icmp sle i32 %A, %B}
define i1 @le(i32 %A, i32 %B) {
%c1 = icmp sgt i32 %A, %B ; <i1> [#uses=1]
diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll
index 0af9bfa..a5a6574 100644
--- a/test/Transforms/InstCombine/and2.ll
+++ b/test/Transforms/InstCombine/and2.ll
@@ -1,5 +1,4 @@
-; RUN: opt < %s -instcombine -S | not grep and
-
+; RUN: opt < %s -instcombine -S | FileCheck %s
; PR1738
define i1 @test1(double %X, double %Y) {
@@ -7,6 +6,5 @@ define i1 @test1(double %X, double %Y) {
%tmp13 = fcmp ord double %Y, 0.000000e+00
%bothcond = and i1 %tmp13, %tmp9
ret i1 %bothcond
+; CHECK: fcmp ord double %Y, %X
}
-
-
diff --git a/test/Transforms/InstCombine/bswap-fold.ll b/test/Transforms/InstCombine/bswap-fold.ll
index 034c70e..a6b30c0 100644
--- a/test/Transforms/InstCombine/bswap-fold.ll
+++ b/test/Transforms/InstCombine/bswap-fold.ll
@@ -67,3 +67,9 @@ define i16 @test8(i64 %A) {
%D = tail call i16 @llvm.bswap.i16(i16 %C) nounwind
ret i16 %D
}
+
+; Misc: Fold bswap(undef) to undef.
+define i64 @foo() {
+ %a = call i64 @llvm.bswap.i64(i64 undef)
+ ret i64 %a
+}
diff --git a/test/Transforms/InstCombine/constant-fold-ptr-casts.ll b/test/Transforms/InstCombine/constant-fold-ptr-casts.ll
deleted file mode 100644
index 9b6c6c3..0000000
--- a/test/Transforms/InstCombine/constant-fold-ptr-casts.ll
+++ /dev/null
@@ -1,18 +0,0 @@
-; RUN: opt < %s -instcombine -S | grep {ret i32 2143034560}
-
-; Instcombine should be able to completely fold this code.
-
-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 = "i686-apple-darwin8"
-
-@bar = constant [3 x i64] [i64 9220983451228067448, i64 9220983451228067449, i64 9220983450959631991], align 8
-
-define i32 @foo() nounwind {
-entry:
- %tmp87.2 = load i64* inttoptr (i32 add (i32 16, i32 ptrtoint ([3 x i64]* @bar to i32)) to i64*), align 8
- %t0 = bitcast i64 %tmp87.2 to double
- %tmp9192.2 = fptrunc double %t0 to float
- %t1 = bitcast float %tmp9192.2 to i32
- ret i32 %t1
-}
-
diff --git a/test/Transforms/InstCombine/crash.ll b/test/Transforms/InstCombine/crash.ll
index 2faa539..854bfc8 100644
--- a/test/Transforms/InstCombine/crash.ll
+++ b/test/Transforms/InstCombine/crash.ll
@@ -237,3 +237,18 @@ entry:
%or = or i32 %and42, %and47
ret i32 %or
}
+
+; PR6503
+define void @test12(i32* %A) nounwind {
+entry:
+ %tmp1 = load i32* %A
+ %cmp = icmp ugt i32 1, %tmp1 ; <i1> [#uses=1]
+ %conv = zext i1 %cmp to i32 ; <i32> [#uses=1]
+ %tmp2 = load i32* %A
+ %cmp3 = icmp ne i32 %tmp2, 0 ; <i1> [#uses=1]
+ %conv4 = zext i1 %cmp3 to i32 ; <i32> [#uses=1]
+ %or = or i32 %conv, %conv4 ; <i32> [#uses=1]
+ %cmp5 = icmp ugt i32 undef, %or ; <i1> [#uses=1]
+ %conv6 = zext i1 %cmp5 to i32 ; <i32> [#uses=0]
+ ret void
+}
diff --git a/test/Transforms/InstCombine/fcmp-select.ll b/test/Transforms/InstCombine/fcmp-select.ll
new file mode 100644
index 0000000..e04ab3e
--- /dev/null
+++ b/test/Transforms/InstCombine/fcmp-select.ll
@@ -0,0 +1,53 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; x != y ? x : y -> x if it's the right kind of != and at least
+; one of x and y is not negative zero.
+
+; CHECK: f0
+; CHECK: ret double %x
+define double @f0(double %x) nounwind readnone {
+entry:
+ %cmp = fcmp une double %x, -1.0
+ %cond = select i1 %cmp, double %x, double -1.0
+ ret double %cond
+}
+; CHECK: f1
+; CHECK: ret double -1.000000e+00
+define double @f1(double %x) nounwind readnone {
+entry:
+ %cmp = fcmp une double %x, -1.0
+ %cond = select i1 %cmp, double -1.0, double %x
+ ret double %cond
+}
+; CHECK: f2
+; CHECK: ret double %cond
+define double @f2(double %x, double %y) nounwind readnone {
+entry:
+ %cmp = fcmp une double %x, %y
+ %cond = select i1 %cmp, double %x, double %y
+ ret double %cond
+}
+; CHECK: f3
+; CHECK: ret double %cond
+define double @f3(double %x, double %y) nounwind readnone {
+entry:
+ %cmp = fcmp une double %x, %y
+ %cond = select i1 %cmp, double %y, double %x
+ ret double %cond
+}
+; CHECK: f4
+; CHECK: ret double %cond
+define double @f4(double %x) nounwind readnone {
+entry:
+ %cmp = fcmp one double %x, -1.0
+ %cond = select i1 %cmp, double %x, double -1.0
+ ret double %cond
+}
+; CHECK: f5
+; CHECK: ret double %cond
+define double @f5(double %x) nounwind readnone {
+entry:
+ %cmp = fcmp one double %x, -1.0
+ %cond = select i1 %cmp, double -1.0, double %x
+ ret double %cond
+}
diff --git a/test/Transforms/InstCombine/fcmp-special.ll b/test/Transforms/InstCombine/fcmp-special.ll
new file mode 100644
index 0000000..a39021e
--- /dev/null
+++ b/test/Transforms/InstCombine/fcmp-special.ll
@@ -0,0 +1,155 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; Infinity
+
+; CHECK: inf0
+; CHECK: ret i1 false
+define i1 @inf0(double %arg) nounwind readnone {
+ %tmp = fcmp ogt double %arg, 0x7FF0000000000000
+ ret i1 %tmp
+}
+
+; CHECK: inf1
+; CHECK: ret i1 true
+define i1 @inf1(double %arg) nounwind readnone {
+ %tmp = fcmp ule double %arg, 0x7FF0000000000000
+ ret i1 %tmp
+}
+
+; Negative infinity
+
+; CHECK: ninf0
+; CHECK: ret i1 false
+define i1 @ninf0(double %arg) nounwind readnone {
+ %tmp = fcmp olt double %arg, 0xFFF0000000000000
+ ret i1 %tmp
+}
+
+; CHECK: ninf1
+; CHECK: ret i1 true
+define i1 @ninf1(double %arg) nounwind readnone {
+ %tmp = fcmp uge double %arg, 0xFFF0000000000000
+ ret i1 %tmp
+}
+
+; NaNs
+
+; CHECK: nan0
+; CHECK: ret i1 false
+define i1 @nan0(double %arg) nounwind readnone {
+ %tmp = fcmp ord double %arg, 0x7FF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nan1
+; CHECK: ret i1 false
+define i1 @nan1(double %arg) nounwind readnone {
+ %tmp = fcmp oeq double %arg, 0x7FF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nan2
+; CHECK: ret i1 false
+define i1 @nan2(double %arg) nounwind readnone {
+ %tmp = fcmp olt double %arg, 0x7FF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nan3
+; CHECK: ret i1 true
+define i1 @nan3(double %arg) nounwind readnone {
+ %tmp = fcmp uno double %arg, 0x7FF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nan4
+; CHECK: ret i1 true
+define i1 @nan4(double %arg) nounwind readnone {
+ %tmp = fcmp une double %arg, 0x7FF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nan5
+; CHECK: ret i1 true
+define i1 @nan5(double %arg) nounwind readnone {
+ %tmp = fcmp ult double %arg, 0x7FF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; Negative NaN.
+
+; CHECK: nnan0
+; CHECK: ret i1 false
+define i1 @nnan0(double %arg) nounwind readnone {
+ %tmp = fcmp ord double %arg, 0xFFF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nnan1
+; CHECK: ret i1 false
+define i1 @nnan1(double %arg) nounwind readnone {
+ %tmp = fcmp oeq double %arg, 0xFFF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nnan2
+; CHECK: ret i1 false
+define i1 @nnan2(double %arg) nounwind readnone {
+ %tmp = fcmp olt double %arg, 0xFFF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nnan3
+; CHECK: ret i1 true
+define i1 @nnan3(double %arg) nounwind readnone {
+ %tmp = fcmp uno double %arg, 0xFFF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nnan4
+; CHECK: ret i1 true
+define i1 @nnan4(double %arg) nounwind readnone {
+ %tmp = fcmp une double %arg, 0xFFF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; CHECK: nnan5
+; CHECK: ret i1 true
+define i1 @nnan5(double %arg) nounwind readnone {
+ %tmp = fcmp ult double %arg, 0xFFF00000FFFFFFFF
+ ret i1 %tmp
+}
+
+; Negative zero.
+
+; CHECK: nzero0
+; CHECK: ret i1 true
+define i1 @nzero0() {
+ %tmp = fcmp oeq double 0.0, -0.0
+ ret i1 %tmp
+}
+
+; CHECK: nzero1
+; CHECK: ret i1 false
+define i1 @nzero1() {
+ %tmp = fcmp ogt double 0.0, -0.0
+ ret i1 %tmp
+}
+
+; Misc.
+
+; CHECK: misc0
+; CHECK: %tmp = fcmp ord double %arg, 0.000000e+00
+; CHECK: ret i1 %tmp
+define i1 @misc0(double %arg) {
+ %tmp = fcmp oeq double %arg, %arg
+ ret i1 %tmp
+}
+
+; CHECK: misc1
+; CHECK: ret i1 false
+define i1 @misc1(double %arg) {
+ %tmp = fcmp one double %arg, %arg
+ ret i1 %tmp
+}
+
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index c2234a1..29997bf 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -48,7 +48,7 @@ entry:
%V = icmp eq <2 x i64> %x, undef
ret <2 x i1> %V
; CHECK: @test5
-; CHECK: ret <2 x i1> undef
+; CHECK: ret <2 x i1> <i1 true, i1 true>
}
define i32 @test6(i32 %a, i32 %b) {
@@ -121,3 +121,13 @@ define i1 @test12(i1 %A) {
; CHECK-NEXT: %B = select i1
; CHECK-NEXT: ret i1 %B
}
+
+; PR6481
+define i1 @test13(i8 %X) nounwind readnone {
+entry:
+ %cmp = icmp slt i8 undef, %X
+ ret i1 %cmp
+; CHECK: @test13
+; CHECK: ret i1 false
+}
+
diff --git a/test/Transforms/InstCombine/load-cmp.ll b/test/Transforms/InstCombine/load-cmp.ll
index fe5df92..5cafb77 100644
--- a/test/Transforms/InstCombine/load-cmp.ll
+++ b/test/Transforms/InstCombine/load-cmp.ll
@@ -89,8 +89,8 @@ define i1 @test8(i32 %X) {
ret i1 %S
; CHECK: @test8
; CHECK-NEXT: add i32 %X, -8
-; CHECK-NEXT: %S = icmp ult i32 {{.*}}, 2
-; CHECK-NEXT: ret i1 %S
+; CHECK-NEXT: icmp ult i32 {{.*}}, 2
+; CHECK-NEXT: ret i1
}
@GA = internal constant [4 x { i32, i32 } ] [
@@ -107,6 +107,6 @@ define i1 @test9(i32 %X) {
ret i1 %R
; CHECK: @test9
; CHECK-NEXT: add i32 %X, -1
-; CHECK-NEXT: %R = icmp ult i32 {{.*}}, 2
-; CHECK-NEXT: ret i1 %R
+; CHECK-NEXT: icmp ult i32 {{.*}}, 2
+; CHECK-NEXT: ret i1
}
diff --git a/test/Transforms/InstCombine/memset_chk.ll b/test/Transforms/InstCombine/memset_chk.ll
new file mode 100644
index 0000000..5a4e6d9
--- /dev/null
+++ b/test/Transforms/InstCombine/memset_chk.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; rdar://7719085
+
+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"
+
+%struct.data = type { [100 x i32], [100 x i32], [1024 x i8] }
+
+define i32 @t() nounwind ssp {
+; CHECK: @t
+; CHECK: @llvm.memset.i64
+entry:
+ %0 = alloca %struct.data, align 8 ; <%struct.data*> [#uses=1]
+ %1 = bitcast %struct.data* %0 to i8* ; <i8*> [#uses=1]
+ %2 = call i8* @__memset_chk(i8* %1, i32 0, i64 1824, i64 1824) nounwind ; <i8*> [#uses=0]
+ ret i32 0
+}
+
+declare i8* @__memset_chk(i8*, i32, i64, i64) nounwind
diff --git a/test/Transforms/InstCombine/multi-use-or.ll b/test/Transforms/InstCombine/multi-use-or.ll
index 9bbef23..8c6a0e0 100644
--- a/test/Transforms/InstCombine/multi-use-or.ll
+++ b/test/Transforms/InstCombine/multi-use-or.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep {add double .sx, .sy}
+; RUN: opt < %s -instcombine -S | grep {fadd double .sx, .sy}
; The 'or' has multiple uses, make sure that this doesn't prevent instcombine
; from propagating the extends to the truncs.
diff --git a/test/Transforms/InstCombine/objsize.ll b/test/Transforms/InstCombine/objsize.ll
index 69e09f6..57dc2fd 100644
--- a/test/Transforms/InstCombine/objsize.ll
+++ b/test/Transforms/InstCombine/objsize.ll
@@ -23,18 +23,17 @@ entry:
br i1 %cmp, label %cond.true, label %cond.false
cond.true:
- %1 = load i8** %retval;
- ret i8* %1;
+ %1 = load i8** %retval
+ ret i8* %1
cond.false:
- %2 = load i8** %retval;
- ret i8* %2;
+ %2 = load i8** %retval
+ ret i8* %2
}
-; FIXME: Should be ret i32 0
define i32 @f() nounwind {
; CHECK: @f
-; CHECK-NEXT: llvm.objectsize.i32
+; CHECK-NEXT: ret i32 0
%1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false)
ret i32 %1
}
@@ -49,4 +48,78 @@ define i1 @baz() nounwind {
ret i1 %2
}
-declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly \ No newline at end of file
+define void @test1(i8* %q, i32 %x) nounwind noinline {
+; CHECK: @test1
+; CHECK: objectsize.i32
+entry:
+ %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false) ; <i64> [#uses=1]
+ %1 = icmp eq i32 %0, -1 ; <i1> [#uses=1]
+ br i1 %1, label %"47", label %"46"
+
+"46": ; preds = %entry
+ unreachable
+
+"47": ; preds = %entry
+ unreachable
+}
+
+@.str5 = private constant [9 x i32] [i32 97, i32 98, i32 99, i32 100, i32 0, i32
+ 101, i32 102, i32 103, i32 0], align 4
+define i32 @test2() nounwind {
+; CHECK: @test2
+; CHECK-NEXT: ret i32 34
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false)
+ ret i32 %1
+}
+
+; rdar://7674946
+@array = internal global [480 x float] zeroinitializer ; <[480 x float]*> [#uses=1]
+
+declare i8* @__memcpy_chk(i8*, i8*, i32, i32) nounwind
+
+declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
+
+declare i8* @__inline_memcpy_chk(i8*, i8*, i32) nounwind inlinehint
+
+define void @test3() nounwind {
+; CHECK: @test3
+entry:
+ br i1 undef, label %bb11, label %bb12
+
+bb11:
+ %0 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; <float*> [#uses=1]
+ %1 = bitcast float* %0 to i8* ; <i8*> [#uses=1]
+ %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) ; <i32> [#uses=1]
+ %3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; <i8*> [#uses=0]
+; CHECK: unreachable
+ unreachable
+
+bb12:
+ %4 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; <float*> [#uses=1]
+ %5 = bitcast float* %4 to i8* ; <i8*> [#uses=1]
+ %6 = call i8* @__inline_memcpy_chk(i8* %5, i8* undef, i32 512) nounwind inlinehint ; <i8*> [#uses=0]
+; CHECK: @__inline_memcpy_chk
+ unreachable
+}
+
+; rdar://7718857
+
+%struct.data = type { [100 x i32], [100 x i32], [1024 x i8] }
+
+define i32 @test4() nounwind ssp {
+; CHECK: @test4
+entry:
+ %0 = alloca %struct.data, align 8
+ %1 = bitcast %struct.data* %0 to i8*
+ %2 = call i64 @llvm.objectsize.i64(i8* %1, i1 false) nounwind
+; CHECK-NOT: @llvm.objectsize
+; CHECK: @llvm.memset.i64(i8* %1, i8 0, i64 1824, i32 8)
+ %3 = call i8* @__memset_chk(i8* %1, i32 0, i64 1824, i64 %2) nounwind
+ ret i32 0
+}
+
+declare i8* @__memset_chk(i8*, i32, i64, i64) nounwind
+
+declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
+
+declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly
diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll
index 189be10..c3526b7 100644
--- a/test/Transforms/InstCombine/or.ll
+++ b/test/Transforms/InstCombine/or.ll
@@ -126,8 +126,8 @@ define i1 @test14(i32 %A, i32 %B) {
%D = or i1 %C1, %C2
ret i1 %D
; CHECK: @test14
-; CHECK: %D = icmp ne i32 %A, %B
-; CHECK: ret i1 %D
+; CHECK: icmp ne i32 %A, %B
+; CHECK: ret i1
}
define i1 @test15(i32 %A, i32 %B) {
@@ -137,8 +137,8 @@ define i1 @test15(i32 %A, i32 %B) {
%D = or i1 %C1, %C2
ret i1 %D
; CHECK: @test15
-; CHECK: %D = icmp ule i32 %A, %B
-; CHECK: ret i1 %D
+; CHECK: icmp ule i32 %A, %B
+; CHECK: ret i1
}
define i32 @test16(i32 %A) {
@@ -171,8 +171,8 @@ define i1 @test18(i32 %A) {
ret i1 %D
; CHECK: @test18
; CHECK: add i32
-; CHECK: %D = icmp ugt
-; CHECK: ret i1 %D
+; CHECK: icmp ugt
+; CHECK: ret i1
}
define i1 @test19(i32 %A) {
@@ -183,8 +183,8 @@ define i1 @test19(i32 %A) {
ret i1 %D
; CHECK: @test19
; CHECK: add i32
-; CHECK: %D = icmp ult
-; CHECK: ret i1 %D
+; CHECK: icmp ult
+; CHECK: ret i1
}
define i32 @test20(i32 %x) {
@@ -236,8 +236,8 @@ define i1 @test24(double %X, double %Y) {
ret i1 %bothcond
; CHECK: @test24
-; CHECK: %bothcond = fcmp uno double %Y, %X ; <i1> [#uses=1]
-; CHECK: ret i1 %bothcond
+; CHECK: = fcmp uno double %Y, %X
+; CHECK: ret i1
}
; PR3266 & PR5276
diff --git a/test/Transforms/InstCombine/phi.ll b/test/Transforms/InstCombine/phi.ll
index f0343e4..fc321e9 100644
--- a/test/Transforms/InstCombine/phi.ll
+++ b/test/Transforms/InstCombine/phi.ll
@@ -362,3 +362,43 @@ end:
; CHECK-NEXT: ret i64
}
+; PR6512 - Shouldn't merge loads from different addr spaces.
+define i32 @test16(i32 addrspace(1)* %pointer1, i32 %flag, i32* %pointer2)
+nounwind {
+entry:
+ %retval = alloca i32, align 4 ; <i32*> [#uses=2]
+ %pointer1.addr = alloca i32 addrspace(1)*, align 4 ; <i32 addrspace(1)**>
+ %flag.addr = alloca i32, align 4 ; <i32*> [#uses=2]
+ %pointer2.addr = alloca i32*, align 4 ; <i32**> [#uses=2]
+ %res = alloca i32, align 4 ; <i32*> [#uses=4]
+ store i32 addrspace(1)* %pointer1, i32 addrspace(1)** %pointer1.addr
+ store i32 %flag, i32* %flag.addr
+ store i32* %pointer2, i32** %pointer2.addr
+ store i32 10, i32* %res
+ %tmp = load i32* %flag.addr ; <i32> [#uses=1]
+ %tobool = icmp ne i32 %tmp, 0 ; <i1> [#uses=1]
+ br i1 %tobool, label %if.then, label %if.else
+
+return: ; preds = %if.end
+ %tmp7 = load i32* %retval ; <i32> [#uses=1]
+ ret i32 %tmp7
+
+if.end: ; preds = %if.else, %if.then
+ %tmp6 = load i32* %res ; <i32> [#uses=1]
+ store i32 %tmp6, i32* %retval
+ br label %return
+
+if.then: ; preds = %entry
+ %tmp1 = load i32 addrspace(1)** %pointer1.addr ; <i32 addrspace(1)*>
+ %arrayidx = getelementptr i32 addrspace(1)* %tmp1, i32 0 ; <i32 addrspace(1)*> [#uses=1]
+ %tmp2 = load i32 addrspace(1)* %arrayidx ; <i32> [#uses=1]
+ store i32 %tmp2, i32* %res
+ br label %if.end
+
+if.else: ; preds = %entry
+ %tmp3 = load i32** %pointer2.addr ; <i32*> [#uses=1]
+ %arrayidx4 = getelementptr i32* %tmp3, i32 0 ; <i32*> [#uses=1]
+ %tmp5 = load i32* %arrayidx4 ; <i32> [#uses=1]
+ store i32 %tmp5, i32* %res
+ br label %if.end
+}
diff --git a/test/Transforms/InstCombine/ptr-int-cast.ll b/test/Transforms/InstCombine/ptr-int-cast.ll
index c7ae689..ad11e43 100644
--- a/test/Transforms/InstCombine/ptr-int-cast.ll
+++ b/test/Transforms/InstCombine/ptr-int-cast.ll
@@ -1,17 +1,29 @@
-; RUN: opt < %s -instcombine -S > %t
+; RUN: opt < %s -instcombine -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 i1 @test1(i32 *%x) nounwind {
entry:
-; RUN: grep {ptrtoint i32\\* %x to i64} %t
+; CHECK: test1
+; CHECK: ptrtoint i32* %x to i64
%tmp = ptrtoint i32* %x to i1
ret i1 %tmp
}
define i32* @test2(i128 %x) nounwind {
entry:
-; RUN: grep {inttoptr i64 %.mp1 to i32\\*} %t
+; CHECK: test2
+; CHECK: inttoptr i64 %tmp1 to i32*
%tmp = inttoptr i128 %x to i32*
ret i32* %tmp
}
+; PR3574
+; CHECK: f0
+; CHECK: %tmp = zext i32 %a0 to i64
+; CHECK: ret i64 %tmp
+define i64 @f0(i32 %a0) nounwind {
+ %t0 = inttoptr i32 %a0 to i8*
+ %t1 = ptrtoint i8* %t0 to i64
+ ret i64 %t1
+}
+
diff --git a/test/Transforms/SimplifyLibCalls/strcpy_chk.ll b/test/Transforms/InstCombine/strcpy_chk.ll
index 422cbd9..a20a13c 100644
--- a/test/Transforms/SimplifyLibCalls/strcpy_chk.ll
+++ b/test/Transforms/InstCombine/strcpy_chk.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+; RUN: opt < %s -instcombine -S | FileCheck %s
@a = common global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*> [#uses=1]
@.str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*> [#uses=1]
diff --git a/test/Transforms/InstCombine/vec_narrow.ll b/test/Transforms/InstCombine/vec_narrow.ll
index daf7bcf..c05c802 100644
--- a/test/Transforms/InstCombine/vec_narrow.ll
+++ b/test/Transforms/InstCombine/vec_narrow.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -instcombine -S | \
-; RUN: grep {add float}
+; RUN: grep {fadd float}
%V = type <4 x float>
diff --git a/test/Transforms/InstCombine/vector-casts.ll b/test/Transforms/InstCombine/vector-casts.ll
index 470d485..24bd04d 100644
--- a/test/Transforms/InstCombine/vector-casts.ll
+++ b/test/Transforms/InstCombine/vector-casts.ll
@@ -51,6 +51,22 @@ entry:
}
+; rdar://7434900
+define <2 x i64> @test5(<4 x float> %a, <4 x float> %b) nounwind readnone {
+entry:
+ %cmp = fcmp ult <4 x float> %a, zeroinitializer
+ %sext = sext <4 x i1> %cmp to <4 x i32>
+ %cmp4 = fcmp ult <4 x float> %b, zeroinitializer
+ %sext5 = sext <4 x i1> %cmp4 to <4 x i32>
+ %and = and <4 x i32> %sext, %sext5
+ %conv = bitcast <4 x i32> %and to <2 x i64>
+ ret <2 x i64> %conv
+
+; CHECK: @test5
+; CHECK: sext <4 x i1> %cmp to <4 x i32>
+; CHECK: sext <4 x i1> %cmp4 to <4 x i32>
+}
+
define void @convert(<2 x i32>* %dst.addr, <2 x i64> %src) nounwind {
entry:
diff --git a/test/Transforms/InstCombine/xor2.ll b/test/Transforms/InstCombine/xor2.ll
index de3d65d..67f05ef 100644
--- a/test/Transforms/InstCombine/xor2.ll
+++ b/test/Transforms/InstCombine/xor2.ll
@@ -22,8 +22,8 @@ define i1 @test1(i32 %A) {
; PR1014
define i32 @test2(i32 %tmp1) {
; CHECK: @test2
-; CHECK-NEXT: or i32 %tmp1, 8
-; CHECK-NEXT: and i32
+; CHECK-NEXT: and i32 %tmp1, 32
+; CHECK-NEXT: or i32 %ovm, 8
; CHECK-NEXT: ret i32
%ovm = and i32 %tmp1, 32
%ov3 = add i32 %ovm, 145
@@ -33,8 +33,8 @@ define i32 @test2(i32 %tmp1) {
define i32 @test3(i32 %tmp1) {
; CHECK: @test3
-; CHECK-NEXT: or i32 %tmp1, 8
-; CHECK-NEXT: and i32
+; CHECK-NEXT: and i32 %tmp1, 32
+; CHECK-NEXT: or i32 %tmp, 8
; CHECK-NEXT: ret i32
%ovm = or i32 %tmp1, 145
%ov31 = and i32 %ovm, 177
diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll
index cf292df..c65fd10 100644
--- a/test/Transforms/JumpThreading/crash.ll
+++ b/test/Transforms/JumpThreading/crash.ll
@@ -313,3 +313,14 @@ for.cond: ; preds = %for.body, %lor.end
for.body: ; preds = %for.cond
br label %for.cond
}
+
+
+; PR6305
+define void @test11() nounwind {
+entry:
+ br label %A
+
+A: ; preds = %entry
+ call void undef(i64 ptrtoint (i8* blockaddress(@test11, %A) to i64)) nounwind
+ unreachable
+}
diff --git a/test/Transforms/JumpThreading/or-undef.ll b/test/Transforms/JumpThreading/or-undef.ll
new file mode 100644
index 0000000..6e35992
--- /dev/null
+++ b/test/Transforms/JumpThreading/or-undef.ll
@@ -0,0 +1,69 @@
+; RUN: opt -jump-threading -S %s | FileCheck %s
+; rdar://7620633
+
+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"
+target triple = "x86_64-apple-darwin11.0"
+
+define void @test1(i8* %args, i32 %from_tty) nounwind optsize ssp {
+entry:
+ %tmp = call i8* @f3(void (i8*)* null, i8* null) nounwind ; <i8*> [#uses=1]
+ %tmp1 = icmp eq i8* %args, null ; <i1> [#uses=1]
+ br i1 %tmp1, label %bb2, label %bb
+
+; CHECK: entry:
+; CHECK-NEXT: %tmp = call i8* @f3
+; CHECK-NEXT: %tmp1 = icmp eq i8* %args, null
+; CHECK-NEXT: br i1 %tmp1, label %bb7, label %bb
+
+bb: ; preds = %entry
+ %tmp2 = call noalias i8** @buildargv(i8* %args) nounwind ; <i8**> [#uses=4]
+ %tmp3 = icmp eq i8** %tmp2, null ; <i1> [#uses=1]
+ br i1 %tmp3, label %bb2, label %bb1
+
+bb1: ; preds = %bb
+ call void @f2(i8** %tmp2) nounwind
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb, %entry
+ %argv.0 = phi i8** [ %tmp2, %bb1 ], [ %tmp2, %bb ], [ undef, %entry ] ; <i8**> [#uses=4]
+ %tmp5 = icmp eq i8* %args, null ; <i1> [#uses=1]
+ %tmp6 = icmp eq i8** %argv.0, null ; <i1> [#uses=1]
+ %tmp7 = or i1 %tmp5, %tmp6 ; <i1> [#uses=1]
+ br i1 %tmp7, label %bb7, label %bb5
+
+bb5: ; preds = %bb2
+ %tmp8 = load i8** %argv.0, align 8 ; <i8*> [#uses=1]
+ %tmp9 = icmp eq i8* %tmp8, null ; <i1> [#uses=1]
+ br i1 %tmp9, label %bb7, label %bb6
+
+bb6: ; preds = %bb5
+ %tmp10 = load i8** %argv.0, align 8 ; <i8*> [#uses=1]
+ %tmp11 = load i8* %tmp10, align 1 ; <i8> [#uses=1]
+ %tmp12 = icmp eq i8 %tmp11, 0 ; <i1> [#uses=1]
+ br i1 %tmp12, label %bb7, label %bb8
+
+bb7: ; preds = %bb6, %bb5, %bb2
+ call void @f1() nounwind optsize ssp
+ br label %bb9
+
+bb8: ; preds = %bb6
+ %tmp13 = load i8** %argv.0, align 8 ; <i8*> [#uses=1]
+ %tmp14 = call i64 @f5(i8* %tmp13) nounwind ; <i64> [#uses=0]
+ br label %bb9
+
+bb9: ; preds = %bb8, %bb7
+ call void @f4(i8* %tmp) nounwind
+ ret void
+}
+
+declare noalias i8** @buildargv(i8*)
+
+declare void @f2(i8**)
+
+declare void @f4(i8*)
+
+declare i8* @f3(void (i8*)*, i8*)
+
+declare void @f1()
+
+declare i64 @f5(i8*)
diff --git a/test/Transforms/LoopDeletion/simplify-then-delete.ll b/test/Transforms/LoopDeletion/simplify-then-delete.ll
new file mode 100644
index 0000000..5a21672
--- /dev/null
+++ b/test/Transforms/LoopDeletion/simplify-then-delete.ll
@@ -0,0 +1,65 @@
+; RUN: opt < %s -S -indvars -loop-deletion -simplifycfg | FileCheck %s
+; PR5794
+
+; Indvars and loop deletion should be able to eliminate all looping
+; in this testcase.
+
+; CHECK: define i32 @pmat(i32 %m, i32 %n, double* %y) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: }
+
+target datalayout = "e-p:64:64:64"
+
+define i32 @pmat(i32 %m, i32 %n, double* %y) nounwind {
+entry:
+ %cmp4 = icmp sgt i32 %m, 0
+ br i1 %cmp4, label %bb.n10, label %w.e12
+
+w.c:
+ %cmp = icmp slt i32 %inc11, %m
+ br i1 %cmp, label %w.c2.p, label %w.c.w.e12c
+
+w.c.w.e12c:
+ br label %w.c.w.e12c.s
+
+w.c.w.e12c.s:
+ br label %w.e12
+
+bb.n10:
+ %cmp51 = icmp sgt i32 %n, 0
+ br i1 %cmp51, label %bb.n10.w.c.w.e12c.sc, label %bb.n10.bb.n10.sc
+
+bb.n10.bb.n10.sc:
+ br label %bb.n10.s
+
+bb.n10.w.c.w.e12c.sc:
+ br label %w.c.w.e12c.s
+
+bb.n10.s:
+ br label %w.c2.p
+
+w.c2.p:
+ %i.05 = phi i32 [ 0, %bb.n10.s ], [ %inc11, %w.c ]
+ br i1 false, label %bb.n, label %w.e
+
+w.c2:
+ br i1 undef, label %w.b6, label %w.c2.w.ec
+
+w.c2.w.ec:
+ br label %w.e
+
+bb.n:
+ br label %w.b6
+
+w.b6:
+ br label %w.c2
+
+w.e:
+ %i.08 = phi i32 [ undef, %w.c2.w.ec ], [ %i.05, %w.c2.p ]
+ %inc11 = add nsw i32 %i.08, 1
+ br label %w.c
+
+w.e12:
+ ret i32 0
+}
diff --git a/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24-dbg.ll b/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24-dbg.ll
deleted file mode 100644
index 4ab95fc..0000000
--- a/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24-dbg.ll
+++ /dev/null
@@ -1,71 +0,0 @@
-; Split loop. Save last value. Split value is off by one in this example.
-; RUN: opt < %s -loop-index-split -disable-output -stats |& \
-; RUN: grep "loop-index-split" | count 1
-
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
-
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"
-
-@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-
-@k = external global i32 ; <i32*> [#uses=2]
-
-define void @foobar(i32 %a, i32 %b) {
-entry:
- br label %bb
-
-bb: ; preds = %cond_next16, %entry
- %i.01.0 = phi i32 [ 0, %entry ], [ %tmp18, %cond_next16 ] ; <i32> [#uses=5]
- %tsum.18.0 = phi i32 [ 42, %entry ], [ %tsum.013.1, %cond_next16 ] ; <i32> [#uses=3]
- %tmp1 = icmp sgt i32 %i.01.0, 50 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp1, label %cond_true, label %cond_false
-
-cond_true: ; preds = %bb
- %tmp4 = tail call i32 @foo( i32 %i.01.0 ) ; <i32> [#uses=1]
- %tmp6 = add i32 %tmp4, %tsum.18.0 ; <i32> [#uses=2]
- %tmp914 = load i32* @k, align 4 ; <i32> [#uses=1]
- %tmp1015 = icmp eq i32 %tmp914, 0 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp1015, label %cond_next16, label %cond_true13
-
-cond_false: ; preds = %bb
- %tmp8 = tail call i32 @bar( i32 %i.01.0 ) ; <i32> [#uses=0]
- %tmp9 = load i32* @k, align 4 ; <i32> [#uses=1]
- %tmp10 = icmp eq i32 %tmp9, 0 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp10, label %cond_next16, label %cond_true13
-
-cond_true13: ; preds = %cond_false, %cond_true
- %tsum.013.0 = phi i32 [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; <i32> [#uses=1]
- %tmp15 = tail call i32 @bar( i32 %i.01.0 ) ; <i32> [#uses=0]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %cond_next16
-
-cond_next16: ; preds = %cond_false, %cond_true, %cond_true13
- %tsum.013.1 = phi i32 [ %tsum.013.0, %cond_true13 ], [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; <i32> [#uses=2]
- %tmp18 = add i32 %i.01.0, 1 ; <i32> [#uses=3]
- %tmp21 = icmp slt i32 %tmp18, 100 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp21, label %bb, label %bb24
-
-bb24: ; preds = %cond_next16
- %tmp18.lcssa = phi i32 [ %tmp18, %cond_next16 ] ; <i32> [#uses=1]
- %tsum.013.1.lcssa = phi i32 [ %tsum.013.1, %cond_next16 ] ; <i32> [#uses=1]
- %tmp27 = tail call i32 @t( i32 %tmp18.lcssa, i32 %tsum.013.1.lcssa ) ; <i32> [#uses=0]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-}
-
-declare i32 @foo(i32)
-
-declare i32 @bar(i32)
-
-declare i32 @t(i32, i32)
diff --git a/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll b/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll
index 7c7a21c..99cb856 100644
--- a/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll
+++ b/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll
@@ -1,5 +1,4 @@
-; RUN: opt < %s -loop-reduce -S | grep ugt
-; PR2535
+; RUN: llc -march=x86-64 < %s -o - | grep {cmpl \\$\[1\], %}
@.str = internal constant [4 x i8] c"%d\0A\00"
@@ -16,7 +15,7 @@ forbody:
%add166 = or i32 %mul15, 1 ; <i32> [#uses=1] *
call i32 (i8*, ...)* @printf( i8* noalias getelementptr ([4 x i8]* @.str, i32 0, i32 0), i32 %add166 ) nounwind
%inc = add i32 %i.0, 1 ; <i32> [#uses=3]
- %cmp = icmp ult i32 %inc, 1027 ; <i1> [#uses=1]
+ %cmp = icmp ne i32 %inc, 1027 ; <i1> [#uses=1]
br i1 %cmp, label %forbody, label %afterfor
afterfor: ; preds = %forcond
diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
index 36941ad..1f7f6ec 100644
--- a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
+++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
@@ -1,10 +1,15 @@
-; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmpl \$4}
+; RUN: llc < %s -o - | 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"
target triple = "x86_64-apple-darwin9"
-; This is like change-compare-stride-trickiness-1.ll except the comparison
-; happens before the relevant use, so the comparison stride can't be
-; easily changed.
+; The comparison happens before the relevant use, but it can still be rewritten
+; to compare with zero.
+
+; CHECK: foo:
+; CHECK: align
+; CHECK: incl %eax
+; CHECK-NEXT: decl %ecx
+; CHECK-NEXT: jne
define void @foo() nounwind {
entry:
diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
index ea8a259..cb63809 100644
--- a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
+++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
@@ -1,10 +1,12 @@
-; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmp. \$8}
+; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmp. \$10}
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"
; 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.
+; TODO: By making the first store post-increment as well, the loop setup
+; could be made simpler.
define void @foo() nounwind {
entry:
diff --git a/test/Transforms/LoopStrengthReduce/count-to-zero.ll b/test/Transforms/LoopStrengthReduce/count-to-zero.ll
index 8cc3b5c..feb79f8 100644
--- a/test/Transforms/LoopStrengthReduce/count-to-zero.ll
+++ b/test/Transforms/LoopStrengthReduce/count-to-zero.ll
@@ -19,7 +19,7 @@ bb3: ; preds = %bb1
%tmp4 = add i32 %c_addr.1, -1 ; <i32> [#uses=1]
%c_addr.1.be = select i1 %tmp2, i32 %tmp3, i32 %tmp4 ; <i32> [#uses=1]
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
-; CHECK: sub i32 %lsr.iv, 1
+; CHECK: add i32 %lsr.iv, -1
br label %bb6
bb6: ; preds = %bb3, %entry
diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
index f86638b..4094e9c 100644
--- a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
+++ b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
@@ -1,5 +1,5 @@
; Check that the index of 'P[outer]' is pulled out of the loop.
-; RUN: opt < %s -loop-reduce -S | \
+; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \
; RUN: not grep {getelementptr.*%outer.*%INDVAR}
declare i1 @pred()
diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
index 37acf0f..e2aed78 100644
--- a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
+++ b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
@@ -1,5 +1,5 @@
; Check that the index of 'P[outer]' is pulled out of the loop.
-; RUN: opt < %s -loop-reduce -S | \
+; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \
; RUN: not grep {getelementptr.*%outer.*%INDVAR}
declare i1 @pred()
diff --git a/test/Transforms/LoopStrengthReduce/nonlinear-postinc.ll b/test/Transforms/LoopStrengthReduce/nonlinear-postinc.ll
new file mode 100644
index 0000000..1e63770
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/nonlinear-postinc.ll
@@ -0,0 +1,44 @@
+; RUN: opt < %s -loop-reduce
+; PR6453
+
+target datalayout = "e-p:64:64:64"
+
+define void @_ZNK15PolynomialSpaceILi3EE13compute_indexEjRA3_j() nounwind {
+entry:
+ br label %bb6
+
+bb6:
+ %t4 = phi i32 [ 0, %entry ], [ %t3, %bb5 ]
+ %t16 = sub i32 undef, %t4
+ %t25 = sub i32 undef, %t4
+ %t26 = add i32 undef, %t25
+ br label %bb4
+
+bb4:
+ %t2 = phi i32 [ %t1, %bb3 ], [ 0, %bb6 ]
+ %t17 = mul i32 %t2, %t16
+ %t18 = zext i32 %t2 to i33
+ %t19 = add i32 %t2, -1
+ %t20 = zext i32 %t19 to i33
+ %t21 = mul i33 %t18, %t20
+ %t22 = lshr i33 %t21, 1
+ %t23 = trunc i33 %t22 to i32
+ %t24 = sub i32 %t17, %t23
+ %t27 = add i32 %t24, %t26
+ br i1 false, label %bb1, label %bb5
+
+bb1:
+ %t = icmp ugt i32 %t27, undef
+ br i1 %t, label %bb2, label %bb3
+
+bb3:
+ %t1 = add i32 %t2, 1
+ br label %bb4
+
+bb5:
+ %t3 = add i32 %t4, 1
+ br label %bb6
+
+bb2:
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
index a032cc9..410d88f 100644
--- a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
+++ b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
@@ -1,7 +1,7 @@
; Check that this test makes INDVAR and related stuff dead, because P[indvar]
; gets reduced, making INDVAR dead.
-; RUN: opt < %s -loop-reduce -S | not grep INDVAR
+; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | not grep INDVAR
declare i1 @pred()
diff --git a/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
index c91f5cd..8959c17 100644
--- a/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
+++ b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -iv-users | grep {Stride i64 {3,+,2}<%loop>:}
+; RUN: opt < %s -analyze -iv-users | grep {\{1,+,3,+,2\}<%loop> (post-inc)}
; The value of %r is dependent on a polynomial iteration expression.
diff --git a/test/Transforms/LoopStrengthReduce/remove_indvar.ll b/test/Transforms/LoopStrengthReduce/remove_indvar.ll
index 53f4b9d..bb39532 100644
--- a/test/Transforms/LoopStrengthReduce/remove_indvar.ll
+++ b/test/Transforms/LoopStrengthReduce/remove_indvar.ll
@@ -7,10 +7,12 @@ define void @test(i32* %P) {
; <label>:0
br label %Loop
Loop: ; preds = %Loop, %0
+ %i = phi i32 [ 0, %0 ], [ %i.next, %Loop ]
%INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2]
%STRRED = getelementptr i32* %P, i32 %INDVAR ; <i32*> [#uses=1]
store i32 0, i32* %STRRED
%INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1]
+ %i.next = add i32 %i, 1
%cond = call i1 @pred( ) ; <i1> [#uses=1]
br i1 %cond, label %Loop, label %Out
Out: ; preds = %Loop
diff --git a/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll b/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll
index a99a823..5ed37dd 100644
--- a/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll
+++ b/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -loop-reduce -S | \
-; RUN: grep {add i32 %lsr.iv.next, 1}
+; RUN: grep {add i32 %indvar630.ui, 1}
;
; Make sure that the use of the IV outside of the loop (the store) uses the
; post incremented value of the IV, not the preincremented value. This
diff --git a/test/Transforms/Reassociate/crash.ll b/test/Transforms/Reassociate/crash.ll
index 060018d..6f21b66 100644
--- a/test/Transforms/Reassociate/crash.ll
+++ b/test/Transforms/Reassociate/crash.ll
@@ -23,11 +23,22 @@ entry:
%3 = add nsw i32 undef, %1
%4 = add nsw i32 %3, %2
%5 = add nsw i32 %4, 4
- %6 = shl i32 %0, 3 ; <i32> [#uses=1]
+ %6 = shl i32 %0, 3
%7 = add nsw i32 %5, %6
br label %bb4.i9
-bb4.i9: ; preds = %bb3.i7, %bb1.i25.i
+bb4.i9:
%8 = add nsw i32 undef, %1
ret i32 0
}
+
+
+define i32 @test3(i32 %Arg, i32 %x1, i32 %x2, i32 %x3) {
+ %A = mul i32 %x1, %Arg
+ %B = mul i32 %Arg, %x2 ;; Part of add operation being factored, also used by C
+ %C = mul i32 %x3, %B
+
+ %D = add i32 %A, %B
+ %E = add i32 %D, %C
+ ret i32 %E
+}
diff --git a/test/Transforms/SCCP/retvalue-undef.ll b/test/Transforms/SCCP/retvalue-undef.ll
new file mode 100644
index 0000000..389561f
--- /dev/null
+++ b/test/Transforms/SCCP/retvalue-undef.ll
@@ -0,0 +1,32 @@
+; RUN: opt -ipsccp -S %s | FileCheck %s
+; PR6414
+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 internal i32 ()* @f() {
+ ret i32 ()* @g
+}
+
+define internal i32 @g() {
+ ret i32 8
+}
+
+; CHECK: internal i32 @g()
+; CHECK-NEXT: ret i32 8
+
+define internal void @outer_mod() {
+ %1 = call i32 ()* ()* @f() ; <i32 ()*> [#uses=1]
+ %2 = call i32 %1() ; <i32> [#uses=0]
+ ret void
+}
+
+define internal void @module_init() {
+ call void @register_outer_mod(void ()* @outer_mod)
+ ret void
+}
+
+declare void @register_outer_mod(void ()*)
+
+define i32 @main() {
+ ret i32 0
+}
diff --git a/test/Transforms/ScalarRepl/2009-03-17-CleanUp.ll b/test/Transforms/ScalarRepl/2009-03-17-CleanUp.ll
deleted file mode 100644
index 9c70aae..0000000
--- a/test/Transforms/ScalarRepl/2009-03-17-CleanUp.ll
+++ /dev/null
@@ -1,3961 +0,0 @@
-; RUN: opt < %s -scalarrepl -S | grep store | not grep undef
-
-; ModuleID = '<stdin>'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
-target triple = "i386-pc-linux-gnu"
- type { } ; type %0
- type { double, double } ; type %1
- type { i32, void ()* } ; type %2
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, %0*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0*, %0*, i32 }
- %llvm.dbg.derivedtype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0* }
- %llvm.dbg.global_variable.type = type { i32, %0*, %0*, i8*, i8*, i8*, %0*, i32, %0*, i1, i1, %0* }
- %llvm.dbg.subprogram.type = type { i32, %0*, %0*, i8*, i8*, i8*, %0*, i32, %0*, i1, i1 }
- %llvm.dbg.subrange.type = type { i32, i64, i64 }
- %llvm.dbg.variable.type = type { i32, %0*, i8*, %0*, i32, %0* }
- %struct..0._50 = type { i32 }
- %struct..1__pthread_mutex_s = type { i32, i32, i32, i32, i32, %struct..0._50 }
- %struct.__class_type_info_pseudo = type { %struct.__type_info_pseudo }
- %struct.__locale_struct = type { [13 x %struct.locale_data*], i16*, i32*, i32*, [13 x i8*] }
- %struct.__pthread_slist_t = type { %struct.__pthread_slist_t* }
- %struct.__si_class_type_info_pseudo = type { %struct.__type_info_pseudo, %"struct.std::type_info"* }
- %struct.__type_info_pseudo = type { i8*, i8* }
- %struct.locale_data = type opaque
- %"struct.polynomial<double>" = type { i32 (...)**, double*, i32 }
- %"struct.polynomial<std::complex<double> >" = type { i32 (...)**, %"struct.std::complex<double>"*, i32 }
- %struct.pthread_attr_t = type { i32, [32 x i8] }
- %struct.pthread_mutex_t = type { %struct..1__pthread_mutex_s }
- %struct.pthread_mutexattr_t = type { i32 }
- %"struct.std::allocator<char>" = type <{ i8 }>
- %"struct.std::basic_ios<char,std::char_traits<char> >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8, i8, %"struct.std::basic_streambuf<char,std::char_traits<char> >"*, %"struct.std::ctype<char>"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"* }
- %"struct.std::basic_ostream<char,std::char_traits<char> >" = type { i32 (...)**, %"struct.std::basic_ios<char,std::char_traits<char> >" }
- %"struct.std::basic_streambuf<char,std::char_traits<char> >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" }
- %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider" = type { i8* }
- %"struct.std::complex<double>" = type { %1 }
- %"struct.std::ctype<char>" = type { %"struct.std::locale::facet", %struct.__locale_struct*, i8, i32*, i32*, i16*, i8, [256 x i8], [256 x i8], i8 }
- %"struct.std::exception" = type { i32 (...)** }
- %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" }
- %"struct.std::ios_base::Init" = type <{ i8 }>
- %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 }
- %"struct.std::ios_base::_Words" = type { i8*, i32 }
- %"struct.std::locale" = type { %"struct.std::locale::_Impl"* }
- %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** }
- %"struct.std::locale::facet" = type { i32 (...)**, i32 }
- %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >" = type { %"struct.std::locale::facet" }
- %"struct.std::num_put<char,std::ostreambuf_iterator<char, std::char_traits<char> > >" = type { %"struct.std::locale::facet" }
- %"struct.std::overflow_error" = type { %"struct.std::runtime_error" }
- %"struct.std::runtime_error" = type { %"struct.std::exception", %"struct.std::string" }
- %"struct.std::string" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider" }
- %"struct.std::type_info" = type { i32 (...)**, i8* }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [13 x i8] c"fftbench.cpp\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str1 = internal constant [42 x i8] c"/developer/home2/zsth/test/debug/tmp3/X3/\00", section "llvm.metadata" ; <[42 x i8]*> [#uses=1]
-@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5641) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([42 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str3 = internal constant [8 x i8] c"complex\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str4 = internal constant [110 x i8] c"/developer/home2/zsth/projects/llvm.org/install/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1\00", section "llvm.metadata" ; <[110 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit5 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([110 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str6 = internal constant [16 x i8] c"complex<double>\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str7 = internal constant [15 x i8] c"complex double\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str7, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 128, i64 64, i64 0, i32 0, i32 3 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str8 = internal constant [9 x i8] c"_M_value\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str8, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1195, i64 128, i64 64, i64 0, i32 1, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype9 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite10 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1161, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite10 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str11 = internal constant [7 x i8] c"double\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.basictype12 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str11, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 64, i64 0, i32 0, i32 4 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array13 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite14 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array13 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram15 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1215, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite14 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str16 = internal constant [15 x i8] c"complex<float>\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@.str18 = internal constant [14 x i8] c"complex float\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.basictype19 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str18, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 32, i64 0, i32 0, i32 3 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.derivedtype20 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str8, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1042, i64 64, i64 32, i64 0, i32 1, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype21 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite171 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array22 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype21 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite23 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array22 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram24 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1007, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite23 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str25 = internal constant [6 x i8] c"float\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.basictype26 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str25, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 4 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array27 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype21 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype26 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype26 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite28 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array27 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram29 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1062, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite28 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype30 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 128, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype31 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype30 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array32 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype21 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite33 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array32 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram34 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1464, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite33 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str35 = internal constant [21 x i8] c"complex<long double>\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@.str37 = internal constant [20 x i8] c"complex long double\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.basictype38 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([20 x i8]* @.str37, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 192, i64 32, i64 0, i32 0, i32 3 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.derivedtype39 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str8, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1348, i64 192, i64 32, i64 0, i32 1, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype38 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype40 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite122 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array41 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype40 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype38 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite42 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array41 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram43 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1314, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite42 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str44 = internal constant [12 x i8] c"long double\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.basictype45 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str44, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 96, i64 32, i64 0, i32 0, i32 4 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array46 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype40 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype45 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype45 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite47 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array46 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram48 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1352, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite47 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype49 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite171 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype50 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype49 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array51 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype40 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype50 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite52 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array51 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram53 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1480, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite52 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array54 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype40 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite55 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array54 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram56 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1484, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite55 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype57 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype45 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array58 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype57 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype40 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite59 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array58 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str60 = internal constant [5 x i8] c"real\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str61 = internal constant [24 x i8] c"_ZNSt7complexIeE4realEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram62 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str61, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1359, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite59 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str63 = internal constant [9 x i8] c"stddef.h\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@.str64 = internal constant [88 x i8] c"/developer/home2/zsth/projects/llvm.org/install/lib/gcc/i686-pc-linux-gnu/4.2.1/include\00", section "llvm.metadata" ; <[88 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit65 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([9 x i8]* @.str63, i32 0, i32 0), i8* getelementptr ([88 x i8]* @.str64, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str66 = internal constant [8 x i8] c"float_t\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype67 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str66, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit65 to %0*), i32 214, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype45 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str68 = internal constant [10 x i8] c"mathdef.h\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str69 = internal constant [18 x i8] c"/usr/include/bits\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit70 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([10 x i8]* @.str68, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str69, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str71 = internal constant [9 x i8] c"double_t\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype72 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str71, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit70 to %0*), i32 36, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype67 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype73 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 96, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype72 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype74 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype73 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype75 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 192, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite122 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype76 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype75 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array77 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype74 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype76 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite78 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array77 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str79 = internal constant [25 x i8] c"_ZNKSt7complexIeE4realEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram80 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str79, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1363, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite78 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str81 = internal constant [5 x i8] c"imag\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str82 = internal constant [24 x i8] c"_ZNSt7complexIeE4imagEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram83 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str82, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1367, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite59 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str84 = internal constant [25 x i8] c"_ZNKSt7complexIeE4imagEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram85 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str84, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1371, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite78 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype86 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite122 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array87 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype86 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype40 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype45 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite88 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array87 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str89 = internal constant [10 x i8] c"operator=\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str90 = internal constant [21 x i8] c"_ZNSt7complexIeEaSEe\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram91 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str90, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1375, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite88 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str92 = internal constant [11 x i8] c"operator+=\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str93 = internal constant [21 x i8] c"_ZNSt7complexIeEpLEe\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram94 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str93, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1383, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite88 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str95 = internal constant [11 x i8] c"operator-=\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str96 = internal constant [21 x i8] c"_ZNSt7complexIeEmIEe\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram97 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str96, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1390, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite88 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str98 = internal constant [11 x i8] c"operator*=\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str99 = internal constant [21 x i8] c"_ZNSt7complexIeEmLEe\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram100 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str99, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1397, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite88 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str101 = internal constant [11 x i8] c"operator/=\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str102 = internal constant [21 x i8] c"_ZNSt7complexIeEdVEe\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram103 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str102, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1404, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite88 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite104 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 55, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype105 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite104 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype106 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype105 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array107 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype86 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype40 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype106 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite108 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array107 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram109 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1335, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite108 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram110 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1337, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite108 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram111 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1339, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite108 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram112 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1341, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite108 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram113 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1343, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite108 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype114 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 192, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype38 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype115 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype114 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array116 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype115 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype76 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite117 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array116 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str118 = internal constant [6 x i8] c"__rep\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str119 = internal constant [26 x i8] c"_ZNKSt7complexIeE5__repEv\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram120 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str119, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1345, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite117 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array121 = internal constant [20 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype39 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram43 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram48 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram53 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram56 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram62 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram80 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram83 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram85 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram91 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram94 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram97 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram100 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram103 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram109 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram110 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram111 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram112 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram113 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram120 to %0*)], section "llvm.metadata" ; <[20 x %0*]*> [#uses=1]
-@llvm.dbg.composite122 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([21 x i8]* @.str35, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1310, i64 192, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([20 x %0*]* @llvm.dbg.array121 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype123 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 192, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite122 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype124 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype123 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array125 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype21 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype124 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite126 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array125 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram127 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1468, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite126 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype128 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype26 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array129 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype128 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype21 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite130 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array129 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str131 = internal constant [24 x i8] c"_ZNSt7complexIfE4realEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram132 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str131, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1046, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite130 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype133 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype26 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype134 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype133 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype135 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype49 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array136 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype134 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype135 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite137 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array136 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str138 = internal constant [25 x i8] c"_ZNKSt7complexIfE4realEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram139 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str138, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1050, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite137 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str140 = internal constant [24 x i8] c"_ZNSt7complexIfE4imagEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram141 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str140, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1054, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite130 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str142 = internal constant [25 x i8] c"_ZNKSt7complexIfE4imagEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram143 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str142, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1058, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite137 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype144 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite171 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array145 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype144 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype21 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype26 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite146 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array145 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str147 = internal constant [21 x i8] c"_ZNSt7complexIfEaSEf\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram148 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str147, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1069, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite146 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str149 = internal constant [21 x i8] c"_ZNSt7complexIfEpLEf\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram150 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str149, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1077, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite146 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str151 = internal constant [21 x i8] c"_ZNSt7complexIfEmIEf\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram152 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str151, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1084, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite146 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str153 = internal constant [21 x i8] c"_ZNSt7complexIfEmLEf\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram154 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str153, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1091, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite146 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str155 = internal constant [21 x i8] c"_ZNSt7complexIfEdVEf\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram156 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str155, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1098, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite146 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array157 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype144 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype21 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype106 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite158 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array157 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram159 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1029, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite158 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram160 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1031, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite158 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram161 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1033, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite158 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram162 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1035, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite158 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram163 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1037, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite158 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype164 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype165 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype164 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array166 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype165 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype135 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite167 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array166 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str168 = internal constant [26 x i8] c"_ZNKSt7complexIfE5__repEv\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram169 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str168, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1039, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite167 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array170 = internal constant [20 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype20 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram24 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram29 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram34 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram127 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram132 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram139 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram141 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram143 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram148 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram150 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram152 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram154 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram156 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram159 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram160 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram161 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram162 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram163 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram169 to %0*)], section "llvm.metadata" ; <[20 x %0*]*> [#uses=1]
-@llvm.dbg.composite171 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str16, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1003, i64 64, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([20 x %0*]* @llvm.dbg.array170 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype172 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite171 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype173 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype172 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array174 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype173 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite175 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array174 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram176 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1472, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite175 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array177 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype124 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite178 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array177 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram179 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1476, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite178 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype180 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array181 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype180 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite182 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array181 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str183 = internal constant [24 x i8] c"_ZNSt7complexIdE4realEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram184 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str183, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1199, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite182 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype185 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 64, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype186 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype185 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype187 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype30 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array188 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype186 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype187 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite189 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array188 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str190 = internal constant [25 x i8] c"_ZNKSt7complexIdE4realEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram191 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str190, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1203, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite189 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str192 = internal constant [24 x i8] c"_ZNSt7complexIdE4imagEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram193 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str192, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1207, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite182 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str194 = internal constant [25 x i8] c"_ZNKSt7complexIdE4imagEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram195 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str194, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1211, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite189 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype196 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array197 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype196 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite198 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array197 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str199 = internal constant [21 x i8] c"_ZNSt7complexIdEaSEd\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram200 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str199, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1222, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite198 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str201 = internal constant [21 x i8] c"_ZNSt7complexIdEpLEd\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram202 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str201, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1230, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite198 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str203 = internal constant [21 x i8] c"_ZNSt7complexIdEmIEd\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram204 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str203, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1237, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite198 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str205 = internal constant [21 x i8] c"_ZNSt7complexIdEmLEd\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram206 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str205, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1244, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite198 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str207 = internal constant [21 x i8] c"_ZNSt7complexIdEdVEd\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram208 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str207, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1251, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite198 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array209 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype196 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype106 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite210 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array209 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram211 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1182, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite210 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram212 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1184, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite210 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram213 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1186, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite210 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram214 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1188, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite210 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram215 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1190, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite210 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype216 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 128, i64 64, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype217 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype216 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array218 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype217 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype187 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite219 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array218 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str220 = internal constant [26 x i8] c"_ZNKSt7complexIdE5__repEv\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram221 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str220, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1192, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite219 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array222 = internal constant [20 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram15 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram176 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram179 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram184 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram191 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram193 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram195 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram200 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram202 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram204 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram206 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram208 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram211 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram212 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram213 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram214 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram215 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram221 to %0*)], section "llvm.metadata" ; <[20 x %0*]*> [#uses=1]
-@llvm.dbg.composite223 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str6, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1157, i64 128, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([20 x %0*]* @llvm.dbg.array222 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype224 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array225 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype224 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array225 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str226 = internal constant [22 x i8] c"_ZNSt7complexIdEC1ECd\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1]
-@llvm.dbg.subprogram227 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str226, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1161, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str230 = internal constant [4 x i8] c"__z\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.variable231 = internal constant %llvm.dbg.variable.type { i32 459009, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram227 to %0*), i8* getelementptr ([4 x i8]* @.str230, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1161, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram232 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str118, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str220, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1192, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite219 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram235 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str183, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1199, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite182 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram237 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str60, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str190, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1203, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite189 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram239 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str81, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str194, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1211, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite189 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str241 = internal constant [22 x i8] c"_ZNSt7complexIdEC1Edd\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1]
-@llvm.dbg.subprogram242 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str241, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1215, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite14 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str244 = internal constant [4 x i8] c"__r\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.subprogram248 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str199, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1222, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite198 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram252 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str101, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str207, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1251, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite198 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array255 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite256 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array255 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str257 = internal constant [14 x i8] c"random_double\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram258 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str257, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str257, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 55, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite256 to %0*), i1 true, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=0]
-@.str259 = internal constant [7 x i8] c"result\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@_ZZL13random_doublevE4seed = internal global i32 1325 ; <i32*> [#uses=14]
-@.str266 = internal constant [19 x i8] c"polynomial<double>\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@.str268 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype269 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str268, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array270 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite271 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array270 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype272 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite271 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype273 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype272 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str274 = internal constant [17 x i8] c"_vptr.polynomial\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype275 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str274, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 84, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype273 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype276 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str277 = internal constant [8 x i8] c"m_coeff\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype278 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str277, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 164, i64 32, i64 32, i64 32, i32 2, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype276 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str279 = internal constant [13 x i8] c"unsigned int\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.basictype280 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str279, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 7 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str281 = internal constant [7 x i8] c"size_t\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype282 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str281, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit65 to %0*), i32 152, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str283 = internal constant [9 x i8] c"m_degree\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype284 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str283, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 167, i64 32, i64 32, i64 64, i32 2, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype285 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array286 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite287 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array286 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str288 = internal constant [11 x i8] c"polynomial\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.subprogram289 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 211, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite287 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype290 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype185 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array291 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype290 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite292 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array291 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram293 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 220, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite292 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array294 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype186 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite295 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array294 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram296 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 232, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite295 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype297 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 96, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype298 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype297 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array299 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype298 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite300 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array299 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram301 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 242, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite300 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array302 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite303 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array302 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str304 = internal constant [12 x i8] c"~polynomial\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.subprogram305 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 252, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite303 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype306 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array307 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype306 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype298 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite308 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array307 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str309 = internal constant [27 x i8] c"_ZN10polynomialIdEaSERKS0_\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram310 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str309, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 259, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite308 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array311 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype186 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite312 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array311 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str313 = internal constant [11 x i8] c"initialize\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str314 = internal constant [35 x i8] c"_ZN10polynomialIdE10initializeERKd\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram315 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str313, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str313, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str314, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 203, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite312 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array316 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype306 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite317 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array316 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str318 = internal constant [8 x i8] c"stretch\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str319 = internal constant [29 x i8] c"_ZN10polynomialIdE7stretchEj\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram320 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str318, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str318, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str319, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 276, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite317 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype321 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype297 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array322 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype321 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite323 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array322 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str324 = internal constant [7 x i8] c"degree\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str325 = internal constant [29 x i8] c"_ZNK10polynomialIdE6degreeEv\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram326 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str325, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 111, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite323 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array327 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype321 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite328 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array327 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str329 = internal constant [4 x i8] c"get\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str330 = internal constant [26 x i8] c"_ZNK10polynomialIdE3getEj\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram331 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str330, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 300, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite328 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array332 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype180 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite333 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array332 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str334 = internal constant [11 x i8] c"operator[]\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str335 = internal constant [23 x i8] c"_ZN10polynomialIdEixEj\00", section "llvm.metadata" ; <[23 x i8]*> [#uses=1]
-@llvm.dbg.subprogram336 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([23 x i8]* @.str335, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 306, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite333 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array337 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype12 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype321 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype186 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite338 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array337 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str339 = internal constant [11 x i8] c"operator()\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str340 = internal constant [26 x i8] c"_ZNK10polynomialIdEclERKd\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram341 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str339, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str339, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str340, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 313, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite338 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array342 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype321 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite343 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array342 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str344 = internal constant [10 x i8] c"operator-\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str345 = internal constant [24 x i8] c"_ZNK10polynomialIdEngEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram346 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str345, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 335, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite343 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str347 = internal constant [10 x i8] c"operator+\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str348 = internal constant [24 x i8] c"_ZNK10polynomialIdEpsEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram349 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str348, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 346, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite343 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array350 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype321 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype298 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite351 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array350 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str352 = internal constant [28 x i8] c"_ZNK10polynomialIdEplERKS0_\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram353 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str352, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 353, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite351 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str354 = internal constant [28 x i8] c"_ZNK10polynomialIdEmiERKS0_\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram355 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str354, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 376, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite351 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array356 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite357 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array356 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str358 = internal constant [5 x i8] c"log2\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str359 = internal constant [26 x i8] c"_ZN10polynomialIdE4log2Ej\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram360 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str358, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str358, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str359, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 404, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite357 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array361 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite362 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array361 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str363 = internal constant [10 x i8] c"flip_bits\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str364 = internal constant [32 x i8] c"_ZN10polynomialIdE9flip_bitsEjj\00", section "llvm.metadata" ; <[32 x i8]*> [#uses=1]
-@llvm.dbg.subprogram365 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str363, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str363, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str364, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 423, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite362 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array366 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite367 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array366 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str368 = internal constant [12 x i8] c"stretch_fft\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str369 = internal constant [34 x i8] c"_ZN10polynomialIdE11stretch_fftEv\00", section "llvm.metadata" ; <[34 x i8]*> [#uses=1]
-@llvm.dbg.subprogram370 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str368, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str368, i32 0, i32 0), i8* getelementptr ([34 x i8]* @.str369, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 443, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite367 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str371 = internal constant [34 x i8] c"polynomial<std::complex<double> >\00", section "llvm.metadata" ; <[34 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype373 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str274, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 84, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype273 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype374 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str277, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 164, i64 32, i64 32, i64 32, i32 2, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype224 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype375 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str283, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 167, i64 32, i64 32, i64 64, i32 2, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype376 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array377 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite378 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array377 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram379 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 211, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite378 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array380 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype187 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite381 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array380 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram382 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 220, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite381 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array383 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite384 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array383 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram385 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 232, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite384 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype386 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 96, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype387 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype386 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array388 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype387 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite389 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array388 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram390 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 242, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite389 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array391 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite392 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array391 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram393 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 252, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite392 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype394 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array395 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype394 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype387 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite396 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array395 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str397 = internal constant [39 x i8] c"_ZN10polynomialISt7complexIdEEaSERKS2_\00", section "llvm.metadata" ; <[39 x i8]*> [#uses=1]
-@llvm.dbg.subprogram398 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([39 x i8]* @.str397, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 259, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite396 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array399 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite400 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array399 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str401 = internal constant [49 x i8] c"_ZN10polynomialISt7complexIdEE10initializeERKS1_\00", section "llvm.metadata" ; <[49 x i8]*> [#uses=1]
-@llvm.dbg.subprogram402 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str313, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str313, i32 0, i32 0), i8* getelementptr ([49 x i8]* @.str401, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 203, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite400 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array403 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype394 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite404 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array403 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str405 = internal constant [41 x i8] c"_ZN10polynomialISt7complexIdEE7stretchEj\00", section "llvm.metadata" ; <[41 x i8]*> [#uses=1]
-@llvm.dbg.subprogram406 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str318, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str318, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str405, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 276, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite404 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype407 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype386 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array408 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype407 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite409 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array408 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str410 = internal constant [41 x i8] c"_ZNK10polynomialISt7complexIdEE6degreeEv\00", section "llvm.metadata" ; <[41 x i8]*> [#uses=1]
-@llvm.dbg.subprogram411 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str410, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 111, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite409 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array412 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype407 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite413 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array412 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str414 = internal constant [38 x i8] c"_ZNK10polynomialISt7complexIdEE3getEj\00", section "llvm.metadata" ; <[38 x i8]*> [#uses=1]
-@llvm.dbg.subprogram415 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([38 x i8]* @.str414, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 300, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite413 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array416 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype196 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite417 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array416 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str418 = internal constant [35 x i8] c"_ZN10polynomialISt7complexIdEEixEj\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram419 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str418, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 306, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite417 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array420 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype407 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite421 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array420 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str422 = internal constant [40 x i8] c"_ZNK10polynomialISt7complexIdEEclERKS1_\00", section "llvm.metadata" ; <[40 x i8]*> [#uses=1]
-@llvm.dbg.subprogram423 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str339, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str339, i32 0, i32 0), i8* getelementptr ([40 x i8]* @.str422, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 313, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite421 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array424 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype407 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite425 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array424 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str426 = internal constant [36 x i8] c"_ZNK10polynomialISt7complexIdEEngEv\00", section "llvm.metadata" ; <[36 x i8]*> [#uses=1]
-@llvm.dbg.subprogram427 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([36 x i8]* @.str426, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 335, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite425 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str428 = internal constant [36 x i8] c"_ZNK10polynomialISt7complexIdEEpsEv\00", section "llvm.metadata" ; <[36 x i8]*> [#uses=1]
-@llvm.dbg.subprogram429 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([36 x i8]* @.str428, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 346, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite425 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array430 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype407 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype387 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite431 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array430 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str432 = internal constant [40 x i8] c"_ZNK10polynomialISt7complexIdEEplERKS2_\00", section "llvm.metadata" ; <[40 x i8]*> [#uses=1]
-@llvm.dbg.subprogram433 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([40 x i8]* @.str432, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 353, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite431 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str434 = internal constant [40 x i8] c"_ZNK10polynomialISt7complexIdEEmiERKS2_\00", section "llvm.metadata" ; <[40 x i8]*> [#uses=1]
-@llvm.dbg.subprogram435 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([40 x i8]* @.str434, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 376, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite431 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str436 = internal constant [38 x i8] c"_ZN10polynomialISt7complexIdEE4log2Ej\00", section "llvm.metadata" ; <[38 x i8]*> [#uses=1]
-@llvm.dbg.subprogram437 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str358, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str358, i32 0, i32 0), i8* getelementptr ([38 x i8]* @.str436, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 404, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite357 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str438 = internal constant [44 x i8] c"_ZN10polynomialISt7complexIdEE9flip_bitsEjj\00", section "llvm.metadata" ; <[44 x i8]*> [#uses=1]
-@llvm.dbg.subprogram439 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str363, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str363, i32 0, i32 0), i8* getelementptr ([44 x i8]* @.str438, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 423, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite362 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array440 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite441 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array440 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str442 = internal constant [46 x i8] c"_ZN10polynomialISt7complexIdEE11stretch_fftEv\00", section "llvm.metadata" ; <[46 x i8]*> [#uses=1]
-@llvm.dbg.subprogram443 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str368, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str368, i32 0, i32 0), i8* getelementptr ([46 x i8]* @.str442, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 443, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite441 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str444 = internal constant [49 x i8] c"polynomial<std::complex<std::complex<double> > >\00", section "llvm.metadata" ; <[49 x i8]*> [#uses=1]
-@llvm.dbg.composite445 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([49 x i8]* @.str444, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 84, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array446 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite445 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype387 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite447 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array446 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str448 = internal constant [12 x i8] c"bit_reverse\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str449 = internal constant [50 x i8] c"_ZN10polynomialISt7complexIdEE11bit_reverseERKS2_\00", section "llvm.metadata" ; <[50 x i8]*> [#uses=1]
-@llvm.dbg.subprogram450 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([50 x i8]* @.str449, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 469, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite447 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype451 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite445 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype452 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype451 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array453 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite445 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype452 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite454 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array453 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str455 = internal constant [59 x i8] c"_ZN10polynomialISt7complexIdEE11bit_reverseERKS_IS0_IS1_EE\00", section "llvm.metadata" ; <[59 x i8]*> [#uses=1]
-@llvm.dbg.subprogram456 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([59 x i8]* @.str455, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 483, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite454 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str457 = internal constant [4 x i8] c"fft\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str458 = internal constant [41 x i8] c"_ZN10polynomialISt7complexIdEE3fftERKS2_\00", section "llvm.metadata" ; <[41 x i8]*> [#uses=1]
-@llvm.dbg.subprogram459 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str457, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str457, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str458, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 497, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite447 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str460 = internal constant [12 x i8] c"inverse_fft\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str461 = internal constant [59 x i8] c"_ZN10polynomialISt7complexIdEE11inverse_fftERKS_IS0_IS1_EE\00", section "llvm.metadata" ; <[59 x i8]*> [#uses=1]
-@llvm.dbg.subprogram462 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str460, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str460, i32 0, i32 0), i8* getelementptr ([59 x i8]* @.str461, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 535, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite454 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str463 = internal constant [10 x i8] c"operator*\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str464 = internal constant [40 x i8] c"_ZNK10polynomialISt7complexIdEEmlERKS2_\00", section "llvm.metadata" ; <[40 x i8]*> [#uses=1]
-@llvm.dbg.subprogram465 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([40 x i8]* @.str464, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 576, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite431 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str466 = internal constant [39 x i8] c"_ZN10polynomialISt7complexIdEEpLERKS2_\00", section "llvm.metadata" ; <[39 x i8]*> [#uses=1]
-@llvm.dbg.subprogram467 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([39 x i8]* @.str466, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 625, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite396 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str468 = internal constant [39 x i8] c"_ZN10polynomialISt7complexIdEEmIERKS2_\00", section "llvm.metadata" ; <[39 x i8]*> [#uses=1]
-@llvm.dbg.subprogram469 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([39 x i8]* @.str468, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 636, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite396 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str470 = internal constant [39 x i8] c"_ZN10polynomialISt7complexIdEEmLERKS2_\00", section "llvm.metadata" ; <[39 x i8]*> [#uses=1]
-@llvm.dbg.subprogram471 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([39 x i8]* @.str470, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 647, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite396 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array472 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite473 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array472 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str474 = internal constant [8 x i8] c"acquire\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str475 = internal constant [41 x i8] c"_ZN10polynomialISt7complexIdEE7acquireEv\00", section "llvm.metadata" ; <[41 x i8]*> [#uses=1]
-@llvm.dbg.subprogram476 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str475, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 181, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite473 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str477 = internal constant [8 x i8] c"release\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str478 = internal constant [41 x i8] c"_ZN10polynomialISt7complexIdEE7releaseEv\00", section "llvm.metadata" ; <[41 x i8]*> [#uses=1]
-@llvm.dbg.subprogram479 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str478, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 188, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite473 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array480 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype376 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype187 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite481 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array480 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str482 = internal constant [10 x i8] c"deep_copy\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str483 = internal constant [47 x i8] c"_ZN10polynomialISt7complexIdEE9deep_copyEPKS1_\00", section "llvm.metadata" ; <[47 x i8]*> [#uses=1]
-@llvm.dbg.subprogram484 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([47 x i8]* @.str483, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 195, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite481 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array485 = internal constant [33 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype373 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype374 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype375 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram379 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram382 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram385 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram390 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram393 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram398 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram402 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram406 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram411 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram415 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram419 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram423 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram427 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram429 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram433 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram435 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram437 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram439 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram443 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram450 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram456 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram459 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram462 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram465 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram467 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram469 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram471 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram476 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram479 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram484 to %0*)], section "llvm.metadata" ; <[33 x %0*]*> [#uses=1]
-@llvm.dbg.composite486 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([34 x i8]* @.str371, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 84, i64 96, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([33 x %0*]* @llvm.dbg.array485 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array487 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype298 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite488 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array487 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str489 = internal constant [38 x i8] c"_ZN10polynomialIdE11bit_reverseERKS0_\00", section "llvm.metadata" ; <[38 x i8]*> [#uses=1]
-@llvm.dbg.subprogram490 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([38 x i8]* @.str489, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 469, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite488 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array491 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype387 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite492 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array491 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str493 = internal constant [52 x i8] c"_ZN10polynomialIdE11bit_reverseERKS_ISt7complexIdEE\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.subprogram494 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str493, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 483, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite492 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str495 = internal constant [29 x i8] c"_ZN10polynomialIdE3fftERKS0_\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram496 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str457, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str457, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str495, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 497, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite488 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str497 = internal constant [52 x i8] c"_ZN10polynomialIdE11inverse_fftERKS_ISt7complexIdEE\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.subprogram498 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str460, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str460, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str497, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 535, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite492 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str499 = internal constant [28 x i8] c"_ZNK10polynomialIdEmlERKS0_\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram500 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str499, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 576, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite351 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str501 = internal constant [27 x i8] c"_ZN10polynomialIdEpLERKS0_\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram502 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str501, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 625, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite308 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str503 = internal constant [27 x i8] c"_ZN10polynomialIdEmIERKS0_\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram504 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str503, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 636, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite308 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str505 = internal constant [27 x i8] c"_ZN10polynomialIdEmLERKS0_\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram506 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str98, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str505, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 647, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite308 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array507 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite508 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array507 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str509 = internal constant [29 x i8] c"_ZN10polynomialIdE7acquireEv\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram510 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str509, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 181, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite508 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str511 = internal constant [29 x i8] c"_ZN10polynomialIdE7releaseEv\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram512 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str511, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 188, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite508 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array513 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype290 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite514 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array513 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str515 = internal constant [33 x i8] c"_ZN10polynomialIdE9deep_copyEPKd\00", section "llvm.metadata" ; <[33 x i8]*> [#uses=1]
-@llvm.dbg.subprogram516 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([33 x i8]* @.str515, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 195, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite514 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array517 = internal constant [33 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype275 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype278 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype284 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram289 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram293 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram296 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram301 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram305 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram310 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram315 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram320 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram326 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram331 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram336 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram341 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram346 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram349 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram353 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram355 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram360 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram365 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram370 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram490 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram494 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram496 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram498 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram500 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram502 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram504 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram506 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram510 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram512 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram516 to %0*)], section "llvm.metadata" ; <[33 x %0*]*> [#uses=1]
-@llvm.dbg.composite518 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([19 x i8]* @.str266, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 84, i64 96, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([33 x %0*]* @llvm.dbg.array517 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype519 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array520 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype180 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype519 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite521 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array520 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram522 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([23 x i8]* @.str335, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 306, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite521 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram527 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str325, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 111, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite323 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram530 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str418, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 306, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite417 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array534 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype196 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype224 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite535 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array534 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str536 = internal constant [19 x i8] c"operator*=<double>\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@.str537 = internal constant [35 x i8] c"_ZNSt7complexIdEmLIdEERS0_RKS_IT_E\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram538 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([19 x i8]* @.str536, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str536, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str537, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1286, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite535 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str541 = internal constant [4 x i8] c"__t\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.variable542 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram538 to %0*), i8* getelementptr ([4 x i8]* @.str541, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1288, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram543 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([33 x i8]* @.str515, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 195, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite514 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram549 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str358, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str358, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str359, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 404, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite357 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array555 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite556 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array555 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str557 = internal constant [18 x i8] c"operator*<double>\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@.str558 = internal constant [32 x i8] c"_ZStmlIdESt7complexIT_ERKS2_S4_\00", section "llvm.metadata" ; <[32 x i8]*> [#uses=1]
-@llvm.dbg.subprogram559 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str557, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str557, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str558, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 378, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite556 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable564 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram559 to %0*), i8* getelementptr ([4 x i8]* @.str244, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 380, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram565 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str482, i32 0, i32 0), i8* getelementptr ([47 x i8]* @.str483, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 195, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite481 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram569 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str324, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str410, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 111, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite409 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array572 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype31 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite573 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array572 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str574 = internal constant [18 x i8] c"operator-<double>\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@.str575 = internal constant [29 x i8] c"_ZStngIdESt7complexIT_ERKS2_\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram576 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str574, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str574, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str575, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 443, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite573 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram578 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str330, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 300, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite328 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram581 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str363, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str363, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str364, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 423, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite362 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str591 = internal constant [19 x i8] c"operator/=<double>\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@.str592 = internal constant [35 x i8] c"_ZNSt7complexIdEdVIdEERS0_RKS_IT_E\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram593 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([19 x i8]* @.str591, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str591, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str592, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1297, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite535 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable596 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram593 to %0*), i8* getelementptr ([4 x i8]* @.str541, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1299, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str597 = internal constant [18 x i8] c"operator/<double>\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@.str598 = internal constant [32 x i8] c"_ZStdvIdESt7complexIT_ERKS2_S4_\00", section "llvm.metadata" ; <[32 x i8]*> [#uses=1]
-@llvm.dbg.subprogram599 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str597, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str597, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str598, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 408, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite556 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable602 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram599 to %0*), i8* getelementptr ([4 x i8]* @.str244, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 410, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str603 = internal constant [19 x i8] c"operator+=<double>\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@.str604 = internal constant [35 x i8] c"_ZNSt7complexIdEpLIdEERS0_RKS_IT_E\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram605 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([19 x i8]* @.str603, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str603, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str604, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1268, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite535 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str608 = internal constant [18 x i8] c"operator+<double>\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@.str609 = internal constant [32 x i8] c"_ZStplIdESt7complexIT_ERKS2_S4_\00", section "llvm.metadata" ; <[32 x i8]*> [#uses=1]
-@llvm.dbg.subprogram610 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str608, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str608, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str609, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 318, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite556 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable613 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram610 to %0*), i8* getelementptr ([4 x i8]* @.str244, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 320, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str614 = internal constant [19 x i8] c"operator-=<double>\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@.str615 = internal constant [35 x i8] c"_ZNSt7complexIdEmIIdEERS0_RKS_IT_E\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram616 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([19 x i8]* @.str614, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str614, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str615, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 1277, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite535 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str619 = internal constant [32 x i8] c"_ZStmiIdESt7complexIT_ERKS2_S4_\00", section "llvm.metadata" ; <[32 x i8]*> [#uses=1]
-@llvm.dbg.subprogram620 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str574, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str574, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str619, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 348, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite556 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable623 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram620 to %0*), i8* getelementptr ([4 x i8]* @.str244, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 350, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram624 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str329, i32 0, i32 0), i8* getelementptr ([38 x i8]* @.str414, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 300, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite413 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array627 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite628 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array627 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str629 = internal constant [42 x i8] c"__static_initialization_and_destruction_0\00", section "llvm.metadata" ; <[42 x i8]*> [#uses=1]
-@llvm.dbg.subprogram630 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([42 x i8]* @.str629, i32 0, i32 0), i8* getelementptr ([42 x i8]* @.str629, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 703, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite628 to %0*), i1 true, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=0]
-@.str635 = internal constant [9 x i8] c"iostream\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit636 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([9 x i8]* @.str635, i32 0, i32 0), i8* getelementptr ([110 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@_ZStL8__ioinit = internal global %"struct.std::allocator<char>" zeroinitializer ; <%"struct.std::allocator<char>"*> [#uses=2]
-@.str638 = internal constant [115 x i8] c"/developer/home2/zsth/projects/llvm.org/install/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits\00", section "llvm.metadata" ; <[115 x i8]*> [#uses=1]
-@__dso_handle = external global i8* ; <i8**> [#uses=1]
-@_ZGVN10polynomialIdE4PI2IE = weak global i64 0, align 8 ; <i64*> [#uses=1]
-@_ZN10polynomialIdE4PI2IE = weak global %"struct.std::complex<double>" zeroinitializer ; <%"struct.std::complex<double>"*> [#uses=3]
-@llvm.dbg.array654 = internal constant [1 x %0*] zeroinitializer, section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite655 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array654 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str656 = internal constant [16 x i8] c"_GLOBAL__I_main\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram657 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str656, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str656, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 704, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite655 to %0*), i1 true, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype658 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* null }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array659 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype658 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite660 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array659 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str661 = internal constant [8 x i8] c"__tcf_0\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.subprogram662 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str661, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str661, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit636 to %0*), i32 77, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite660 to %0*), i1 true, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram665 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str511, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 188, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite508 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str667 = internal constant [23 x i8] c"_ZN10polynomialIdED0Ev\00", section "llvm.metadata" ; <[23 x i8]*> [#uses=1]
-@llvm.dbg.subprogram668 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([23 x i8]* @.str667, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 252, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite508 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@_ZTV10polynomialIdE = weak constant [4 x i32 (...)*] [i32 (...)* null, i32 (...)* bitcast (%struct.__class_type_info_pseudo* @_ZTI10polynomialIdE to i32 (...)*), i32 (...)* bitcast (void (%"struct.polynomial<double>"*)* @_ZN10polynomialIdED1Ev to i32 (...)*), i32 (...)* bitcast (void (%"struct.polynomial<double>"*)* @_ZN10polynomialIdED0Ev to i32 (...)*)], align 8 ; <[4 x i32 (...)*]*> [#uses=1]
-@_ZTI10polynomialIdE = weak constant %struct.__class_type_info_pseudo { %struct.__type_info_pseudo { i8* inttoptr (i32 add (i32 ptrtoint ([0 x i32 (...)*]* @_ZTVN10__cxxabiv117__class_type_infoE to i32), i32 8) to i8*), i8* getelementptr ([16 x i8]* @_ZTS10polynomialIdE, i32 0, i32 0) } } ; <%struct.__class_type_info_pseudo*> [#uses=1]
-@_ZTVN10__cxxabiv117__class_type_infoE = external constant [0 x i32 (...)*] ; <[0 x i32 (...)*]*> [#uses=1]
-@_ZTS10polynomialIdE = weak constant [16 x i8] c"10polynomialIdE\00" ; <[16 x i8]*> [#uses=1]
-@.str671 = internal constant [5 x i8] c"char\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.basictype672 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str671, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 6 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str676 = internal constant [11 x i8] c"<built-in>\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit677 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([11 x i8]* @.str676, i32 0, i32 0), i8* getelementptr ([42 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@llvm.dbg.array680 = internal constant [0 x %0*] zeroinitializer, section "llvm.metadata" ; <[0 x %0*]*> [#uses=1]
-@.str690 = internal constant [23 x i8] c"_ZN10polynomialIdED1Ev\00", section "llvm.metadata" ; <[23 x i8]*> [#uses=1]
-@llvm.dbg.subprogram691 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([23 x i8]* @.str690, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 252, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite508 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram693 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str477, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str478, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 188, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite473 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str695 = internal constant [35 x i8] c"_ZN10polynomialISt7complexIdEED0Ev\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram696 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str695, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 252, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite473 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@_ZTV10polynomialISt7complexIdEE = weak constant [4 x i32 (...)*] [i32 (...)* null, i32 (...)* bitcast (%struct.__class_type_info_pseudo* @_ZTI10polynomialISt7complexIdEE to i32 (...)*), i32 (...)* bitcast (void (%"struct.polynomial<std::complex<double> >"*)* @_ZN10polynomialISt7complexIdEED1Ev to i32 (...)*), i32 (...)* bitcast (void (%"struct.polynomial<std::complex<double> >"*)* @_ZN10polynomialISt7complexIdEED0Ev to i32 (...)*)], align 8 ; <[4 x i32 (...)*]*> [#uses=1]
-@_ZTI10polynomialISt7complexIdEE = weak constant %struct.__class_type_info_pseudo { %struct.__type_info_pseudo { i8* inttoptr (i32 add (i32 ptrtoint ([0 x i32 (...)*]* @_ZTVN10__cxxabiv117__class_type_infoE to i32), i32 8) to i8*), i8* getelementptr ([28 x i8]* @_ZTS10polynomialISt7complexIdEE, i32 0, i32 0) } } ; <%struct.__class_type_info_pseudo*> [#uses=1]
-@_ZTS10polynomialISt7complexIdEE = weak constant [28 x i8] c"10polynomialISt7complexIdEE\00" ; <[28 x i8]*> [#uses=1]
-@.str707 = internal constant [35 x i8] c"_ZN10polynomialISt7complexIdEED1Ev\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram708 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str304, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str707, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 252, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite473 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram710 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str509, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 181, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite508 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str712 = internal constant [23 x i8] c"_ZN10polynomialIdEC1Ej\00", section "llvm.metadata" ; <[23 x i8]*> [#uses=1]
-@llvm.dbg.subprogram713 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([23 x i8]* @.str712, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 211, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite287 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str716 = internal constant [27 x i8] c"_ZN10polynomialIdEC1ERKS0_\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram717 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str716, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 242, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite300 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram720 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str318, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str318, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str319, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 276, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite317 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram729 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str309, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 259, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite308 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram732 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str474, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str475, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 181, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite473 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str734 = internal constant [35 x i8] c"_ZN10polynomialISt7complexIdEEC1Ej\00", section "llvm.metadata" ; <[35 x i8]*> [#uses=1]
-@llvm.dbg.subprogram735 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str288, i32 0, i32 0), i8* getelementptr ([35 x i8]* @.str734, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 211, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite378 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram738 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([38 x i8]* @.str489, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 469, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite488 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable744 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram738 to %0*), i8* getelementptr ([7 x i8]* @.str259, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 473, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram747 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str448, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str493, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 483, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite492 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable751 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram747 to %0*), i8* getelementptr ([7 x i8]* @.str259, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 487, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram753 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([39 x i8]* @.str397, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 259, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite396 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram756 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str368, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str368, i32 0, i32 0), i8* getelementptr ([34 x i8]* @.str369, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 443, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite367 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str759 = internal constant [35 x i8] c"overflow in fft polynomial stretch\00" ; <[35 x i8]*> [#uses=1]
-@_ZTISt14overflow_error = weak constant %struct.__si_class_type_info_pseudo { %struct.__type_info_pseudo { i8* inttoptr (i32 add (i32 ptrtoint ([0 x i32 (...)*]* @_ZTVN10__cxxabiv120__si_class_type_infoE to i32), i32 8) to i8*), i8* getelementptr ([19 x i8]* @_ZTSSt14overflow_error, i32 0, i32 0) }, %"struct.std::type_info"* bitcast (%struct.__si_class_type_info_pseudo* @_ZTISt13runtime_error to %"struct.std::type_info"*) } ; <%struct.__si_class_type_info_pseudo*> [#uses=2]
-@_ZTVN10__cxxabiv120__si_class_type_infoE = external constant [0 x i32 (...)*] ; <[0 x i32 (...)*]*> [#uses=1]
-@_ZTSSt14overflow_error = weak constant [19 x i8] c"St14overflow_error\00" ; <[19 x i8]*> [#uses=1]
-@_ZTISt13runtime_error = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=1]
-@.str769 = internal constant [10 x i8] c"stdexcept\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit770 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([10 x i8]* @.str769, i32 0, i32 0), i8* getelementptr ([110 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str773 = internal constant [15 x i8] c"overflow_error\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@.str775 = internal constant [14 x i8] c"runtime_error\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@.str777 = internal constant [10 x i8] c"exception\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit778 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([10 x i8]* @.str777, i32 0, i32 0), i8* getelementptr ([110 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str780 = internal constant [16 x i8] c"_vptr.exception\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype781 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str780, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit778 to %0*), i32 57, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype273 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype782 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite800 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array783 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype782 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite784 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array783 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram785 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str777, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str777, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit778 to %0*), i32 59, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite784 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array786 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype782 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite787 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array786 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str788 = internal constant [11 x i8] c"~exception\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.subprogram789 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str788, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str788, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit778 to %0*), i32 60, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite787 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype790 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype791 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype790 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype792 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite800 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype793 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype792 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array794 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype793 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite795 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array794 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str796 = internal constant [5 x i8] c"what\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str797 = internal constant [24 x i8] c"_ZNKSt9exception4whatEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram798 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str796, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str796, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str797, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit778 to %0*), i32 63, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite795 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array799 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype781 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram785 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram789 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram798 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite800 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str777, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit778 to %0*), i32 57, i64 32, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array799 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype801 = internal constant %llvm.dbg.derivedtype.type { i32 458780, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite800 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str802 = internal constant [12 x i8] c"stringfwd.h\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit803 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([12 x i8]* @.str802, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str804 = internal constant [64 x i8] c"basic_string<char,std::char_traits<char>,std::allocator<char> >\00", section "llvm.metadata" ; <[64 x i8]*> [#uses=1]
-@.str806 = internal constant [15 x i8] c"basic_string.h\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit807 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([15 x i8]* @.str806, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str808 = internal constant [13 x i8] c"_Alloc_hider\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str810 = internal constant [16 x i8] c"allocator<char>\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str812 = internal constant [16 x i8] c"new_allocator.h\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str813 = internal constant [114 x i8] c"/developer/home2/zsth/projects/llvm.org/install/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/ext\00", section "llvm.metadata" ; <[114 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit814 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([16 x i8]* @.str812, i32 0, i32 0), i8* getelementptr ([114 x i8]* @.str813, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str815 = internal constant [20 x i8] c"new_allocator<char>\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype817 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite877 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array818 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite819 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array818 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str820 = internal constant [14 x i8] c"new_allocator\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram821 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str820, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str820, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 68, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite819 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype822 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite877 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype823 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype822 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array824 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype823 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite825 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array824 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram826 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str820, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str820, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 70, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite825 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite827 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 54, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype828 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite827 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype829 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype828 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array830 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype829 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite831 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array830 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram832 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str820, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str820, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 73, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite831 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array833 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite834 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array833 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str835 = internal constant [15 x i8] c"~new_allocator\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram836 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str835, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str835, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 75, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite834 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype837 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype838 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype822 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype839 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array840 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype838 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype839 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite841 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array840 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str842 = internal constant [8 x i8] c"address\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str843 = internal constant [44 x i8] c"_ZNK9__gnu_cxx13new_allocatorIcE7addressERc\00", section "llvm.metadata" ; <[44 x i8]*> [#uses=1]
-@llvm.dbg.subprogram844 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str842, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str842, i32 0, i32 0), i8* getelementptr ([44 x i8]* @.str843, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 78, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite841 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype845 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype790 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array846 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype838 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype845 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite847 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array846 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str848 = internal constant [45 x i8] c"_ZNK9__gnu_cxx13new_allocatorIcE7addressERKc\00", section "llvm.metadata" ; <[45 x i8]*> [#uses=1]
-@llvm.dbg.subprogram849 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str842, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str842, i32 0, i32 0), i8* getelementptr ([45 x i8]* @.str848, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 81, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite847 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype850 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* null }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array851 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype850 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite852 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array851 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str853 = internal constant [9 x i8] c"allocate\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@.str854 = internal constant [46 x i8] c"_ZN9__gnu_cxx13new_allocatorIcE8allocateEjPKv\00", section "llvm.metadata" ; <[46 x i8]*> [#uses=1]
-@llvm.dbg.subprogram855 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str853, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str853, i32 0, i32 0), i8* getelementptr ([46 x i8]* @.str854, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 86, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite852 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array856 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite857 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array856 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str858 = internal constant [11 x i8] c"deallocate\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str859 = internal constant [48 x i8] c"_ZN9__gnu_cxx13new_allocatorIcE10deallocateEPcj\00", section "llvm.metadata" ; <[48 x i8]*> [#uses=1]
-@llvm.dbg.subprogram860 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str858, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str858, i32 0, i32 0), i8* getelementptr ([48 x i8]* @.str859, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 96, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite857 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array861 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype838 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite862 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array861 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str863 = internal constant [9 x i8] c"max_size\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@.str864 = internal constant [44 x i8] c"_ZNK9__gnu_cxx13new_allocatorIcE8max_sizeEv\00", section "llvm.metadata" ; <[44 x i8]*> [#uses=1]
-@llvm.dbg.subprogram865 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str863, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str863, i32 0, i32 0), i8* getelementptr ([44 x i8]* @.str864, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 100, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite862 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array866 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype845 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite867 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array866 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str868 = internal constant [10 x i8] c"construct\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str869 = internal constant [48 x i8] c"_ZN9__gnu_cxx13new_allocatorIcE9constructEPcRKc\00", section "llvm.metadata" ; <[48 x i8]*> [#uses=1]
-@llvm.dbg.subprogram870 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str868, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str868, i32 0, i32 0), i8* getelementptr ([48 x i8]* @.str869, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 106, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite867 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array871 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype817 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite872 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array871 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str873 = internal constant [8 x i8] c"destroy\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str874 = internal constant [43 x i8] c"_ZN9__gnu_cxx13new_allocatorIcE7destroyEPc\00", section "llvm.metadata" ; <[43 x i8]*> [#uses=1]
-@llvm.dbg.subprogram875 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str873, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str873, i32 0, i32 0), i8* getelementptr ([43 x i8]* @.str874, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 110, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite872 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array876 = internal constant [11 x %0*] [%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram821 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram826 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram832 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram836 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram844 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram849 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram855 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram860 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram865 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram870 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram875 to %0*)], section "llvm.metadata" ; <[11 x %0*]*> [#uses=1]
-@llvm.dbg.composite877 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([20 x i8]* @.str815, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit814 to %0*), i32 54, i64 8, i64 8, i64 0, i32 0, %0* null, %0* bitcast ([11 x %0*]* @llvm.dbg.array876 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype878 = internal constant %llvm.dbg.derivedtype.type { i32 458780, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit803 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite877 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype879 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite902 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array880 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype879 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite881 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array880 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str882 = internal constant [12 x i8] c"allocator.h\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit883 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([12 x i8]* @.str882, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str884 = internal constant [10 x i8] c"allocator\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.subprogram885 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str884, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str884, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit883 to %0*), i32 100, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite881 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype886 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite902 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype887 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype886 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array888 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype879 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite889 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array888 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram890 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str884, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str884, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit883 to %0*), i32 102, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite889 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite891 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit803 to %0*), i32 49, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype892 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite891 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype893 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype892 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array894 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype879 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype893 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite895 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array894 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram896 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str884, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str884, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit883 to %0*), i32 106, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite895 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array897 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype879 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite898 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array897 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str899 = internal constant [11 x i8] c"~allocator\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.subprogram900 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str899, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str899, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit883 to %0*), i32 108, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite898 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array901 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype878 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram885 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram890 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram896 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram900 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite902 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str810, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit803 to %0*), i32 49, i64 8, i64 8, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array901 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype903 = internal constant %llvm.dbg.derivedtype.type { i32 458780, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite902 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str904 = internal constant [5 x i8] c"_M_p\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype905 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str904, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 264, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype906 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite911 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array907 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype906 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite908 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array907 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram909 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str808, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str808, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 261, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite908 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array910 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype903 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype905 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram909 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite911 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str808, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 260, i64 32, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array910 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str912 = internal constant [12 x i8] c"_M_dataplus\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype913 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str912, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 276, i64 32, i64 32, i64 0, i32 1, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite911 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str914 = internal constant [7 x i8] c"string\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype915 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str914, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit803 to %0*), i32 56, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1693 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype916 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype915 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype917 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype916 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array918 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite919 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array918 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str920 = internal constant [8 x i8] c"_M_data\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str921 = internal constant [17 x i8] c"_ZNKSs7_M_dataEv\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram922 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str920, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str920, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str921, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 279, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite919 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype923 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1693 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array924 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite925 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array924 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str926 = internal constant [17 x i8] c"_ZNSs7_M_dataEPc\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram927 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str920, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str920, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str926, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 283, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite925 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str928 = internal constant [5 x i8] c"_Rep\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str930 = internal constant [10 x i8] c"_Rep_base\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str932 = internal constant [10 x i8] c"_M_length\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype933 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str932, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 149, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str934 = internal constant [12 x i8] c"_M_capacity\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype935 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str934, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 150, i64 32, i64 32, i64 32, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str936 = internal constant [10 x i8] c"ptrdiff_t\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype937 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str936, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit677 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype938 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype937 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str939 = internal constant [8 x i8] c"types.h\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit940 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([8 x i8]* @.str939, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str69, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str941 = internal constant [10 x i8] c"__int32_t\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype942 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str941, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 43, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype938 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str943 = internal constant [8 x i8] c"__pid_t\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype944 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str943, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 145, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype942 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str945 = internal constant [10 x i8] c"__daddr_t\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype946 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str945, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 154, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype944 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str947 = internal constant [8 x i8] c"__key_t\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype948 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str947, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 157, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype946 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str949 = internal constant [12 x i8] c"__clockid_t\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype950 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str949, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 158, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype948 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str951 = internal constant [10 x i8] c"__ssize_t\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype952 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str951, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 181, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype950 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str953 = internal constant [11 x i8] c"__intptr_t\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype954 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str953, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 189, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype952 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str955 = internal constant [12 x i8] c"_G_config.h\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str956 = internal constant [13 x i8] c"/usr/include\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit957 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([12 x i8]* @.str955, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str958 = internal constant [11 x i8] c"_G_int32_t\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype959 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str958, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit957 to %0*), i32 55, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype954 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str960 = internal constant [11 x i8] c"nl_types.h\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit961 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([11 x i8]* @.str960, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str962 = internal constant [8 x i8] c"nl_item\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype963 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str962, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit961 to %0*), i32 34, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype959 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str964 = internal constant [7 x i8] c"time.h\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit965 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([7 x i8]* @.str964, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str966 = internal constant [10 x i8] c"clockid_t\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype967 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str966, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit965 to %0*), i32 77, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype963 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str968 = internal constant [6 x i8] c"pid_t\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype969 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str968, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit965 to %0*), i32 105, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype967 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str970 = internal constant [15 x i8] c"__sig_atomic_t\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype971 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str970, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit965 to %0*), i32 413, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype969 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str972 = internal constant [15 x i8] c"pthreadtypes.h\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit973 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([15 x i8]* @.str972, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str69, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str974 = internal constant [15 x i8] c"pthread_once_t\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype975 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str974, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit973 to %0*), i32 109, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype971 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype976 = internal constant %llvm.dbg.derivedtype.type { i32 458805, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype975 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str977 = internal constant [19 x i8] c"pthread_spinlock_t\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype978 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([19 x i8]* @.str977, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit973 to %0*), i32 142, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype976 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str979 = internal constant [10 x i8] c"pthread.h\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit980 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([10 x i8]* @.str979, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str981 = internal constant [8 x i8] c"ssize_t\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype982 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str981, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit980 to %0*), i32 1101, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype978 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str983 = internal constant [9 x i8] c"unistd.h\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit984 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([9 x i8]* @.str983, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str985 = internal constant [9 x i8] c"intptr_t\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype986 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str985, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit984 to %0*), i32 226, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype982 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str987 = internal constant [15 x i8] c"gthr-default.h\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@.str988 = internal constant [133 x i8] c"/developer/home2/zsth/projects/llvm.org/install/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/i686-pc-linux-gnu/bits\00", section "llvm.metadata" ; <[133 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit989 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([15 x i8]* @.str987, i32 0, i32 0), i8* getelementptr ([133 x i8]* @.str988, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str990 = internal constant [17 x i8] c"__gthread_once_t\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype991 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str990, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit989 to %0*), i32 46, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype986 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype992 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str941, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 43, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype991 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str993 = internal constant [9 x i8] c"stdint.h\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit994 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([9 x i8]* @.str993, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str995 = internal constant [8 x i8] c"int32_t\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype996 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str995, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit994 to %0*), i32 38, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype992 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str997 = internal constant [14 x i8] c"int_least32_t\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype998 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str997, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit994 to %0*), i32 67, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype996 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str999 = internal constant [13 x i8] c"int_fast16_t\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1000 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str999, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit994 to %0*), i32 91, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype998 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1001 = internal constant [13 x i8] c"int_fast32_t\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1002 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1001, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit994 to %0*), i32 97, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1000 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1003 = internal constant [11 x i8] c"postypes.h\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1004 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([11 x i8]* @.str1003, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1005 = internal constant [11 x i8] c"streamsize\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1006 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1005, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1004 to %0*), i32 72, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1002 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1007 = internal constant [17 x i8] c"/usr/include/sys\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1008 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([8 x i8]* @.str939, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1007, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1009 = internal constant [8 x i8] c"daddr_t\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1010 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1009, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1008 to %0*), i32 105, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1006 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1011 = internal constant [6 x i8] c"key_t\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1012 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1011, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1008 to %0*), i32 117, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1010 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1013 = internal constant [11 x i8] c"register_t\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1014 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1013, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1008 to %0*), i32 204, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1012 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1015 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str936, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit677 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1014 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1016 = internal constant [9 x i8] c"stdlib.h\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1017 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([9 x i8]* @.str1016, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1018 = internal constant [13 x i8] c"_Atomic_word\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1019 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1018, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1017 to %0*), i32 962, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1015 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1020 = internal constant [12 x i8] c"_M_refcount\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1021 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str1020, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 151, i64 32, i64 32, i64 64, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1019 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1022 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype933 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype935 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1021 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1023 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str930, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 148, i64 96, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1022 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype1024 = internal constant %llvm.dbg.derivedtype.type { i32 458780, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1023 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1025 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1091 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1026 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1025 to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite1027 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array1026 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1028 = internal constant [13 x i8] c"_S_empty_rep\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str1029 = internal constant [27 x i8] c"_ZNSs4_Rep12_S_empty_repEv\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1030 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1028, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1028, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str1029, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 180, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1027 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1031 = internal constant [5 x i8] c"bool\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.basictype1032 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1031, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 2 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.derivedtype1033 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 96, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1091 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1034 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1033 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1035 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype1032 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1034 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1036 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1035 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1037 = internal constant [13 x i8] c"_M_is_leaked\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str1038 = internal constant [28 x i8] c"_ZNKSs4_Rep12_M_is_leakedEv\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1039 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1037, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1037, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str1038, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 190, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1036 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1040 = internal constant [13 x i8] c"_M_is_shared\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str1041 = internal constant [28 x i8] c"_ZNKSs4_Rep12_M_is_sharedEv\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1042 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1040, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1040, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str1041, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 194, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1036 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype1043 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1091 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1044 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1043 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1045 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1044 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1046 = internal constant [14 x i8] c"_M_set_leaked\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@.str1047 = internal constant [28 x i8] c"_ZNSs4_Rep13_M_set_leakedEv\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1048 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1046, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1046, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str1047, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 198, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1045 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1049 = internal constant [16 x i8] c"_M_set_sharable\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str1050 = internal constant [30 x i8] c"_ZNSs4_Rep15_M_set_sharableEv\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1051 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str1049, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1049, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str1050, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 202, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1045 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1052 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1043 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1053 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1052 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1054 = internal constant [27 x i8] c"_M_set_length_and_sharable\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@.str1055 = internal constant [41 x i8] c"_ZNSs4_Rep26_M_set_length_and_sharableEj\00", section "llvm.metadata" ; <[41 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1056 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([27 x i8]* @.str1054, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str1054, i32 0, i32 0), i8* getelementptr ([41 x i8]* @.str1055, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 206, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1053 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1057 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1043 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1058 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1057 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1059 = internal constant [11 x i8] c"_M_refdata\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str1060 = internal constant [25 x i8] c"_ZNSs4_Rep10_M_refdataEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1061 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1059, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1059, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str1060, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 216, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1058 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1062 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1043 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1063 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1062 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1064 = internal constant [8 x i8] c"_M_grab\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1065 = internal constant [30 x i8] c"_ZNSs4_Rep7_M_grabERKSaIcES2_\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1066 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1064, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1064, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str1065, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 220, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1063 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1067 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1043 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1068 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1067 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1069 = internal constant [17 x i8] c"basic_string.tcc\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1070 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([17 x i8]* @.str1069, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1071 = internal constant [10 x i8] c"_S_create\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str1072 = internal constant [31 x i8] c"_ZNSs4_Rep9_S_createEjjRKSaIcE\00", section "llvm.metadata" ; <[31 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1073 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str1071, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str1071, i32 0, i32 0), i8* getelementptr ([31 x i8]* @.str1072, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 529, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1068 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1074 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1043 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1075 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1074 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1076 = internal constant [11 x i8] c"_M_dispose\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str1077 = internal constant [31 x i8] c"_ZNSs4_Rep10_M_disposeERKSaIcE\00", section "llvm.metadata" ; <[31 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1078 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1076, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1076, i32 0, i32 0), i8* getelementptr ([31 x i8]* @.str1077, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 231, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1075 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1079 = internal constant [11 x i8] c"_M_destroy\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str1080 = internal constant [31 x i8] c"_ZNSs4_Rep10_M_destroyERKSaIcE\00", section "llvm.metadata" ; <[31 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1081 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1079, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1079, i32 0, i32 0), i8* getelementptr ([31 x i8]* @.str1080, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 427, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1075 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1082 = internal constant [11 x i8] c"_M_refcopy\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str1083 = internal constant [25 x i8] c"_ZNSs4_Rep10_M_refcopyEv\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1084 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1082, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1082, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str1083, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 245, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1058 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1085 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1043 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1086 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1085 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1087 = internal constant [9 x i8] c"_M_clone\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@.str1088 = internal constant [29 x i8] c"_ZNSs4_Rep8_M_cloneERKSaIcEj\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1089 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str1087, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str1087, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str1088, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 606, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1086 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1090 = internal constant [14 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1024 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1030 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1039 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1042 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1048 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1051 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1056 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1061 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1066 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1073 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1078 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1081 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1084 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1089 to %0*)], section "llvm.metadata" ; <[14 x %0*]*> [#uses=1]
-@llvm.dbg.composite1091 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str928, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 155, i64 96, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([14 x %0*]* @llvm.dbg.array1090 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype1092 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1091 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1093 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1092 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1094 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1093 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1095 = internal constant [16 x i8] c"_ZNKSs6_M_repEv\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1096 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str1087, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str1087, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1095, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 287, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1094 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1097 = internal constant [15 x i8] c"stl_iterator.h\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1098 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([15 x i8]* @.str1097, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1099 = internal constant [97 x i8] c"__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >\00", section "llvm.metadata" ; <[97 x i8]*> [#uses=1]
-@.str1101 = internal constant [11 x i8] c"_M_current\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1102 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1101, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 639, i64 32, i64 32, i64 0, i32 2, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1103 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1104 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1103 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1105 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1104 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1106 = internal constant [18 x i8] c"__normal_iterator\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1107 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str1106, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1106, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 650, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1105 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1108 = internal constant [10 x i8] c"__caddr_t\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1109 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str1108, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit940 to %0*), i32 188, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1110 = internal constant [15 x i8] c"__gnuc_va_list\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1111 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str1110, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit957 to %0*), i32 58, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1109 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1112 = internal constant [8 x i8] c"libio.h\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1113 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([8 x i8]* @.str1112, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str956, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1114 = internal constant [8 x i8] c"va_list\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1115 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1114, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1113 to %0*), i32 491, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1111 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1116 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1115 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1117 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1116 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1118 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1103 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1117 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1119 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1118 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1120 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str1106, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1106, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 653, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1119 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite1121 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 637, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype1122 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1121 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1123 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1122 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1124 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1103 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1123 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1125 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1124 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1126 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str1106, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1106, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 660, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1125 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype1127 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1128 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1127 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1129 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype839 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1128 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1130 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1129 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1131 = internal constant [44 x i8] c"_ZNK9__gnu_cxx17__normal_iteratorIPcSsEdeEv\00", section "llvm.metadata" ; <[44 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1132 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([44 x i8]* @.str1131, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 665, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1130 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1133 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1128 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1134 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1133 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1135 = internal constant [11 x i8] c"operator->\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str1136 = internal constant [44 x i8] c"_ZNK9__gnu_cxx17__normal_iteratorIPcSsEptEv\00", section "llvm.metadata" ; <[44 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1137 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1135, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1135, i32 0, i32 0), i8* getelementptr ([44 x i8]* @.str1136, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 669, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1134 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype1138 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1139 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1138 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1103 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1140 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1139 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1141 = internal constant [11 x i8] c"operator++\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str1142 = internal constant [43 x i8] c"_ZN9__gnu_cxx17__normal_iteratorIPcSsEppEv\00", section "llvm.metadata" ; <[43 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1143 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1141, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1141, i32 0, i32 0), i8* getelementptr ([43 x i8]* @.str1142, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 673, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1140 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1144 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1103 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1145 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1144 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1146 = internal constant [43 x i8] c"_ZN9__gnu_cxx17__normal_iteratorIPcSsEppEi\00", section "llvm.metadata" ; <[43 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1147 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1141, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1141, i32 0, i32 0), i8* getelementptr ([43 x i8]* @.str1146, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 680, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1145 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1148 = internal constant [11 x i8] c"operator--\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str1149 = internal constant [43 x i8] c"_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEv\00", section "llvm.metadata" ; <[43 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1150 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1148, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1148, i32 0, i32 0), i8* getelementptr ([43 x i8]* @.str1149, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 685, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1140 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1151 = internal constant [43 x i8] c"_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEi\00", section "llvm.metadata" ; <[43 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1152 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str1148, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1148, i32 0, i32 0), i8* getelementptr ([43 x i8]* @.str1151, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 692, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1145 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype1153 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1015 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1154 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype839 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1128 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1153 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1155 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1154 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1156 = internal constant [46 x i8] c"_ZNK9__gnu_cxx17__normal_iteratorIPcSsEixERKi\00", section "llvm.metadata" ; <[46 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1157 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([46 x i8]* @.str1156, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 697, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1155 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1158 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1138 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1103 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1153 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1159 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1158 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1160 = internal constant [45 x i8] c"_ZN9__gnu_cxx17__normal_iteratorIPcSsEpLERKi\00", section "llvm.metadata" ; <[45 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1161 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([45 x i8]* @.str1160, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 701, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1159 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1162 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1128 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1153 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1163 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1162 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1164 = internal constant [46 x i8] c"_ZNK9__gnu_cxx17__normal_iteratorIPcSsEplERKi\00", section "llvm.metadata" ; <[46 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1165 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str347, i32 0, i32 0), i8* getelementptr ([46 x i8]* @.str1164, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 705, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1163 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1166 = internal constant [45 x i8] c"_ZN9__gnu_cxx17__normal_iteratorIPcSsEmIERKi\00", section "llvm.metadata" ; <[45 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1167 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str95, i32 0, i32 0), i8* getelementptr ([45 x i8]* @.str1166, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 709, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1159 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1168 = internal constant [46 x i8] c"_ZNK9__gnu_cxx17__normal_iteratorIPcSsEmiERKi\00", section "llvm.metadata" ; <[46 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1169 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str344, i32 0, i32 0), i8* getelementptr ([46 x i8]* @.str1168, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 713, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1163 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1170 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1117 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1128 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1171 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1170 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1172 = internal constant [5 x i8] c"base\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1173 = internal constant [47 x i8] c"_ZNK9__gnu_cxx17__normal_iteratorIPcSsE4baseEv\00", section "llvm.metadata" ; <[47 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1174 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1172, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1172, i32 0, i32 0), i8* getelementptr ([47 x i8]* @.str1173, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 717, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1171 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1175 = internal constant [16 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1102 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1107 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1120 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1126 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1132 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1137 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1143 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1147 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1150 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1152 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1157 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1161 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1165 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1167 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1169 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1174 to %0*)], section "llvm.metadata" ; <[16 x %0*]*> [#uses=1]
-@llvm.dbg.composite1176 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([97 x i8]* @.str1099, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 637, i64 32, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([16 x %0*]* @llvm.dbg.array1175 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1177 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1178 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1177 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1179 = internal constant [19 x i8] c"_ZNKSs9_M_ibeginEv\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1180 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1172, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1172, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1179, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 293, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1178 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1181 = internal constant [8 x i8] c"_M_iend\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1182 = internal constant [17 x i8] c"_ZNKSs7_M_iendEv\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1183 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1181, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1181, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1182, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 297, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1178 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1184 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1185 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1184 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1186 = internal constant [8 x i8] c"_M_leak\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1187 = internal constant [16 x i8] c"_ZNSs7_M_leakEv\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1188 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1186, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1186, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1187, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 301, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1185 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1189 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1190 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1189 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1191 = internal constant [9 x i8] c"_M_check\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@.str1192 = internal constant [21 x i8] c"_ZNKSs8_M_checkEjPKc\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1193 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str1191, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str1191, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1192, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 308, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1190 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1194 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1195 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1194 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1196 = internal constant [16 x i8] c"_M_check_length\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str1197 = internal constant [30 x i8] c"_ZNKSs15_M_check_lengthEjjPKc\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1198 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str1196, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1196, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str1197, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 316, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1195 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1199 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1200 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1199 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1201 = internal constant [9 x i8] c"_M_limit\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@.str1202 = internal constant [19 x i8] c"_ZNKSs8_M_limitEjj\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1203 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str1201, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str1201, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1202, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 324, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1200 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1204 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype1032 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1205 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1204 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1206 = internal constant [12 x i8] c"_M_disjunct\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str1207 = internal constant [24 x i8] c"_ZNKSs11_M_disjunctEPKc\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1208 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str1206, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str1206, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str1207, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 332, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1205 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1209 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1210 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1209 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1211 = internal constant [8 x i8] c"_M_copy\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1212 = internal constant [21 x i8] c"_ZNSs7_M_copyEPcPKcj\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1213 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1211, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1211, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1212, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 341, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1210 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1214 = internal constant [8 x i8] c"_M_move\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1215 = internal constant [21 x i8] c"_ZNSs7_M_moveEPcPKcj\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1216 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1214, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1214, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1215, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 350, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1210 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1217 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1218 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1217 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1219 = internal constant [10 x i8] c"_M_assign\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str1220 = internal constant [21 x i8] c"_ZNSs9_M_assignEPcjc\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1221 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str1219, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str1219, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1220, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 359, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1218 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1222 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* null, %0* null], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1223 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1222 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1224 = internal constant [14 x i8] c"_S_copy_chars\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1225 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 371, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1223 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1226 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1227 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1226 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1228 = internal constant [64 x i8] c"_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_\00", section "llvm.metadata" ; <[64 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1229 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([64 x i8]* @.str1228, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 378, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1227 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1230 = internal constant [103 x i8] c"__normal_iterator<const char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >\00", section "llvm.metadata" ; <[103 x i8]*> [#uses=1]
-@llvm.dbg.composite1231 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([103 x i8]* @.str1230, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 637, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1232 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1231 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1231 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1233 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1232 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1234 = internal constant [65 x i8] c"_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_\00", section "llvm.metadata" ; <[65 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1235 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([65 x i8]* @.str1234, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 382, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1233 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1236 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1237 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1236 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1238 = internal constant [28 x i8] c"_ZNSs13_S_copy_charsEPcS_S_\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1239 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str1238, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 386, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1237 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1240 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1241 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1240 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1242 = internal constant [30 x i8] c"_ZNSs13_S_copy_charsEPcPKcS1_\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1243 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1224, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str1242, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 390, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1241 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1244 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1245 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1244 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1246 = internal constant [10 x i8] c"_M_mutate\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str1247 = internal constant [20 x i8] c"_ZNSs9_M_mutateEjjj\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1248 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str1246, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str1246, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1247, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 451, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1245 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1249 = internal constant [13 x i8] c"_M_leak_hard\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str1250 = internal constant [22 x i8] c"_ZNSs12_M_leak_hardEv\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1251 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1249, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1249, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str1250, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 437, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1185 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1252 = internal constant [22 x i8] c"_ZNSs12_S_empty_repEv\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1253 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1028, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1028, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str1252, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 400, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1027 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1254 = internal constant [13 x i8] c"basic_string\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1255 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 2055, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1185 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1256 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1257 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1256 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1258 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 191, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1257 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype1259 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype916 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1260 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1261 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1260 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1262 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 183, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1261 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1263 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1264 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1263 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1265 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 197, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1264 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1266 = internal constant [6 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1267 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1266 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1268 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 208, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1267 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1269 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1270 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1269 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1271 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 219, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1270 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1272 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1273 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1272 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1274 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 226, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1273 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1275 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1276 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1275 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1277 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 233, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1276 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1278 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1279 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1278 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1280 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1254, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 477, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1279 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1281 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1282 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1281 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1283 = internal constant [14 x i8] c"~basic_string\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1284 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1283, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1283, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 482, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1282 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype1285 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1693 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1286 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1287 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1286 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1288 = internal constant [13 x i8] c"_ZNSsaSERKSs\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1289 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1288, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 490, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1287 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1290 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1291 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1290 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1292 = internal constant [12 x i8] c"_ZNSsaSEPKc\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1293 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str1292, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 498, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1291 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1294 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1295 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1294 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1296 = internal constant [10 x i8] c"_ZNSsaSEc\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1297 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str89, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str1296, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 509, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1295 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1298 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1299 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1298 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1300 = internal constant [6 x i8] c"begin\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1301 = internal constant [14 x i8] c"_ZNSs5beginEv\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1302 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1300, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1300, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1301, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 521, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1299 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1303 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1231 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1304 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1303 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1305 = internal constant [15 x i8] c"_ZNKSs5beginEv\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1306 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1300, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1300, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1305, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 532, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1304 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1307 = internal constant [4 x i8] c"end\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1308 = internal constant [12 x i8] c"_ZNSs3endEv\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1309 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str1307, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str1307, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str1308, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 540, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1299 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1310 = internal constant [13 x i8] c"_ZNKSs3endEv\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1311 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str1307, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str1307, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1310, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 551, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1304 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1312 = internal constant [128 x i8] c"reverse_iterator<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >\00", section "llvm.metadata" ; <[128 x i8]*> [#uses=1]
-@llvm.dbg.composite1313 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([128 x i8]* @.str1312, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 100, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1314 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1313 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1315 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1314 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1316 = internal constant [7 x i8] c"rbegin\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1317 = internal constant [15 x i8] c"_ZNSs6rbeginEv\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1318 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1316, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1316, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1317, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 560, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1315 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1319 = internal constant [134 x i8] c"reverse_iterator<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >\00", section "llvm.metadata" ; <[134 x i8]*> [#uses=1]
-@llvm.dbg.composite1320 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([134 x i8]* @.str1319, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1098 to %0*), i32 100, i64 0, i64 0, i64 0, i32 4, %0* null, %0* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1321 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1320 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1322 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1321 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1323 = internal constant [16 x i8] c"_ZNKSs6rbeginEv\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1324 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1316, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1316, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1323, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 569, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1322 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1325 = internal constant [5 x i8] c"rend\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1326 = internal constant [13 x i8] c"_ZNSs4rendEv\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1327 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1325, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1325, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1326, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 578, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1315 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1328 = internal constant [14 x i8] c"_ZNKSs4rendEv\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1329 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1325, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1325, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1328, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 587, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1322 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1330 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1331 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1330 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1332 = internal constant [5 x i8] c"size\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1333 = internal constant [14 x i8] c"_ZNKSs4sizeEv\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1334 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1332, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1332, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1333, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 595, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1331 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1335 = internal constant [7 x i8] c"length\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1336 = internal constant [16 x i8] c"_ZNKSs6lengthEv\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1337 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1335, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1335, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1336, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 601, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1331 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1338 = internal constant [18 x i8] c"_ZNKSs8max_sizeEv\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1339 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str863, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str863, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1338, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 606, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1331 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1340 = internal constant [4 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1341 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1340 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1342 = internal constant [7 x i8] c"resize\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1343 = internal constant [16 x i8] c"_ZNSs6resizeEjc\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1344 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1342, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1342, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1343, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 622, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1341 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1345 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1346 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1345 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1347 = internal constant [15 x i8] c"_ZNSs6resizeEj\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1348 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1342, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1342, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1347, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 633, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1346 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1349 = internal constant [9 x i8] c"capacity\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@.str1350 = internal constant [18 x i8] c"_ZNKSs8capacityEv\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1351 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @.str1349, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str1349, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1350, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 641, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1331 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite1352 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1345 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1353 = internal constant [8 x i8] c"reserve\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1354 = internal constant [16 x i8] c"_ZNSs7reserveEj\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1355 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1353, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1353, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1354, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 484, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1352 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1356 = internal constant [6 x i8] c"clear\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1357 = internal constant [14 x i8] c"_ZNSs5clearEv\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1358 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1356, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1356, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1357, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 668, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1185 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1359 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype1032 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1360 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1359 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1361 = internal constant [6 x i8] c"empty\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1362 = internal constant [15 x i8] c"_ZNKSs5emptyEv\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1363 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1361, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1361, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1362, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 675, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1360 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1364 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype845 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1365 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1364 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1366 = internal constant [11 x i8] c"_ZNKSsixEj\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1367 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1366, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 690, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1365 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1368 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype839 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1369 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1368 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1370 = internal constant [10 x i8] c"_ZNSsixEj\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1371 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str334, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str1370, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 707, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1369 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1372 = internal constant [3 x i8] c"at\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1]
-@.str1373 = internal constant [12 x i8] c"_ZNKSs2atEj\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1374 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([3 x i8]* @.str1372, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str1372, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str1373, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 728, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1365 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1375 = internal constant [11 x i8] c"_ZNSs2atEj\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1376 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([3 x i8]* @.str1372, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str1372, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str1375, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 747, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1369 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1377 = internal constant [13 x i8] c"_ZNSspLERKSs\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1378 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1377, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 762, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1287 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1379 = internal constant [12 x i8] c"_ZNSspLEPKc\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1380 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str1379, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 771, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1291 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1381 = internal constant [10 x i8] c"_ZNSspLEc\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1382 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str92, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str1381, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 780, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1295 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1383 = internal constant [7 x i8] c"append\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1384 = internal constant [18 x i8] c"_ZNSs6appendERKSs\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1385 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1384, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 330, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1287 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1386 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1387 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1386 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1388 = internal constant [20 x i8] c"_ZNSs6appendERKSsjj\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1389 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1388, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 347, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1387 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1390 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1391 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1390 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1392 = internal constant [18 x i8] c"_ZNSs6appendEPKcj\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1393 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1392, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 303, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1391 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1394 = internal constant [17 x i8] c"_ZNSs6appendEPKc\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1395 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1394, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 824, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1291 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1396 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1397 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1396 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1398 = internal constant [16 x i8] c"_ZNSs6appendEjc\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1399 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1398, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 286, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1397 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1400 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* null, %0* null], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1401 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1400 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1402 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1383, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 851, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1401 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1403 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1404 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1403 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1405 = internal constant [10 x i8] c"push_back\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str1406 = internal constant [18 x i8] c"_ZNSs9push_backEc\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1407 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str1405, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str1405, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1406, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 859, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1404 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1408 = internal constant [7 x i8] c"assign\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1409 = internal constant [18 x i8] c"_ZNSs6assignERKSs\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1410 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1409, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 248, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1287 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1411 = internal constant [20 x i8] c"_ZNSs6assignERKSsjj\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1412 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1411, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 889, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1387 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1413 = internal constant [18 x i8] c"_ZNSs6assignEPKcj\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1414 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1413, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 264, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1391 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1415 = internal constant [17 x i8] c"_ZNSs6assignEPKc\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1416 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1415, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 917, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1291 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1417 = internal constant [16 x i8] c"_ZNSs6assignEjc\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1418 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1417, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 933, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1397 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite1419 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1400 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1420 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1408, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 946, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1419 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1421 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1422 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1421 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1423 = internal constant [7 x i8] c"insert\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1424 = internal constant [53 x i8] c"_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEjc\00", section "llvm.metadata" ; <[53 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1425 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([53 x i8]* @.str1424, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 962, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1422 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1426 = internal constant [5 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* null, %0* null], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1427 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1426 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1428 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 978, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1427 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1429 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1430 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1429 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1431 = internal constant [19 x i8] c"_ZNSs6insertEjRKSs\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1432 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1431, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 993, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1430 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1433 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1434 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1433 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1435 = internal constant [21 x i8] c"_ZNSs6insertEjRKSsjj\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1436 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1435, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1016, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1434 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1437 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1438 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1437 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1439 = internal constant [19 x i8] c"_ZNSs6insertEjPKcj\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1440 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1439, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 365, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1438 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1441 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1442 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1441 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1443 = internal constant [18 x i8] c"_ZNSs6insertEjPKc\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1444 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1443, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1056, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1442 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1445 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1446 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1445 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1447 = internal constant [17 x i8] c"_ZNSs6insertEjjc\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1448 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1447, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1079, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1446 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1449 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1450 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1449 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1451 = internal constant [52 x i8] c"_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEc\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1452 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1423, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str1451, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1096, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1450 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1453 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1454 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1453 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1455 = internal constant [6 x i8] c"erase\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1456 = internal constant [15 x i8] c"_ZNSs5eraseEjj\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1457 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1455, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1455, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1456, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1120, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1454 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1458 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1459 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1458 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1460 = internal constant [50 x i8] c"_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE\00", section "llvm.metadata" ; <[50 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1461 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1455, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1455, i32 0, i32 0), i8* getelementptr ([50 x i8]* @.str1460, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1136, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1459 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1462 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1463 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1462 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1464 = internal constant [53 x i8] c"_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_\00", section "llvm.metadata" ; <[53 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1465 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1455, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1455, i32 0, i32 0), i8* getelementptr ([53 x i8]* @.str1464, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1156, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1463 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1466 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1467 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1466 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1468 = internal constant [8 x i8] c"replace\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1469 = internal constant [21 x i8] c"_ZNSs7replaceEjjRKSs\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1470 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1469, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1183, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1467 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1471 = internal constant [7 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[7 x %0*]*> [#uses=1]
-@llvm.dbg.composite1472 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([7 x %0*]* @llvm.dbg.array1471 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1473 = internal constant [23 x i8] c"_ZNSs7replaceEjjRKSsjj\00", section "llvm.metadata" ; <[23 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1474 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([23 x i8]* @.str1473, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1206, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1472 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1475 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1476 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1475 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1477 = internal constant [21 x i8] c"_ZNSs7replaceEjjPKcj\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1478 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1477, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 397, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1476 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1479 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1480 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1479 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1481 = internal constant [20 x i8] c"_ZNSs7replaceEjjPKc\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1482 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1481, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1248, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1480 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1483 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1484 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1483 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1485 = internal constant [19 x i8] c"_ZNSs7replaceEjjjc\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1486 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1485, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1271, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1484 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1487 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1488 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1487 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1489 = internal constant [59 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs\00", section "llvm.metadata" ; <[59 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1490 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([59 x i8]* @.str1489, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1289, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1488 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1491 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1492 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1491 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1493 = internal constant [59 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcj\00", section "llvm.metadata" ; <[59 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1494 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([59 x i8]* @.str1493, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1307, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1492 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1495 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1496 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1495 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1497 = internal constant [58 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKc\00", section "llvm.metadata" ; <[58 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1498 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([58 x i8]* @.str1497, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1328, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1496 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1499 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1500 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1499 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1501 = internal constant [57 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc\00", section "llvm.metadata" ; <[57 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1502 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([57 x i8]* @.str1501, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1349, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1500 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1503 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* null, %0* null], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1504 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1503 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1505 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1373, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1504 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1506 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1507 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1506 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1508 = internal constant [61 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1_\00", section "llvm.metadata" ; <[61 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1509 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([61 x i8]* @.str1508, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1385, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1507 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1510 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1511 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1510 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1512 = internal constant [61 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_\00", section "llvm.metadata" ; <[61 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1513 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([61 x i8]* @.str1512, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1396, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1511 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1514 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1515 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1514 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1516 = internal constant [61 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2_\00", section "llvm.metadata" ; <[61 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1517 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([61 x i8]* @.str1516, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1406, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1515 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1518 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1231 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1231 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1519 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1518 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1520 = internal constant [70 x i8] c"_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_\00", section "llvm.metadata" ; <[70 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1521 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1468, i32 0, i32 0), i8* getelementptr ([70 x i8]* @.str1520, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1417, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1519 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1522 = internal constant [18 x i8] c"cpp_type_traits.h\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1523 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([18 x i8]* @.str1522, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1524 = internal constant [12 x i8] c"__true_type\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@llvm.dbg.composite1526 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str1524, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1523 to %0*), i32 97, i64 8, i64 8, i64 0, i32 0, %0* null, %0* bitcast ([0 x %0*]* @llvm.dbg.array680 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1527 = internal constant [7 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1526 to %0*)], section "llvm.metadata" ; <[7 x %0*]*> [#uses=1]
-@llvm.dbg.composite1528 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([7 x %0*]* @llvm.dbg.array1527 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1529 = internal constant [20 x i8] c"_M_replace_dispatch\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1530 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([20 x i8]* @.str1529, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1529, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1430, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1528 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1531 = internal constant [13 x i8] c"__false_type\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.composite1533 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1531, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1523 to %0*), i32 98, i64 8, i64 8, i64 0, i32 0, %0* null, %0* bitcast ([0 x %0*]* @llvm.dbg.array680 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1534 = internal constant [7 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1176 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1533 to %0*)], section "llvm.metadata" ; <[7 x %0*]*> [#uses=1]
-@llvm.dbg.composite1535 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([7 x %0*]* @llvm.dbg.array1534 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1536 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([20 x i8]* @.str1529, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1529, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1436, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1535 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1537 = internal constant [15 x i8] c"_M_replace_aux\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@.str1538 = internal constant [27 x i8] c"_ZNSs14_M_replace_auxEjjjc\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1539 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str1537, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1537, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str1538, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 651, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1484 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1540 = internal constant [16 x i8] c"_M_replace_safe\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str1541 = internal constant [30 x i8] c"_ZNSs15_M_replace_safeEjjPKcj\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1542 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str1540, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1540, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str1541, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 664, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1476 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1543 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1533 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1544 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1543 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1545 = internal constant [17 x i8] c"_S_construct_aux\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1546 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str1545, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1545, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1451, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1544 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1547 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1526 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1548 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1547 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1549 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str1545, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1545, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1460, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1548 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1550 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1551 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1550 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1552 = internal constant [13 x i8] c"_S_construct\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1553 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1466, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1551 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1554 = internal constant [26 x i8] c"stl_iterator_base_types.h\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit1555 = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 4, i8* getelementptr ([26 x i8]* @.str1554, i32 0, i32 0), i8* getelementptr ([115 x i8]* @.str638, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str1556 = internal constant [19 x i8] c"input_iterator_tag\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.composite1558 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([19 x i8]* @.str1556, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1555 to %0*), i32 80, i64 8, i64 8, i64 0, i32 0, %0* null, %0* bitcast ([0 x %0*]* @llvm.dbg.array680 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1559 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1558 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1560 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1559 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1561 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1476, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1560 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1562 = internal constant [21 x i8] c"forward_iterator_tag\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1564 = internal constant %llvm.dbg.derivedtype.type { i32 458780, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1555 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1558 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1565 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1564 to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite1566 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([21 x i8]* @.str1562, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1555 to %0*), i32 84, i64 8, i64 8, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array1565 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.array1567 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* null, %0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*), %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1566 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1568 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1567 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1569 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1483, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1568 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1570 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype887 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1571 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1570 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1572 = internal constant [30 x i8] c"_ZNSs12_S_constructEjcRKSaIcE\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1573 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1552, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str1572, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 166, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1571 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1574 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1575 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1574 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1576 = internal constant [5 x i8] c"copy\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1577 = internal constant [17 x i8] c"_ZNKSs4copyEPcjj\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1578 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1576, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1576, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1577, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 705, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1575 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1579 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype923 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1285 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1580 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1579 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1581 = internal constant [5 x i8] c"swap\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1582 = internal constant [15 x i8] c"_ZNSs4swapERSs\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1583 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1581, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1581, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1582, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 501, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1580 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1584 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1585 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1584 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1586 = internal constant [6 x i8] c"c_str\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1587 = internal constant [15 x i8] c"_ZNKSs5c_strEv\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1588 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1586, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1586, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1587, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1522, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1585 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1589 = internal constant [5 x i8] c"data\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1590 = internal constant [14 x i8] c"_ZNKSs4dataEv\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1591 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1589, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1589, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1590, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1532, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1585 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1592 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite902 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1593 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1592 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1594 = internal constant [14 x i8] c"get_allocator\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@.str1595 = internal constant [24 x i8] c"_ZNKSs13get_allocatorEv\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1596 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1594, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1594, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str1595, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1539, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1593 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1597 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1598 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1597 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1599 = internal constant [5 x i8] c"find\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str1600 = internal constant [18 x i8] c"_ZNKSs4findEPKcjj\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1601 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1600, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 719, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1598 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1602 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1603 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1602 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1604 = internal constant [18 x i8] c"_ZNKSs4findERKSsj\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1605 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1604, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1567, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1603 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1606 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1607 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1606 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1608 = internal constant [17 x i8] c"_ZNKSs4findEPKcj\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1609 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1608, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1581, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1607 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1610 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype282 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype672 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1611 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1610 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1612 = internal constant [15 x i8] c"_ZNKSs4findEcj\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1613 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1599, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1612, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 742, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1611 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite1614 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1602 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1615 = internal constant [6 x i8] c"rfind\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1616 = internal constant [19 x i8] c"_ZNKSs5rfindERKSsj\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1617 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1616, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1611, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1614 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1618 = internal constant [19 x i8] c"_ZNKSs5rfindEPKcjj\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1619 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1618, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 760, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1598 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite1620 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1606 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1621 = internal constant [18 x i8] c"_ZNKSs5rfindEPKcj\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1622 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1621, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1639, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1620 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.composite1623 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1610 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1624 = internal constant [16 x i8] c"_ZNKSs5rfindEcj\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1625 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1615, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1624, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 781, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1623 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1626 = internal constant [14 x i8] c"find_first_of\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@.str1627 = internal constant [28 x i8] c"_ZNKSs13find_first_ofERKSsj\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1628 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str1627, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1669, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1603 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1629 = internal constant [28 x i8] c"_ZNKSs13find_first_ofEPKcjj\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1630 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str1629, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 798, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1598 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1631 = internal constant [27 x i8] c"_ZNKSs13find_first_ofEPKcj\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1632 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str1631, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1697, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1607 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1633 = internal constant [25 x i8] c"_ZNKSs13find_first_ofEcj\00", section "llvm.metadata" ; <[25 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1634 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1626, i32 0, i32 0), i8* getelementptr ([25 x i8]* @.str1633, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1716, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1611 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1635 = internal constant [13 x i8] c"find_last_of\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str1636 = internal constant [27 x i8] c"_ZNKSs12find_last_ofERKSsj\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1637 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str1636, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1730, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1614 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1638 = internal constant [27 x i8] c"_ZNKSs12find_last_ofEPKcjj\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1639 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str1638, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 813, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1598 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1640 = internal constant [26 x i8] c"_ZNKSs12find_last_ofEPKcj\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1641 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1640, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1758, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1620 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1642 = internal constant [24 x i8] c"_ZNKSs12find_last_ofEcj\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1643 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str1635, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str1642, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1777, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1623 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1644 = internal constant [18 x i8] c"find_first_not_of\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
-@.str1645 = internal constant [32 x i8] c"_ZNKSs17find_first_not_ofERKSsj\00", section "llvm.metadata" ; <[32 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1646 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str1645, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1791, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1603 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1647 = internal constant [32 x i8] c"_ZNKSs17find_first_not_ofEPKcjj\00", section "llvm.metadata" ; <[32 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1648 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([32 x i8]* @.str1647, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 834, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1598 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1649 = internal constant [31 x i8] c"_ZNKSs17find_first_not_ofEPKcj\00", section "llvm.metadata" ; <[31 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1650 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([31 x i8]* @.str1649, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1820, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1607 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1651 = internal constant [29 x i8] c"_ZNKSs17find_first_not_ofEcj\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1652 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str1644, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str1651, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 846, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1611 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1653 = internal constant [17 x i8] c"find_last_not_of\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@.str1654 = internal constant [31 x i8] c"_ZNKSs16find_last_not_ofERKSsj\00", section "llvm.metadata" ; <[31 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1655 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([31 x i8]* @.str1654, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1850, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1614 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1656 = internal constant [31 x i8] c"_ZNKSs16find_last_not_ofEPKcjj\00", section "llvm.metadata" ; <[31 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1657 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([31 x i8]* @.str1656, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 857, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1598 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1658 = internal constant [30 x i8] c"_ZNKSs16find_last_not_ofEPKcj\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1659 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str1658, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1879, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1620 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1660 = internal constant [28 x i8] c"_ZNKSs16find_last_not_ofEcj\00", section "llvm.metadata" ; <[28 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1661 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1653, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str1660, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 878, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1623 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1662 = internal constant [4 x %0*] [%0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1693 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[4 x %0*]*> [#uses=1]
-@llvm.dbg.composite1663 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([4 x %0*]* @llvm.dbg.array1662 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1664 = internal constant [7 x i8] c"substr\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1665 = internal constant [17 x i8] c"_ZNKSs6substrEjj\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1666 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1664, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str1664, i32 0, i32 0), i8* getelementptr ([17 x i8]* @.str1665, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1911, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1663 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1667 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1668 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1667 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1669 = internal constant [8 x i8] c"compare\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str1670 = internal constant [20 x i8] c"_ZNKSs7compareERKSs\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1671 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1670, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit807 to %0*), i32 1929, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1668 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1672 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1673 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1672 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1674 = internal constant [22 x i8] c"_ZNKSs7compareEjjRKSs\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1675 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str1674, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 898, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1673 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1676 = internal constant [7 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1259 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[7 x %0*]*> [#uses=1]
-@llvm.dbg.composite1677 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([7 x %0*]* @llvm.dbg.array1676 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1678 = internal constant [24 x i8] c"_ZNKSs7compareEjjRKSsjj\00", section "llvm.metadata" ; <[24 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1679 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([24 x i8]* @.str1678, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 914, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1677 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1680 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1681 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1680 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1682 = internal constant [19 x i8] c"_ZNKSs7compareEPKc\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1683 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([19 x i8]* @.str1682, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 931, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1681 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1684 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1685 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1684 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1686 = internal constant [21 x i8] c"_ZNKSs7compareEjjPKc\00", section "llvm.metadata" ; <[21 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1687 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([21 x i8]* @.str1686, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 946, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1685 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1688 = internal constant [6 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype917 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype280 to %0*)], section "llvm.metadata" ; <[6 x %0*]*> [#uses=1]
-@llvm.dbg.composite1689 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([6 x %0*]* @llvm.dbg.array1688 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1690 = internal constant [22 x i8] c"_ZNKSs7compareEjjPKcj\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1691 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str1669, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str1690, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit1070 to %0*), i32 963, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1689 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1692 = internal constant [143 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype913 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram922 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram927 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1096 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1180 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1183 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1188 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1193 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1198 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1203 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1208 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1213 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1216 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1221 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1225 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1229 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1235 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1239 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1243 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1248 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1251 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1253 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1255 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1258 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1262 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1265 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1268 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1271 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1274 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1277 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1280 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1284 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1289 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1293 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1297 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1302 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1306 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1309 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1311 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1318 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1324 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1327 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1329 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1334 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1337 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1339 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1344 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1348 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1351 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1355 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1358 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1363 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1367 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1371 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1374 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1376 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1378 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1380 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1382 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1385 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1389 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1393 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1395 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1399 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1402 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1407 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1410 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1412 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1414 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1416 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1418 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1420 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1425 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1428 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1432 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1436 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1440 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1444 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1448 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1452 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1457 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1461 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1465 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1470 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1474 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1478 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1482 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1486 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1490 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1494 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1498 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1502 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1505 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1509 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1513 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1517 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1521 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1530 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1536 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1539 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1542 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1546 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1549 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1553 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1561 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1569 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1573 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1578 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1583 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1588 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1591 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1596 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1601 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1605 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1609 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1613 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1617 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1619 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1622 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1625 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1628 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1630 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1632 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1634 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1637 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1639 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1641 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1643 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1646 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1648 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1650 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1652 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1655 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1657 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1659 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1661 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1666 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1671 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1675 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1679 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1683 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1687 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1691 to %0*)], section "llvm.metadata" ; <[143 x %0*]*> [#uses=1]
-@llvm.dbg.composite1693 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([64 x i8]* @.str804, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit803 to %0*), i32 56, i64 32, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([143 x %0*]* @llvm.dbg.array1692 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype1694 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str914, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit803 to %0*), i32 56, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1693 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str1695 = internal constant [7 x i8] c"_M_msg\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype1696 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str1695, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 109, i64 32, i64 32, i64 32, i32 1, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1694 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1697 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1714 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1698 = internal constant %llvm.dbg.derivedtype.type { i32 458774, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([7 x i8]* @.str914, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit803 to %0*), i32 56, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype916 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1699 = internal constant %llvm.dbg.derivedtype.type { i32 458768, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1698 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1700 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1697 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1699 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1701 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1700 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1702 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str775, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str775, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 114, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1701 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1703 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1697 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1704 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1703 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1705 = internal constant [15 x i8] c"~runtime_error\00", section "llvm.metadata" ; <[15 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1706 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str1705, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str1705, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 117, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1704 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.derivedtype1707 = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 64, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1714 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1708 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1707 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1709 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype791 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1708 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1710 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1709 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1711 = internal constant [29 x i8] c"_ZNKSt13runtime_error4whatEv\00", section "llvm.metadata" ; <[29 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1712 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str796, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str796, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str1711, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 122, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1710 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1713 = internal constant [5 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype801 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1696 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1702 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1706 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1712 to %0*)], section "llvm.metadata" ; <[5 x %0*]*> [#uses=1]
-@llvm.dbg.composite1714 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str775, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 108, i64 64, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([5 x %0*]* @llvm.dbg.array1713 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype1715 = internal constant %llvm.dbg.derivedtype.type { i32 458780, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1714 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype1716 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1721 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1717 = internal constant [3 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1716 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1699 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1718 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1717 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram1719 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str773, i32 0, i32 0), i8* getelementptr ([15 x i8]* @.str773, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 136, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1718 to %0*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1720 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1715 to %0*), %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1719 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1721 = internal constant %llvm.dbg.composite.type { i32 458771, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([15 x i8]* @.str773, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 134, i64 64, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1720 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype1722 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1721 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1723 = internal constant [2 x %0*] [%0* null, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1722 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1724 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1723 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1725 = internal constant [16 x i8] c"~overflow_error\00", section "llvm.metadata" ; <[16 x i8]*> [#uses=1]
-@.str1726 = internal constant [26 x i8] c"_ZNSt14overflow_errorD1Ev\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1727 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str1725, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1725, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1726, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*), i32 134, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1724 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@_ZTVSt14overflow_error = weak constant [5 x i32 (...)*] [i32 (...)* null, i32 (...)* bitcast (%struct.__si_class_type_info_pseudo* @_ZTISt14overflow_error to i32 (...)*), i32 (...)* bitcast (void (%"struct.std::overflow_error"*)* @_ZNSt14overflow_errorD1Ev to i32 (...)*), i32 (...)* bitcast (void (%"struct.std::overflow_error"*)* @_ZNSt14overflow_errorD0Ev to i32 (...)*), i32 (...)* bitcast (i8* (%"struct.std::runtime_error"*)* @_ZNKSt13runtime_error4whatEv to i32 (...)*)], align 8 ; <[5 x i32 (...)*]*> [#uses=1]
-@.str1735 = internal constant [26 x i8] c"_ZNSt14overflow_errorD0Ev\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1736 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([16 x i8]* @.str1725, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1725, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1735, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 702, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1724 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array1738 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite1739 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array1738 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1740 = internal constant [14 x i8] c"__complex_exp\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@.str1741 = internal constant [22 x i8] c"_ZSt13__complex_expCd\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1742 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @.str1740, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str1740, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str1741, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 730, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1739 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1744 = internal constant [12 x i8] c"exp<double>\00", section "llvm.metadata" ; <[12 x i8]*> [#uses=1]
-@.str1745 = internal constant [31 x i8] c"_ZSt3expIdESt7complexIT_ERKS2_\00", section "llvm.metadata" ; <[31 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1746 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str1744, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str1744, i32 0, i32 0), i8* getelementptr ([31 x i8]* @.str1745, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*), i32 738, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite573 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprogram1748 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @.str457, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str457, i32 0, i32 0), i8* getelementptr ([29 x i8]* @.str495, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 497, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite488 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable1751 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1748 to %0*), i8* getelementptr ([7 x i8]* @.str259, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 503, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1752 = internal constant [2 x i8] c"u\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable1753 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1748 to %0*), i8* getelementptr ([2 x i8]* @.str1752, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 501, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1754 = internal constant [2 x i8] c"t\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable1755 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1748 to %0*), i8* getelementptr ([2 x i8]* @.str1754, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 501, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1756 = internal constant [2 x i8] c"w\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable1757 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1748 to %0*), i8* getelementptr ([2 x i8]* @.str1756, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 501, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1758 = internal constant [3 x i8] c"wm\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1]
-@llvm.dbg.variable1759 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1748 to %0*), i8* getelementptr ([3 x i8]* @.str1758, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 501, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram1771 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @.str460, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str460, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str497, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 535, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite492 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable1774 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1771 to %0*), i8* getelementptr ([7 x i8]* @.str259, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 541, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.variable1775 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1771 to %0*), i8* getelementptr ([2 x i8]* @.str1752, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 539, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.variable1776 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1771 to %0*), i8* getelementptr ([2 x i8]* @.str1754, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 539, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.variable1777 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1771 to %0*), i8* getelementptr ([2 x i8]* @.str1756, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 539, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.variable1778 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1771 to %0*), i8* getelementptr ([3 x i8]* @.str1758, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 539, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite223 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.subprogram1785 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str463, i32 0, i32 0), i8* getelementptr ([28 x i8]* @.str499, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 576, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite351 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable1791 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1785 to %0*), i8* getelementptr ([7 x i8]* @.str259, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 614, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1794 = internal constant [5 x i8] c"dft2\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.variable1795 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1785 to %0*), i8* getelementptr ([5 x i8]* @.str1794, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 601, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1796 = internal constant [5 x i8] c"dft1\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.variable1797 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1785 to %0*), i8* getelementptr ([5 x i8]* @.str1796, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 600, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite486 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1798 = internal constant [3 x i8] c"a2\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1]
-@llvm.dbg.variable1799 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1785 to %0*), i8* getelementptr ([3 x i8]* @.str1798, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 591, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1800 = internal constant [3 x i8] c"a1\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1]
-@llvm.dbg.variable1801 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1785 to %0*), i8* getelementptr ([3 x i8]* @.str1800, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 590, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@llvm.dbg.derivedtype1802 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype837 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array1803 = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype269 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype1802 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite1804 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array1803 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str1805 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@llvm.dbg.subprogram1806 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @.str1805, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1805, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 654, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite1804 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str1816 = internal constant [6 x i8] c"poly3\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.variable1817 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1806 to %0*), i8* getelementptr ([6 x i8]* @.str1816, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 674, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1818 = internal constant [6 x i8] c"poly2\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.variable1819 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1806 to %0*), i8* getelementptr ([6 x i8]* @.str1818, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 673, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1820 = internal constant [6 x i8] c"poly1\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.variable1821 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1806 to %0*), i8* getelementptr ([6 x i8]* @.str1820, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 672, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite518 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-@.str1824 = internal constant [4 x i8] c"-ga\00", align 4 ; <[4 x i8]*> [#uses=0]
-@_ZSt4cout = external global %"struct.std::basic_ostream<char,std::char_traits<char> >" ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=3]
-@.str1825 = internal constant [32 x i8] c"\0Afftbench (Std. C++) run time: \00" ; <[32 x i8]*> [#uses=1]
-@.str1826 = internal constant [3 x i8] c"\0A\0A\00" ; <[3 x i8]*> [#uses=1]
-@llvm.global_ctors = appending global [1 x %2] [%2 { i32 65535, void ()* @_GLOBAL__I_main }] ; <[1 x %2]*> [#uses=0]
-
-@_ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)* @pthread_once ; <i32 (i32*, void ()*)*> [#uses=0]
-@_ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)* @pthread_getspecific ; <i8* (i32)*> [#uses=0]
-@_ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)* @pthread_setspecific ; <i32 (i32, i8*)*> [#uses=0]
-@_ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_ = alias weak i32 (i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)* @pthread_create ; <i32 (i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)*> [#uses=0]
-@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i32)* @pthread_cancel ; <i32 (i32)*> [#uses=0]
-@_ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_lock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
-@_ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_trylock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
-@_ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_unlock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
-@_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t = alias weak i32 (%struct.pthread_mutex_t*, %struct..0._50*)* @pthread_mutex_init ; <i32 (%struct.pthread_mutex_t*, %struct..0._50*)*> [#uses=0]
-@_ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*, void (i8*)*)* @pthread_key_create ; <i32 (i32*, void (i8*)*)*> [#uses=0]
-@_ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)* @pthread_key_delete ; <i32 (i32)*> [#uses=0]
-@_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias weak i32 (%struct..0._50*)* @pthread_mutexattr_init ; <i32 (%struct..0._50*)*> [#uses=0]
-@_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%struct..0._50*, i32)* @pthread_mutexattr_settype ; <i32 (%struct..0._50*, i32)*> [#uses=0]
-@_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%struct..0._50*)* @pthread_mutexattr_destroy ; <i32 (%struct..0._50*)*> [#uses=0]
-
-define i32 @main(i32 %argc, i8** nocapture %argv) {
-entry:
- %n.0.reg2mem = alloca i32 ; <i32*> [#uses=5]
- %poly3 = alloca %"struct.polynomial<double>", align 8 ; <%"struct.polynomial<double>"*> [#uses=5]
- %poly2 = alloca %"struct.polynomial<double>", align 8 ; <%"struct.polynomial<double>"*> [#uses=6]
- %poly1 = alloca %"struct.polynomial<double>", align 8 ; <%"struct.polynomial<double>"*> [#uses=6]
- %0 = alloca %"struct.polynomial<double>", align 8 ; <%"struct.polynomial<double>"*> [#uses=4]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1806 to %0*))
- %1 = bitcast %"struct.polynomial<double>"* %poly3 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %1, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1817 to %0*))
- %2 = bitcast %"struct.polynomial<double>"* %poly2 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %2, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1819 to %0*))
- %3 = bitcast %"struct.polynomial<double>"* %poly1 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %3, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1821 to %0*))
- call void @llvm.dbg.stoppoint(i32 659, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %4 = icmp sgt i32 %argc, 1 ; <i1> [#uses=1]
- br i1 %4, label %bb4, label %bb5
-
-bb1: ; preds = %bb4
- call void @llvm.dbg.stoppoint(i32 663, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %5 = getelementptr i8** %argv, i32 1 ; <i8**> [#uses=1]
- %6 = load i8** %5, align 1 ; <i8*> [#uses=1]
- %tmp = bitcast i8* %6 to i32* ; <i32*> [#uses=1]
- %lhsv = load i32* %tmp, align 1 ; <i32> [#uses=1]
- %7 = icmp eq i32 %lhsv, 6383405 ; <i1> [#uses=1]
- br i1 %7, label %bb5, label %bb3
-
-bb3: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 661, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %8 = add i32 %i.0, 1 ; <i32> [#uses=1]
- br label %bb4
-
-bb4: ; preds = %bb3, %entry
- %i.0 = phi i32 [ %8, %bb3 ], [ 1, %entry ] ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 661, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %9 = icmp slt i32 %i.0, %argc ; <i1> [#uses=1]
- br i1 %9, label %bb1, label %bb5
-
-bb5: ; preds = %bb4, %bb1, %entry
- %ga_testing.0 = phi i8 [ 0, %entry ], [ 0, %bb4 ], [ 1, %bb1 ] ; <i8> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 672, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdEC1Ej(%"struct.polynomial<double>"* %poly1, i32 524288)
- call void @llvm.dbg.stoppoint(i32 673, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdEC1Ej(%"struct.polynomial<double>"* %poly2, i32 524288)
- to label %invcont unwind label %lpad
-
-invcont: ; preds = %bb5
- call void @llvm.dbg.stoppoint(i32 674, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdEC1Ej(%"struct.polynomial<double>"* %poly3, i32 1048575)
- to label %bb8.thread unwind label %lpad47
-
-bb8.thread: ; preds = %invcont
- store i32 0, i32* %n.0.reg2mem
- call void @llvm.dbg.stoppoint(i32 676, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb7
-
-bb7: ; preds = %bb8, %bb8.thread
- call void @llvm.dbg.stoppoint(i32 678, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %n.0.reload3 = load i32* %n.0.reg2mem ; <i32> [#uses=1]
- %10 = call double* @_ZN10polynomialIdEixEj(%"struct.polynomial<double>"* %poly1, i32 %n.0.reload3) nounwind ; <double*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 68, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %11 = load i32* @_ZZL13random_doublevE4seed, align 4 ; <i32> [#uses=1]
- %12 = xor i32 %11, 123459876 ; <i32> [#uses=3]
- store i32 %12, i32* @_ZZL13random_doublevE4seed, align 4
- call void @llvm.dbg.stoppoint(i32 69, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %13 = sdiv i32 %12, 127773 ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 70, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %14 = mul i32 %13, 127773 ; <i32> [#uses=1]
- %15 = sub i32 %12, %14 ; <i32> [#uses=1]
- %16 = mul i32 %15, 16807 ; <i32> [#uses=1]
- %17 = mul i32 %13, 2836 ; <i32> [#uses=1]
- %18 = sub i32 %16, %17 ; <i32> [#uses=2]
- store i32 %18, i32* @_ZZL13random_doublevE4seed, align 4
- call void @llvm.dbg.stoppoint(i32 72, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %19 = icmp slt i32 %18, 0 ; <i1> [#uses=1]
- br i1 %19, label %bb.i, label %_ZL13random_doublev.exit
-
-bb.i: ; preds = %bb7
- call void @llvm.dbg.stoppoint(i32 73, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %20 = load i32* @_ZZL13random_doublevE4seed, align 4 ; <i32> [#uses=1]
- %21 = add i32 %20, 2147483647 ; <i32> [#uses=1]
- store i32 %21, i32* @_ZZL13random_doublevE4seed, align 4
- br label %_ZL13random_doublev.exit
-
-_ZL13random_doublev.exit: ; preds = %bb.i, %bb7
- call void @llvm.dbg.stoppoint(i32 75, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %22 = load i32* @_ZZL13random_doublevE4seed, align 4 ; <i32> [#uses=2]
- %23 = sitofp i32 %22 to double ; <double> [#uses=1]
- %24 = fmul double %23, 0x3E340000002813D9 ; <double> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 76, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %25 = xor i32 %22, 123459876 ; <i32> [#uses=1]
- store i32 %25, i32* @_ZZL13random_doublevE4seed, align 4
- call void @llvm.dbg.stoppoint(i32 78, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- store double %24, double* %10, align 8
- call void @llvm.dbg.stoppoint(i32 679, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %n.0.reload4 = load i32* %n.0.reg2mem ; <i32> [#uses=1]
- %26 = call double* @_ZN10polynomialIdEixEj(%"struct.polynomial<double>"* %poly2, i32 %n.0.reload4) nounwind ; <double*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 68, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %27 = load i32* @_ZZL13random_doublevE4seed, align 4 ; <i32> [#uses=1]
- %28 = xor i32 %27, 123459876 ; <i32> [#uses=3]
- store i32 %28, i32* @_ZZL13random_doublevE4seed, align 4
- call void @llvm.dbg.stoppoint(i32 69, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %29 = sdiv i32 %28, 127773 ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 70, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %30 = mul i32 %29, 127773 ; <i32> [#uses=1]
- %31 = sub i32 %28, %30 ; <i32> [#uses=1]
- %32 = mul i32 %31, 16807 ; <i32> [#uses=1]
- %33 = mul i32 %29, 2836 ; <i32> [#uses=1]
- %34 = sub i32 %32, %33 ; <i32> [#uses=2]
- store i32 %34, i32* @_ZZL13random_doublevE4seed, align 4
- call void @llvm.dbg.stoppoint(i32 72, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %35 = icmp slt i32 %34, 0 ; <i1> [#uses=1]
- br i1 %35, label %bb.i1, label %bb8
-
-bb.i1: ; preds = %_ZL13random_doublev.exit
- call void @llvm.dbg.stoppoint(i32 73, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %36 = load i32* @_ZZL13random_doublevE4seed, align 4 ; <i32> [#uses=1]
- %37 = add i32 %36, 2147483647 ; <i32> [#uses=1]
- store i32 %37, i32* @_ZZL13random_doublevE4seed, align 4
- br label %bb8
-
-bb8: ; preds = %bb.i1, %_ZL13random_doublev.exit
- call void @llvm.dbg.stoppoint(i32 75, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %38 = load i32* @_ZZL13random_doublevE4seed, align 4 ; <i32> [#uses=2]
- %39 = sitofp i32 %38 to double ; <double> [#uses=1]
- %40 = fmul double %39, 0x3E340000002813D9 ; <double> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 76, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %41 = xor i32 %38, 123459876 ; <i32> [#uses=1]
- store i32 %41, i32* @_ZZL13random_doublevE4seed, align 4
- call void @llvm.dbg.stoppoint(i32 78, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- store double %40, double* %26, align 8
- call void @llvm.dbg.stoppoint(i32 676, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %n.0.reload5 = load i32* %n.0.reg2mem ; <i32> [#uses=1]
- %42 = add i32 %n.0.reload5, 1 ; <i32> [#uses=2]
- store i32 %42, i32* %n.0.reg2mem
- call void @llvm.dbg.stoppoint(i32 676, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %43 = icmp sgt i32 %42, 524287 ; <i1> [#uses=1]
- br i1 %43, label %bb9, label %bb7
-
-bb9: ; preds = %bb8
- call void @llvm.dbg.stoppoint(i32 687, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZNK10polynomialIdEmlERKS0_(%"struct.polynomial<double>"* noalias sret %0, %"struct.polynomial<double>"* %poly1, %"struct.polynomial<double>"* %poly2)
- to label %invcont10 unwind label %lpad51
-
-invcont10: ; preds = %bb9
- call void @llvm.dbg.stoppoint(i32 687, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %44 = invoke %"struct.polynomial<double>"* @_ZN10polynomialIdEaSERKS0_(%"struct.polynomial<double>"* %poly3, %"struct.polynomial<double>"* %0)
- to label %invcont11 unwind label %lpad55 ; <%"struct.polynomial<double>"*> [#uses=0]
-
-invcont11: ; preds = %invcont10
- call void @llvm.dbg.stoppoint(i32 687, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %0)
- to label %bb16 unwind label %lpad51
-
-bb16: ; preds = %invcont11
- call void @llvm.dbg.stoppoint(i32 695, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %toBool = icmp eq i8 %ga_testing.0, 0 ; <i1> [#uses=1]
- br i1 %toBool, label %bb19, label %bb17
-
-bb17: ; preds = %bb16
- call void @llvm.dbg.stoppoint(i32 696, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %45 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZNSolsEd(%"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZSt4cout, double 0.000000e+00)
- to label %bb23 unwind label %lpad51 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=0]
-
-bb19: ; preds = %bb16
- call void @llvm.dbg.stoppoint(i32 698, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %46 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZSt4cout, i8* getelementptr ([32 x i8]* @.str1825, i32 0, i32 0))
- to label %invcont20 unwind label %lpad51 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=1]
-
-invcont20: ; preds = %bb19
- call void @llvm.dbg.stoppoint(i32 698, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %47 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZNSolsEd(%"struct.std::basic_ostream<char,std::char_traits<char> >"* %46, double 0.000000e+00)
- to label %invcont21 unwind label %lpad51 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=1]
-
-invcont21: ; preds = %invcont20
- call void @llvm.dbg.stoppoint(i32 698, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %48 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"struct.std::basic_ostream<char,std::char_traits<char> >"* %47, i8* getelementptr ([3 x i8]* @.str1826, i32 0, i32 0))
- to label %bb23 unwind label %lpad51 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=0]
-
-bb23: ; preds = %invcont21, %bb17
- call void @llvm.dbg.stoppoint(i32 700, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %49 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZNSo5flushEv(%"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZSt4cout)
- to label %invcont24 unwind label %lpad51 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=0]
-
-invcont24: ; preds = %bb23
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %poly3)
- to label %bb31 unwind label %lpad47
-
-bb31: ; preds = %invcont24
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %poly2)
- to label %bb38 unwind label %lpad
-
-bb38: ; preds = %bb31
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %poly1)
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1806 to %0*))
- ret i32 0
-
-lpad: ; preds = %bb31, %bb5
- %eh_ptr = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select46 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad
-
-lpad47: ; preds = %invcont24, %invcont
- %eh_ptr48 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select50 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr48, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad75
-
-lpad51: ; preds = %bb23, %invcont21, %invcont20, %bb19, %bb17, %invcont11, %bb9
- %eh_ptr52 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select54 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr52, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad76
-
-lpad55: ; preds = %invcont10
- %eh_ptr56 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select58 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr56, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 687, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %0)
- to label %ppad76 unwind label %lpad59
-
-lpad59: ; preds = %lpad55
- %eh_ptr60 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select62 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr60, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 687, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad63: ; preds = %ppad76
- %eh_ptr64 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select66 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr64, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad67: ; preds = %ppad75
- %eh_ptr68 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select70 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr68, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad71: ; preds = %ppad
- %eh_ptr72 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select74 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr72, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-ppad: ; preds = %ppad75, %lpad
- %eh_exception.2 = phi i8* [ %eh_ptr, %lpad ], [ %eh_exception.1, %ppad75 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %poly1)
- to label %Unwind unwind label %lpad71
-
-ppad75: ; preds = %ppad76, %lpad47
- %eh_exception.1 = phi i8* [ %eh_ptr48, %lpad47 ], [ %eh_exception.0, %ppad76 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %poly2)
- to label %ppad unwind label %lpad67
-
-ppad76: ; preds = %lpad55, %lpad51
- %eh_exception.0 = phi i8* [ %eh_ptr52, %lpad51 ], [ %eh_ptr56, %lpad55 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 702, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %poly3)
- to label %ppad75 unwind label %lpad63
-
-Unwind: ; preds = %ppad
- call void @_Unwind_Resume(i8* %eh_exception.2)
- unreachable
-}
-
-define internal void @_GLOBAL__I_main() {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram657 to %0*))
- call void @llvm.dbg.stoppoint(i32 77, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit636 to %0*))
- call void @_ZNSt8ios_base4InitC1Ev(%"struct.std::allocator<char>"* @_ZStL8__ioinit)
- %0 = call i32 @__cxa_atexit(void (i8*)* @__tcf_0, i8* null, i8* bitcast (i8** @__dso_handle to i8*)) nounwind ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 400, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = load i8* bitcast (i64* @_ZGVN10polynomialIdE4PI2IE to i8*), align 8 ; <i8> [#uses=1]
- %2 = icmp eq i8 %1, 0 ; <i1> [#uses=1]
- br i1 %2, label %bb2.i, label %_Z41__static_initialization_and_destruction_0ii.exit
-
-bb2.i: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 400, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- store i8 1, i8* bitcast (i64* @_ZGVN10polynomialIdE4PI2IE to i8*), align 8
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* @_ZN10polynomialIdE4PI2IE, double 0.000000e+00, double 0x401921FB54442D18) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram657 to %0*))
- ret void
-
-_Z41__static_initialization_and_destruction_0ii.exit: ; preds = %entry
- ret void
-}
-
-define linkonce void @_ZNSt7complexIdEC1ECd(%"struct.std::complex<double>"* %this, %1 %__z) nounwind {
-entry:
- %__z_addr = alloca %1, align 8 ; <%1*> [#uses=4]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram227 to %0*))
- %0 = bitcast %1* %__z_addr to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %0, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable231 to %0*))
- store %1 %__z, %1* %__z_addr, align 8
- call void @llvm.dbg.stoppoint(i32 1161, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %1 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %2 = getelementptr %1* %__z_addr, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = load double* %2, align 8 ; <double> [#uses=1]
- store double %3, double* %1, align 4
- %4 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %5 = getelementptr %1* %__z_addr, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 8 ; <double> [#uses=1]
- store double %6, double* %4, align 4
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram227 to %0*))
- ret void
-}
-
-declare void @llvm.dbg.func.start(%0*) nounwind readnone
-
-declare void @llvm.dbg.declare(%0*, %0*) nounwind readnone
-
-declare void @llvm.dbg.stoppoint(i32, i32, %0*) nounwind readnone
-
-declare void @llvm.dbg.region.end(%0*) nounwind readnone
-
-define linkonce %1* @_ZNKSt7complexIdE5__repEv(%"struct.std::complex<double>"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram232 to %0*))
- call void @llvm.dbg.stoppoint(i32 1192, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0 ; <%1*> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram232 to %0*))
- ret %1* %0
-}
-
-define linkonce double* @_ZNSt7complexIdE4realEv(%"struct.std::complex<double>"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram235 to %0*))
- call void @llvm.dbg.stoppoint(i32 1200, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram235 to %0*))
- ret double* %0
-}
-
-define linkonce double* @_ZNKSt7complexIdE4realEv(%"struct.std::complex<double>"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram237 to %0*))
- call void @llvm.dbg.stoppoint(i32 1204, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram237 to %0*))
- ret double* %0
-}
-
-define linkonce double* @_ZNKSt7complexIdE4imagEv(%"struct.std::complex<double>"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram239 to %0*))
- call void @llvm.dbg.stoppoint(i32 1212, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram239 to %0*))
- ret double* %0
-}
-
-define linkonce void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %this, double %__r, double %__i) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram242 to %0*))
- call void @llvm.dbg.stoppoint(i32 1217, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- store double %__r, double* %0, align 4
- call void @llvm.dbg.stoppoint(i32 1218, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %1 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- store double %__i, double* %1, align 4
- call void @llvm.dbg.stoppoint(i32 1219, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram242 to %0*))
- ret void
-}
-
-define linkonce %"struct.std::complex<double>"* @_ZNSt7complexIdEaSEd(%"struct.std::complex<double>"* %this, double %__d) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram248 to %0*))
- call void @llvm.dbg.stoppoint(i32 1224, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- store double %__d, double* %0, align 4
- call void @llvm.dbg.stoppoint(i32 1225, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %1 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- store double 0.000000e+00, double* %1, align 4
- call void @llvm.dbg.stoppoint(i32 1226, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram248 to %0*))
- ret %"struct.std::complex<double>"* %this
-}
-
-define linkonce %"struct.std::complex<double>"* @_ZNSt7complexIdEdVEd(%"struct.std::complex<double>"* %this, double %__d) nounwind {
-entry:
- %0 = alloca %1, align 8 ; <%1*> [#uses=4]
- %1 = alloca %1, align 8 ; <%1*> [#uses=4]
- %2 = alloca %1, align 8 ; <%1*> [#uses=4]
- %memtmp = alloca %1, align 8 ; <%1*> [#uses=4]
- %memtmp1 = alloca %1, align 8 ; <%1*> [#uses=4]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram252 to %0*))
- call void @llvm.dbg.stoppoint(i32 1253, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %3 = getelementptr %1* %2, i32 0, i32 0 ; <double*> [#uses=1]
- %4 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %5 = load double* %4, align 4 ; <double> [#uses=1]
- store double %5, double* %3, align 8
- %6 = getelementptr %1* %2, i32 0, i32 1 ; <double*> [#uses=1]
- %7 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %8 = load double* %7, align 4 ; <double> [#uses=1]
- store double %8, double* %6, align 8
- %real = getelementptr %1* %1, i32 0, i32 0 ; <double*> [#uses=1]
- store double %__d, double* %real, align 8
- %imag = getelementptr %1* %1, i32 0, i32 1 ; <double*> [#uses=1]
- store double 0.000000e+00, double* %imag, align 8
- %9 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %10 = getelementptr %1* %2, i32 0, i32 0 ; <double*> [#uses=1]
- %11 = load double* %10, align 8 ; <double> [#uses=1]
- store double %11, double* %9, align 8
- %12 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %13 = getelementptr %1* %2, i32 0, i32 1 ; <double*> [#uses=1]
- %14 = load double* %13, align 8 ; <double> [#uses=1]
- store double %14, double* %12, align 8
- %15 = getelementptr %1* %memtmp1, i32 0, i32 0 ; <double*> [#uses=1]
- %16 = getelementptr %1* %1, i32 0, i32 0 ; <double*> [#uses=1]
- %17 = load double* %16, align 8 ; <double> [#uses=1]
- store double %17, double* %15, align 8
- %18 = getelementptr %1* %memtmp1, i32 0, i32 1 ; <double*> [#uses=1]
- %19 = getelementptr %1* %1, i32 0, i32 1 ; <double*> [#uses=1]
- %20 = load double* %19, align 8 ; <double> [#uses=1]
- store double %20, double* %18, align 8
- %real2 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %real3 = load double* %real2, align 8 ; <double> [#uses=2]
- %imag4 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %imag5 = load double* %imag4, align 8 ; <double> [#uses=2]
- %real6 = getelementptr %1* %memtmp1, i32 0, i32 0 ; <double*> [#uses=1]
- %real7 = load double* %real6, align 8 ; <double> [#uses=4]
- %imag8 = getelementptr %1* %memtmp1, i32 0, i32 1 ; <double*> [#uses=1]
- %imag9 = load double* %imag8, align 8 ; <double> [#uses=4]
- %21 = fmul double %real3, %real7 ; <double> [#uses=1]
- %22 = fmul double %imag5, %imag9 ; <double> [#uses=1]
- %23 = fadd double %21, %22 ; <double> [#uses=1]
- %24 = fmul double %real7, %real7 ; <double> [#uses=1]
- %25 = fmul double %imag9, %imag9 ; <double> [#uses=1]
- %26 = fadd double %24, %25 ; <double> [#uses=2]
- %27 = fdiv double %23, %26 ; <double> [#uses=1]
- %28 = fmul double %imag5, %real7 ; <double> [#uses=1]
- %29 = fmul double %real3, %imag9 ; <double> [#uses=1]
- %30 = fsub double %28, %29 ; <double> [#uses=1]
- %31 = fdiv double %30, %26 ; <double> [#uses=1]
- %real10 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- store double %27, double* %real10, align 8
- %imag11 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- store double %31, double* %imag11, align 8
- %32 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %33 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- %34 = load double* %33, align 8 ; <double> [#uses=1]
- store double %34, double* %32, align 4
- %35 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %36 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- %37 = load double* %36, align 8 ; <double> [#uses=1]
- store double %37, double* %35, align 4
- call void @llvm.dbg.stoppoint(i32 1254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram252 to %0*))
- ret %"struct.std::complex<double>"* %this
-}
-
-define linkonce double* @_ZN10polynomialIdEixEj(%"struct.polynomial<double>"* %this, i32 %term) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram522 to %0*))
- call void @llvm.dbg.stoppoint(i32 308, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %1 = load double** %0, align 4 ; <double*> [#uses=1]
- %2 = getelementptr double* %1, i32 %term ; <double*> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram522 to %0*))
- ret double* %2
-}
-
-define linkonce i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram527 to %0*))
- call void @llvm.dbg.stoppoint(i32 113, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram527 to %0*))
- ret i32 %1
-}
-
-define linkonce %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %this, i32 %term) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram530 to %0*))
- call void @llvm.dbg.stoppoint(i32 308, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- %1 = load %"struct.std::complex<double>"** %0, align 4 ; <%"struct.std::complex<double>"*> [#uses=1]
- %2 = getelementptr %"struct.std::complex<double>"* %1, i32 %term ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram530 to %0*))
- ret %"struct.std::complex<double>"* %2
-}
-
-define linkonce %"struct.std::complex<double>"* @_ZNSt7complexIdEmLIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %this, %"struct.std::complex<double>"* %__z) nounwind {
-entry:
- %__t = alloca %1, align 8 ; <%1*> [#uses=7]
- %0 = alloca %1, align 8 ; <%1*> [#uses=4]
- %1 = alloca %1, align 8 ; <%1*> [#uses=4]
- %memtmp = alloca %1, align 8 ; <%1*> [#uses=4]
- %memtmp3 = alloca %1, align 8 ; <%1*> [#uses=4]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram538 to %0*))
- %2 = bitcast %1* %__t to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %2, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable542 to %0*))
- call void @llvm.dbg.stoppoint(i32 1289, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %3 = call double* @_ZNKSt7complexIdE4realEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %4 = load double* %3, align 8 ; <double> [#uses=1]
- %5 = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 8 ; <double> [#uses=1]
- %real = getelementptr %1* %__t, i32 0, i32 0 ; <double*> [#uses=1]
- store double %4, double* %real, align 8
- %imag = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- store double %6, double* %imag, align 8
- call void @llvm.dbg.stoppoint(i32 1290, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %7 = call double* @_ZNKSt7complexIdE4imagEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %8 = load double* %7, align 8 ; <double> [#uses=1]
- %imag2 = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- store double %8, double* %imag2, align 8
- call void @llvm.dbg.stoppoint(i32 1291, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %9 = getelementptr %1* %1, i32 0, i32 0 ; <double*> [#uses=1]
- %10 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %11 = load double* %10, align 4 ; <double> [#uses=1]
- store double %11, double* %9, align 8
- %12 = getelementptr %1* %1, i32 0, i32 1 ; <double*> [#uses=1]
- %13 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %14 = load double* %13, align 4 ; <double> [#uses=1]
- store double %14, double* %12, align 8
- %15 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %16 = getelementptr %1* %1, i32 0, i32 0 ; <double*> [#uses=1]
- %17 = load double* %16, align 8 ; <double> [#uses=1]
- store double %17, double* %15, align 8
- %18 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %19 = getelementptr %1* %1, i32 0, i32 1 ; <double*> [#uses=1]
- %20 = load double* %19, align 8 ; <double> [#uses=1]
- store double %20, double* %18, align 8
- %21 = getelementptr %1* %memtmp3, i32 0, i32 0 ; <double*> [#uses=1]
- %22 = getelementptr %1* %__t, i32 0, i32 0 ; <double*> [#uses=1]
- %23 = load double* %22, align 8 ; <double> [#uses=1]
- store double %23, double* %21, align 8
- %24 = getelementptr %1* %memtmp3, i32 0, i32 1 ; <double*> [#uses=1]
- %25 = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- %26 = load double* %25, align 8 ; <double> [#uses=1]
- store double %26, double* %24, align 8
- %real4 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %real5 = load double* %real4, align 8 ; <double> [#uses=2]
- %imag6 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %imag7 = load double* %imag6, align 8 ; <double> [#uses=2]
- %real8 = getelementptr %1* %memtmp3, i32 0, i32 0 ; <double*> [#uses=1]
- %real9 = load double* %real8, align 8 ; <double> [#uses=2]
- %imag10 = getelementptr %1* %memtmp3, i32 0, i32 1 ; <double*> [#uses=1]
- %imag11 = load double* %imag10, align 8 ; <double> [#uses=2]
- %27 = fmul double %real5, %real9 ; <double> [#uses=1]
- %28 = fmul double %imag7, %imag11 ; <double> [#uses=1]
- %29 = fsub double %27, %28 ; <double> [#uses=1]
- %30 = fmul double %real5, %imag11 ; <double> [#uses=1]
- %31 = fmul double %real9, %imag7 ; <double> [#uses=1]
- %32 = fadd double %30, %31 ; <double> [#uses=1]
- %real12 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- store double %29, double* %real12, align 8
- %imag13 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- store double %32, double* %imag13, align 8
- %33 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %34 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- %35 = load double* %34, align 8 ; <double> [#uses=1]
- store double %35, double* %33, align 4
- %36 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %37 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- %38 = load double* %37, align 8 ; <double> [#uses=1]
- store double %38, double* %36, align 4
- call void @llvm.dbg.stoppoint(i32 1292, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram538 to %0*))
- ret %"struct.std::complex<double>"* %this
-}
-
-define linkonce void @_ZN10polynomialIdE9deep_copyEPKd(%"struct.polynomial<double>"* %this, double* %source) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram543 to %0*))
- call void @llvm.dbg.stoppoint(i32 197, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb1
-
-bb: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 198, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %1 = load double** %0, align 4 ; <double*> [#uses=1]
- %2 = getelementptr double* %source, i32 %n.0 ; <double*> [#uses=1]
- %3 = load double* %2, align 1 ; <double> [#uses=1]
- %4 = getelementptr double* %1, i32 %n.0 ; <double*> [#uses=1]
- store double %3, double* %4, align 1
- call void @llvm.dbg.stoppoint(i32 197, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %5 = add i32 %n.0, 1 ; <i32> [#uses=1]
- br label %bb1
-
-bb1: ; preds = %bb, %entry
- %n.0 = phi i32 [ 0, %entry ], [ %5, %bb ] ; <i32> [#uses=4]
- call void @llvm.dbg.stoppoint(i32 197, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %6 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %7 = load i32* %6, align 4 ; <i32> [#uses=1]
- %8 = icmp ugt i32 %7, %n.0 ; <i1> [#uses=1]
- br i1 %8, label %bb, label %return
-
-return: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 198, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram543 to %0*))
- ret void
-}
-
-define linkonce i32 @_ZN10polynomialIdE4log2Ej(i32 %n) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram549 to %0*))
- call void @llvm.dbg.stoppoint(i32 407, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb1
-
-bb: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 411, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = add i32 %c.0, 1 ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 412, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = shl i32 %x.0, 1 ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 414, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %2 = icmp eq i32 %1, 0 ; <i1> [#uses=1]
- br i1 %2, label %return, label %bb1
-
-bb1: ; preds = %bb, %entry
- %c.0 = phi i32 [ 0, %entry ], [ %0, %bb ] ; <i32> [#uses=2]
- %x.0 = phi i32 [ 1, %entry ], [ %1, %bb ] ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 409, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %3 = icmp ult i32 %x.0, %n ; <i1> [#uses=1]
- br i1 %3, label %bb, label %return
-
-return: ; preds = %bb1, %bb
- %c.1 = phi i32 [ %c.0, %bb1 ], [ %0, %bb ] ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 418, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram549 to %0*))
- ret i32 %c.1
-}
-
-define linkonce void @_ZStmlIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %agg.result, %"struct.std::complex<double>"* %__x, %"struct.std::complex<double>"* %__y) nounwind {
-entry:
- %__r = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram559 to %0*))
- %0 = bitcast %"struct.std::complex<double>"* %__r to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %0, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable564 to %0*))
- call void @llvm.dbg.stoppoint(i32 380, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %1 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %2 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = load double* %2, align 4 ; <double> [#uses=1]
- store double %3, double* %1, align 4
- %4 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %5 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 4 ; <double> [#uses=1]
- store double %6, double* %4, align 4
- call void @llvm.dbg.stoppoint(i32 381, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %7 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEmLIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %agg.result, %"struct.std::complex<double>"* %__y) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram559 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialISt7complexIdEE9deep_copyEPKS1_(%"struct.polynomial<std::complex<double> >"* %this, %"struct.std::complex<double>"* %source) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram565 to %0*))
- call void @llvm.dbg.stoppoint(i32 197, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb1
-
-bb: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 198, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- %1 = load %"struct.std::complex<double>"** %0, align 4 ; <%"struct.std::complex<double>"*> [#uses=2]
- %2 = getelementptr %"struct.std::complex<double>"* %1, i32 %n.0, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = getelementptr %"struct.std::complex<double>"* %source, i32 %n.0, i32 0, i32 0 ; <double*> [#uses=1]
- %4 = load double* %3, align 1 ; <double> [#uses=1]
- store double %4, double* %2, align 1
- %5 = getelementptr %"struct.std::complex<double>"* %1, i32 %n.0, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = getelementptr %"struct.std::complex<double>"* %source, i32 %n.0, i32 0, i32 1 ; <double*> [#uses=1]
- %7 = load double* %6, align 1 ; <double> [#uses=1]
- store double %7, double* %5, align 1
- call void @llvm.dbg.stoppoint(i32 197, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %8 = add i32 %n.0, 1 ; <i32> [#uses=1]
- br label %bb1
-
-bb1: ; preds = %bb, %entry
- %n.0 = phi i32 [ 0, %entry ], [ %8, %bb ] ; <i32> [#uses=6]
- call void @llvm.dbg.stoppoint(i32 197, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %9 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %10 = load i32* %9, align 4 ; <i32> [#uses=1]
- %11 = icmp ugt i32 %10, %n.0 ; <i1> [#uses=1]
- br i1 %11, label %bb, label %return
-
-return: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 198, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram565 to %0*))
- ret void
-}
-
-define linkonce i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram569 to %0*))
- call void @llvm.dbg.stoppoint(i32 113, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram569 to %0*))
- ret i32 %1
-}
-
-define linkonce void @_ZStngIdESt7complexIT_ERKS2_(%"struct.std::complex<double>"* noalias sret %agg.result, %"struct.std::complex<double>"* %__x) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram576 to %0*))
- call void @llvm.dbg.stoppoint(i32 444, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = call double* @_ZNKSt7complexIdE4imagEv(%"struct.std::complex<double>"* %__x) nounwind ; <double*> [#uses=1]
- %1 = load double* %0, align 8 ; <double> [#uses=1]
- %2 = fsub double -0.000000e+00, %1 ; <double> [#uses=1]
- %3 = call double* @_ZNKSt7complexIdE4realEv(%"struct.std::complex<double>"* %__x) nounwind ; <double*> [#uses=1]
- %4 = load double* %3, align 8 ; <double> [#uses=1]
- %5 = fsub double -0.000000e+00, %4 ; <double> [#uses=1]
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %agg.result, double %5, double %2) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram576 to %0*))
- ret void
-}
-
-define linkonce double @_ZNK10polynomialIdE3getEj(%"struct.polynomial<double>"* %this, i32 %term) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram578 to %0*))
- call void @llvm.dbg.stoppoint(i32 302, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %1 = load double** %0, align 4 ; <double*> [#uses=1]
- %2 = getelementptr double* %1, i32 %term ; <double*> [#uses=1]
- %3 = load double* %2, align 1 ; <double> [#uses=1]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram578 to %0*))
- ret double %3
-}
-
-define linkonce i32 @_ZN10polynomialIdE9flip_bitsEjj(i32 %k, i32 %bits) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram581 to %0*))
- call void @llvm.dbg.stoppoint(i32 425, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = add i32 %bits, -1 ; <i32> [#uses=1]
- %1 = shl i32 1, %0 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 427, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb3
-
-bb: ; preds = %bb3
- call void @llvm.dbg.stoppoint(i32 431, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %2 = and i32 %rm.0, %k ; <i32> [#uses=1]
- %3 = icmp ne i32 %2, 0 ; <i1> [#uses=1]
- %4 = select i1 %3, i32 %lm.0, i32 0 ; <i32> [#uses=1]
- %.r.1 = or i32 %r.1, %4 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 434, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %5 = lshr i32 %lm.0, 1 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 435, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %6 = shl i32 %rm.0, 1 ; <i32> [#uses=1]
- br label %bb3
-
-bb3: ; preds = %bb, %entry
- %r.1 = phi i32 [ 0, %entry ], [ %.r.1, %bb ] ; <i32> [#uses=2]
- %rm.0 = phi i32 [ 1, %entry ], [ %6, %bb ] ; <i32> [#uses=2]
- %lm.0 = phi i32 [ %1, %entry ], [ %5, %bb ] ; <i32> [#uses=3]
- call void @llvm.dbg.stoppoint(i32 429, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %7 = icmp eq i32 %lm.0, 0 ; <i1> [#uses=1]
- br i1 %7, label %return, label %bb
-
-return: ; preds = %bb3
- call void @llvm.dbg.stoppoint(i32 438, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram581 to %0*))
- ret i32 %r.1
-}
-
-define linkonce %"struct.std::complex<double>"* @_ZNSt7complexIdEdVIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %this, %"struct.std::complex<double>"* %__z) nounwind {
-entry:
- %__t = alloca %1, align 8 ; <%1*> [#uses=7]
- %0 = alloca %1, align 8 ; <%1*> [#uses=4]
- %1 = alloca %1, align 8 ; <%1*> [#uses=4]
- %memtmp = alloca %1, align 8 ; <%1*> [#uses=4]
- %memtmp3 = alloca %1, align 8 ; <%1*> [#uses=4]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram593 to %0*))
- %2 = bitcast %1* %__t to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %2, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable596 to %0*))
- call void @llvm.dbg.stoppoint(i32 1300, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %3 = call double* @_ZNKSt7complexIdE4realEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %4 = load double* %3, align 8 ; <double> [#uses=1]
- %5 = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 8 ; <double> [#uses=1]
- %real = getelementptr %1* %__t, i32 0, i32 0 ; <double*> [#uses=1]
- store double %4, double* %real, align 8
- %imag = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- store double %6, double* %imag, align 8
- call void @llvm.dbg.stoppoint(i32 1301, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %7 = call double* @_ZNKSt7complexIdE4imagEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %8 = load double* %7, align 8 ; <double> [#uses=1]
- %imag2 = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- store double %8, double* %imag2, align 8
- call void @llvm.dbg.stoppoint(i32 1302, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %9 = getelementptr %1* %1, i32 0, i32 0 ; <double*> [#uses=1]
- %10 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %11 = load double* %10, align 4 ; <double> [#uses=1]
- store double %11, double* %9, align 8
- %12 = getelementptr %1* %1, i32 0, i32 1 ; <double*> [#uses=1]
- %13 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %14 = load double* %13, align 4 ; <double> [#uses=1]
- store double %14, double* %12, align 8
- %15 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %16 = getelementptr %1* %1, i32 0, i32 0 ; <double*> [#uses=1]
- %17 = load double* %16, align 8 ; <double> [#uses=1]
- store double %17, double* %15, align 8
- %18 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %19 = getelementptr %1* %1, i32 0, i32 1 ; <double*> [#uses=1]
- %20 = load double* %19, align 8 ; <double> [#uses=1]
- store double %20, double* %18, align 8
- %21 = getelementptr %1* %memtmp3, i32 0, i32 0 ; <double*> [#uses=1]
- %22 = getelementptr %1* %__t, i32 0, i32 0 ; <double*> [#uses=1]
- %23 = load double* %22, align 8 ; <double> [#uses=1]
- store double %23, double* %21, align 8
- %24 = getelementptr %1* %memtmp3, i32 0, i32 1 ; <double*> [#uses=1]
- %25 = getelementptr %1* %__t, i32 0, i32 1 ; <double*> [#uses=1]
- %26 = load double* %25, align 8 ; <double> [#uses=1]
- store double %26, double* %24, align 8
- %real4 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %real5 = load double* %real4, align 8 ; <double> [#uses=2]
- %imag6 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %imag7 = load double* %imag6, align 8 ; <double> [#uses=2]
- %real8 = getelementptr %1* %memtmp3, i32 0, i32 0 ; <double*> [#uses=1]
- %real9 = load double* %real8, align 8 ; <double> [#uses=4]
- %imag10 = getelementptr %1* %memtmp3, i32 0, i32 1 ; <double*> [#uses=1]
- %imag11 = load double* %imag10, align 8 ; <double> [#uses=4]
- %27 = fmul double %real5, %real9 ; <double> [#uses=1]
- %28 = fmul double %imag7, %imag11 ; <double> [#uses=1]
- %29 = fadd double %27, %28 ; <double> [#uses=1]
- %30 = fmul double %real9, %real9 ; <double> [#uses=1]
- %31 = fmul double %imag11, %imag11 ; <double> [#uses=1]
- %32 = fadd double %30, %31 ; <double> [#uses=2]
- %33 = fdiv double %29, %32 ; <double> [#uses=1]
- %34 = fmul double %imag7, %real9 ; <double> [#uses=1]
- %35 = fmul double %real5, %imag11 ; <double> [#uses=1]
- %36 = fsub double %34, %35 ; <double> [#uses=1]
- %37 = fdiv double %36, %32 ; <double> [#uses=1]
- %real12 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- store double %33, double* %real12, align 8
- %imag13 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- store double %37, double* %imag13, align 8
- %38 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %39 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- %40 = load double* %39, align 8 ; <double> [#uses=1]
- store double %40, double* %38, align 4
- %41 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %42 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- %43 = load double* %42, align 8 ; <double> [#uses=1]
- store double %43, double* %41, align 4
- call void @llvm.dbg.stoppoint(i32 1303, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram593 to %0*))
- ret %"struct.std::complex<double>"* %this
-}
-
-define linkonce void @_ZStdvIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %agg.result, %"struct.std::complex<double>"* %__x, %"struct.std::complex<double>"* %__y) {
-entry:
- %__r = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram599 to %0*))
- %0 = bitcast %"struct.std::complex<double>"* %__r to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %0, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable602 to %0*))
- call void @llvm.dbg.stoppoint(i32 410, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %1 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %2 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = load double* %2, align 4 ; <double> [#uses=1]
- store double %3, double* %1, align 4
- %4 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %5 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 4 ; <double> [#uses=1]
- store double %6, double* %4, align 4
- call void @llvm.dbg.stoppoint(i32 411, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %7 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEdVIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %agg.result, %"struct.std::complex<double>"* %__y) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram599 to %0*))
- ret void
-}
-
-define linkonce %"struct.std::complex<double>"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %this, %"struct.std::complex<double>"* %__z) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram605 to %0*))
- call void @llvm.dbg.stoppoint(i32 1270, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %1 = load double* %0, align 4 ; <double> [#uses=1]
- %2 = call double* @_ZNKSt7complexIdE4realEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %3 = load double* %2, align 8 ; <double> [#uses=1]
- %4 = fadd double %1, %3 ; <double> [#uses=1]
- %5 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- store double %4, double* %5, align 4
- call void @llvm.dbg.stoppoint(i32 1271, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %6 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %7 = load double* %6, align 4 ; <double> [#uses=1]
- %8 = call double* @_ZNKSt7complexIdE4imagEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %9 = load double* %8, align 8 ; <double> [#uses=1]
- %10 = fadd double %7, %9 ; <double> [#uses=1]
- %11 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- store double %10, double* %11, align 4
- call void @llvm.dbg.stoppoint(i32 1272, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram605 to %0*))
- ret %"struct.std::complex<double>"* %this
-}
-
-define linkonce void @_ZStplIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %agg.result, %"struct.std::complex<double>"* %__x, %"struct.std::complex<double>"* %__y) {
-entry:
- %__r = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram610 to %0*))
- %0 = bitcast %"struct.std::complex<double>"* %__r to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %0, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable613 to %0*))
- call void @llvm.dbg.stoppoint(i32 320, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %1 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %2 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = load double* %2, align 4 ; <double> [#uses=1]
- store double %3, double* %1, align 4
- %4 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %5 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 4 ; <double> [#uses=1]
- store double %6, double* %4, align 4
- call void @llvm.dbg.stoppoint(i32 321, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %7 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %agg.result, %"struct.std::complex<double>"* %__y) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram610 to %0*))
- ret void
-}
-
-define linkonce %"struct.std::complex<double>"* @_ZNSt7complexIdEmIIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %this, %"struct.std::complex<double>"* %__z) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram616 to %0*))
- call void @llvm.dbg.stoppoint(i32 1279, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %0 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %1 = load double* %0, align 4 ; <double> [#uses=1]
- %2 = call double* @_ZNKSt7complexIdE4realEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %3 = load double* %2, align 8 ; <double> [#uses=1]
- %4 = fsub double %1, %3 ; <double> [#uses=1]
- %5 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- store double %4, double* %5, align 4
- call void @llvm.dbg.stoppoint(i32 1280, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %6 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %7 = load double* %6, align 4 ; <double> [#uses=1]
- %8 = call double* @_ZNKSt7complexIdE4imagEv(%"struct.std::complex<double>"* %__z) nounwind ; <double*> [#uses=1]
- %9 = load double* %8, align 8 ; <double> [#uses=1]
- %10 = fsub double %7, %9 ; <double> [#uses=1]
- %11 = getelementptr %"struct.std::complex<double>"* %this, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- store double %10, double* %11, align 4
- call void @llvm.dbg.stoppoint(i32 1281, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram616 to %0*))
- ret %"struct.std::complex<double>"* %this
-}
-
-define linkonce void @_ZStmiIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %agg.result, %"struct.std::complex<double>"* %__x, %"struct.std::complex<double>"* %__y) {
-entry:
- %__r = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram620 to %0*))
- %0 = bitcast %"struct.std::complex<double>"* %__r to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %0, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable623 to %0*))
- call void @llvm.dbg.stoppoint(i32 350, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %1 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %2 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = load double* %2, align 4 ; <double> [#uses=1]
- store double %3, double* %1, align 4
- %4 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %5 = getelementptr %"struct.std::complex<double>"* %__x, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 4 ; <double> [#uses=1]
- store double %6, double* %4, align 4
- call void @llvm.dbg.stoppoint(i32 351, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %7 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEmIIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %agg.result, %"struct.std::complex<double>"* %__y) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram620 to %0*))
- ret void
-}
-
-define linkonce void @_ZNK10polynomialISt7complexIdEE3getEj(%"struct.std::complex<double>"* noalias sret %agg.result, %"struct.polynomial<std::complex<double> >"* %this, i32 %term) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram624 to %0*))
- call void @llvm.dbg.stoppoint(i32 302, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- %1 = load %"struct.std::complex<double>"** %0, align 4 ; <%"struct.std::complex<double>"*> [#uses=2]
- %2 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = getelementptr %"struct.std::complex<double>"* %1, i32 %term, i32 0, i32 0 ; <double*> [#uses=1]
- %4 = load double* %3, align 1 ; <double> [#uses=1]
- store double %4, double* %2, align 1
- %5 = getelementptr %"struct.std::complex<double>"* %agg.result, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = getelementptr %"struct.std::complex<double>"* %1, i32 %term, i32 0, i32 1 ; <double*> [#uses=1]
- %7 = load double* %6, align 1 ; <double> [#uses=1]
- store double %7, double* %5, align 1
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram624 to %0*))
- ret void
-}
-
-declare void @_ZNSt8ios_base4InitC1Ev(%"struct.std::allocator<char>"*)
-
-declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) nounwind
-
-define internal void @__tcf_0(i8* nocapture %unnamed_arg) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram662 to %0*))
- call void @llvm.dbg.stoppoint(i32 77, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit636 to %0*))
- call void @_ZNSt8ios_base4InitD1Ev(%"struct.std::allocator<char>"* @_ZStL8__ioinit)
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram662 to %0*))
- ret void
-}
-
-declare void @_ZNSt8ios_base4InitD1Ev(%"struct.std::allocator<char>"*)
-
-define linkonce void @_ZN10polynomialIdE7releaseEv(%"struct.polynomial<double>"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram665 to %0*))
- call void @llvm.dbg.stoppoint(i32 190, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %1 = load double** %0, align 4 ; <double*> [#uses=1]
- %2 = icmp eq double* %1, null ; <i1> [#uses=1]
- br i1 %2, label %return, label %bb
-
-bb: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 190, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %3 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %4 = load double** %3, align 4 ; <double*> [#uses=1]
- %5 = bitcast double* %4 to i8* ; <i8*> [#uses=1]
- call void @_ZdaPv(i8* %5) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram665 to %0*))
- ret void
-
-return: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 190, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- ret void
-}
-
-declare void @_ZdaPv(i8*) nounwind
-
-define linkonce void @_ZN10polynomialIdED0Ev(%"struct.polynomial<double>"* %this) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram668 to %0*))
- call void @llvm.dbg.stoppoint(i32 255, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([4 x i32 (...)*]* @_ZTV10polynomialIdE, i32 0, i32 2), i32 (...)*** %0, align 4
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE7releaseEv(%"struct.polynomial<double>"* %this) nounwind
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = bitcast %"struct.polynomial<double>"* %this to i8* ; <i8*> [#uses=1]
- call void @_ZdlPv(i8* %1) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram668 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %this) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram691 to %0*))
- call void @llvm.dbg.stoppoint(i32 255, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([4 x i32 (...)*]* @_ZTV10polynomialIdE, i32 0, i32 2), i32 (...)*** %0, align 4
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE7releaseEv(%"struct.polynomial<double>"* %this) nounwind
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- ret void
-}
-
-declare void @_ZdlPv(i8*) nounwind
-
-define linkonce void @_ZN10polynomialISt7complexIdEE7releaseEv(%"struct.polynomial<std::complex<double> >"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram693 to %0*))
- call void @llvm.dbg.stoppoint(i32 190, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- %1 = load %"struct.std::complex<double>"** %0, align 4 ; <%"struct.std::complex<double>"*> [#uses=1]
- %2 = icmp eq %"struct.std::complex<double>"* %1, null ; <i1> [#uses=1]
- br i1 %2, label %return, label %bb
-
-bb: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 190, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %3 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- %4 = load %"struct.std::complex<double>"** %3, align 4 ; <%"struct.std::complex<double>"*> [#uses=1]
- %5 = bitcast %"struct.std::complex<double>"* %4 to i8* ; <i8*> [#uses=1]
- call void @_ZdaPv(i8* %5) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram693 to %0*))
- ret void
-
-return: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 190, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialISt7complexIdEED0Ev(%"struct.polynomial<std::complex<double> >"* %this) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram696 to %0*))
- call void @llvm.dbg.stoppoint(i32 255, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([4 x i32 (...)*]* @_ZTV10polynomialISt7complexIdEE, i32 0, i32 2), i32 (...)*** %0, align 4
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialISt7complexIdEE7releaseEv(%"struct.polynomial<std::complex<double> >"* %this) nounwind
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = bitcast %"struct.polynomial<std::complex<double> >"* %this to i8* ; <i8*> [#uses=1]
- call void @_ZdlPv(i8* %1) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram696 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %this) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram708 to %0*))
- call void @llvm.dbg.stoppoint(i32 255, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([4 x i32 (...)*]* @_ZTV10polynomialISt7complexIdEE, i32 0, i32 2), i32 (...)*** %0, align 4
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialISt7complexIdEE7releaseEv(%"struct.polynomial<std::complex<double> >"* %this) nounwind
- call void @llvm.dbg.stoppoint(i32 254, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialIdE7acquireEv(%"struct.polynomial<double>"* %this) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram710 to %0*))
- call void @llvm.dbg.stoppoint(i32 183, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=1]
- %2 = shl i32 %1, 3 ; <i32> [#uses=1]
- %3 = call i8* @_Znaj(i32 %2) ; <i8*> [#uses=1]
- %4 = bitcast i8* %3 to double* ; <double*> [#uses=1]
- %5 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- store double* %4, double** %5, align 4
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram710 to %0*))
- ret void
-}
-
-declare i8* @_Znaj(i32)
-
-define linkonce void @_ZN10polynomialIdEC1Ej(%"struct.polynomial<double>"* %this, i32 %degree) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram713 to %0*))
- call void @llvm.dbg.stoppoint(i32 213, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([4 x i32 (...)*]* @_ZTV10polynomialIdE, i32 0, i32 2), i32 (...)*** %0, align 4
- %1 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- store double* null, double** %1, align 4
- %2 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %degree, i32* %2, align 4
- call void @llvm.dbg.stoppoint(i32 215, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE7acquireEv(%"struct.polynomial<double>"* %this)
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram713 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialIdEC1ERKS0_(%"struct.polynomial<double>"* %this, %"struct.polynomial<double>"* %source) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram717 to %0*))
- call void @llvm.dbg.stoppoint(i32 244, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([4 x i32 (...)*]* @_ZTV10polynomialIdE, i32 0, i32 2), i32 (...)*** %0, align 4
- %1 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- store double* null, double** %1, align 4
- %2 = getelementptr %"struct.polynomial<double>"* %source, i32 0, i32 2 ; <i32*> [#uses=1]
- %3 = load i32* %2, align 4 ; <i32> [#uses=1]
- %4 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %3, i32* %4, align 4
- call void @llvm.dbg.stoppoint(i32 246, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE7acquireEv(%"struct.polynomial<double>"* %this)
- call void @llvm.dbg.stoppoint(i32 247, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %5 = getelementptr %"struct.polynomial<double>"* %source, i32 0, i32 1 ; <double**> [#uses=1]
- %6 = load double** %5, align 4 ; <double*> [#uses=1]
- call void @_ZN10polynomialIdE9deep_copyEPKd(%"struct.polynomial<double>"* %this, double* %6) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram717 to %0*))
- ret void
-}
-
-define linkonce %"struct.polynomial<double>"* @_ZN10polynomialIdE7stretchEj(%"struct.polynomial<double>"* %this, i32 %degrees) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram720 to %0*))
- call void @llvm.dbg.stoppoint(i32 278, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = icmp eq i32 %degrees, 0 ; <i1> [#uses=1]
- br i1 %0, label %return, label %bb
-
-bb: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 280, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %2 = load double** %1, align 4 ; <double*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 281, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %3 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %4 = load i32* %3, align 4 ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 283, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %5 = add i32 %4, %degrees ; <i32> [#uses=1]
- %6 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %5, i32* %6, align 4
- call void @llvm.dbg.stoppoint(i32 284, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE7acquireEv(%"struct.polynomial<double>"* %this)
- call void @llvm.dbg.stoppoint(i32 286, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb2
-
-bb1: ; preds = %bb2
- call void @llvm.dbg.stoppoint(i32 289, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %7 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %8 = load double** %7, align 4 ; <double*> [#uses=1]
- %9 = getelementptr double* %2, i32 %n.0 ; <double*> [#uses=1]
- %10 = load double* %9, align 1 ; <double> [#uses=1]
- %11 = getelementptr double* %8, i32 %n.0 ; <double*> [#uses=1]
- store double %10, double* %11, align 1
- call void @llvm.dbg.stoppoint(i32 288, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %12 = add i32 %n.0, 1 ; <i32> [#uses=1]
- br label %bb2
-
-bb2: ; preds = %bb1, %bb
- %n.0 = phi i32 [ 0, %bb ], [ %12, %bb1 ] ; <i32> [#uses=5]
- call void @llvm.dbg.stoppoint(i32 288, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %13 = icmp ult i32 %n.0, %4 ; <i1> [#uses=1]
- br i1 %13, label %bb1, label %bb5
-
-bb4: ; preds = %bb5
- call void @llvm.dbg.stoppoint(i32 292, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %14 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 1 ; <double**> [#uses=1]
- %15 = load double** %14, align 4 ; <double*> [#uses=1]
- %16 = getelementptr double* %15, i32 %n.1 ; <double*> [#uses=1]
- store double 0.000000e+00, double* %16, align 1
- call void @llvm.dbg.stoppoint(i32 291, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %17 = add i32 %n.1, 1 ; <i32> [#uses=1]
- br label %bb5
-
-bb5: ; preds = %bb4, %bb2
- %n.1 = phi i32 [ %17, %bb4 ], [ %n.0, %bb2 ] ; <i32> [#uses=3]
- call void @llvm.dbg.stoppoint(i32 291, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %18 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %19 = load i32* %18, align 4 ; <i32> [#uses=1]
- %20 = icmp ugt i32 %19, %n.1 ; <i1> [#uses=1]
- br i1 %20, label %bb4, label %return
-
-return: ; preds = %bb5, %entry
- call void @llvm.dbg.stoppoint(i32 295, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram720 to %0*))
- ret %"struct.polynomial<double>"* %this
-}
-
-define linkonce %"struct.polynomial<double>"* @_ZN10polynomialIdEaSERKS0_(%"struct.polynomial<double>"* %this, %"struct.polynomial<double>"* %source) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram729 to %0*))
- call void @llvm.dbg.stoppoint(i32 261, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=1]
- %2 = getelementptr %"struct.polynomial<double>"* %source, i32 0, i32 2 ; <i32*> [#uses=1]
- %3 = load i32* %2, align 4 ; <i32> [#uses=1]
- %4 = icmp eq i32 %1, %3 ; <i1> [#uses=1]
- br i1 %4, label %bb1, label %bb
-
-bb: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 263, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE7releaseEv(%"struct.polynomial<double>"* %this) nounwind
- call void @llvm.dbg.stoppoint(i32 265, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %5 = getelementptr %"struct.polynomial<double>"* %source, i32 0, i32 2 ; <i32*> [#uses=1]
- %6 = load i32* %5, align 4 ; <i32> [#uses=1]
- %7 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %6, i32* %7, align 4
- call void @llvm.dbg.stoppoint(i32 266, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE7acquireEv(%"struct.polynomial<double>"* %this)
- br label %bb1
-
-bb1: ; preds = %bb, %entry
- call void @llvm.dbg.stoppoint(i32 269, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %8 = getelementptr %"struct.polynomial<double>"* %source, i32 0, i32 1 ; <double**> [#uses=1]
- %9 = load double** %8, align 4 ; <double*> [#uses=1]
- call void @_ZN10polynomialIdE9deep_copyEPKd(%"struct.polynomial<double>"* %this, double* %9) nounwind
- call void @llvm.dbg.stoppoint(i32 271, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram729 to %0*))
- ret %"struct.polynomial<double>"* %this
-}
-
-define linkonce void @_ZN10polynomialISt7complexIdEE7acquireEv(%"struct.polynomial<std::complex<double> >"* %this) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram732 to %0*))
- call void @llvm.dbg.stoppoint(i32 183, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=2]
- %2 = shl i32 %1, 4 ; <i32> [#uses=1]
- %3 = call i8* @_Znaj(i32 %2) ; <i8*> [#uses=1]
- %4 = bitcast i8* %3 to %"struct.std::complex<double>"* ; <%"struct.std::complex<double>"*> [#uses=2]
- br label %bb1
-
-bb: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 183, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %.0, double 0.000000e+00, double 0.000000e+00) nounwind
- %5 = getelementptr %"struct.std::complex<double>"* %.0, i32 1 ; <%"struct.std::complex<double>"*> [#uses=1]
- br label %bb1
-
-bb1: ; preds = %bb, %entry
- %.01.in = phi i32 [ %1, %entry ], [ %.01, %bb ] ; <i32> [#uses=1]
- %.0 = phi %"struct.std::complex<double>"* [ %4, %entry ], [ %5, %bb ] ; <%"struct.std::complex<double>"*> [#uses=2]
- %.01 = add i32 %.01.in, -1 ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 183, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %6 = icmp eq i32 %.01, -1 ; <i1> [#uses=1]
- br i1 %6, label %bb2, label %bb
-
-bb2: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 183, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %7 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- store %"struct.std::complex<double>"* %4, %"struct.std::complex<double>"** %7, align 4
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram732 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialISt7complexIdEEC1Ej(%"struct.polynomial<std::complex<double> >"* %this, i32 %degree) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram735 to %0*))
- call void @llvm.dbg.stoppoint(i32 213, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([4 x i32 (...)*]* @_ZTV10polynomialISt7complexIdEE, i32 0, i32 2), i32 (...)*** %0, align 4
- %1 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- store %"struct.std::complex<double>"* null, %"struct.std::complex<double>"** %1, align 4
- %2 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %degree, i32* %2, align 4
- call void @llvm.dbg.stoppoint(i32 215, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialISt7complexIdEE7acquireEv(%"struct.polynomial<std::complex<double> >"* %this)
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram735 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialIdE11bit_reverseERKS0_(%"struct.polynomial<std::complex<double> >"* noalias sret %agg.result, %"struct.polynomial<double>"* %poly) {
-entry:
- %result = alloca %"struct.polynomial<std::complex<double> >", align 8 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=1]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram738 to %0*))
- %0 = bitcast %"struct.polynomial<std::complex<double> >"* %result to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %0, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable744 to %0*))
- call void @llvm.dbg.stoppoint(i32 471, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %poly) nounwind ; <i32> [#uses=1]
- %2 = call i32 @_ZN10polynomialIdE4log2Ej(i32 %1) nounwind ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 473, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %3 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %poly) nounwind ; <i32> [#uses=1]
- call void @_ZN10polynomialISt7complexIdEEC1Ej(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %3)
- call void @llvm.dbg.stoppoint(i32 475, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb6
-
-bb: ; preds = %bb6
- call void @llvm.dbg.stoppoint(i32 476, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %4 = call double @_ZNK10polynomialIdE3getEj(%"struct.polynomial<double>"* %poly, i32 %n.0) nounwind ; <double> [#uses=1]
- %5 = call i32 @_ZN10polynomialIdE9flip_bitsEjj(i32 %n.0, i32 %2) nounwind ; <i32> [#uses=1]
- %6 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %5) nounwind ; <%"struct.std::complex<double>"*> [#uses=1]
- %7 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEaSEd(%"struct.std::complex<double>"* %6, double %4) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 475, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %8 = add i32 %n.0, 1 ; <i32> [#uses=1]
- br label %bb6
-
-bb6: ; preds = %bb, %entry
- %n.0 = phi i32 [ 0, %entry ], [ %8, %bb ] ; <i32> [#uses=4]
- call void @llvm.dbg.stoppoint(i32 475, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %9 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %poly) nounwind ; <i32> [#uses=1]
- %10 = icmp ugt i32 %9, %n.0 ; <i1> [#uses=1]
- br i1 %10, label %bb, label %return
-
-return: ; preds = %bb6
- call void @llvm.dbg.stoppoint(i32 475, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram738 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialIdE11bit_reverseERKS_ISt7complexIdEE(%"struct.polynomial<std::complex<double> >"* noalias sret %agg.result, %"struct.polynomial<std::complex<double> >"* %poly) {
-entry:
- %result = alloca %"struct.polynomial<std::complex<double> >", align 8 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=1]
- %memtmp7 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram747 to %0*))
- %0 = bitcast %"struct.polynomial<std::complex<double> >"* %result to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %0, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable751 to %0*))
- call void @llvm.dbg.stoppoint(i32 485, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %1 = call i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %poly) nounwind ; <i32> [#uses=1]
- %2 = call i32 @_ZN10polynomialIdE4log2Ej(i32 %1) nounwind ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 487, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %3 = call i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %poly) nounwind ; <i32> [#uses=1]
- call void @_ZN10polynomialISt7complexIdEEC1Ej(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %3)
- call void @llvm.dbg.stoppoint(i32 489, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb8
-
-bb: ; preds = %bb8
- call void @llvm.dbg.stoppoint(i32 490, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %4 = call i32 @_ZN10polynomialIdE9flip_bitsEjj(i32 %n.0, i32 %2) nounwind ; <i32> [#uses=1]
- %5 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %4) nounwind ; <%"struct.std::complex<double>"*> [#uses=2]
- call void @_ZNK10polynomialISt7complexIdEE3getEj(%"struct.std::complex<double>"* noalias sret %memtmp7, %"struct.polynomial<std::complex<double> >"* %poly, i32 %n.0) nounwind
- %6 = getelementptr %"struct.std::complex<double>"* %5, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %7 = getelementptr %"struct.std::complex<double>"* %memtmp7, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %8 = load double* %7, align 8 ; <double> [#uses=1]
- store double %8, double* %6, align 4
- %9 = getelementptr %"struct.std::complex<double>"* %5, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %10 = getelementptr %"struct.std::complex<double>"* %memtmp7, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %11 = load double* %10, align 8 ; <double> [#uses=1]
- store double %11, double* %9, align 4
- call void @llvm.dbg.stoppoint(i32 489, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %12 = add i32 %n.0, 1 ; <i32> [#uses=1]
- br label %bb8
-
-bb8: ; preds = %bb, %entry
- %n.0 = phi i32 [ 0, %entry ], [ %12, %bb ] ; <i32> [#uses=4]
- call void @llvm.dbg.stoppoint(i32 489, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %13 = call i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %poly) nounwind ; <i32> [#uses=1]
- %14 = icmp ugt i32 %13, %n.0 ; <i1> [#uses=1]
- br i1 %14, label %bb, label %return
-
-return: ; preds = %bb8
- call void @llvm.dbg.stoppoint(i32 489, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram747 to %0*))
- ret void
-}
-
-define linkonce %"struct.polynomial<std::complex<double> >"* @_ZN10polynomialISt7complexIdEEaSERKS2_(%"struct.polynomial<std::complex<double> >"* %this, %"struct.polynomial<std::complex<double> >"* %source) {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram753 to %0*))
- call void @llvm.dbg.stoppoint(i32 261, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %0 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=1]
- %2 = getelementptr %"struct.polynomial<std::complex<double> >"* %source, i32 0, i32 2 ; <i32*> [#uses=1]
- %3 = load i32* %2, align 4 ; <i32> [#uses=1]
- %4 = icmp eq i32 %1, %3 ; <i1> [#uses=1]
- br i1 %4, label %bb1, label %bb
-
-bb: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 263, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialISt7complexIdEE7releaseEv(%"struct.polynomial<std::complex<double> >"* %this) nounwind
- call void @llvm.dbg.stoppoint(i32 265, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %5 = getelementptr %"struct.polynomial<std::complex<double> >"* %source, i32 0, i32 2 ; <i32*> [#uses=1]
- %6 = load i32* %5, align 4 ; <i32> [#uses=1]
- %7 = getelementptr %"struct.polynomial<std::complex<double> >"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %6, i32* %7, align 4
- call void @llvm.dbg.stoppoint(i32 266, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialISt7complexIdEE7acquireEv(%"struct.polynomial<std::complex<double> >"* %this)
- br label %bb1
-
-bb1: ; preds = %bb, %entry
- call void @llvm.dbg.stoppoint(i32 269, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %8 = getelementptr %"struct.polynomial<std::complex<double> >"* %source, i32 0, i32 1 ; <%"struct.std::complex<double>"**> [#uses=1]
- %9 = load %"struct.std::complex<double>"** %8, align 4 ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @_ZN10polynomialISt7complexIdEE9deep_copyEPKS1_(%"struct.polynomial<std::complex<double> >"* %this, %"struct.std::complex<double>"* %9) nounwind
- call void @llvm.dbg.stoppoint(i32 271, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram753 to %0*))
- ret %"struct.polynomial<std::complex<double> >"* %this
-}
-
-define linkonce i32 @_ZN10polynomialIdE11stretch_fftEv(%"struct.polynomial<double>"* %this) {
-entry:
- %0 = alloca %"struct.std::allocator<char>", align 8 ; <%"struct.std::allocator<char>"*> [#uses=4]
- %1 = alloca %"struct.std::string", align 8 ; <%"struct.std::string"*> [#uses=4]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram756 to %0*))
- call void @llvm.dbg.stoppoint(i32 445, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb
-
-bb: ; preds = %bb1, %entry
- %n.0 = phi i32 [ 1, %entry ], [ %5, %bb1 ] ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 449, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %2 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %3 = load i32* %2, align 4 ; <i32> [#uses=1]
- %4 = icmp ugt i32 %3, %n.0 ; <i1> [#uses=1]
- %5 = shl i32 %n.0, 1 ; <i32> [#uses=4]
- br i1 %4, label %bb1, label %bb17
-
-bb1: ; preds = %bb
- call void @llvm.dbg.stoppoint(i32 454, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %6 = icmp eq i32 %5, 0 ; <i1> [#uses=1]
- br i1 %6, label %bb2, label %bb
-
-bb2: ; preds = %bb1
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZNSaIcEC1Ev(%"struct.std::allocator<char>"* %0) nounwind
- invoke void @_ZNSsC1EPKcRKSaIcE(%"struct.std::string"* %1, i8* getelementptr ([35 x i8]* @.str759, i32 0, i32 0), %"struct.std::allocator<char>"* %0)
- to label %invcont unwind label %lpad
-
-invcont: ; preds = %bb2
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %7 = call i8* @__cxa_allocate_exception(i32 8) nounwind ; <i8*> [#uses=3]
- %8 = bitcast i8* %7 to %"struct.std::overflow_error"* ; <%"struct.std::overflow_error"*> [#uses=1]
- invoke void @_ZNSt14overflow_errorC1ERKSs(%"struct.std::overflow_error"* %8, %"struct.std::string"* %1)
- to label %invcont3 unwind label %lpad23
-
-invcont3: ; preds = %invcont
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZNSsD1Ev(%"struct.std::string"* %1)
- to label %bb11 unwind label %lpad31
-
-bb11: ; preds = %invcont3
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZNSaIcED1Ev(%"struct.std::allocator<char>"* %0) nounwind
- call void @__cxa_throw(i8* %7, i8* bitcast (%struct.__si_class_type_info_pseudo* @_ZTISt14overflow_error to i8*), void (i8*)* bitcast (void (%"struct.std::overflow_error"*)* @_ZNSt14overflow_errorD1Ev to void (i8*)*)) noreturn
- unreachable
-
-bb17: ; preds = %bb
- call void @llvm.dbg.stoppoint(i32 459, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %9 = getelementptr %"struct.polynomial<double>"* %this, i32 0, i32 2 ; <i32*> [#uses=1]
- %10 = load i32* %9, align 4 ; <i32> [#uses=2]
- %11 = sub i32 %5, %10 ; <i32> [#uses=3]
- call void @llvm.dbg.stoppoint(i32 461, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %12 = icmp eq i32 %5, %10 ; <i1> [#uses=1]
- br i1 %12, label %return, label %bb18
-
-bb18: ; preds = %bb17
- call void @llvm.dbg.stoppoint(i32 462, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %13 = call %"struct.polynomial<double>"* @_ZN10polynomialIdE7stretchEj(%"struct.polynomial<double>"* %this, i32 %11) ; <%"struct.polynomial<double>"*> [#uses=0]
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram756 to %0*))
- ret i32 %11
-
-return: ; preds = %bb17
- call void @llvm.dbg.stoppoint(i32 464, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- ret i32 %11
-
-lpad: ; preds = %bb2
- %eh_ptr = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select22 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad
-
-lpad23: ; preds = %invcont
- %eh_ptr24 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select26 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr24, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @__cxa_free_exception(i8* %7) nounwind
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZNSsD1Ev(%"struct.std::string"* %1)
- to label %ppad unwind label %lpad27
-
-lpad27: ; preds = %lpad23
- %eh_ptr28 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select30 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr28, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad31: ; preds = %invcont3
- %eh_ptr32 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select34 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr32, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-ppad: ; preds = %lpad23, %lpad
- %eh_exception.0 = phi i8* [ %eh_ptr, %lpad ], [ %eh_ptr24, %lpad23 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 455, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZNSaIcED1Ev(%"struct.std::allocator<char>"* %0) nounwind
- call void @_Unwind_Resume(i8* %eh_exception.0)
- unreachable
-}
-
-declare void @_ZNSaIcEC1Ev(%"struct.std::allocator<char>"*) nounwind
-
-declare void @_ZNSsC1EPKcRKSaIcE(%"struct.std::string"*, i8*, %"struct.std::allocator<char>"*)
-
-declare i8* @__cxa_allocate_exception(i32) nounwind
-
-declare void @_ZNSt14overflow_errorC1ERKSs(%"struct.std::overflow_error"*, %"struct.std::string"*)
-
-declare void @_ZNSsD1Ev(%"struct.std::string"*)
-
-declare i8* @llvm.eh.exception() nounwind
-
-declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind
-
-declare void @__cxa_free_exception(i8*) nounwind
-
-declare void @_ZSt9terminatev() noreturn nounwind
-
-declare void @_ZNSaIcED1Ev(%"struct.std::allocator<char>"*) nounwind
-
-declare void @__cxa_throw(i8*, i8*, void (i8*)*) noreturn
-
-define linkonce void @_ZNSt14overflow_errorD1Ev(%"struct.std::overflow_error"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1727 to %0*))
- call void @llvm.dbg.stoppoint(i32 134, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*))
- %0 = getelementptr %"struct.std::overflow_error"* %this, i32 0, i32 0, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([5 x i32 (...)*]* @_ZTVSt14overflow_error, i32 0, i32 2), i32 (...)*** %0, align 4
- %1 = getelementptr %"struct.std::overflow_error"* %this, i32 0, i32 0 ; <%"struct.std::runtime_error"*> [#uses=1]
- call void @_ZNSt13runtime_errorD2Ev(%"struct.std::runtime_error"* %1) nounwind
- call void @llvm.dbg.stoppoint(i32 134, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*))
- ret void
-}
-
-declare i32 @__gxx_personality_v0(...)
-
-declare void @_Unwind_Resume(i8*)
-
-define linkonce void @_ZNSt14overflow_errorD0Ev(%"struct.std::overflow_error"* %this) nounwind {
-entry:
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1736 to %0*))
- call void @llvm.dbg.stoppoint(i32 134, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*))
- %0 = getelementptr %"struct.std::overflow_error"* %this, i32 0, i32 0, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
- store i32 (...)** getelementptr ([5 x i32 (...)*]* @_ZTVSt14overflow_error, i32 0, i32 2), i32 (...)*** %0, align 4
- %1 = getelementptr %"struct.std::overflow_error"* %this, i32 0, i32 0 ; <%"struct.std::runtime_error"*> [#uses=1]
- call void @_ZNSt13runtime_errorD2Ev(%"struct.std::runtime_error"* %1) nounwind
- call void @llvm.dbg.stoppoint(i32 134, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit770 to %0*))
- %2 = bitcast %"struct.std::overflow_error"* %this to i8* ; <i8*> [#uses=1]
- call void @_ZdlPv(i8* %2) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1736 to %0*))
- ret void
-}
-
-declare i8* @_ZNKSt13runtime_error4whatEv(%"struct.std::runtime_error"*) nounwind
-
-declare void @_ZNSt13runtime_errorD2Ev(%"struct.std::runtime_error"*) nounwind
-
-define linkonce void @_ZSt13__complex_expCd(%1* noalias sret %agg.result, %1 %__z) nounwind {
-entry:
- %0 = alloca %1, align 8 ; <%1*> [#uses=4]
- %memtmp = alloca %1, align 8 ; <%1*> [#uses=3]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1742 to %0*))
- call void @llvm.dbg.stoppoint(i32 730, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- call void @cexp(%1* noalias sret %memtmp, %1 %__z) nounwind
- %1 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- %2 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %3 = load double* %2, align 8 ; <double> [#uses=1]
- store double %3, double* %1, align 8
- %4 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- %5 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %6 = load double* %5, align 8 ; <double> [#uses=1]
- store double %6, double* %4, align 8
- %7 = getelementptr %1* %agg.result, i32 0, i32 0 ; <double*> [#uses=1]
- %8 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- %9 = load double* %8, align 8 ; <double> [#uses=1]
- store double %9, double* %7, align 8
- %10 = getelementptr %1* %agg.result, i32 0, i32 1 ; <double*> [#uses=1]
- %11 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- %12 = load double* %11, align 8 ; <double> [#uses=1]
- store double %12, double* %10, align 8
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1742 to %0*))
- ret void
-}
-
-declare void @cexp(%1* noalias sret, %1) nounwind
-
-define linkonce void @_ZSt3expIdESt7complexIT_ERKS2_(%"struct.std::complex<double>"* noalias sret %agg.result, %"struct.std::complex<double>"* %__z) nounwind {
-entry:
- %0 = alloca %1, align 8 ; <%1*> [#uses=3]
- %1 = alloca %1, align 8 ; <%1*> [#uses=3]
- %memtmp = alloca %1, align 8 ; <%1*> [#uses=3]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1746 to %0*))
- call void @llvm.dbg.stoppoint(i32 738, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to %0*))
- %2 = call %1* @_ZNKSt7complexIdE5__repEv(%"struct.std::complex<double>"* %__z) nounwind ; <%1*> [#uses=2]
- %3 = getelementptr %1* %1, i32 0, i32 0 ; <double*> [#uses=1]
- %4 = getelementptr %1* %2, i32 0, i32 0 ; <double*> [#uses=1]
- %5 = load double* %4, align 8 ; <double> [#uses=1]
- store double %5, double* %3, align 8
- %6 = getelementptr %1* %1, i32 0, i32 1 ; <double*> [#uses=1]
- %7 = getelementptr %1* %2, i32 0, i32 1 ; <double*> [#uses=1]
- %8 = load double* %7, align 8 ; <double> [#uses=1]
- store double %8, double* %6, align 8
- %9 = load %1* %1, align 8 ; <%1> [#uses=1]
- call void @_ZSt13__complex_expCd(%1* noalias sret %memtmp, %1 %9) nounwind
- %10 = getelementptr %1* %0, i32 0, i32 0 ; <double*> [#uses=1]
- %11 = getelementptr %1* %memtmp, i32 0, i32 0 ; <double*> [#uses=1]
- %12 = load double* %11, align 8 ; <double> [#uses=1]
- store double %12, double* %10, align 8
- %13 = getelementptr %1* %0, i32 0, i32 1 ; <double*> [#uses=1]
- %14 = getelementptr %1* %memtmp, i32 0, i32 1 ; <double*> [#uses=1]
- %15 = load double* %14, align 8 ; <double> [#uses=1]
- store double %15, double* %13, align 8
- %16 = load %1* %0, align 8 ; <%1> [#uses=1]
- call void @_ZNSt7complexIdEC1ECd(%"struct.std::complex<double>"* %agg.result, %1 %16) nounwind
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1746 to %0*))
- ret void
-}
-
-define linkonce void @_ZN10polynomialIdE3fftERKS0_(%"struct.polynomial<std::complex<double> >"* noalias sret %agg.result, %"struct.polynomial<double>"* %poly) {
-entry:
- %result = alloca %"struct.polynomial<std::complex<double> >", align 8 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=1]
- %u = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=6]
- %t = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=6]
- %w = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=5]
- %wm = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=5]
- %0 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=2]
- %1 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=2]
- %memtmp20 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- %memtmp23 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- %memtmp24 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- %memtmp26 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1748 to %0*))
- %2 = bitcast %"struct.polynomial<std::complex<double> >"* %result to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %2, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1751 to %0*))
- %3 = bitcast %"struct.std::complex<double>"* %u to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %3, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1753 to %0*))
- %4 = bitcast %"struct.std::complex<double>"* %t to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %4, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1755 to %0*))
- %5 = bitcast %"struct.std::complex<double>"* %w to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %5, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1757 to %0*))
- %6 = bitcast %"struct.std::complex<double>"* %wm to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %6, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1759 to %0*))
- call void @llvm.dbg.stoppoint(i32 499, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %7 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %poly) nounwind ; <i32> [#uses=1]
- %8 = call i32 @_ZN10polynomialIdE4log2Ej(i32 %7) nounwind ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 501, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %wm, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %w, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %t, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %u, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @llvm.dbg.stoppoint(i32 503, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE11bit_reverseERKS0_(%"struct.polynomial<std::complex<double> >"* noalias sret %agg.result, %"struct.polynomial<double>"* %poly)
- call void @llvm.dbg.stoppoint(i32 508, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb32
-
-bb: ; preds = %bb32
- call void @llvm.dbg.stoppoint(i32 510, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %9 = uitofp i32 %m.0 to double ; <double> [#uses=1]
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %0, double %9, double 0.000000e+00) nounwind
- invoke void @_ZStdvIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %1, %"struct.std::complex<double>"* @_ZN10polynomialIdE4PI2IE, %"struct.std::complex<double>"* %0)
- to label %invcont unwind label %lpad
-
-invcont: ; preds = %bb
- call void @llvm.dbg.stoppoint(i32 510, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt3expIdESt7complexIT_ERKS2_(%"struct.std::complex<double>"* noalias sret %memtmp20, %"struct.std::complex<double>"* %1) nounwind
- %10 = getelementptr %"struct.std::complex<double>"* %wm, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %11 = getelementptr %"struct.std::complex<double>"* %memtmp20, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %12 = load double* %11, align 8 ; <double> [#uses=1]
- store double %12, double* %10, align 8
- %13 = getelementptr %"struct.std::complex<double>"* %wm, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %14 = getelementptr %"struct.std::complex<double>"* %memtmp20, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %15 = load double* %14, align 8 ; <double> [#uses=1]
- store double %15, double* %13, align 8
- call void @llvm.dbg.stoppoint(i32 511, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %16 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEaSEd(%"struct.std::complex<double>"* %w, double 1.000000e+00) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 513, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb30
-
-bb22: ; preds = %bb28
- call void @llvm.dbg.stoppoint(i32 517, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %17 = add i32 %k.0, %m2.0 ; <i32> [#uses=1]
- %18 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %17) nounwind ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @_ZStmlIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %memtmp23, %"struct.std::complex<double>"* %w, %"struct.std::complex<double>"* %18) nounwind
- %19 = getelementptr %"struct.std::complex<double>"* %t, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %20 = getelementptr %"struct.std::complex<double>"* %memtmp23, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %21 = load double* %20, align 8 ; <double> [#uses=1]
- store double %21, double* %19, align 8
- %22 = getelementptr %"struct.std::complex<double>"* %t, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %23 = getelementptr %"struct.std::complex<double>"* %memtmp23, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %24 = load double* %23, align 8 ; <double> [#uses=1]
- store double %24, double* %22, align 8
- call void @llvm.dbg.stoppoint(i32 518, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %25 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %k.0) nounwind ; <%"struct.std::complex<double>"*> [#uses=2]
- %26 = getelementptr %"struct.std::complex<double>"* %u, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %27 = getelementptr %"struct.std::complex<double>"* %25, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %28 = load double* %27, align 4 ; <double> [#uses=1]
- store double %28, double* %26, align 8
- %29 = getelementptr %"struct.std::complex<double>"* %u, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %30 = getelementptr %"struct.std::complex<double>"* %25, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %31 = load double* %30, align 4 ; <double> [#uses=1]
- store double %31, double* %29, align 8
- call void @llvm.dbg.stoppoint(i32 519, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %32 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %k.0) nounwind ; <%"struct.std::complex<double>"*> [#uses=2]
- invoke void @_ZStplIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %memtmp24, %"struct.std::complex<double>"* %u, %"struct.std::complex<double>"* %t)
- to label %invcont25 unwind label %lpad
-
-invcont25: ; preds = %bb22
- %33 = getelementptr %"struct.std::complex<double>"* %32, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %34 = getelementptr %"struct.std::complex<double>"* %memtmp24, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %35 = load double* %34, align 8 ; <double> [#uses=1]
- store double %35, double* %33, align 4
- %36 = getelementptr %"struct.std::complex<double>"* %32, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %37 = getelementptr %"struct.std::complex<double>"* %memtmp24, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %38 = load double* %37, align 8 ; <double> [#uses=1]
- store double %38, double* %36, align 4
- call void @llvm.dbg.stoppoint(i32 520, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %39 = add i32 %k.0, %m2.0 ; <i32> [#uses=1]
- %40 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %39) nounwind ; <%"struct.std::complex<double>"*> [#uses=2]
- invoke void @_ZStmiIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %memtmp26, %"struct.std::complex<double>"* %u, %"struct.std::complex<double>"* %t)
- to label %invcont27 unwind label %lpad
-
-invcont27: ; preds = %invcont25
- %41 = getelementptr %"struct.std::complex<double>"* %40, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %42 = getelementptr %"struct.std::complex<double>"* %memtmp26, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %43 = load double* %42, align 8 ; <double> [#uses=1]
- store double %43, double* %41, align 4
- %44 = getelementptr %"struct.std::complex<double>"* %40, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %45 = getelementptr %"struct.std::complex<double>"* %memtmp26, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %46 = load double* %45, align 8 ; <double> [#uses=1]
- store double %46, double* %44, align 4
- call void @llvm.dbg.stoppoint(i32 515, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %47 = add i32 %k.0, %m.0 ; <i32> [#uses=1]
- br label %bb28
-
-bb28: ; preds = %bb30, %invcont27
- %k.0 = phi i32 [ %47, %invcont27 ], [ %j.0, %bb30 ] ; <i32> [#uses=6]
- call void @llvm.dbg.stoppoint(i32 515, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %48 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %poly) nounwind ; <i32> [#uses=1]
- %49 = add i32 %48, -1 ; <i32> [#uses=1]
- %50 = icmp ult i32 %49, %k.0 ; <i1> [#uses=1]
- br i1 %50, label %bb29, label %bb22
-
-bb29: ; preds = %bb28
- call void @llvm.dbg.stoppoint(i32 523, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %51 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEmLIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %w, %"struct.std::complex<double>"* %wm) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 513, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %52 = add i32 %j.0, 1 ; <i32> [#uses=1]
- br label %bb30
-
-bb30: ; preds = %bb29, %invcont
- %j.0 = phi i32 [ 0, %invcont ], [ %52, %bb29 ] ; <i32> [#uses=3]
- call void @llvm.dbg.stoppoint(i32 513, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %53 = add i32 %m2.0, -1 ; <i32> [#uses=1]
- %54 = icmp ult i32 %53, %j.0 ; <i1> [#uses=1]
- br i1 %54, label %bb31, label %bb28
-
-bb31: ; preds = %bb30
- call void @llvm.dbg.stoppoint(i32 526, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %55 = shl i32 %m.0, 1 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 527, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %56 = shl i32 %m2.0, 1 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 508, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %57 = add i32 %s.0, 1 ; <i32> [#uses=1]
- br label %bb32
-
-bb32: ; preds = %bb31, %entry
- %m.0 = phi i32 [ 2, %entry ], [ %55, %bb31 ] ; <i32> [#uses=3]
- %m2.0 = phi i32 [ 1, %entry ], [ %56, %bb31 ] ; <i32> [#uses=4]
- %s.0 = phi i32 [ 0, %entry ], [ %57, %bb31 ] ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 508, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %58 = icmp ult i32 %s.0, %8 ; <i1> [#uses=1]
- br i1 %58, label %bb, label %return
-
-return: ; preds = %bb32
- call void @llvm.dbg.stoppoint(i32 530, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1748 to %0*))
- ret void
-
-lpad: ; preds = %invcont25, %bb22, %bb
- %eh_ptr = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select40 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 530, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %agg.result)
- to label %Unwind unwind label %lpad41
-
-lpad41: ; preds = %lpad
- %eh_ptr42 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select44 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr42, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 530, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-Unwind: ; preds = %lpad
- call void @_Unwind_Resume(i8* %eh_ptr)
- unreachable
-}
-
-define linkonce void @_ZN10polynomialIdE11inverse_fftERKS_ISt7complexIdEE(%"struct.polynomial<std::complex<double> >"* noalias sret %agg.result, %"struct.polynomial<std::complex<double> >"* %poly) {
-entry:
- %result = alloca %"struct.polynomial<std::complex<double> >", align 8 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=1]
- %u = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=6]
- %t = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=6]
- %w = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=5]
- %wm = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=5]
- %0 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=2]
- %1 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=2]
- %2 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=2]
- %memtmp22 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- %memtmp25 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- %memtmp26 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- %memtmp28 = alloca %"struct.std::complex<double>", align 8 ; <%"struct.std::complex<double>"*> [#uses=3]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1771 to %0*))
- %3 = bitcast %"struct.polynomial<std::complex<double> >"* %result to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %3, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1774 to %0*))
- %4 = bitcast %"struct.std::complex<double>"* %u to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %4, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1775 to %0*))
- %5 = bitcast %"struct.std::complex<double>"* %t to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %5, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1776 to %0*))
- %6 = bitcast %"struct.std::complex<double>"* %w to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %6, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1777 to %0*))
- %7 = bitcast %"struct.std::complex<double>"* %wm to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %7, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1778 to %0*))
- call void @llvm.dbg.stoppoint(i32 537, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %8 = call i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %poly) nounwind ; <i32> [#uses=1]
- %9 = call i32 @_ZN10polynomialIdE4log2Ej(i32 %8) nounwind ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 539, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %wm, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %w, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %t, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %u, double 0.000000e+00, double 0.000000e+00) nounwind
- call void @llvm.dbg.stoppoint(i32 541, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdE11bit_reverseERKS_ISt7complexIdEE(%"struct.polynomial<std::complex<double> >"* noalias sret %agg.result, %"struct.polynomial<std::complex<double> >"* %poly)
- call void @llvm.dbg.stoppoint(i32 546, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb34
-
-bb: ; preds = %bb34
- call void @llvm.dbg.stoppoint(i32 548, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %10 = uitofp i32 %m.0 to double ; <double> [#uses=1]
- call void @_ZNSt7complexIdEC1Edd(%"struct.std::complex<double>"* %1, double %10, double 0.000000e+00) nounwind
- call void @_ZStngIdESt7complexIT_ERKS2_(%"struct.std::complex<double>"* noalias sret %0, %"struct.std::complex<double>"* @_ZN10polynomialIdE4PI2IE) nounwind
- invoke void @_ZStdvIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %2, %"struct.std::complex<double>"* %0, %"struct.std::complex<double>"* %1)
- to label %invcont unwind label %lpad
-
-invcont: ; preds = %bb
- call void @llvm.dbg.stoppoint(i32 548, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt3expIdESt7complexIT_ERKS2_(%"struct.std::complex<double>"* noalias sret %memtmp22, %"struct.std::complex<double>"* %2) nounwind
- %11 = getelementptr %"struct.std::complex<double>"* %wm, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %12 = getelementptr %"struct.std::complex<double>"* %memtmp22, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %13 = load double* %12, align 8 ; <double> [#uses=1]
- store double %13, double* %11, align 8
- %14 = getelementptr %"struct.std::complex<double>"* %wm, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %15 = getelementptr %"struct.std::complex<double>"* %memtmp22, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %16 = load double* %15, align 8 ; <double> [#uses=1]
- store double %16, double* %14, align 8
- call void @llvm.dbg.stoppoint(i32 549, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %17 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEaSEd(%"struct.std::complex<double>"* %w, double 1.000000e+00) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 551, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb32
-
-bb24: ; preds = %bb30
- call void @llvm.dbg.stoppoint(i32 555, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %18 = add i32 %k.0, %m2.0 ; <i32> [#uses=1]
- %19 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %18) nounwind ; <%"struct.std::complex<double>"*> [#uses=1]
- call void @_ZStmlIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %memtmp25, %"struct.std::complex<double>"* %w, %"struct.std::complex<double>"* %19) nounwind
- %20 = getelementptr %"struct.std::complex<double>"* %t, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %21 = getelementptr %"struct.std::complex<double>"* %memtmp25, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %22 = load double* %21, align 8 ; <double> [#uses=1]
- store double %22, double* %20, align 8
- %23 = getelementptr %"struct.std::complex<double>"* %t, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %24 = getelementptr %"struct.std::complex<double>"* %memtmp25, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %25 = load double* %24, align 8 ; <double> [#uses=1]
- store double %25, double* %23, align 8
- call void @llvm.dbg.stoppoint(i32 556, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %26 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %k.0) nounwind ; <%"struct.std::complex<double>"*> [#uses=2]
- %27 = getelementptr %"struct.std::complex<double>"* %u, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %28 = getelementptr %"struct.std::complex<double>"* %26, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %29 = load double* %28, align 4 ; <double> [#uses=1]
- store double %29, double* %27, align 8
- %30 = getelementptr %"struct.std::complex<double>"* %u, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %31 = getelementptr %"struct.std::complex<double>"* %26, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %32 = load double* %31, align 4 ; <double> [#uses=1]
- store double %32, double* %30, align 8
- call void @llvm.dbg.stoppoint(i32 557, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %33 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %k.0) nounwind ; <%"struct.std::complex<double>"*> [#uses=2]
- invoke void @_ZStplIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %memtmp26, %"struct.std::complex<double>"* %u, %"struct.std::complex<double>"* %t)
- to label %invcont27 unwind label %lpad
-
-invcont27: ; preds = %bb24
- %34 = getelementptr %"struct.std::complex<double>"* %33, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %35 = getelementptr %"struct.std::complex<double>"* %memtmp26, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %36 = load double* %35, align 8 ; <double> [#uses=1]
- store double %36, double* %34, align 4
- %37 = getelementptr %"struct.std::complex<double>"* %33, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %38 = getelementptr %"struct.std::complex<double>"* %memtmp26, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %39 = load double* %38, align 8 ; <double> [#uses=1]
- store double %39, double* %37, align 4
- call void @llvm.dbg.stoppoint(i32 558, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %40 = add i32 %k.0, %m2.0 ; <i32> [#uses=1]
- %41 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %40) nounwind ; <%"struct.std::complex<double>"*> [#uses=2]
- invoke void @_ZStmiIdESt7complexIT_ERKS2_S4_(%"struct.std::complex<double>"* noalias sret %memtmp28, %"struct.std::complex<double>"* %u, %"struct.std::complex<double>"* %t)
- to label %invcont29 unwind label %lpad
-
-invcont29: ; preds = %invcont27
- %42 = getelementptr %"struct.std::complex<double>"* %41, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %43 = getelementptr %"struct.std::complex<double>"* %memtmp28, i32 0, i32 0, i32 0 ; <double*> [#uses=1]
- %44 = load double* %43, align 8 ; <double> [#uses=1]
- store double %44, double* %42, align 4
- %45 = getelementptr %"struct.std::complex<double>"* %41, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %46 = getelementptr %"struct.std::complex<double>"* %memtmp28, i32 0, i32 0, i32 1 ; <double*> [#uses=1]
- %47 = load double* %46, align 8 ; <double> [#uses=1]
- store double %47, double* %45, align 4
- call void @llvm.dbg.stoppoint(i32 553, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %48 = add i32 %k.0, %m.0 ; <i32> [#uses=1]
- br label %bb30
-
-bb30: ; preds = %bb32, %invcont29
- %k.0 = phi i32 [ %48, %invcont29 ], [ %j.0, %bb32 ] ; <i32> [#uses=6]
- call void @llvm.dbg.stoppoint(i32 553, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %49 = call i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %poly) nounwind ; <i32> [#uses=1]
- %50 = add i32 %49, -1 ; <i32> [#uses=1]
- %51 = icmp ult i32 %50, %k.0 ; <i1> [#uses=1]
- br i1 %51, label %bb31, label %bb24
-
-bb31: ; preds = %bb30
- call void @llvm.dbg.stoppoint(i32 561, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %52 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEmLIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %w, %"struct.std::complex<double>"* %wm) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 551, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %53 = add i32 %j.0, 1 ; <i32> [#uses=1]
- br label %bb32
-
-bb32: ; preds = %bb31, %invcont
- %j.0 = phi i32 [ 0, %invcont ], [ %53, %bb31 ] ; <i32> [#uses=3]
- call void @llvm.dbg.stoppoint(i32 551, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %54 = add i32 %m2.0, -1 ; <i32> [#uses=1]
- %55 = icmp ult i32 %54, %j.0 ; <i1> [#uses=1]
- br i1 %55, label %bb33, label %bb30
-
-bb33: ; preds = %bb32
- call void @llvm.dbg.stoppoint(i32 564, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %56 = shl i32 %m.0, 1 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 565, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %57 = shl i32 %m2.0, 1 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 546, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %58 = add i32 %s.0, 1 ; <i32> [#uses=1]
- br label %bb34
-
-bb34: ; preds = %bb33, %entry
- %m.0 = phi i32 [ 2, %entry ], [ %56, %bb33 ] ; <i32> [#uses=3]
- %m2.0 = phi i32 [ 1, %entry ], [ %57, %bb33 ] ; <i32> [#uses=4]
- %s.0 = phi i32 [ 0, %entry ], [ %58, %bb33 ] ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 546, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %59 = icmp ult i32 %s.0, %9 ; <i1> [#uses=1]
- br i1 %59, label %bb, label %bb37
-
-bb36: ; preds = %bb37
- call void @llvm.dbg.stoppoint(i32 569, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %60 = call i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %poly) nounwind ; <i32> [#uses=1]
- %61 = uitofp i32 %60 to double ; <double> [#uses=1]
- %62 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %agg.result, i32 %j.1) nounwind ; <%"struct.std::complex<double>"*> [#uses=1]
- %63 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEdVEd(%"struct.std::complex<double>"* %62, double %61) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 568, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %64 = add i32 %j.1, 1 ; <i32> [#uses=1]
- br label %bb37
-
-bb37: ; preds = %bb36, %bb34
- %j.1 = phi i32 [ %64, %bb36 ], [ 0, %bb34 ] ; <i32> [#uses=3]
- call void @llvm.dbg.stoppoint(i32 568, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %65 = call i32 @_ZNK10polynomialISt7complexIdEE6degreeEv(%"struct.polynomial<std::complex<double> >"* %poly) nounwind ; <i32> [#uses=1]
- %66 = icmp ugt i32 %65, %j.1 ; <i1> [#uses=1]
- br i1 %66, label %bb36, label %return
-
-return: ; preds = %bb37
- call void @llvm.dbg.stoppoint(i32 571, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1771 to %0*))
- ret void
-
-lpad: ; preds = %invcont27, %bb24, %bb
- %eh_ptr = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select46 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 571, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %agg.result)
- to label %Unwind unwind label %lpad47
-
-lpad47: ; preds = %lpad
- %eh_ptr48 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select50 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr48, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 571, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-Unwind: ; preds = %lpad
- call void @_Unwind_Resume(i8* %eh_ptr)
- unreachable
-}
-
-define linkonce void @_ZNK10polynomialIdEmlERKS0_(%"struct.polynomial<double>"* noalias sret %agg.result, %"struct.polynomial<double>"* %this, %"struct.polynomial<double>"* %poly) {
-entry:
- %result = alloca %"struct.polynomial<double>", align 8 ; <%"struct.polynomial<double>"*> [#uses=1]
- %dft2 = alloca %"struct.polynomial<std::complex<double> >", align 8 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=7]
- %dft1 = alloca %"struct.polynomial<std::complex<double> >", align 8 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=6]
- %a2 = alloca %"struct.polynomial<double>", align 8 ; <%"struct.polynomial<double>"*> [#uses=8]
- %a1 = alloca %"struct.polynomial<double>", align 8 ; <%"struct.polynomial<double>"*> [#uses=9]
- %0 = alloca %"struct.polynomial<std::complex<double> >", align 8 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=4]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1785 to %0*))
- %1 = bitcast %"struct.polynomial<double>"* %result to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %1, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1791 to %0*))
- %2 = bitcast %"struct.polynomial<std::complex<double> >"* %dft2 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %2, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1795 to %0*))
- %3 = bitcast %"struct.polynomial<std::complex<double> >"* %dft1 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %3, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1797 to %0*))
- %4 = bitcast %"struct.polynomial<double>"* %a2 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %4, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1799 to %0*))
- %5 = bitcast %"struct.polynomial<double>"* %a1 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %5, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable1801 to %0*))
- call void @llvm.dbg.stoppoint(i32 590, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdEC1ERKS0_(%"struct.polynomial<double>"* %a1, %"struct.polynomial<double>"* %this)
- call void @llvm.dbg.stoppoint(i32 591, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdEC1ERKS0_(%"struct.polynomial<double>"* %a2, %"struct.polynomial<double>"* %poly)
- to label %invcont unwind label %lpad
-
-invcont: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 594, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %6 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %a1) nounwind ; <i32> [#uses=1]
- %7 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %a2) nounwind ; <i32> [#uses=1]
- %8 = icmp ugt i32 %6, %7 ; <i1> [#uses=1]
- br i1 %8, label %bb, label %bb26
-
-bb: ; preds = %invcont
- call void @llvm.dbg.stoppoint(i32 595, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %9 = invoke i32 @_ZN10polynomialIdE11stretch_fftEv(%"struct.polynomial<double>"* %a1)
- to label %invcont24 unwind label %lpad76 ; <i32> [#uses=1]
-
-invcont24: ; preds = %bb
- call void @llvm.dbg.stoppoint(i32 595, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %10 = invoke %"struct.polynomial<double>"* @_ZN10polynomialIdE7stretchEj(%"struct.polynomial<double>"* %a2, i32 %9)
- to label %bb29 unwind label %lpad76 ; <%"struct.polynomial<double>"*> [#uses=0]
-
-bb26: ; preds = %invcont
- call void @llvm.dbg.stoppoint(i32 597, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %11 = invoke i32 @_ZN10polynomialIdE11stretch_fftEv(%"struct.polynomial<double>"* %a2)
- to label %invcont27 unwind label %lpad76 ; <i32> [#uses=1]
-
-invcont27: ; preds = %bb26
- call void @llvm.dbg.stoppoint(i32 597, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %12 = invoke %"struct.polynomial<double>"* @_ZN10polynomialIdE7stretchEj(%"struct.polynomial<double>"* %a1, i32 %11)
- to label %bb29 unwind label %lpad76 ; <%"struct.polynomial<double>"*> [#uses=0]
-
-bb29: ; preds = %invcont27, %invcont24
- call void @llvm.dbg.stoppoint(i32 600, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdE3fftERKS0_(%"struct.polynomial<std::complex<double> >"* noalias sret %dft1, %"struct.polynomial<double>"* %a1)
- to label %invcont30 unwind label %lpad76
-
-invcont30: ; preds = %bb29
- call void @llvm.dbg.stoppoint(i32 601, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdE3fftERKS0_(%"struct.polynomial<std::complex<double> >"* noalias sret %dft2, %"struct.polynomial<double>"* %a2)
- to label %invcont31 unwind label %lpad80
-
-invcont31: ; preds = %invcont30
- call void @llvm.dbg.stoppoint(i32 604, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %13 = call i32 @_ZNK10polynomialIdE6degreeEv(%"struct.polynomial<double>"* %a1) nounwind ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 606, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- br label %bb33
-
-bb32: ; preds = %bb33
- call void @llvm.dbg.stoppoint(i32 607, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %14 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %dft2, i32 %k15.0) nounwind ; <%"struct.std::complex<double>"*> [#uses=1]
- %15 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %dft1, i32 %k15.0) nounwind ; <%"struct.std::complex<double>"*> [#uses=1]
- %16 = call %"struct.std::complex<double>"* @_ZNSt7complexIdEmLIdEERS0_RKS_IT_E(%"struct.std::complex<double>"* %15, %"struct.std::complex<double>"* %14) nounwind ; <%"struct.std::complex<double>"*> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 606, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %17 = add i32 %k15.0, 1 ; <i32> [#uses=1]
- br label %bb33
-
-bb33: ; preds = %bb32, %invcont31
- %k15.0 = phi i32 [ 0, %invcont31 ], [ %17, %bb32 ] ; <i32> [#uses=4]
- call void @llvm.dbg.stoppoint(i32 606, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %18 = icmp ult i32 %k15.0, %13 ; <i1> [#uses=1]
- br i1 %18, label %bb32, label %bb34
-
-bb34: ; preds = %bb33
- call void @llvm.dbg.stoppoint(i32 610, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdE11inverse_fftERKS_ISt7complexIdEE(%"struct.polynomial<std::complex<double> >"* noalias sret %0, %"struct.polynomial<std::complex<double> >"* %dft1)
- to label %invcont35 unwind label %lpad84
-
-invcont35: ; preds = %bb34
- call void @llvm.dbg.stoppoint(i32 610, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %19 = invoke %"struct.polynomial<std::complex<double> >"* @_ZN10polynomialISt7complexIdEEaSERKS2_(%"struct.polynomial<std::complex<double> >"* %dft2, %"struct.polynomial<std::complex<double> >"* %0)
- to label %invcont36 unwind label %lpad88 ; <%"struct.polynomial<std::complex<double> >"*> [#uses=0]
-
-invcont36: ; preds = %invcont35
- call void @llvm.dbg.stoppoint(i32 610, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %0)
- to label %bb43 unwind label %lpad84
-
-bb43: ; preds = %invcont36
- call void @llvm.dbg.stoppoint(i32 613, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %20 = add i32 %13, -1 ; <i32> [#uses=2]
- call void @llvm.dbg.stoppoint(i32 614, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdEC1Ej(%"struct.polynomial<double>"* %agg.result, i32 %20)
- to label %bb46 unwind label %lpad84
-
-bb45: ; preds = %bb46
- call void @llvm.dbg.stoppoint(i32 617, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %21 = call double* @_ZN10polynomialIdEixEj(%"struct.polynomial<double>"* %agg.result, i32 %k.0) nounwind ; <double*> [#uses=1]
- %22 = call %"struct.std::complex<double>"* @_ZN10polynomialISt7complexIdEEixEj(%"struct.polynomial<std::complex<double> >"* %dft2, i32 %k.0) nounwind ; <%"struct.std::complex<double>"*> [#uses=1]
- %23 = call double* @_ZNSt7complexIdE4realEv(%"struct.std::complex<double>"* %22) nounwind ; <double*> [#uses=1]
- %24 = load double* %23, align 8 ; <double> [#uses=1]
- store double %24, double* %21, align 8
- call void @llvm.dbg.stoppoint(i32 616, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %25 = add i32 %k.0, 1 ; <i32> [#uses=1]
- br label %bb46
-
-bb46: ; preds = %bb45, %bb43
- %k.0 = phi i32 [ %25, %bb45 ], [ 0, %bb43 ] ; <i32> [#uses=4]
- call void @llvm.dbg.stoppoint(i32 616, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %26 = icmp ult i32 %k.0, %20 ; <i1> [#uses=1]
- br i1 %26, label %bb45, label %bb47
-
-bb47: ; preds = %bb46
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %dft2)
- to label %bb54 unwind label %lpad80
-
-bb54: ; preds = %bb47
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %dft1)
- to label %bb61 unwind label %lpad76
-
-bb61: ; preds = %bb54
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %a2)
- to label %bb68 unwind label %lpad
-
-bb68: ; preds = %bb61
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %a1)
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram1785 to %0*))
- ret void
-
-lpad: ; preds = %bb61, %entry
- %eh_ptr = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select75 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad
-
-lpad76: ; preds = %bb54, %bb29, %invcont27, %bb26, %invcont24, %bb
- %eh_ptr77 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select79 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr77, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad112
-
-lpad80: ; preds = %bb47, %invcont30
- %eh_ptr81 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select83 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr81, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad113
-
-lpad84: ; preds = %bb43, %invcont36, %bb34
- %eh_ptr85 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select87 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr85, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- br label %ppad114
-
-lpad88: ; preds = %invcont35
- %eh_ptr89 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %eh_select91 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr89, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 610, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %0)
- to label %ppad114 unwind label %lpad92
-
-lpad92: ; preds = %lpad88
- %eh_ptr93 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select95 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr93, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 610, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad96: ; preds = %ppad114
- %eh_ptr97 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select99 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr97, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad100: ; preds = %ppad113
- %eh_ptr101 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select103 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr101, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad104: ; preds = %ppad112
- %eh_ptr105 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select107 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr105, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-lpad108: ; preds = %ppad
- %eh_ptr109 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %eh_select111 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr109, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @_ZSt9terminatev() noreturn nounwind
- unreachable
-
-ppad: ; preds = %ppad112, %lpad
- %eh_exception.3 = phi i8* [ %eh_ptr, %lpad ], [ %eh_exception.2, %ppad112 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %a1)
- to label %Unwind unwind label %lpad108
-
-ppad112: ; preds = %ppad113, %lpad76
- %eh_exception.2 = phi i8* [ %eh_ptr77, %lpad76 ], [ %eh_exception.1, %ppad113 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialIdED1Ev(%"struct.polynomial<double>"* %a2)
- to label %ppad unwind label %lpad104
-
-ppad113: ; preds = %ppad114, %lpad80
- %eh_exception.1 = phi i8* [ %eh_ptr81, %lpad80 ], [ %eh_exception.0, %ppad114 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %dft1)
- to label %ppad112 unwind label %lpad100
-
-ppad114: ; preds = %lpad88, %lpad84
- %eh_exception.0 = phi i8* [ %eh_ptr85, %lpad84 ], [ %eh_ptr89, %lpad88 ] ; <i8*> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 620, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- invoke void @_ZN10polynomialISt7complexIdEED1Ev(%"struct.polynomial<std::complex<double> >"* %dft2)
- to label %ppad113 unwind label %lpad96
-
-Unwind: ; preds = %ppad
- call void @_Unwind_Resume(i8* %eh_exception.3)
- unreachable
-}
-
-declare i32 @strcmp(i8* nocapture, i8* nocapture) nounwind readonly
-
-declare %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZNSolsEd(%"struct.std::basic_ostream<char,std::char_traits<char> >"*, double)
-
-declare %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8*)
-
-declare %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZNSo5flushEv(%"struct.std::basic_ostream<char,std::char_traits<char> >"*)
-
-declare extern_weak i32 @pthread_once(i32*, void ()*)
-
-declare extern_weak i8* @pthread_getspecific(i32)
-
-declare extern_weak i32 @pthread_setspecific(i32, i8*)
-
-declare extern_weak i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)
-
-declare extern_weak i32 @pthread_cancel(i32)
-
-declare extern_weak i32 @pthread_mutex_lock(%struct.pthread_mutex_t*)
-
-declare extern_weak i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*)
-
-declare extern_weak i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*)
-
-declare extern_weak i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct..0._50*)
-
-declare extern_weak i32 @pthread_key_create(i32*, void (i8*)*)
-
-declare extern_weak i32 @pthread_key_delete(i32)
-
-declare extern_weak i32 @pthread_mutexattr_init(%struct..0._50*)
-
-declare extern_weak i32 @pthread_mutexattr_settype(%struct..0._50*, i32)
-
-declare extern_weak i32 @pthread_mutexattr_destroy(%struct..0._50*)
-
-declare i32 @memcmp(i8* nocapture, i8* nocapture, i32) nounwind readonly
diff --git a/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll b/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll
index 72a15b1..f99cbe1 100644
--- a/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll
+++ b/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll
@@ -144,11 +144,11 @@ invcont57: ; preds = %invcont51
store double %tmp64, double* %tmp62
%tmp65 = call double* @_ZN6QSizeF6rwidthEv( %struct.QPointF* %scaledPageSize ) ; <double*> [#uses=2]
%tmp67 = load double* %tmp65 ; <double> [#uses=1]
- %tmp69 = mul double %tmp67, %tmp48 ; <double> [#uses=1]
+ %tmp69 = fmul double %tmp67, %tmp48 ; <double> [#uses=1]
store double %tmp69, double* %tmp65
%tmp71 = call double* @_ZN6QSizeF7rheightEv( %struct.QPointF* %scaledPageSize ) ; <double*> [#uses=2]
%tmp73 = load double* %tmp71 ; <double> [#uses=1]
- %tmp75 = mul double %tmp73, %tmp54 ; <double> [#uses=1]
+ %tmp75 = fmul double %tmp73, %tmp54 ; <double> [#uses=1]
store double %tmp75, double* %tmp71
%tmp78 = getelementptr %struct.QPrinter* %printer, i32 0, i32 0 ; <%struct.QPaintDevice*> [#uses=1]
%tmp80 = invoke i32 @_ZNK12QPaintDevice6heightEv( %struct.QPaintDevice* %tmp78 )
@@ -190,7 +190,7 @@ invcont104: ; preds = %invcont103
to label %invcont106 unwind label %cleanup329 ; <i32> [#uses=1]
invcont106: ; preds = %invcont104
%tmp108 = sitofp i32 %tmp107 to double ; <double> [#uses=1]
- %tmp109 = mul double %tmp108, 0x3FE93264C993264C ; <double> [#uses=1]
+ %tmp109 = fmul double %tmp108, 0x3FE93264C993264C ; <double> [#uses=1]
%tmp109.upgrd.17 = fptosi double %tmp109 to i32 ; <i32> [#uses=3]
%tmp.upgrd.18 = call %struct.QTextBlockGroup* @_ZNK13QTextDocument9rootFrameEv( %struct.QAbstractTextDocumentLayout* %tmp95 ) ; <%struct.QTextBlockGroup*> [#uses=1]
invoke void @_ZNK10QTextFrame11frameFormatEv( %struct.QTextBlockFormat* sret %fmt, %struct.QTextBlockGroup* %tmp.upgrd.18 )
@@ -237,7 +237,7 @@ invcont124: ; preds = %invcont122
store double %tmp137, double* %tmp135
%tmp138 = call double @_ZNK6QRectF6heightEv( %struct.QRectF* %body ) ; <double> [#uses=1]
%tmp139 = sitofp i32 %tmp109.upgrd.17 to double ; <double> [#uses=1]
- %tmp140 = sub double %tmp138, %tmp139 ; <double> [#uses=1]
+ %tmp140 = fsub double %tmp138, %tmp139 ; <double> [#uses=1]
%tmp142 = invoke %struct.QPaintDevice* @_ZNK8QPainter6deviceEv( %struct.QPainter* %p )
to label %invcont141 unwind label %cleanup192 ; <%struct.QPaintDevice*> [#uses=1]
invcont141: ; preds = %invcont124
@@ -251,7 +251,7 @@ invcont146: ; preds = %invcont144
to label %invcont148 unwind label %cleanup168 ; <i32> [#uses=1]
invcont148: ; preds = %invcont146
%tmp149.upgrd.21 = sitofp i32 %tmp149 to double ; <double> [#uses=1]
- %tmp150 = add double %tmp140, %tmp149.upgrd.21 ; <double> [#uses=1]
+ %tmp150 = fadd double %tmp140, %tmp149.upgrd.21 ; <double> [#uses=1]
%tmp152 = invoke %struct.QPaintDevice* @_ZNK8QPainter6deviceEv( %struct.QPainter* %p )
to label %invcont151 unwind label %cleanup168 ; <%struct.QPaintDevice*> [#uses=1]
invcont151: ; preds = %invcont148
@@ -261,10 +261,10 @@ invcont153: ; preds = %invcont151
%tmp155 = mul i32 %tmp154, 5 ; <i32> [#uses=1]
%tmp156 = sdiv i32 %tmp155, 72 ; <i32> [#uses=1]
%tmp156.upgrd.22 = sitofp i32 %tmp156 to double ; <double> [#uses=1]
- %tmp157 = add double %tmp150, %tmp156.upgrd.22 ; <double> [#uses=1]
+ %tmp157 = fadd double %tmp150, %tmp156.upgrd.22 ; <double> [#uses=1]
%tmp158 = call double @_ZNK6QRectF5widthEv( %struct.QRectF* %body ) ; <double> [#uses=1]
%tmp159 = sitofp i32 %tmp109.upgrd.17 to double ; <double> [#uses=1]
- %tmp160 = sub double %tmp158, %tmp159 ; <double> [#uses=1]
+ %tmp160 = fsub double %tmp158, %tmp159 ; <double> [#uses=1]
call void @_ZN7QPointFC1Edd( %struct.QPointF* %tmp2, double %tmp160, double %tmp157 )
%tmp161 = getelementptr %struct.QPointF* %pageNumberPos, i32 0, i32 0 ; <double*> [#uses=1]
%tmp162 = getelementptr %struct.QPointF* %tmp2, i32 0, i32 0 ; <double*> [#uses=1]
diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg
index 34372bb..5fe0732 100644
--- a/test/Unit/lit.cfg
+++ b/test/Unit/lit.cfg
@@ -23,7 +23,14 @@ config.test_format = lit.formats.GoogleTest(llvm_build_mode, 'Tests')
###
-import os
+# If necessary, point the dynamic loader at libLLVM.so.
+if config.enable_shared:
+ libdir = os.path.join(config.llvm_obj_root, config.llvm_build_mode, 'lib')
+ shlibpath = config.environment.get(config.shlibpath_var,'')
+ if shlibpath:
+ shlibpath = ':' + shlibpath
+ shlibpath = libdir + shlibpath
+ config.environment[config.shlibpath_var] = shlibpath
# Check that the object root is known.
if config.test_exec_root is None:
diff --git a/test/Unit/lit.site.cfg.in b/test/Unit/lit.site.cfg.in
index c190ffa..51b5bc4 100644
--- a/test/Unit/lit.site.cfg.in
+++ b/test/Unit/lit.site.cfg.in
@@ -5,6 +5,8 @@ config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.llvmgcc_dir = "@LLVMGCCDIR@"
config.llvm_build_mode = "@LLVM_BUILD_MODE@"
+config.enable_shared = @ENABLE_SHARED@
+config.shlibpath_var = "@SHLIBPATH_VAR@"
# Let the main config do the real work.
lit.load_config(config, "@LLVM_SOURCE_DIR@/test/Unit/lit.cfg")
diff --git a/test/lib/llvm.exp b/test/lib/llvm.exp
index 319cc11..19a2729 100644
--- a/test/lib/llvm.exp
+++ b/test/lib/llvm.exp
@@ -47,7 +47,7 @@ proc execOneLine { test PRS outcome lineno line } {
# cases.
proc substitute { line test tmpFile } {
global srcroot objroot srcdir objdir subdir target_triplet
- global llvmgcc llvmgxx llvmgcc_version llvmgccmajvers ocamlopt
+ global llvmgcc llvmgxx ocamlopt
global gccpath gxxpath compile_c compile_cxx link shlibext llvmlibsdir
global llvmdsymutil valgrind grep gas bugpoint_topts
set path [file join $srcdir $subdir]
@@ -119,7 +119,7 @@ proc substitute { line test tmpFile } {
# This procedure runs the set of tests for the test_source_files array.
proc RunLLVMTests { test_source_files } {
- global srcroot objroot srcdir objdir subdir target_triplet llvmgcc_version
+ global srcroot objroot srcdir objdir subdir target_triplet
set timeout 60
set path [file join $objdir $subdir]
@@ -194,12 +194,6 @@ proc RunLLVMTests { test_source_files } {
if {$targetPASS != 1} {
set outcome XFAIL
}
- } elseif { [regexp {llvmgcc(([0-9]+)|([0-9]+[.][0-9]+))} $target match submatch submatch2] } {
- if { [regexp ^($submatch)$|^(($submatch)(\.)) $llvmgcc_version match] } {
- if {$targetPASS != 1} {
- set outcome XFAIL
- }
- }
}
}
} elseif {[regexp {XTARGET:[ *](.+)} $line match targets]} {
@@ -213,11 +207,6 @@ proc RunLLVMTests { test_source_files } {
} elseif { [regexp $target $target_triplet match] } {
set targetPASS 1
set outcome PASS
- } elseif { [regexp {llvmgcc(([0-9]+)|([0-9]+[.][0-9]+))} $target match submatch submatch2] } {
- if { [regexp ^($submatch)$|^(($submatch)(\.)) $llvmgcc_version match] } {
- set targetPASS 1
- set outcome PASS
- }
}
}
}
diff --git a/test/lit.cfg b/test/lit.cfg
index 0894d9b..b4aec5a 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -40,13 +40,14 @@ if llvm_obj_root is not None:
config.environment['PATH'] = path
llvmgcc_dir = getattr(config, 'llvmgcc_dir', None)
- if not llvm_tools_dir:
- lit.fatal('No llvm-gcc dir set!')
if llvmgcc_dir:
path = os.path.pathsep.join((os.path.join(llvmgcc_dir, 'bin'),
config.environment['PATH']))
config.environment['PATH'] = path
+# Propogate 'HOME' through the environment.
+config.environment['HOME'] = os.environ['HOME']
+
###
import os
@@ -143,6 +144,9 @@ bindings = set(site_exp['llvm_bindings'].split(','))
def llvm_supports_binding(name):
return name in bindings
+config.conditions["TARGET"] = llvm_supports_target
+config.conditions["BINDING"] = llvm_supports_binding
+
# Provide on_clone hook for reading 'dg.exp'.
import os
simpleLibData = re.compile(r"""load_lib llvm.exp
diff --git a/test/site.exp.in b/test/site.exp.in
index f88d361..c760c2c 100644
--- a/test/site.exp.in
+++ b/test/site.exp.in
@@ -3,7 +3,6 @@
set target_triplet "@TARGET_TRIPLE@"
set TARGETS_TO_BUILD "@TARGETS_TO_BUILD@"
set llvmgcc_langs "@LLVMGCC_LANGS@"
-set llvmgcc_version "@LLVMGCC_VERSION@"
set llvmtoolsdir "@LLVM_TOOLS_DIR@"
set llvmlibsdir "@LLVM_LIBS_DIR@"
set llvm_bindings "@LLVM_BINDINGS@"
@@ -18,7 +17,6 @@ set compile_cxx "@TEST_COMPILE_CXX_CMD@"
set link "@TEST_LINK_CMD@"
set llvmgcc "@LLVMGCC@"
set llvmgxx "@LLVMGXX@"
-set llvmgccmajvers "@LLVMGCCMAJVERS@"
set bugpoint_topts "@BUGPOINT_TOPTS@"
set shlibext "@SHLIBEXT@"
set ocamlopt "@OCAMLOPT@"
diff --git a/tools/Makefile b/tools/Makefile
index c9b9ff2..86ba72d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -21,8 +21,8 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \
llvm-ld llvm-prof llvm-link \
lli llvm-extract \
bugpoint llvm-bcanalyzer llvm-stub \
- llvm-mc llvmc \
- edis
+ llvm-mc llvmc
+
# Let users override the set of tools to build from the command line.
ifdef ONLY_TOOLS
@@ -32,16 +32,27 @@ endif
include $(LEVEL)/Makefile.config
+# These libraries build as dynamic libraries (.dylib /.so), they can only be
+# built if ENABLE_PIC is set.
ifeq ($(ENABLE_PIC),1)
- DIRS += lto
- ifdef BINUTILS_INCDIR
- DIRS += gold
+ # No support for dynamic libraries on windows targets.
+ ifneq ($(TARGET_OS), $(filter $(TARGET_OS), Cygwin MingW))
+ PARALLEL_DIRS += edis
+
+ # gold only builds if binutils is around. It requires "lto" to build before
+ # it so it is added to DIRS.
+ ifdef BINUTILS_INCDIR
+ PARALLEL_DIRS += gold
+ DIRS += lto
+ else
+ PARALLEL_DIRS += lto
+ endif
endif
endif
-# No support for lto / gold on windows targets
-ifeq ($(TARGET_OS), $(filter $(TARGET_OS), Cygwin MingW))
- DIRS := $(filter-out lto gold, $(DIRS))
+# Only build edis if X86 target support is enabled.
+ifeq ($(filter $(TARGETS_TO_BUILD), X86),)
+ PARALLEL_DIRS := $(filter-out edis, $(PARALLEL_DIRS))
endif
include $(LEVEL)/Makefile.common
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index b348a08..b51bdb4 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -295,7 +295,7 @@ bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
TerminatorInst *BBTerm = BB->getTerminator();
- if (isa<StructType>(BBTerm->getType()))
+ if (BBTerm->getType()->isStructTy())
BBTerm->replaceAllUsesWith(UndefValue::get(BBTerm->getType()));
else if (BB->getTerminator()->getType() !=
Type::getVoidTy(BB->getContext()))
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 70011a7..eaa2c53 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -73,7 +73,7 @@ Module *BugDriver::deleteInstructionFromProgram(const Instruction *I,
Instruction *TheInst = RI; // Got the corresponding instruction!
// If this instruction produces a value, replace any users with null values
- if (isa<StructType>(TheInst->getType()))
+ if (TheInst->getType()->isStructTy())
TheInst->replaceAllUsesWith(UndefValue::get(TheInst->getType()));
else if (TheInst->getType() != Type::getVoidTy(I->getContext()))
TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType()));
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index fe34bd1..810ba42 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -305,6 +305,14 @@ int main(int argc, char **argv) {
case '3': OLvl = CodeGenOpt::Aggressive; break;
}
+ // Request that addPassesToEmitFile run the Verifier after running
+ // passes which modify the IR.
+#ifndef NDEBUG
+ bool DisableVerify = false;
+#else
+ bool DisableVerify = true;
+#endif
+
// If this target requires addPassesToEmitWholeFile, do it now. This is
// used by strange things like the C backend.
if (Target.WantsWholeFile()) {
@@ -320,7 +328,8 @@ int main(int argc, char **argv) {
PM.add(createVerifierPass());
// Ask the target to add backend passes as necessary.
- if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl)) {
+ if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl,
+ DisableVerify)) {
errs() << argv[0] << ": target does not support generation of this"
<< " file type!\n";
if (Out != &fouts()) delete Out;
@@ -347,7 +356,8 @@ int main(int argc, char **argv) {
// Override default to generate verbose assembly.
Target.setAsmVerbosityDefault(true);
- if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) {
+ if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl,
+ DisableVerify)) {
errs() << argv[0] << ": target does not support generation of this"
<< " file type!\n";
if (Out != &fouts()) delete Out;
diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt
index 8a710ea..7a43dba 100644
--- a/tools/llvm-config/CMakeLists.txt
+++ b/tools/llvm-config/CMakeLists.txt
@@ -18,8 +18,6 @@ execute_process(COMMAND date
#set(LLVMGCCDIR "")
#set(LLVMGCC "")
#set(LLVMGXX "")
-#set(LLVMGCC_VERSION "")
-#set(LLVMGCC_MAJVERS "")
test_big_endian(IS_BIG_ENDIAN)
if( IS_BIG_ENDIAN )
set(ENDIAN "big")
diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile
index cc5cf43..c7f7b32 100644
--- a/tools/llvm-config/Makefile
+++ b/tools/llvm-config/Makefile
@@ -126,6 +126,6 @@ clean-local::
$(LibDeps) GenLibDeps.out
install-local:: all-local
$(Echo) Installing llvm-config
- $(Verb) $(MKDIR) $(PROJ_bindir)
- $(Verb) $(ScriptInstall) $(ToolDir)/llvm-config $(PROJ_bindir)
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_bindir)
+ $(Verb) $(ScriptInstall) $(ToolDir)/llvm-config $(DESTDIR)$(PROJ_bindir)
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index 517244f..231634c 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -49,15 +49,15 @@ static cl::opt<bool>
Relink("relink",
cl::desc("Turn external linkage for callees of function to delete"));
-// ExtractFunc - The function to extract from the module...
-static cl::opt<std::string>
-ExtractFunc("func", cl::desc("Specify function to extract"), cl::init(""),
- cl::value_desc("function"));
+// ExtractFuncs - The functions to extract from the module...
+static cl::list<std::string>
+ExtractFuncs("func", cl::desc("Specify function to extract"),
+ cl::ZeroOrMore, cl::value_desc("function"));
-// ExtractGlobal - The global to extract from the module...
-static cl::opt<std::string>
-ExtractGlobal("glob", cl::desc("Specify global to extract"), cl::init(""),
- cl::value_desc("global"));
+// ExtractGlobals - The globals to extract from the module...
+static cl::list<std::string>
+ExtractGlobals("glob", cl::desc("Specify global to extract"),
+ cl::ZeroOrMore, cl::value_desc("global"));
static cl::opt<bool>
OutputAssembly("S",
@@ -81,28 +81,34 @@ int main(int argc, char **argv) {
return 1;
}
- // Figure out which function we should extract
- GlobalVariable *G = !ExtractGlobal.empty() ?
- M.get()->getNamedGlobal(ExtractGlobal) : 0;
-
- // Figure out which function we should extract
- if (ExtractFunc.empty() && ExtractGlobal.empty()) ExtractFunc = "main";
- Function *F = M.get()->getFunction(ExtractFunc);
+ std::vector<GlobalValue *> GVs;
+
+ // Figure out which globals we should extract.
+ for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
+ GlobalValue *GV = M.get()->getNamedGlobal(ExtractGlobals[i]);
+ if (!GV) {
+ errs() << argv[0] << ": program doesn't contain global named '"
+ << ExtractGlobals[i] << "'!\n";
+ return 1;
+ }
+ GVs.push_back(GV);
+ }
- if (F == 0 && G == 0) {
- errs() << argv[0] << ": program doesn't contain function named '"
- << ExtractFunc << "' or a global named '" << ExtractGlobal << "'!\n";
- return 1;
+ // Figure out which functions we should extract.
+ for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) {
+ GlobalValue *GV = M.get()->getFunction(ExtractFuncs[i]);
+ if (!GV) {
+ errs() << argv[0] << ": program doesn't contain function named '"
+ << ExtractFuncs[i] << "'!\n";
+ return 1;
+ }
+ GVs.push_back(GV);
}
// In addition to deleting all other functions, we also want to spiff it
// up a little bit. Do this now.
PassManager Passes;
Passes.add(new TargetData(M.get())); // Use correct TargetData
- // Either isolate the function or delete it from the Module
- std::vector<GlobalValue*> GVs;
- if (F) GVs.push_back(F);
- if (G) GVs.push_back(G);
Passes.add(createGVExtractionPass(GVs, DeleteFn, Relink));
if (!DeleteFn)
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index c05bd52..76ce080 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -266,14 +266,14 @@ static int AssembleInput(const char *ProgName) {
if (FileType == OFT_AssemblyFile) {
IP.reset(TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *Out));
if (ShowEncoding)
- CE.reset(TheTarget->createCodeEmitter(*TM));
+ CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
Str.reset(createAsmStreamer(Ctx, *Out, *MAI,
TM->getTargetData()->isLittleEndian(),
/*asmverbose*/true, IP.get(), CE.get(),
ShowInst));
} else {
assert(FileType == OFT_ObjectFile && "Invalid file type!");
- CE.reset(TheTarget->createCodeEmitter(*TM));
+ CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
Str.reset(createMachOStreamer(Ctx, *Out, CE.get()));
}
diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile
new file mode 100644
index 0000000..ce29bf8
--- /dev/null
+++ b/tools/llvm-shlib/Makefile
@@ -0,0 +1,60 @@
+##===- tools/shlib/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 = LLVM-$(LLVMVersion)
+
+NO_BUILD_ARCHIVE = 1
+LINK_LIBS_IN_SHARED = 1
+SHARED_LIBRARY = 1
+
+include $(LEVEL)/Makefile.common
+
+# Include all archives in libLLVM.(so|dylib) except the ones that have
+# their own dynamic libraries.
+Archives := $(wildcard $(LibDir)/libLLVM*.a)
+SharedLibraries := $(wildcard $(LibDir)/libLLVM*$(SHLIBEXT))
+IncludeInLibLlvm := $(filter-out $(basename $(SharedLibraries)).a, $(Archives))
+LLVMLibsOptions := $(IncludeInLibLlvm:$(LibDir)/lib%.a=-l%)
+LLVMLibsPaths := $(IncludeInLibLlvm)
+
+$(LibName.SO): $(LLVMLibsPaths)
+
+ifeq ($(HOST_OS),Darwin)
+ # set dylib internal version number to llvmCore submission number
+ ifdef LLVM_SUBMIT_VERSION
+ LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version \
+ -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) \
+ -Wl,-compatibility_version -Wl,1
+ endif
+ # Include everything from the .a's into the shared library.
+ LLVMLibsOptions := $(LLVMLibsOptions) -all_load
+ # extra options to override libtool defaults
+ LLVMLibsOptions := $(LLVMLibsOptions) \
+ -avoid-version \
+ -Wl,-dead_strip \
+ -Wl,-seg1addr -Wl,0xE0000000
+
+ # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
+ DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
+ ifneq ($(DARWIN_VERS),8)
+ LLVMLibsOptions := $(LLVMLibsOptions) \
+ -Wl,-install_name \
+ -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)"
+ endif
+endif
+
+ifeq ($(HOST_OS), Linux)
+ # Include everything from the .a's into the shared library.
+ LLVMLibsOptions := -Wl,--whole-archive $(LLVMLibsOptions) \
+ -Wl,--no-whole-archive
+ # Don't allow unresolved symbols.
+ LLVMLibsOptions += -Wl,--no-undefined
+endif
diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst
index dfe3898..ca8500d 100644
--- a/tools/llvmc/doc/LLVMC-Reference.rst
+++ b/tools/llvmc/doc/LLVMC-Reference.rst
@@ -329,16 +329,22 @@ separate option groups syntactically.
- ``required`` - this option must be specified exactly once (or, in case of
the list options without the ``multi_val`` property, at least
- once). Incompatible with ``zero_or_one`` and ``one_or_more``.
-
- - ``one_or_more`` - the option must be specified at least one time. Useful
- only for list options in conjunction with ``multi_val``; for ordinary lists
- it is synonymous with ``required``. Incompatible with ``required`` and
- ``zero_or_one``.
-
- - ``optional`` - the option can be specified zero or one times. Useful only
- for list options in conjunction with ``multi_val``. Incompatible with
- ``required`` and ``one_or_more``.
+ once). Incompatible with ``optional`` and ``one_or_more``.
+
+ - ``optional`` - the option can be specified either zero times or exactly
+ once. The default for switch options. Useful only for list options in
+ conjunction with ``multi_val``. Incompatible with ``required``,
+ ``zero_or_more`` and ``one_or_more``.
+
+ - ``one_or_more`` - the option must be specified at least once. Can be useful
+ to allow switch options be both obligatory and be specified multiple
+ times. For list options is useful only in conjunction with ``multi_val``;
+ for ordinary it is synonymous with ``required``. Incompatible with
+ ``required``, ``optional`` and ``zero_or_more``.
+
+ - ``zero_or_more`` - the option can be specified zero or more times. Useful
+ to allow a single switch option to be specified more than
+ once. Incompatible with ``required``, ``optional`` and ``one_or_more``.
- ``hidden`` - the description of this option will not appear in
the ``--help`` output (but will appear in the ``--help-hidden``
diff --git a/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
index f13b9f8..25149ad 100644
--- a/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
+++ b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
@@ -56,7 +56,7 @@ def OptionList : OptionList<[
// (parameter_option "pre-RA-sched",
// (help "Example of an option that is passed to llc")),
(parameter_option "regalloc",
- (help "Register allocator to use.(possible values: simple, linearscan, pbqp, local. default = linearscan)")),
+ (help "Register allocator to use (possible values: simple, linearscan, pbqp, local; default=linearscan)")),
(prefix_list_option "Wa,", (comma_separated),
(help "Pass options to assembler (Run 'gpasm -help' for assembler options)")),
(prefix_list_option "Wl,", (comma_separated),
@@ -72,16 +72,14 @@ class clang_based<string language, string cmd, string ext_E> : Tool<
[(in_language language),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line (case
- (switch_on "E"),
- (case
- (not_empty "o"), !strconcat(cmd, " -E $INFILE -o $OUTFILE"),
- (default), !strconcat(cmd, " -E $INFILE")),
- (default), !strconcat(cmd, " $INFILE -o $OUTFILE"))),
- (actions (case
- (and (multiple_input_files), (or (switch_on "S"), (switch_on "c"))),
- (error "cannot specify -o with -c or -S with multiple files"),
- (switch_on "E"), [(stop_compilation), (output_suffix ext_E)],
+ (command cmd),
+ (actions (case
+ (and (multiple_input_files),
+ (or (switch_on "S"), (switch_on "c"))),
+ (error "cannot specify -o with -c or -S with multiple files"),
+ (switch_on "E"), [(forward "E"),
+ (stop_compilation), (output_suffix ext_E)],
+ (and (switch_on "E"), (empty "o")), (no_out_file),
(switch_on "bc"),[(stop_compilation), (output_suffix "bc")],
(switch_on "g"), (append_cmd "-g"),
(switch_on "w"), (append_cmd "-w"),
@@ -116,12 +114,13 @@ def llvm_ld : Tool<[
(in_language "llvm-bitcode"),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -disable-gvn -disable-licm-promotion -disable-mem2reg $INFILE -b $OUTFILE -l std"),
+ (command "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -disable-licm-promotion -l std"),
+ (out_file_option "-b"),
(actions (case
(switch_on "O0"), (append_cmd "-disable-opt"),
(switch_on "O1"), (append_cmd "-disable-opt"),
// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
- (switch_on "O2"), (append_cmd ""),
+ (switch_on "O2"), (append_cmd ""),
(switch_on "O3"), (append_cmd ""),
(default), (append_cmd "-disable-inlining"))),
(join)
@@ -134,12 +133,13 @@ def llvm_ld_optimizer : Tool<[
(output_suffix "bc"),
// FIXME: we are still not disabling licm-promotion.
// -disable-licm-promotion and building stdn library causes c16-71 to fail.
- (cmd_line "$CALL(GetBinDir)llvm-ld -disable-gvn -disable-mem2reg $INFILE -b $OUTFILE"),
+ (command "$CALL(GetBinDir)llvm-ld "),
+ (out_file_option "-b"),
(actions (case
(switch_on "O0"), (append_cmd "-disable-opt"),
(switch_on "O1"), (append_cmd "-disable-opt"),
// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
- (switch_on "O2"), (append_cmd ""),
+ (switch_on "O2"), (append_cmd ""),
(switch_on "O3"), (append_cmd ""),
(default), (append_cmd "-disable-inlining")))
]>;
@@ -149,7 +149,7 @@ def pic16passes : Tool<[
(in_language "llvm-bitcode"),
(out_language "llvm-bitcode"),
(output_suffix "obc"),
- (cmd_line "$CALL(GetBinDir)opt -pic16cg -pic16overlay $INFILE -f -o $OUTFILE"),
+ (command "$CALL(GetBinDir)opt -pic16cloner -pic16overlay -f"),
(actions (case
(switch_on "O0"), (append_cmd "-disable-opt")))
]>;
@@ -158,7 +158,7 @@ def llc : Tool<[
(in_language "llvm-bitcode"),
(out_language "assembler"),
(output_suffix "s"),
- (cmd_line "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -f $INFILE -o $OUTFILE"),
+ (command "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -f"),
(actions (case
(switch_on "S"), (stop_compilation),
// (not_empty "Wllc,"), (unpack_values "Wllc,"),
@@ -171,7 +171,7 @@ def gpasm : Tool<[
(in_language "assembler"),
(out_language "object-code"),
(output_suffix "o"),
- (cmd_line "$CALL(GetBinDir)gpasm -z -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2 $INFILE -o $OUTFILE"),
+ (command "$CALL(GetBinDir)gpasm -z -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2"),
(actions (case
(switch_on "c"), (stop_compilation),
(switch_on "g"), (append_cmd "-g"),
@@ -184,7 +184,7 @@ def mplink : Tool<[
(in_language "object-code"),
(out_language "executable"),
(output_suffix "cof"),
- (cmd_line "$CALL(GetBinDir)mplink -e -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib $INFILE -o $OUTFILE"),
+ (command "$CALL(GetBinDir)mplink -e -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib"),
(actions (case
(not_empty "Wl,"), (forward_value "Wl,"),
(switch_on "X"), (append_cmd "-x"),
@@ -217,13 +217,13 @@ def LanguageMap : LanguageMap<[
def CompilationGraph : CompilationGraph<[
Edge<"root", "clang_cc">,
Edge<"root", "llvm_ld">,
- OptionalEdge<"root", "llvm_ld_optimizer", (case
+ OptionalEdge<"root", "llvm_ld_optimizer", (case
(switch_on "S"), (inc_weight),
(switch_on "c"), (inc_weight))>,
Edge<"root", "gpasm">,
Edge<"root", "mplink">,
Edge<"clang_cc", "llvm_ld">,
- OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case
+ OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case
(switch_on "S"), (inc_weight),
(switch_on "c"), (inc_weight))>,
Edge<"llvm_ld", "pic16passes">,
diff --git a/tools/llvmc/plugins/Base/Base.td.in b/tools/llvmc/plugins/Base/Base.td.in
index c94c3df..ac0f665 100644
--- a/tools/llvmc/plugins/Base/Base.td.in
+++ b/tools/llvmc/plugins/Base/Base.td.in
@@ -25,13 +25,13 @@ def OptList : OptionList<[
(switch_option "opt",
(help "Enable opt")),
(switch_option "O0",
- (help "Turn off optimization")),
+ (help "Turn off optimization"), (zero_or_more)),
(switch_option "O1",
- (help "Optimization level 1")),
+ (help "Optimization level 1"), (zero_or_more)),
(switch_option "O2",
- (help "Optimization level 2")),
+ (help "Optimization level 2"), (zero_or_more)),
(switch_option "O3",
- (help "Optimization level 3")),
+ (help "Optimization level 3"), (zero_or_more)),
(switch_option "S",
(help "Stop after compilation, do not assemble")),
(switch_option "c",
@@ -49,12 +49,7 @@ def OptList : OptionList<[
(parameter_option "linker",
(help "Choose linker (possible values: gcc, g++)")),
(parameter_option "mtune",
- (help "Target a specific CPU type"), (hidden)),
- (parameter_option "fmessage-length",
- (help "Format error messages to fit on lines of about n characters "),
- (hidden)),
- (parameter_option "std",
- (help "Determine the language standard"), (hidden)),
+ (help "Target a specific CPU type"), (hidden), (forward_not_split)),
// TODO: Add a conditional compilation mechanism to make Darwin-only options
// like '-arch' really Darwin-only.
@@ -62,9 +57,11 @@ def OptList : OptionList<[
(parameter_option "arch",
(help "Compile for the specified target architecture"), (hidden)),
(parameter_option "march",
- (help "A synonym for -mtune"), (hidden)),
+ (help "A synonym for -mtune"), (hidden), (forward_not_split)),
(parameter_option "mcpu",
- (help "A deprecated synonym for -mtune"), (hidden)),
+ (help "A deprecated synonym for -mtune"), (hidden), (forward_not_split)),
+ (switch_option "mfix-and-continue",
+ (help "Needed by gdb to load .o files dynamically"), (hidden)),
(parameter_option "MF",
(help "Specify a file to write dependencies to"), (hidden)),
(parameter_list_option "MT",
@@ -79,14 +76,20 @@ def OptList : OptionList<[
(help "Specifies a framework to link against")),
(parameter_list_option "weak_framework",
(help "Specifies a framework to weakly link against"), (hidden)),
+ (parameter_option "filelist", (hidden),
+ (help "Link the files listed in file")),
(prefix_list_option "F",
(help "Add a directory to framework search path")),
(prefix_list_option "I",
(help "Add a directory to include path")),
(prefix_list_option "D",
(help "Define a macro")),
+ (parameter_list_option "Xpreprocessor", (hidden),
+ (help "Pass options to preprocessor")),
(prefix_list_option "Wa,", (comma_separated),
(help "Pass options to assembler")),
+ (parameter_list_option "Xassembler", (hidden),
+ (help "Pass options to assembler")),
(prefix_list_option "Wllc,", (comma_separated),
(help "Pass options to llc")),
(prefix_list_option "L",
@@ -95,11 +98,27 @@ def OptList : OptionList<[
(help "Search a library when linking")),
(prefix_list_option "Wl,",
(help "Pass options to linker")),
+ (parameter_list_option "Xlinker", (hidden),
+ (help "Pass options to linker")),
(prefix_list_option "Wo,", (comma_separated),
(help "Pass options to opt")),
(prefix_list_option "m",
(help "Enable or disable various extensions (-mmmx, -msse, etc.)"),
- (hidden))
+ (hidden)),
+ (switch_option "dynamiclib", (hidden),
+ (help "Produce a dynamic library")),
+ (switch_option "prebind", (hidden),
+ (help "Prebind all undefined symbols")),
+ (switch_option "dead_strip", (hidden),
+ (help "Remove unreachable blocks of code")),
+ (switch_option "single_module", (hidden),
+ (help "Build the library so it contains only one module")),
+ (parameter_option "install_name", (hidden),
+ (help "File name the library will be installed in")),
+ (parameter_option "compatibility_version", (hidden),
+ (help "Compatibility version number")),
+ (parameter_option "current_version", (hidden),
+ (help "Current version number"))
]>;
// Option preprocessor.
@@ -117,31 +136,31 @@ def Preprocess : OptionPreprocessor<
// Tools
-class llvm_gcc_based <string cmd_prefix, string in_lang, string E_ext> : Tool<
+class llvm_gcc_based <string cmd_prefix, string in_lang,
+ string E_ext, string out_lang> : Tool<
[(in_language in_lang),
(out_language "llvm-bitcode"),
- (output_suffix "bc"),
- (cmd_line (case
- (switch_on "E"),
- (case (not_empty "o"),
- !strconcat(cmd_prefix, " -E $INFILE -o $OUTFILE"),
- (default),
- !strconcat(cmd_prefix, " -E $INFILE")),
- (switch_on "fsyntax-only"),
- !strconcat(cmd_prefix, " -fsyntax-only $INFILE"),
- (and (switch_on "S"), (switch_on "emit-llvm")),
- !strconcat(cmd_prefix, " -S $INFILE -o $OUTFILE -emit-llvm"),
- (default),
- !strconcat(cmd_prefix, " -c $INFILE -o $OUTFILE -emit-llvm"))),
+ (output_suffix out_lang),
+ (command cmd_prefix),
(actions
(case
- (and (multiple_input_files), (or (switch_on "S"), (switch_on "c"))),
+ (and (not_empty "o"),
+ (multiple_input_files), (or (switch_on "S"), (switch_on "c"))),
(error "cannot specify -o with -c or -S with multiple files"),
- (switch_on "E"), [(stop_compilation), (output_suffix E_ext)],
+ (switch_on "E"),
+ [(forward "E"), (stop_compilation), (output_suffix E_ext)],
+ (and (switch_on "E"), (empty "o")), (no_out_file),
(switch_on ["emit-llvm", "S"]),
[(output_suffix "ll"), (stop_compilation)],
(switch_on ["emit-llvm", "c"]), (stop_compilation),
- (switch_on "fsyntax-only"), (stop_compilation),
+ (switch_on "fsyntax-only"), [(forward "fsyntax-only"),
+ (no_out_file), (stop_compilation)],
+ (switch_on ["S", "emit-llvm"]), [(forward "S"), (forward "emit-llvm")],
+ (not (or (switch_on ["S", "emit-llvm"]), (switch_on "fsyntax-only"))),
+ [(append_cmd "-c"), (append_cmd "-emit-llvm")],
+
+ // Forwards
+ (not_empty "Xpreprocessor"), (forward "Xpreprocessor"),
(not_empty "include"), (forward "include"),
(not_empty "iquote"), (forward "iquote"),
(not_empty "save-temps"), (append_cmd "-save-temps"),
@@ -153,8 +172,7 @@ class llvm_gcc_based <string cmd_prefix, string in_lang, string E_ext> : Tool<
(not_empty "mtune"), (forward "mtune"),
(not_empty "mcpu"), (forward "mcpu"),
(not_empty "m"), (forward "m"),
- (not_empty "std"), (forward "std"),
- (not_empty "fmessage-length"), (forward "fmessage-length"),
+ (switch_on "mfix-and-continue"), (forward "mfix-and-continue"),
(switch_on "m32"), (forward "m32"),
(switch_on "m64"), (forward "m64"),
(switch_on "O0"), (forward "O0"),
@@ -168,12 +186,24 @@ class llvm_gcc_based <string cmd_prefix, string in_lang, string E_ext> : Tool<
(sink)
]>;
-def llvm_gcc_c : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c", "c", "i">;
-def llvm_gcc_cpp : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++", "c++", "i">;
+def llvm_gcc_c : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c", "c", "i", "bc">;
+def llvm_gcc_cpp : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++", "c++", "i", "bc">;
def llvm_gcc_m : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c",
- "objective-c", "mi">;
+ "objective-c", "mi", "bc">;
def llvm_gcc_mxx : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++",
- "objective-c++", "mi">;
+ "objective-c++", "mi", "bc">;
+
+def llvm_gcc_c_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c-header",
+ "c-header", "i", "gch">;
+def llvm_gcc_cpp_pch : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++-header",
+ "c++-header",
+ "i", "gch">;
+def llvm_gcc_m_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c-header",
+ "objective-c-header",
+ "mi", "gch">;
+def llvm_gcc_mxx_pch
+ : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++-header",
+ "objective-c++-header", "mi", "gch">;
def opt : Tool<
[(in_language "llvm-bitcode"),
@@ -183,14 +213,14 @@ def opt : Tool<
(switch_on "O1"), (forward "O1"),
(switch_on "O2"), (forward "O2"),
(switch_on "O3"), (forward "O3"))),
- (cmd_line "opt -f $INFILE -o $OUTFILE")
+ (command "opt -f")
]>;
def llvm_as : Tool<
[(in_language "llvm-assembler"),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line "llvm-as $INFILE -o $OUTFILE"),
+ (command "llvm-as"),
(actions (case (switch_on "emit-llvm"), (stop_compilation)))
]>;
@@ -198,19 +228,19 @@ def llvm_gcc_assembler : Tool<
[(in_language "assembler"),
(out_language "object-code"),
(output_suffix "o"),
- (cmd_line "@LLVMGCCCOMMAND@ -c -x assembler $INFILE -o $OUTFILE"),
+ (command "@LLVMGCCCOMMAND@ -c -x assembler"),
(actions (case
(switch_on "c"), (stop_compilation),
(not_empty "arch"), (forward "arch"),
- (not_empty "fmessage-length"), (forward "fmessage-length"),
- (not_empty "Wa,"), (forward_value "Wa,")))
+ (not_empty "Xassembler"), (forward "Xassembler"),
+ (not_empty "Wa,"), (forward "Wa,")))
]>;
def llc : Tool<
[(in_language ["llvm-bitcode", "llvm-assembler"]),
(out_language "assembler"),
(output_suffix "s"),
- (cmd_line "llc -f $INFILE -o $OUTFILE"),
+ (command "llc -f"),
(actions (case
(switch_on "S"), (stop_compilation),
(switch_on "O0"), (forward "O0"),
@@ -220,8 +250,8 @@ def llc : Tool<
(switch_on "fPIC"), (append_cmd "-relocation-model=pic"),
(switch_on "mdynamic-no-pic"),
(append_cmd "-relocation-model=dynamic-no-pic"),
- (not_empty "march"), (forward "mcpu"),
- (not_empty "mtune"), (forward "mcpu"),
+ (not_empty "march"), (forward_as "mtune", "-mcpu"),
+ (not_empty "mtune"), (forward_as "mtune", "-mcpu"),
(not_empty "mcpu"), (forward "mcpu"),
(not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"),
(not_empty "Wllc,"), (forward_value "Wllc,")))
@@ -232,7 +262,9 @@ class llvm_gcc_based_linker <string cmd_prefix> : Tool<
[(in_language "object-code"),
(out_language "executable"),
(output_suffix "out"),
- (cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")),
+ (command cmd_prefix),
+ (works_on_empty (case (not_empty "filelist"), true,
+ (default), false)),
(join),
(actions (case
(switch_on "pthread"), (append_cmd "-lpthread"),
@@ -241,11 +273,20 @@ class llvm_gcc_based_linker <string cmd_prefix> : Tool<
(not_empty "arch"), (forward "arch"),
(not_empty "framework"), (forward "framework"),
(not_empty "weak_framework"), (forward "weak_framework"),
+ (not_empty "filelist"), (forward "filelist"),
(switch_on "m32"), (forward "m32"),
(switch_on "m64"), (forward "m64"),
- (not_empty "fmessage-length"), (forward "fmessage-length"),
(not_empty "l"), (forward "l"),
- (not_empty "Wl,"), (forward "Wl,")))
+ (not_empty "Xlinker"), (forward "Xlinker"),
+ (not_empty "Wl,"), (forward "Wl,"),
+ (switch_on "dynamiclib"), (forward "dynamiclib"),
+ (switch_on "prebind"), (forward "prebind"),
+ (switch_on "dead_strip"), (forward "dead_strip"),
+ (switch_on "single_module"), (forward "single_module"),
+ (not_empty "compatibility_version"),
+ (forward "compatibility_version"),
+ (not_empty "current_version"), (forward "current_version"),
+ (not_empty "install_name"), (forward "install_name")))
]>;
// Default linker
@@ -257,16 +298,20 @@ def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"@LLVMGXXCOMMAND@">;
def LanguageMap : LanguageMap<
[LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
+ LangToSuffixes<"c++-header", ["hpp"]>,
LangToSuffixes<"c", ["c"]>,
+ LangToSuffixes<"c-header", ["h"]>,
LangToSuffixes<"c-cpp-output", ["i"]>,
LangToSuffixes<"objective-c-cpp-output", ["mi"]>,
LangToSuffixes<"objective-c++", ["mm"]>,
+ LangToSuffixes<"objective-c++-header", ["hmm"]>,
LangToSuffixes<"objective-c", ["m"]>,
+ LangToSuffixes<"objective-c-header", ["hm"]>,
LangToSuffixes<"assembler", ["s"]>,
LangToSuffixes<"assembler-with-cpp", ["S"]>,
LangToSuffixes<"llvm-assembler", ["ll"]>,
LangToSuffixes<"llvm-bitcode", ["bc"]>,
- LangToSuffixes<"object-code", ["o"]>,
+ LangToSuffixes<"object-code", ["o", "*empty*"]>,
LangToSuffixes<"executable", ["out"]>
]>;
@@ -280,6 +325,11 @@ def CompilationGraph : CompilationGraph<[
Edge<"root", "llvm_gcc_mxx">,
Edge<"root", "llc">,
+ Edge<"root", "llvm_gcc_c_pch">,
+ Edge<"root", "llvm_gcc_cpp_pch">,
+ Edge<"root", "llvm_gcc_m_pch">,
+ Edge<"root", "llvm_gcc_mxx_pch">,
+
Edge<"llvm_gcc_c", "llc">,
Edge<"llvm_gcc_cpp", "llc">,
Edge<"llvm_gcc_m", "llc">,
diff --git a/tools/llvmc/plugins/Clang/Clang.td b/tools/llvmc/plugins/Clang/Clang.td
index ac8ac15..988d9b1 100644
--- a/tools/llvmc/plugins/Clang/Clang.td
+++ b/tools/llvmc/plugins/Clang/Clang.td
@@ -1,12 +1,3 @@
-// A replacement for the Clang's ccc script.
-// Depends on the Base plugin.
-// To compile, use this command:
-//
-// cd $LLVMC2_DIR
-// make DRIVER_NAME=ccc2 BUILTIN_PLUGINS=Clang
-//
-// Or just use the default llvmc, which now has this plugin enabled.
-
include "llvm/CompilerDriver/Common.td"
def Priority : PluginPriority<1>;
@@ -33,23 +24,17 @@ class clang_based<string language, string cmd, string ext_E> : Tool<
[(in_language language),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line (case
- (switch_on "E"),
- (case
- (not_empty "o"),
- !strconcat(cmd, " -E $INFILE -o $OUTFILE"),
- (default),
- !strconcat(cmd, " -E $INFILE")),
- (and (switch_on "S"), (switch_on "emit-llvm")),
- !strconcat(cmd, " -emit-llvm $INFILE -o $OUTFILE"),
- (default),
- !strconcat(cmd, " -emit-llvm-bc $INFILE -o $OUTFILE"))),
+ (command cmd),
(actions (case (switch_on "E"),
- [(stop_compilation), (output_suffix ext_E)],
+ [(forward "E"), (stop_compilation), (output_suffix ext_E)],
+ (and (switch_on "E"), (empty "o")), (no_out_file),
(switch_on "fsyntax-only"), (stop_compilation),
- (and (switch_on "S"), (switch_on "emit-llvm")),
- [(stop_compilation), (output_suffix "ll")],
- (and (switch_on "c"), (switch_on "emit-llvm")),
+ (switch_on ["S", "emit-llvm"]),
+ [(append_cmd "-emit-llvm"),
+ (stop_compilation), (output_suffix "ll")],
+ (not (switch_on ["S", "emit-llvm"])),
+ (append_cmd "-emit-llvm-bc"),
+ (switch_on ["c", "emit-llvm"]),
(stop_compilation),
(not_empty "include"), (forward "include"),
(not_empty "I"), (forward "I"))),
@@ -67,7 +52,7 @@ def as : Tool<
[(in_language "assembler"),
(out_language "object-code"),
(output_suffix "o"),
- (cmd_line "as $INFILE -o $OUTFILE"),
+ (command "as"),
(actions (case (not_empty "Wa,"), (forward_value "Wa,"),
(switch_on "c"), (stop_compilation)))
]>;
@@ -77,7 +62,7 @@ def llvm_ld : Tool<
[(in_language "object-code"),
(out_language "executable"),
(output_suffix "out"),
- (cmd_line "llvm-ld -native -disable-internalize $INFILE -o $OUTFILE"),
+ (command "llvm-ld -native -disable-internalize"),
(actions (case
(switch_on "pthread"), (append_cmd "-lpthread"),
(not_empty "L"), (forward "L"),
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 5200180..b123d54 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -475,10 +475,11 @@ int main(int argc, char **argv) {
errs() << argv[0] << ": cannot create pass: "
<< PassInf->getPassName() << "\n";
if (P) {
+ PassKind Kind = P->getPassKind();
addPass(Passes, P);
if (AnalyzeOnly) {
- switch (P->getPassKind()) {
+ switch (Kind) {
case PT_BasicBlock:
Passes.add(new BasicBlockPassPrinter(PassInf));
break;
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index b02cc3e..5719960 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -236,6 +236,13 @@ TEST(APFloatTest, fromDecimalString) {
EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble, "002.05000e12").convertToDouble());
EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble, "002.05000e+12").convertToDouble());
EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble, "002.05000e-12").convertToDouble());
+
+ // These are "carefully selected" to overflow the fast log-base
+ // calculations in APFloat.cpp
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "99e99999").isInfinity());
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-99e99999").isInfinity());
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "1e-99999").isPosZero());
+ EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-1e-99999").isNegZero());
}
TEST(APFloatTest, fromHexadecimalString) {
@@ -337,6 +344,35 @@ TEST(APFloatTest, toString) {
ASSERT_EQ("8.731834E+2", convertToString(873.1834, 0, 0));
}
+static APInt nanbits(const fltSemantics &Sem,
+ bool SNaN, bool Negative, uint64_t fill) {
+ APInt apfill(64, fill);
+ if (SNaN)
+ return APFloat::getSNaN(Sem, Negative, &apfill).bitcastToAPInt();
+ else
+ return APFloat::getQNaN(Sem, Negative, &apfill).bitcastToAPInt();
+}
+
+TEST(APFloatTest, makeNaN) {
+ ASSERT_EQ(0x7fc00000, nanbits(APFloat::IEEEsingle, false, false, 0));
+ ASSERT_EQ(0xffc00000, nanbits(APFloat::IEEEsingle, false, true, 0));
+ ASSERT_EQ(0x7fc0ae72, nanbits(APFloat::IEEEsingle, false, false, 0xae72));
+ ASSERT_EQ(0x7fffae72, nanbits(APFloat::IEEEsingle, false, false, 0xffffae72));
+ ASSERT_EQ(0x7fa00000, nanbits(APFloat::IEEEsingle, true, false, 0));
+ ASSERT_EQ(0xffa00000, nanbits(APFloat::IEEEsingle, true, true, 0));
+ ASSERT_EQ(0x7f80ae72, nanbits(APFloat::IEEEsingle, true, false, 0xae72));
+ ASSERT_EQ(0x7fbfae72, nanbits(APFloat::IEEEsingle, true, false, 0xffffae72));
+
+ ASSERT_EQ(0x7ff8000000000000ULL, nanbits(APFloat::IEEEdouble, false, false, 0));
+ ASSERT_EQ(0xfff8000000000000ULL, nanbits(APFloat::IEEEdouble, false, true, 0));
+ ASSERT_EQ(0x7ff800000000ae72ULL, nanbits(APFloat::IEEEdouble, false, false, 0xae72));
+ ASSERT_EQ(0x7fffffffffffae72ULL, nanbits(APFloat::IEEEdouble, false, false, 0xffffffffffffae72ULL));
+ ASSERT_EQ(0x7ff4000000000000ULL, nanbits(APFloat::IEEEdouble, true, false, 0));
+ ASSERT_EQ(0xfff4000000000000ULL, nanbits(APFloat::IEEEdouble, true, true, 0));
+ ASSERT_EQ(0x7ff000000000ae72ULL, nanbits(APFloat::IEEEdouble, true, false, 0xae72));
+ ASSERT_EQ(0x7ff7ffffffffae72ULL, nanbits(APFloat::IEEEdouble, true, false, 0xffffffffffffae72ULL));
+}
+
#ifdef GTEST_HAS_DEATH_TEST
TEST(APFloatTest, SemanticsDeath) {
EXPECT_DEATH(APFloat(APFloat::IEEEsingle, 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 3dcdc39..413f068 100644
--- a/unittests/ADT/StringMapTest.cpp
+++ b/unittests/ADT/StringMapTest.cpp
@@ -191,6 +191,7 @@ TEST_F(StringMapTest, StringMapEntryTest) {
testKeyFirst, testKeyFirst + testKeyLength, 1u);
EXPECT_STREQ(testKey, entry->first());
EXPECT_EQ(1u, entry->second);
+ free(entry);
}
// Test insert() method.
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 84ee0e3..b85f724 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -65,6 +65,8 @@ public:
stubsAllocated = 0;
}
+ void setSizeRequired(bool Required) { SizeRequired = Required; }
+
virtual void setMemoryWritable() { Base->setMemoryWritable(); }
virtual void setMemoryExecutable() { Base->setMemoryExecutable(); }
virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); }
@@ -628,6 +630,54 @@ TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) {
<< " not 7 from the IR version.";
}
+TEST_F(JITTest, NeedsExactSizeWithManyGlobals) {
+ // PR5291: When the JMM needed the exact size of function bodies before
+ // starting to emit them, the JITEmitter would modify a set while iterating
+ // over it.
+ TheJIT->DisableLazyCompilation(true);
+ RJMM->setSizeRequired(true);
+
+ LoadAssembly("@A = global i32 42 "
+ "@B = global i32* @A "
+ "@C = global i32** @B "
+ "@D = global i32*** @C "
+ "@E = global i32**** @D "
+ "@F = global i32***** @E "
+ "@G = global i32****** @F "
+ "@H = global i32******* @G "
+ "@I = global i32******** @H "
+ "define i32********* @test() { "
+ " ret i32********* @I "
+ "}");
+ Function *testIR = M->getFunction("test");
+ int32_t********* (*test)() = reinterpret_cast<int32_t*********(*)()>(
+ (intptr_t)TheJIT->getPointerToFunction(testIR));
+ EXPECT_EQ(42, *********test());
+}
+
+TEST_F(JITTest, EscapedLazyStubStillCallable) {
+ TheJIT->DisableLazyCompilation(false);
+ LoadAssembly("define internal i32 @stubbed() { "
+ " ret i32 42 "
+ "} "
+ " "
+ "define i32()* @get_stub() { "
+ " ret i32()* @stubbed "
+ "} ");
+ typedef int32_t(*StubTy)();
+
+ // Call get_stub() to get the address of @stubbed without actually JITting it.
+ Function *get_stubIR = M->getFunction("get_stub");
+ StubTy (*get_stub)() = reinterpret_cast<StubTy(*)()>(
+ (intptr_t)TheJIT->getPointerToFunction(get_stubIR));
+ StubTy stubbed = get_stub();
+ // Now get_stubIR is the only reference to stubbed's stub.
+ get_stubIR->eraseFromParent();
+ // Now there are no references inside the JIT, but we've got a pointer outside
+ // it. The stub should be callable and return the right value.
+ EXPECT_EQ(42, stubbed());
+}
+
// Converts the LLVM assembly to bitcode and returns it in a std::string. An
// empty string indicates an error.
std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) {
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
new file mode 100644
index 0000000..8997d39
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
@@ -0,0 +1,164 @@
+//===- MultiJITTest.cpp - Unit tests for instantiating multiple JITs ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/Parser.h"
+#include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/Support/SourceMgr.h"
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+
+bool LoadAssemblyInto(Module *M, const char *assembly) {
+ SMDiagnostic Error;
+ bool success =
+ NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ Error.Print("", os);
+ EXPECT_TRUE(success) << os.str();
+ return success;
+}
+
+void createModule1(LLVMContext &Context1, Module *&M1, Function *&FooF1) {
+ M1 = new Module("test1", Context1);
+ LoadAssemblyInto(M1,
+ "define i32 @add1(i32 %ArgX1) { "
+ "entry: "
+ " %addresult = add i32 1, %ArgX1 "
+ " ret i32 %addresult "
+ "} "
+ " "
+ "define i32 @foo1() { "
+ "entry: "
+ " %add1 = call i32 @add1(i32 10) "
+ " ret i32 %add1 "
+ "} ");
+ FooF1 = M1->getFunction("foo1");
+}
+
+void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
+ M2 = new Module("test2", Context2);
+ LoadAssemblyInto(M2,
+ "define i32 @add2(i32 %ArgX2) { "
+ "entry: "
+ " %addresult = add i32 2, %ArgX2 "
+ " ret i32 %addresult "
+ "} "
+ " "
+ "define i32 @foo2() { "
+ "entry: "
+ " %add2 = call i32 @add2(i32 10) "
+ " ret i32 %add2 "
+ "} ");
+ FooF2 = M2->getFunction("foo2");
+}
+
+TEST(MultiJitTest, EagerMode) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create the JIT in eager mode
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ EE1->DisableLazyCompilation(true);
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ EE2->DisableLazyCompilation(true);
+
+ // Call the `foo' function with no arguments:
+ std::vector<GenericValue> noargs;
+ GenericValue gv1 = EE1->runFunction(FooF1, noargs);
+ GenericValue gv2 = EE2->runFunction(FooF2, noargs);
+
+ // Import result of execution:
+ EXPECT_EQ(gv1.IntVal, 11);
+ EXPECT_EQ(gv2.IntVal, 12);
+
+ EE1->freeMachineCodeForFunction(FooF1);
+ EE2->freeMachineCodeForFunction(FooF2);
+}
+
+TEST(MultiJitTest, LazyMode) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create the JIT in lazy mode
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ EE1->DisableLazyCompilation(false);
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ EE2->DisableLazyCompilation(false);
+
+ // Call the `foo' function with no arguments:
+ std::vector<GenericValue> noargs;
+ GenericValue gv1 = EE1->runFunction(FooF1, noargs);
+ GenericValue gv2 = EE2->runFunction(FooF2, noargs);
+
+ // Import result of execution:
+ EXPECT_EQ(gv1.IntVal, 11);
+ EXPECT_EQ(gv2.IntVal, 12);
+
+ EE1->freeMachineCodeForFunction(FooF1);
+ EE2->freeMachineCodeForFunction(FooF2);
+}
+
+extern "C" {
+ extern void *getPointerToNamedFunction(const char *Name);
+}
+
+TEST(MultiJitTest, JitPool) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create two JITs
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+
+ Function *F1 = EE1->FindFunctionNamed("foo1");
+ void *foo1 = EE1->getPointerToFunction(F1);
+
+ Function *F2 = EE2->FindFunctionNamed("foo2");
+ void *foo2 = EE2->getPointerToFunction(F2);
+
+ // Function in M1
+ EXPECT_EQ(getPointerToNamedFunction("foo1"), foo1);
+
+ // Function in M2
+ EXPECT_EQ(getPointerToNamedFunction("foo2"), foo2);
+
+ // Symbol search
+ EXPECT_EQ((intptr_t)getPointerToNamedFunction("getPointerToNamedFunction"),
+ (intptr_t)&getPointerToNamedFunction);
+}
+
+} // anonymous namespace
diff --git a/unittests/Makefile.unittest b/unittests/Makefile.unittest
index 6fbef54..b1c1d2c 100644
--- a/unittests/Makefile.unittest
+++ b/unittests/Makefile.unittest
@@ -28,6 +28,15 @@ CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/
CPP.Flags += $(NO_VARIADIC_MACROS)
TESTLIBS = -lGoogleTest -lUnitTestMain
+ifeq ($(ENABLE_SHARED), 1)
+ # Add the absolute path to the dynamic library. This is ok because
+ # we'll never install unittests.
+ LD.Flags += $(RPATH) -Wl,$(LibDir)
+ # Also set {DYLD,LD}_LIBRARY_PATH because OSX ignores the rpath most
+ # of the time.
+ Run.Shared := $(SHLIBPATH_VAR)="$(LibDir)$${$(SHLIBPATH_VAR):+:}$$$(SHLIBPATH_VAR)"
+endif
+
$(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths)
$(Echo) Linking $(BuildMode) unit test $(TESTNAME) $(StripWarnMsg)
$(Verb) $(Link) -o $@ $(TOOLLINKOPTS) $(ObjectsO) $(ProjLibsOptions) \
@@ -38,6 +47,6 @@ $(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths)
all:: $(LLVMUnitTestExe)
unitcheck:: $(LLVMUnitTestExe)
- $(LLVMUnitTestExe)
+ $(Run.Shared) $(LLVMUnitTestExe)
endif
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
index 2a01f3a..6c0fca9 100644
--- a/unittests/Support/AllocatorTest.cpp
+++ b/unittests/Support/AllocatorTest.cpp
@@ -88,7 +88,7 @@ TEST(AllocatorTest, TestOverflow) {
Alloc.Allocate(4096 - sizeof(MemSlab), 0);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
- // If we dont't allocate a new slab, then we will have overflowed.
+ // If we don't allocate a new slab, then we will have overflowed.
Alloc.Allocate(1, 0);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
diff --git a/unittests/Support/RegexTest.cpp b/unittests/Support/RegexTest.cpp
index 44c7e55..65b66c3 100644
--- a/unittests/Support/RegexTest.cpp
+++ b/unittests/Support/RegexTest.cpp
@@ -62,4 +62,33 @@ TEST_F(RegexTest, Basics) {
EXPECT_TRUE(r5.match(String));
}
+TEST_F(RegexTest, Substitution) {
+ std::string Error;
+
+ EXPECT_EQ("aNUMber", Regex("[0-9]+").sub("NUM", "a1234ber"));
+
+ // Standard Escapes
+ EXPECT_EQ("a\\ber", Regex("[0-9]+").sub("\\\\", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+ EXPECT_EQ("a\nber", Regex("[0-9]+").sub("\\n", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+ EXPECT_EQ("a\tber", Regex("[0-9]+").sub("\\t", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+ EXPECT_EQ("ajber", Regex("[0-9]+").sub("\\j", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+
+ EXPECT_EQ("aber", Regex("[0-9]+").sub("\\", "a1234ber", &Error));
+ EXPECT_EQ(Error, "replacement string contained trailing backslash");
+
+ // Backreferences
+ EXPECT_EQ("aa1234bber", Regex("a[0-9]+b").sub("a\\0b", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+
+ EXPECT_EQ("a1234ber", Regex("a([0-9]+)b").sub("a\\1b", "a1234ber", &Error));
+ EXPECT_EQ(Error, "");
+
+ EXPECT_EQ("aber", Regex("a[0-9]+b").sub("a\\100b", "a1234ber", &Error));
+ EXPECT_EQ(Error, "invalid backreference string '100'");
+}
+
}
diff --git a/unittests/VMCore/DerivedTypesTest.cpp b/unittests/VMCore/DerivedTypesTest.cpp
index 11b4dff..2e0450d 100644
--- a/unittests/VMCore/DerivedTypesTest.cpp
+++ b/unittests/VMCore/DerivedTypesTest.cpp
@@ -18,14 +18,16 @@ namespace {
TEST(OpaqueTypeTest, RegisterWithContext) {
LLVMContext C;
- LLVMContextImpl *pImpl = C.pImpl;
+ LLVMContextImpl *pImpl = C.pImpl;
- EXPECT_EQ(0u, pImpl->OpaqueTypes.size());
+ // 1 refers to the AlwaysOpaqueTy allocated in the Context's constructor and
+ // destroyed in the destructor.
+ EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
{
PATypeHolder Type = OpaqueType::get(C);
- EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
+ EXPECT_EQ(2u, pImpl->OpaqueTypes.size());
}
- EXPECT_EQ(0u, pImpl->OpaqueTypes.size());
+ EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
}
} // namespace
diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp
index e374789..13bf27e 100644
--- a/unittests/VMCore/MetadataTest.cpp
+++ b/unittests/VMCore/MetadataTest.cpp
@@ -20,11 +20,15 @@ using namespace llvm;
namespace {
-LLVMContext &Context = getGlobalContext();
+class MetadataTest : public testing::Test {
+protected:
+ LLVMContext Context;
+};
+typedef MetadataTest MDStringTest;
// Test that construction of MDString with different value produces different
// MDString objects, even with the same string pointer and nulls in the string.
-TEST(MDStringTest, CreateDifferent) {
+TEST_F(MDStringTest, CreateDifferent) {
char x[3] = { 'f', 0, 'A' };
MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
x[2] = 'B';
@@ -34,7 +38,7 @@ TEST(MDStringTest, CreateDifferent) {
// Test that creation of MDStrings with the same string contents produces the
// same MDString object, even with different pointers.
-TEST(MDStringTest, CreateSame) {
+TEST_F(MDStringTest, CreateSame) {
char x[4] = { 'a', 'b', 'c', 'X' };
char y[4] = { 'a', 'b', 'c', 'Y' };
@@ -44,7 +48,7 @@ TEST(MDStringTest, CreateSame) {
}
// Test that MDString prints out the string we fed it.
-TEST(MDStringTest, PrintingSimple) {
+TEST_F(MDStringTest, PrintingSimple) {
char *str = new char[13];
strncpy(str, "testing 1 2 3", 13);
MDString *s = MDString::get(Context, StringRef(str, 13));
@@ -58,7 +62,7 @@ TEST(MDStringTest, PrintingSimple) {
}
// Test printing of MDString with non-printable characters.
-TEST(MDStringTest, PrintingComplex) {
+TEST_F(MDStringTest, PrintingComplex) {
char str[5] = {0, '\n', '"', '\\', -1};
MDString *s = MDString::get(Context, StringRef(str+0, 5));
std::string Str;
@@ -67,8 +71,10 @@ TEST(MDStringTest, PrintingComplex) {
EXPECT_STREQ("metadata !\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str());
}
+typedef MetadataTest MDNodeTest;
+
// Test the two constructors, and containing other Constants.
-TEST(MDNodeTest, Simple) {
+TEST_F(MDNodeTest, Simple) {
char x[3] = { 'a', 'b', 'c' };
char y[3] = { '1', '2', '3' };
@@ -101,7 +107,7 @@ TEST(MDNodeTest, Simple) {
EXPECT_EQ(n1, n2->getOperand(0));
}
-TEST(MDNodeTest, Delete) {
+TEST_F(MDNodeTest, Delete) {
Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1);
Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext()));
@@ -115,8 +121,9 @@ TEST(MDNodeTest, Delete) {
}
TEST(NamedMDNodeTest, Search) {
- Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1);
- Constant *C2 = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 2);
+ LLVMContext Context;
+ Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1);
+ Constant *C2 = ConstantInt::get(Type::getInt32Ty(Context), 2);
Value *const V = C;
Value *const V2 = C2;
@@ -125,9 +132,9 @@ TEST(NamedMDNodeTest, Search) {
MDNode *Nodes[2] = { n, n2 };
- Module *M = new Module("MyModule", getGlobalContext());
+ Module *M = new Module("MyModule", Context);
const char *Name = "llvm.NMD1";
- NamedMDNode *NMD = NamedMDNode::Create(getGlobalContext(), Name, &Nodes[0], 2, M);
+ NamedMDNode *NMD = NamedMDNode::Create(Context, Name, &Nodes[0], 2, M);
std::string Str;
raw_string_ostream oss(Str);
NMD->print(oss);
diff --git a/unittests/VMCore/VerifierTest.cpp b/unittests/VMCore/VerifierTest.cpp
new file mode 100644
index 0000000..c8838c5
--- /dev/null
+++ b/unittests/VMCore/VerifierTest.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/VMCore/VerifierTest.cpp - Verifier unit tests --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Analysis/Verifier.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+TEST(VerifierTest, Branch_i1) {
+ LLVMContext &C = getGlobalContext();
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
+ Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage);
+ BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
+ BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
+ ReturnInst::Create(C, Exit);
+
+ // To avoid triggering an assertion in BranchInst::Create, we first create
+ // a branch with an 'i1' condition ...
+
+ Constant *False = ConstantInt::getFalse(C);
+ BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry);
+
+ // ... then use setOperand to redirect it to a value of different type.
+
+ Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0);
+ BI->setOperand(0, Zero32);
+
+ EXPECT_TRUE(verifyFunction(*F, ReturnStatusAction));
+}
+
+}
+}
diff --git a/utils/GenLibDeps.pl b/utils/GenLibDeps.pl
index b320a91..f1f7e72 100755
--- a/utils/GenLibDeps.pl
+++ b/utils/GenLibDeps.pl
@@ -70,6 +70,8 @@ opendir DIR,$Directory;
my @files = readdir DIR;
closedir DIR;
my @libs = grep(/libLLVM.*\.(dylib|so|a)$/,sort(@files));
+# Omit the all-of-llvm shared library.
+@libs = grep(!/libLLVM-\d\.\d(svn)?\.(dylib|so)/, @libs);
my @objs = grep(/LLVM.*\.o$/,sort(@files));
# Declare the hashes we will use to keep track of the library and object file
diff --git a/utils/TableGen/Android.mk b/utils/TableGen/Android.mk
new file mode 100644
index 0000000..e600305
--- /dev/null
+++ b/utils/TableGen/Android.mk
@@ -0,0 +1,46 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ AsmMatcherEmitter.cpp \
+ AsmWriterEmitter.cpp \
+ AsmWriterInst.cpp \
+ CallingConvEmitter.cpp \
+ ClangDiagnosticsEmitter.cpp \
+ CodeEmitterGen.cpp \
+ CodeGenDAGPatterns.cpp \
+ CodeGenInstruction.cpp \
+ CodeGenTarget.cpp \
+ DAGISelEmitter.cpp \
+ DAGISelMatcher.cpp \
+ DAGISelMatcherEmitter.cpp \
+ DAGISelMatcherGen.cpp \
+ DAGISelMatcherOpt.cpp \
+ DisassemblerEmitter.cpp \
+ EDEmitter.cpp \
+ FastISelEmitter.cpp \
+ InstrEnumEmitter.cpp \
+ InstrInfoEmitter.cpp \
+ IntrinsicEmitter.cpp \
+ LLVMCConfigurationEmitter.cpp \
+ OptParserEmitter.cpp \
+ Record.cpp \
+ RegisterInfoEmitter.cpp \
+ SubtargetEmitter.cpp \
+ TGLexer.cpp \
+ TGParser.cpp \
+ TGValueTypes.cpp \
+ TableGen.cpp \
+ TableGenBackend.cpp \
+ X86DisassemblerTables.cpp \
+ X86RecognizableInstr.cpp
+
+REQUIRES_EH := 1
+REQUIRES_RTTI := 1
+
+LOCAL_STATIC_LIBRARIES := libLLVMSupport libLLVMSystem
+LOCAL_MODULE := tblgen
+LOCAL_LDLIBS += -lpthread -lm -ldl
+
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 5b5dd2b..b823e57 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -975,6 +975,16 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
}
+static std::pair<unsigned, unsigned> *
+GetTiedOperandAtIndex(SmallVectorImpl<std::pair<unsigned, unsigned> > &List,
+ unsigned Index) {
+ for (unsigned i = 0, e = List.size(); i != e; ++i)
+ if (Index == List[i].first)
+ return &List[i];
+
+ return 0;
+}
+
static void EmitConvertToMCInst(CodeGenTarget &Target,
std::vector<InstructionInfo*> &Infos,
raw_ostream &OS) {
@@ -1051,15 +1061,12 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
//
// FIXME: This should be removed from the MCInst structure.
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
- // See if this is a tied operand.
- unsigned i, e = TiedOperands.size();
- for (i = 0; i != e; ++i)
- if (CurIndex == TiedOperands[i].first)
- break;
- if (i == e)
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
+ if (!Tie)
Signature += "__Imp";
else
- Signature += "__Tie" + utostr(TiedOperands[i].second);
+ Signature += "__Tie" + utostr(Tie->second);
}
Signature += "__";
@@ -1080,8 +1087,14 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
}
// Add any trailing implicit operands.
- for (; CurIndex != NumMIOperands; ++CurIndex)
- Signature += "Imp";
+ for (; CurIndex != NumMIOperands; ++CurIndex) {
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
+ if (!Tie)
+ Signature += "__Imp";
+ else
+ Signature += "__Tie" + utostr(Tie->second);
+ }
II.ConversionFnKind = Signature;
@@ -1103,21 +1116,18 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
// Add the implicit operands.
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
// See if this is a tied operand.
- unsigned i, e = TiedOperands.size();
- for (i = 0; i != e; ++i)
- if (CurIndex == TiedOperands[i].first)
- break;
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
- if (i == e) {
+ if (!Tie) {
// If not, this is some implicit operand. Just assume it is a register
// for now.
CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
} else {
// Copy the tied operand.
- assert(TiedOperands[i].first > TiedOperands[i].second &&
- "Tied operand preceeds its target!");
+ assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
CvtOS << " Inst.addOperand(Inst.getOperand("
- << TiedOperands[i].second << "));\n";
+ << Tie->second << "));\n";
}
}
@@ -1129,8 +1139,22 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
}
// And add trailing implicit operands.
- for (; CurIndex != NumMIOperands; ++CurIndex)
- CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
+ for (; CurIndex != NumMIOperands; ++CurIndex) {
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
+
+ if (!Tie) {
+ // If not, this is some implicit operand. Just assume it is a register
+ // for now.
+ CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
+ } else {
+ // Copy the tied operand.
+ assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
+ CvtOS << " Inst.addOperand(Inst.getOperand("
+ << Tie->second << "));\n";
+ }
+ }
+
CvtOS << " break;\n";
}
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 143a2f7..3a38dd4 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -494,11 +494,55 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
<< "}\n";
}
+void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) {
+ CodeGenTarget Target;
+ Record *AsmWriter = Target.getAsmWriter();
+ std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+
+ std::vector<const CodeGenInstruction*> NumberedInstructions;
+ Target.getInstructionsByEnumValue(NumberedInstructions);
+
+ StringToOffsetTable StringTable;
+ O <<
+"\n\n#ifdef GET_INSTRUCTION_NAME\n"
+"#undef GET_INSTRUCTION_NAME\n\n"
+"/// getInstructionName: This method is automatically generated by tblgen\n"
+"/// from the instruction set description. This returns the enum name of the\n"
+"/// specified instruction.\n"
+ "const char *" << Target.getName() << ClassName
+ << "::getInstructionName(unsigned Opcode) {\n"
+ << " assert(Opcode < " << NumberedInstructions.size()
+ << " && \"Invalid instruction number!\");\n"
+ << "\n"
+ << " static const unsigned InstAsmOffset[] = {";
+ for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ const CodeGenInstruction &Inst = *NumberedInstructions[i];
+
+ std::string AsmName = Inst.TheDef->getName();
+ if ((i % 14) == 0)
+ O << "\n ";
+
+ O << StringTable.GetOrAddStringOffset(AsmName) << ", ";
+ }
+ O << "0\n"
+ << " };\n"
+ << "\n";
+
+ O << " const char *Strs =\n";
+ StringTable.EmitString(O);
+ O << ";\n";
+
+ O << " return Strs+InstAsmOffset[Opcode];\n"
+ << "}\n\n#endif\n";
+}
+
+
void AsmWriterEmitter::run(raw_ostream &O) {
EmitSourceFileHeader("Assembly Writer Source Fragment", O);
EmitPrintInstruction(O);
EmitGetRegisterName(O);
+ EmitGetInstructionName(O);
}
diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h
index 7862caa..9f7d776 100644
--- a/utils/TableGen/AsmWriterEmitter.h
+++ b/utils/TableGen/AsmWriterEmitter.h
@@ -37,6 +37,7 @@ namespace llvm {
private:
void EmitPrintInstruction(raw_ostream &o);
void EmitGetRegisterName(raw_ostream &o);
+ void EmitGetInstructionName(raw_ostream &o);
AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {
assert(ID < NumberedInstructions.size());
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt
index f344b28..881b50a 100644
--- a/utils/TableGen/CMakeLists.txt
+++ b/utils/TableGen/CMakeLists.txt
@@ -9,6 +9,10 @@ add_executable(tblgen
CodeGenInstruction.cpp
CodeGenTarget.cpp
DAGISelEmitter.cpp
+ DAGISelMatcherEmitter.cpp
+ DAGISelMatcherGen.cpp
+ DAGISelMatcherOpt.cpp
+ DAGISelMatcher.cpp
DisassemblerEmitter.cpp
EDEmitter.cpp
FastISelEmitter.cpp
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index cf79365..ce737bf 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -447,6 +447,30 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end());
}
+/// getKnownType - If the type constraints on this node imply a fixed type
+/// (e.g. all stores return void, etc), then return it as an
+/// MVT::SimpleValueType. Otherwise, return EEVT::isUnknown.
+unsigned SDNodeInfo::getKnownType() const {
+ unsigned NumResults = getNumResults();
+ assert(NumResults <= 1 &&
+ "We only work with nodes with zero or one result so far!");
+
+ for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) {
+ // Make sure that this applies to the correct node result.
+ if (TypeConstraints[i].OperandNo >= NumResults) // FIXME: need value #
+ continue;
+
+ switch (TypeConstraints[i].ConstraintType) {
+ default: break;
+ case SDTypeConstraint::SDTCisVT:
+ return TypeConstraints[i].x.SDTCisVT_Info.VT;
+ case SDTypeConstraint::SDTCisPtrTy:
+ return MVT::iPTR;
+ }
+ }
+ return EEVT::isUnknown;
+}
+
//===----------------------------------------------------------------------===//
// TreePatternNode implementation
//
@@ -568,33 +592,36 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
return true; // unreachable
}
+static std::string GetTypeName(unsigned char TypeID) {
+ switch (TypeID) {
+ case MVT::Other: return "Other";
+ case MVT::iAny: return "iAny";
+ case MVT::fAny: return "fAny";
+ case MVT::vAny: return "vAny";
+ case EEVT::isUnknown: return "isUnknown";
+ case MVT::iPTR: return "iPTR";
+ case MVT::iPTRAny: return "iPTRAny";
+ default:
+ std::string VTName = llvm::getName((MVT::SimpleValueType)TypeID);
+ // Strip off EVT:: prefix if present.
+ if (VTName.substr(0,5) == "MVT::")
+ VTName = VTName.substr(5);
+ return VTName;
+ }
+}
+
void TreePatternNode::print(raw_ostream &OS) const {
if (isLeaf()) {
OS << *getLeafValue();
} else {
- OS << "(" << getOperator()->getName();
+ OS << '(' << getOperator()->getName();
}
// FIXME: At some point we should handle printing all the value types for
// nodes that are multiply typed.
- switch (getExtTypeNum(0)) {
- case MVT::Other: OS << ":Other"; break;
- case MVT::iAny: OS << ":iAny"; break;
- case MVT::fAny : OS << ":fAny"; break;
- case MVT::vAny: OS << ":vAny"; break;
- case EEVT::isUnknown: ; /*OS << ":?";*/ break;
- case MVT::iPTR: OS << ":iPTR"; break;
- case MVT::iPTRAny: OS << ":iPTRAny"; break;
- default: {
- std::string VTName = llvm::getName(getTypeNum(0));
- // Strip off EVT:: prefix if present.
- if (VTName.substr(0,5) == "MVT::")
- VTName = VTName.substr(5);
- OS << ":" << VTName;
- break;
- }
- }
+ if (getExtTypeNum(0) != EEVT::isUnknown)
+ OS << ':' << GetTypeName(getExtTypeNum(0));
if (!isLeaf()) {
if (getNumChildren() != 0) {
@@ -674,6 +701,15 @@ TreePatternNode *TreePatternNode::clone() const {
return New;
}
+/// RemoveAllTypes - Recursively strip all the types of this tree.
+void TreePatternNode::RemoveAllTypes() {
+ removeTypes();
+ if (isLeaf()) return;
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+ getChild(i)->RemoveAllTypes();
+}
+
+
/// SubstituteFormalArguments - Replace the formal arguments in this tree
/// with actual values specified by ArgMap.
void TreePatternNode::
@@ -768,7 +804,7 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
/// references from the register file information, for example.
///
static std::vector<unsigned char> getImplicitType(Record *R, bool NotRegisters,
- TreePattern &TP) {
+ TreePattern &TP) {
// Some common return values
std::vector<unsigned char> Unknown(1, EEVT::isUnknown);
std::vector<unsigned char> Other(1, MVT::Other);
@@ -825,6 +861,48 @@ getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const {
return &CDP.getIntrinsicInfo(IID);
}
+/// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
+/// return the ComplexPattern information, otherwise return null.
+const ComplexPattern *
+TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const {
+ if (!isLeaf()) return 0;
+
+ DefInit *DI = dynamic_cast<DefInit*>(getLeafValue());
+ if (DI && DI->getDef()->isSubClassOf("ComplexPattern"))
+ return &CGP.getComplexPattern(DI->getDef());
+ return 0;
+}
+
+/// NodeHasProperty - Return true if this node has the specified property.
+bool TreePatternNode::NodeHasProperty(SDNP Property,
+ const CodeGenDAGPatterns &CGP) const {
+ if (isLeaf()) {
+ if (const ComplexPattern *CP = getComplexPatternInfo(CGP))
+ return CP->hasProperty(Property);
+ return false;
+ }
+
+ Record *Operator = getOperator();
+ if (!Operator->isSubClassOf("SDNode")) return false;
+
+ return CGP.getSDNodeInfo(Operator).hasProperty(Property);
+}
+
+
+
+
+/// TreeHasProperty - Return true if any node in this tree has the specified
+/// property.
+bool TreePatternNode::TreeHasProperty(SDNP Property,
+ const CodeGenDAGPatterns &CGP) const {
+ if (NodeHasProperty(Property, CGP))
+ return true;
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+ if (getChild(i)->TreeHasProperty(Property, CGP))
+ return true;
+ return false;
+}
+
/// isCommutativeIntrinsic - Return true if the node corresponds to a
/// commutative intrinsic.
bool
@@ -845,7 +923,9 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
// If it's a regclass or something else known, include the type.
return UpdateNodeType(getImplicitType(DI->getDef(), NotRegisters, TP),TP);
- } else if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
+ }
+
+ if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
// Int inits are always integers. :)
bool MadeChange = UpdateNodeType(MVT::iAny, TP);
@@ -903,19 +983,25 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MadeChange |= UpdateNodeType(MVT::isVoid, TP);
}
return MadeChange;
- } else if (getOperator()->getName() == "implicit" ||
- getOperator()->getName() == "parallel") {
+ }
+
+ if (getOperator()->getName() == "implicit" ||
+ getOperator()->getName() == "parallel") {
bool MadeChange = false;
for (unsigned i = 0; i < getNumChildren(); ++i)
MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
MadeChange |= UpdateNodeType(MVT::isVoid, TP);
return MadeChange;
- } else if (getOperator()->getName() == "COPY_TO_REGCLASS") {
+ }
+
+ if (getOperator()->getName() == "COPY_TO_REGCLASS") {
bool MadeChange = false;
MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters);
return MadeChange;
- } else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
+ }
+
+ if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
bool MadeChange = false;
// Apply the result type to the node.
@@ -939,7 +1025,9 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
}
return MadeChange;
- } else if (getOperator()->isSubClassOf("SDNode")) {
+ }
+
+ if (getOperator()->isSubClassOf("SDNode")) {
const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator());
bool MadeChange = NI.ApplyTypeConstraints(this, TP);
@@ -951,7 +1039,9 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MadeChange |= UpdateNodeType(MVT::isVoid, TP);
return MadeChange;
- } else if (getOperator()->isSubClassOf("Instruction")) {
+ }
+
+ if (getOperator()->isSubClassOf("Instruction")) {
const DAGInstruction &Inst = CDP.getInstruction(getOperator());
bool MadeChange = false;
unsigned NumResults = Inst.getNumResults();
@@ -1027,24 +1117,24 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
"' was provided too many operands!");
return MadeChange;
- } else {
- assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
-
- // Node transforms always take one operand.
- if (getNumChildren() != 1)
- TP.error("Node transform '" + getOperator()->getName() +
- "' requires one operand!");
-
- // If either the output or input of the xform does not have exact
- // type info. We assume they must be the same. Otherwise, it is perfectly
- // legal to transform from one type to a completely different type.
- if (!hasTypeSet() || !getChild(0)->hasTypeSet()) {
- bool MadeChange = UpdateNodeType(getChild(0)->getExtTypes(), TP);
- MadeChange |= getChild(0)->UpdateNodeType(getExtTypes(), TP);
- return MadeChange;
- }
- return false;
}
+
+ assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
+
+ // Node transforms always take one operand.
+ if (getNumChildren() != 1)
+ TP.error("Node transform '" + getOperator()->getName() +
+ "' requires one operand!");
+
+ // If either the output or input of the xform does not have exact
+ // type info. We assume they must be the same. Otherwise, it is perfectly
+ // legal to transform from one type to a completely different type.
+ if (!hasTypeSet() || !getChild(0)->hasTypeSet()) {
+ bool MadeChange = UpdateNodeType(getChild(0)->getExtTypes(), TP);
+ MadeChange |= getChild(0)->UpdateNodeType(getExtTypes(), TP);
+ return MadeChange;
+ }
+ return false;
}
/// OnlyOnRHSOfCommutative - Return true if this value is only allowed on the
@@ -1317,7 +1407,6 @@ void TreePattern::dump() const { print(errs()); }
// CodeGenDAGPatterns implementation
//
-// FIXME: REMOVE OSTREAM ARGUMENT
CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
Intrinsics = LoadIntrinsics(Records, false);
TgtIntrinsics = LoadIntrinsics(Records, true);
@@ -1516,10 +1605,10 @@ void CodeGenDAGPatterns::ParseDefaultOperands() {
if (TPN->ContainsUnresolvedType()) {
if (iter == 0)
throw "Value #" + utostr(i) + " of PredicateOperand '" +
- DefaultOps[iter][i]->getName() + "' doesn't have a concrete type!";
+ DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
else
throw "Value #" + utostr(i) + " of OptionalDefOperand '" +
- DefaultOps[iter][i]->getName() + "' doesn't have a concrete type!";
+ DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
}
DefaultOpInfo.DefaultOps.push_back(TPN);
}
@@ -1563,21 +1652,21 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
TreePatternNode *&Slot = InstInputs[Pat->getName()];
if (!Slot) {
Slot = Pat;
+ return true;
+ }
+ Record *SlotRec;
+ if (Slot->isLeaf()) {
+ SlotRec = dynamic_cast<DefInit*>(Slot->getLeafValue())->getDef();
} else {
- Record *SlotRec;
- if (Slot->isLeaf()) {
- SlotRec = dynamic_cast<DefInit*>(Slot->getLeafValue())->getDef();
- } else {
- assert(Slot->getNumChildren() == 0 && "can't be a use with children!");
- SlotRec = Slot->getOperator();
- }
-
- // Ensure that the inputs agree if we've already seen this input.
- if (Rec != SlotRec)
- I->error("All $" + Pat->getName() + " inputs must agree with each other");
- if (Slot->getExtTypes() != Pat->getExtTypes())
- I->error("All $" + Pat->getName() + " inputs must agree with each other");
+ assert(Slot->getNumChildren() == 0 && "can't be a use with children!");
+ SlotRec = Slot->getOperator();
}
+
+ // Ensure that the inputs agree if we've already seen this input.
+ if (Rec != SlotRec)
+ I->error("All $" + Pat->getName() + " inputs must agree with each other");
+ if (Slot->getExtTypes() != Pat->getExtTypes())
+ I->error("All $" + Pat->getName() + " inputs must agree with each other");
return true;
}
@@ -1595,7 +1684,9 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
if (!isUse && Pat->getTransformFn())
I->error("Cannot specify a transform function for a non-input value!");
return;
- } else if (Pat->getOperator()->getName() == "implicit") {
+ }
+
+ if (Pat->getOperator()->getName() == "implicit") {
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
TreePatternNode *Dest = Pat->getChild(i);
if (!Dest->isLeaf())
@@ -1607,7 +1698,9 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
InstImpResults.push_back(Val->getDef());
}
return;
- } else if (Pat->getOperator()->getName() != "set") {
+ }
+
+ if (Pat->getOperator()->getName() != "set") {
// If this is not a set, verify that the children nodes are not void typed,
// and recurse.
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
@@ -1624,7 +1717,7 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
if (!isUse && Pat->getTransformFn())
I->error("Cannot specify a transform function for a non-input value!");
return;
- }
+ }
// Otherwise, this is a set, validate and collect instruction results.
if (Pat->getNumChildren() == 0)
@@ -2010,20 +2103,100 @@ void CodeGenDAGPatterns::ParseInstructions() {
SrcPattern = Pattern;
}
- std::string Reason;
- if (!SrcPattern->canPatternMatch(Reason, *this))
- I->error("Instruction can never match: " + Reason);
-
Record *Instr = II->first;
- TreePatternNode *DstPattern = TheInst.getResultPattern();
- PatternsToMatch.
- push_back(PatternToMatch(Instr->getValueAsListInit("Predicates"),
- SrcPattern, DstPattern, TheInst.getImpResults(),
- Instr->getValueAsInt("AddedComplexity")));
+ AddPatternToMatch(I,
+ PatternToMatch(Instr->getValueAsListInit("Predicates"),
+ SrcPattern,
+ TheInst.getResultPattern(),
+ TheInst.getImpResults(),
+ Instr->getValueAsInt("AddedComplexity"),
+ Instr->getID()));
}
}
+typedef std::pair<const TreePatternNode*, unsigned> NameRecord;
+
+static void FindNames(const TreePatternNode *P,
+ std::map<std::string, NameRecord> &Names,
+ const TreePattern *PatternTop) {
+ if (!P->getName().empty()) {
+ NameRecord &Rec = Names[P->getName()];
+ // If this is the first instance of the name, remember the node.
+ if (Rec.second++ == 0)
+ Rec.first = P;
+ else if (Rec.first->getExtTypes() != P->getExtTypes())
+ PatternTop->error("repetition of value: $" + P->getName() +
+ " where different uses have different types!");
+ }
+
+ if (!P->isLeaf()) {
+ for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+ FindNames(P->getChild(i), Names, PatternTop);
+ }
+}
+
+void CodeGenDAGPatterns::AddPatternToMatch(const TreePattern *Pattern,
+ const PatternToMatch &PTM) {
+ // Do some sanity checking on the pattern we're about to match.
+ std::string Reason;
+ if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this))
+ Pattern->error("Pattern can never match: " + Reason);
+
+ // If the source pattern's root is a complex pattern, that complex pattern
+ // must specify the nodes it can potentially match.
+ if (const ComplexPattern *CP =
+ PTM.getSrcPattern()->getComplexPatternInfo(*this))
+ if (CP->getRootNodes().empty())
+ Pattern->error("ComplexPattern at root must specify list of opcodes it"
+ " could match");
+
+
+ // Find all of the named values in the input and output, ensure they have the
+ // same type.
+ std::map<std::string, NameRecord> SrcNames, DstNames;
+ FindNames(PTM.getSrcPattern(), SrcNames, Pattern);
+ FindNames(PTM.getDstPattern(), DstNames, Pattern);
+
+ // Scan all of the named values in the destination pattern, rejecting them if
+ // they don't exist in the input pattern.
+ for (std::map<std::string, NameRecord>::iterator
+ I = DstNames.begin(), E = DstNames.end(); I != E; ++I) {
+ if (SrcNames[I->first].first == 0)
+ Pattern->error("Pattern has input without matching name in output: $" +
+ I->first);
+
+#if 0
+ const std::vector<unsigned char> &SrcTypeVec =
+ SrcNames[I->first].first->getExtTypes();
+ const std::vector<unsigned char> &DstTypeVec =
+ I->second.first->getExtTypes();
+ if (SrcTypeVec == DstTypeVec) continue;
+
+ std::string SrcType, DstType;
+ for (unsigned i = 0, e = SrcTypeVec.size(); i != e; ++i)
+ SrcType += ":" + GetTypeName(SrcTypeVec[i]);
+ for (unsigned i = 0, e = DstTypeVec.size(); i != e; ++i)
+ DstType += ":" + GetTypeName(DstTypeVec[i]);
+
+ Pattern->error("Variable $" + I->first +
+ " has different types in source (" + SrcType +
+ ") and dest (" + DstType + ") pattern!");
+#endif
+ }
+
+ // Scan all of the named values in the source pattern, rejecting them if the
+ // name isn't used in the dest, and isn't used to tie two values together.
+ for (std::map<std::string, NameRecord>::iterator
+ I = SrcNames.begin(), E = SrcNames.end(); I != E; ++I)
+ if (DstNames[I->first].first == 0 && SrcNames[I->first].second == 1)
+ Pattern->error("Pattern has dead named input: $" + I->first);
+
+ PatternsToMatch.push_back(PTM);
+}
+
+
+
void CodeGenDAGPatterns::InferInstructionFlags() {
std::map<std::string, CodeGenInstruction> &InstrDescs =
Target.getInstructions();
@@ -2151,15 +2324,13 @@ void CodeGenDAGPatterns::ParsePatterns() {
TreePattern Temp(Result->getRecord(), DstPattern, false, *this);
Temp.InferAllTypes();
- std::string Reason;
- if (!Pattern->getTree(0)->canPatternMatch(Reason, *this))
- Pattern->error("Pattern can never match: " + Reason);
- PatternsToMatch.
- push_back(PatternToMatch(Patterns[i]->getValueAsListInit("Predicates"),
- Pattern->getTree(0),
- Temp.getOnlyTree(), InstImpResults,
- Patterns[i]->getValueAsInt("AddedComplexity")));
+ AddPatternToMatch(Pattern,
+ PatternToMatch(Patterns[i]->getValueAsListInit("Predicates"),
+ Pattern->getTree(0),
+ Temp.getOnlyTree(), InstImpResults,
+ Patterns[i]->getValueAsInt("AddedComplexity"),
+ Patterns[i]->getID()));
}
}
@@ -2181,13 +2352,13 @@ static void CombineChildVariants(TreePatternNode *Orig,
bool NotDone;
do {
#ifndef NDEBUG
- if (DebugFlag && !Idxs.empty()) {
- errs() << Orig->getOperator()->getName() << ": Idxs = [ ";
- for (unsigned i = 0; i < Idxs.size(); ++i) {
- errs() << Idxs[i] << " ";
- }
- errs() << "]\n";
- }
+ DEBUG(if (!Idxs.empty()) {
+ errs() << Orig->getOperator()->getName() << ": Idxs = [ ";
+ for (unsigned i = 0; i < Idxs.size(); ++i) {
+ errs() << Idxs[i] << " ";
+ }
+ errs() << "]\n";
+ });
#endif
// Create the variant and add it to the output list.
std::vector<TreePatternNode*> NewChildren;
@@ -2453,7 +2624,8 @@ void CodeGenDAGPatterns::GenerateVariants() {
push_back(PatternToMatch(PatternsToMatch[i].getPredicates(),
Variant, PatternsToMatch[i].getDstPattern(),
PatternsToMatch[i].getDstRegs(),
- PatternsToMatch[i].getAddedComplexity()));
+ PatternsToMatch[i].getAddedComplexity(),
+ Record::getNewUID()));
}
DEBUG(errs() << "\n");
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index c51232a..37d633e 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -125,6 +125,11 @@ public:
return TypeConstraints;
}
+ /// getKnownType - If the type constraints on this node imply a fixed type
+ /// (e.g. all stores return void, etc), then return it as an
+ /// MVT::SimpleValueType. Otherwise, return EEVT::isUnknown.
+ unsigned getKnownType() const;
+
/// hasProperty - Return true if this node has the specified property.
///
bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
@@ -216,8 +221,15 @@ public:
void setChild(unsigned i, TreePatternNode *N) {
Children[i] = N;
}
+
+ /// hasChild - Return true if N is any of our children.
+ bool hasChild(const TreePatternNode *N) const {
+ for (unsigned i = 0, e = Children.size(); i != e; ++i)
+ if (Children[i] == N) return true;
+ return false;
+ }
- const std::vector<std::string> &getPredicateFns() const { return PredicateFns; }
+ const std::vector<std::string> &getPredicateFns() const {return PredicateFns;}
void clearPredicateFns() { PredicateFns.clear(); }
void setPredicateFns(const std::vector<std::string> &Fns) {
assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
@@ -237,6 +249,18 @@ public:
/// CodeGenIntrinsic information for it, otherwise return a null pointer.
const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
+ /// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
+ /// return the ComplexPattern information, otherwise return null.
+ const ComplexPattern *
+ getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const;
+
+ /// NodeHasProperty - Return true if this node has the specified property.
+ bool NodeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
+
+ /// TreeHasProperty - Return true if any node in this tree has the specified
+ /// property.
+ bool TreeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
+
/// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
/// marked isCommutative.
bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
@@ -249,6 +273,9 @@ public: // Higher level manipulation routines.
/// clone - Return a new copy of this tree.
///
TreePatternNode *clone() const;
+
+ /// RemoveAllTypes - Recursively strip all the types of this tree.
+ void RemoveAllTypes();
/// isIsomorphicTo - Return true if this node is recursively isomorphic to
/// the specified node. For this comparison, all of the state of the node
@@ -298,6 +325,11 @@ public: // Higher level manipulation routines.
bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
};
+inline raw_ostream &operator<<(raw_ostream &OS, const TreePatternNode &TPN) {
+ TPN.print(OS);
+ return OS;
+}
+
/// TreePattern - Represent a pattern, used for instructions, pattern
/// fragments, etc.
@@ -439,19 +471,21 @@ public:
/// PatternToMatch - Used by CodeGenDAGPatterns to keep tab of patterns
/// processed to produce isel.
-struct PatternToMatch {
+class PatternToMatch {
+public:
PatternToMatch(ListInit *preds,
TreePatternNode *src, TreePatternNode *dst,
const std::vector<Record*> &dstregs,
- unsigned complexity):
- Predicates(preds), SrcPattern(src), DstPattern(dst), Dstregs(dstregs),
- AddedComplexity(complexity) {}
+ unsigned complexity, unsigned uid)
+ : Predicates(preds), SrcPattern(src), DstPattern(dst),
+ Dstregs(dstregs), AddedComplexity(complexity), ID(uid) {}
ListInit *Predicates; // Top level predicate conditions to match.
TreePatternNode *SrcPattern; // Source pattern to match.
TreePatternNode *DstPattern; // Resulting pattern.
std::vector<Record*> Dstregs; // Physical register defs being matched.
unsigned AddedComplexity; // Add to matching pattern complexity.
+ unsigned ID; // Unique ID for the record.
ListInit *getPredicates() const { return Predicates; }
TreePatternNode *getSrcPattern() const { return SrcPattern; }
@@ -547,7 +581,7 @@ public:
abort();
}
- const DAGDefaultOperand &getDefaultOperand(Record *R) {
+ const DAGDefaultOperand &getDefaultOperand(Record *R) const {
assert(DefaultOperands.count(R) &&"Isn't an analyzed default operand!");
return DefaultOperands.find(R)->second;
}
@@ -597,6 +631,7 @@ private:
void InferInstructionFlags();
void GenerateVariants();
+ void AddPatternToMatch(const TreePattern *Pattern, const PatternToMatch &PTM);
void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
std::map<std::string,
TreePatternNode*> &InstInputs,
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index d31502b1..f5b52ec 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -117,7 +117,6 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
hasCtrlDep = R->getValueAsBit("hasCtrlDep");
isNotDuplicable = R->getValueAsBit("isNotDuplicable");
hasSideEffects = R->getValueAsBit("hasSideEffects");
- mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects");
neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
@@ -125,7 +124,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
hasOptionalDef = false;
isVariadic = false;
- if (mayHaveSideEffects + neverHasSideEffects + hasSideEffects > 1)
+ if (neverHasSideEffects + hasSideEffects > 1)
throw R->getName() + ": multiple conflicting side-effect flags set!";
DagInit *DI;
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index e81e7f4..aae2cac 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -41,6 +41,7 @@ namespace llvm {
static ConstraintInfo getEarlyClobber() {
ConstraintInfo I;
I.Kind = EarlyClobber;
+ I.OtherTiedOperand = 0;
return I;
}
@@ -132,7 +133,6 @@ namespace llvm {
bool isNotDuplicable;
bool hasOptionalDef;
bool hasSideEffects;
- bool mayHaveSideEffects;
bool neverHasSideEffects;
bool isAsCheapAsAMove;
bool hasExtraSrcRegAllocReq;
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index c97582b..e0fa7c8 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -12,63 +12,15 @@
//===----------------------------------------------------------------------===//
#include "DAGISelEmitter.h"
+#include "DAGISelMatcher.h"
#include "Record.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Debug.h"
-#include <algorithm>
-#include <deque>
-#include <iostream>
using namespace llvm;
-static cl::opt<bool>
-GenDebug("gen-debug", cl::desc("Generate debug code"), cl::init(false));
-
//===----------------------------------------------------------------------===//
// DAGISelEmitter Helper methods
//
-/// getNodeName - The top level Select_* functions have an "SDNode* N"
-/// argument. When expanding the pattern-matching code, the intermediate
-/// variables have type SDValue. This function provides a uniform way to
-/// reference the underlying "SDNode *" for both cases.
-static std::string getNodeName(const std::string &S) {
- if (S == "N") return S;
- return S + ".getNode()";
-}
-
-/// getNodeValue - Similar to getNodeName, except it provides a uniform
-/// way to access the SDValue for both cases.
-static std::string getValueName(const std::string &S) {
- if (S == "N") return "SDValue(N, 0)";
- return S;
-}
-
-/// NodeIsComplexPattern - return true if N is a leaf node and a subclass of
-/// ComplexPattern.
-static bool NodeIsComplexPattern(TreePatternNode *N) {
- return (N->isLeaf() &&
- dynamic_cast<DefInit*>(N->getLeafValue()) &&
- static_cast<DefInit*>(N->getLeafValue())->getDef()->
- isSubClassOf("ComplexPattern"));
-}
-
-/// NodeGetComplexPattern - return the pointer to the ComplexPattern if N
-/// is a leaf node and a subclass of ComplexPattern, else it returns NULL.
-static const ComplexPattern *NodeGetComplexPattern(TreePatternNode *N,
- CodeGenDAGPatterns &CGP) {
- if (N->isLeaf() &&
- dynamic_cast<DefInit*>(N->getLeafValue()) &&
- static_cast<DefInit*>(N->getLeafValue())->getDef()->
- isSubClassOf("ComplexPattern")) {
- return &CGP.getComplexPattern(static_cast<DefInit*>(N->getLeafValue())
- ->getDef());
- }
- return NULL;
-}
-
/// getPatternSize - Return the 'size' of this pattern. We want to match large
/// patterns before small ones. This is used to determine the size of a
/// pattern.
@@ -91,7 +43,7 @@ static unsigned getPatternSize(TreePatternNode *P, CodeGenDAGPatterns &CGP) {
// Later we can allow complexity / cost for each pattern to be (optionally)
// specified. To get best possible pattern match we'll need to dynamically
// calculate the complexity of all patterns a dag can potentially map to.
- const ComplexPattern *AM = NodeGetComplexPattern(P, CGP);
+ const ComplexPattern *AM = P->getComplexPatternInfo(CGP);
if (AM)
Size += AM->getNumOperands() * 3;
@@ -108,7 +60,7 @@ static unsigned getPatternSize(TreePatternNode *P, CodeGenDAGPatterns &CGP) {
else if (Child->isLeaf()) {
if (dynamic_cast<IntInit*>(Child->getLeafValue()))
Size += 5; // Matches a ConstantSDNode (+3) and a specific value (+2).
- else if (NodeIsComplexPattern(Child))
+ else if (Child->getComplexPatternInfo(CGP))
Size += getPatternSize(Child, CGP);
else if (!Child->getPredicateFns().empty())
++Size;
@@ -154,164 +106,6 @@ static unsigned getResultPatternSize(TreePatternNode *P,
return Cost;
}
-// PatternSortingPredicate - return true if we prefer to match LHS before RHS.
-// In particular, we want to match maximal patterns first and lowest cost within
-// a particular complexity first.
-struct PatternSortingPredicate {
- PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {}
- CodeGenDAGPatterns &CGP;
-
- typedef std::pair<unsigned, std::string> CodeLine;
- typedef std::vector<CodeLine> CodeList;
- typedef std::vector<std::pair<const PatternToMatch*, CodeList> > PatternList;
-
- bool operator()(const std::pair<const PatternToMatch*, CodeList> &LHSPair,
- const std::pair<const PatternToMatch*, CodeList> &RHSPair) {
- const PatternToMatch *LHS = LHSPair.first;
- const PatternToMatch *RHS = RHSPair.first;
-
- unsigned LHSSize = getPatternSize(LHS->getSrcPattern(), CGP);
- unsigned RHSSize = getPatternSize(RHS->getSrcPattern(), CGP);
- LHSSize += LHS->getAddedComplexity();
- RHSSize += RHS->getAddedComplexity();
- if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost
- if (LHSSize < RHSSize) return false;
-
- // If the patterns have equal complexity, compare generated instruction cost
- unsigned LHSCost = getResultPatternCost(LHS->getDstPattern(), CGP);
- unsigned RHSCost = getResultPatternCost(RHS->getDstPattern(), CGP);
- if (LHSCost < RHSCost) return true;
- if (LHSCost > RHSCost) return false;
-
- return getResultPatternSize(LHS->getDstPattern(), CGP) <
- getResultPatternSize(RHS->getDstPattern(), CGP);
- }
-};
-
-/// getRegisterValueType - Look up and return the ValueType of the specified
-/// register. If the register is a member of multiple register classes which
-/// have different associated types, return MVT::Other.
-static MVT::SimpleValueType getRegisterValueType(Record *R, const CodeGenTarget &T) {
- bool FoundRC = false;
- MVT::SimpleValueType VT = MVT::Other;
- const std::vector<CodeGenRegisterClass> &RCs = T.getRegisterClasses();
- std::vector<CodeGenRegisterClass>::const_iterator RC;
- std::vector<Record*>::const_iterator Element;
-
- for (RC = RCs.begin() ; RC != RCs.end() ; RC++) {
- Element = find((*RC).Elements.begin(), (*RC).Elements.end(), R);
- if (Element != (*RC).Elements.end()) {
- if (!FoundRC) {
- FoundRC = true;
- VT = (*RC).getValueTypeNum(0);
- } else {
- // In multiple RC's
- if (VT != (*RC).getValueTypeNum(0)) {
- // Types of the RC's do not agree. Return MVT::Other. The
- // target is responsible for handling this.
- return MVT::Other;
- }
- }
- }
- }
- return VT;
-}
-
-
-/// RemoveAllTypes - A quick recursive walk over a pattern which removes all
-/// type information from it.
-static void RemoveAllTypes(TreePatternNode *N) {
- N->removeTypes();
- if (!N->isLeaf())
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
- RemoveAllTypes(N->getChild(i));
-}
-
-/// NodeHasProperty - return true if TreePatternNode has the specified
-/// property.
-static bool NodeHasProperty(TreePatternNode *N, SDNP Property,
- CodeGenDAGPatterns &CGP) {
- if (N->isLeaf()) {
- const ComplexPattern *CP = NodeGetComplexPattern(N, CGP);
- if (CP)
- return CP->hasProperty(Property);
- return false;
- }
- Record *Operator = N->getOperator();
- if (!Operator->isSubClassOf("SDNode")) return false;
-
- return CGP.getSDNodeInfo(Operator).hasProperty(Property);
-}
-
-static bool PatternHasProperty(TreePatternNode *N, SDNP Property,
- CodeGenDAGPatterns &CGP) {
- if (NodeHasProperty(N, Property, CGP))
- return true;
-
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- TreePatternNode *Child = N->getChild(i);
- if (PatternHasProperty(Child, Property, CGP))
- return true;
- }
-
- return false;
-}
-
-static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
- return CGP.getSDNodeInfo(Op).getEnumName();
-}
-
-static
-bool DisablePatternForFastISel(TreePatternNode *N, CodeGenDAGPatterns &CGP) {
- bool isStore = !N->isLeaf() &&
- getOpcodeName(N->getOperator(), CGP) == "ISD::STORE";
- if (!isStore && NodeHasProperty(N, SDNPHasChain, CGP))
- return false;
-
- bool HasChain = false;
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- TreePatternNode *Child = N->getChild(i);
- if (PatternHasProperty(Child, SDNPHasChain, CGP)) {
- HasChain = true;
- break;
- }
- }
- return HasChain;
-}
-
-//===----------------------------------------------------------------------===//
-// Node Transformation emitter implementation.
-//
-void DAGISelEmitter::EmitNodeTransforms(raw_ostream &OS) {
- // Walk the pattern fragments, adding them to a map, which sorts them by
- // name.
- typedef std::map<std::string, CodeGenDAGPatterns::NodeXForm> NXsByNameTy;
- NXsByNameTy NXsByName;
-
- for (CodeGenDAGPatterns::nx_iterator I = CGP.nx_begin(), E = CGP.nx_end();
- I != E; ++I)
- NXsByName.insert(std::make_pair(I->first->getName(), I->second));
-
- OS << "\n// Node transformations.\n";
-
- for (NXsByNameTy::iterator I = NXsByName.begin(), E = NXsByName.end();
- I != E; ++I) {
- Record *SDNode = I->second.first;
- std::string Code = I->second.second;
-
- if (Code.empty()) continue; // Empty code? Skip it.
-
- std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
- const char *C2 = ClassName == "SDNode" ? "N" : "inN";
-
- OS << "inline SDValue Transform_" << I->first << "(SDNode *" << C2
- << ") {\n";
- if (ClassName != "SDNode")
- OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
- OS << Code << "\n}\n";
- }
-}
-
//===----------------------------------------------------------------------===//
// Predicate emitter implementation.
//
@@ -340,14 +134,14 @@ void DAGISelEmitter::EmitPredicateFunctions(raw_ostream &OS) {
if (P->getOnlyTree()->isLeaf())
OS << "inline bool Predicate_" << PatFragRecord->getName()
- << "(SDNode *N) {\n";
+ << "(SDNode *N) const {\n";
else {
std::string ClassName =
CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
const char *C2 = ClassName == "SDNode" ? "N" : "inN";
OS << "inline bool Predicate_" << PatFragRecord->getName()
- << "(SDNode *" << C2 << ") {\n";
+ << "(SDNode *" << C2 << ") const {\n";
if (ClassName != "SDNode")
OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
}
@@ -357,1685 +151,41 @@ void DAGISelEmitter::EmitPredicateFunctions(raw_ostream &OS) {
OS << "\n\n";
}
-
-//===----------------------------------------------------------------------===//
-// PatternCodeEmitter implementation.
-//
-class PatternCodeEmitter {
-private:
+namespace {
+// PatternSortingPredicate - return true if we prefer to match LHS before RHS.
+// In particular, we want to match maximal patterns first and lowest cost within
+// a particular complexity first.
+struct PatternSortingPredicate {
+ PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {}
CodeGenDAGPatterns &CGP;
-
- // Predicates.
- std::string PredicateCheck;
- // Pattern cost.
- unsigned Cost;
- // Instruction selector pattern.
- TreePatternNode *Pattern;
- // Matched instruction.
- TreePatternNode *Instruction;
- // Node to name mapping
- std::map<std::string, std::string> VariableMap;
- // Node to operator mapping
- std::map<std::string, Record*> OperatorMap;
- // Name of the folded node which produces a flag.
- std::pair<std::string, unsigned> FoldedFlag;
- // Names of all the folded nodes which produce chains.
- std::vector<std::pair<std::string, unsigned> > FoldedChains;
- // Original input chain(s).
- std::vector<std::pair<std::string, std::string> > OrigChains;
- std::set<std::string> Duplicates;
-
- /// LSI - Load/Store information.
- /// Save loads/stores matched by a pattern, and generate a MemOperandSDNode
- /// for each memory access. This facilitates the use of AliasAnalysis in
- /// the backend.
- std::vector<std::string> LSI;
-
- /// GeneratedCode - This is the buffer that we emit code to. The first int
- /// indicates whether this is an exit predicate (something that should be
- /// tested, and if true, the match fails) [when 1], or normal code to emit
- /// [when 0], or initialization code to emit [when 2].
- std::vector<std::pair<unsigned, std::string> > &GeneratedCode;
- /// GeneratedDecl - This is the set of all SDValue declarations needed for
- /// the set of patterns for each top-level opcode.
- std::set<std::string> &GeneratedDecl;
- /// TargetOpcodes - The target specific opcodes used by the resulting
- /// instructions.
- std::vector<std::string> &TargetOpcodes;
- std::vector<std::string> &TargetVTs;
- /// OutputIsVariadic - Records whether the instruction output pattern uses
- /// variable_ops. This requires that the Emit function be passed an
- /// additional argument to indicate where the input varargs operands
- /// begin.
- bool &OutputIsVariadic;
- /// NumInputRootOps - Records the number of operands the root node of the
- /// input pattern has. This information is used in the generated code to
- /// pass to Emit functions when variable_ops processing is needed.
- unsigned &NumInputRootOps;
-
- std::string ChainName;
- unsigned TmpNo;
- unsigned OpcNo;
- unsigned VTNo;
-
- void emitCheck(const std::string &S) {
- if (!S.empty())
- GeneratedCode.push_back(std::make_pair(1, S));
- }
- void emitCode(const std::string &S) {
- if (!S.empty())
- GeneratedCode.push_back(std::make_pair(0, S));
- }
- void emitInit(const std::string &S) {
- if (!S.empty())
- GeneratedCode.push_back(std::make_pair(2, S));
- }
- void emitDecl(const std::string &S) {
- assert(!S.empty() && "Invalid declaration");
- GeneratedDecl.insert(S);
- }
- void emitOpcode(const std::string &Opc) {
- TargetOpcodes.push_back(Opc);
- OpcNo++;
- }
- void emitVT(const std::string &VT) {
- TargetVTs.push_back(VT);
- VTNo++;
- }
-public:
- PatternCodeEmitter(CodeGenDAGPatterns &cgp, std::string predcheck,
- TreePatternNode *pattern, TreePatternNode *instr,
- std::vector<std::pair<unsigned, std::string> > &gc,
- std::set<std::string> &gd,
- std::vector<std::string> &to,
- std::vector<std::string> &tv,
- bool &oiv,
- unsigned &niro)
- : CGP(cgp), PredicateCheck(predcheck), Pattern(pattern), Instruction(instr),
- GeneratedCode(gc), GeneratedDecl(gd),
- TargetOpcodes(to), TargetVTs(tv),
- OutputIsVariadic(oiv), NumInputRootOps(niro),
- TmpNo(0), OpcNo(0), VTNo(0) {}
-
- /// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
- /// if the match fails. At this point, we already know that the opcode for N
- /// matches, and the SDNode for the result has the RootName specified name.
- void EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
- const std::string &RootName, const std::string &ChainSuffix,
- bool &FoundChain) {
-
- // Save loads/stores matched by a pattern.
- if (!N->isLeaf() && N->getName().empty()) {
- if (NodeHasProperty(N, SDNPMemOperand, CGP))
- LSI.push_back(getNodeName(RootName));
- }
-
- bool isRoot = (P == NULL);
- // Emit instruction predicates. Each predicate is just a string for now.
- if (isRoot) {
- // Record input varargs info.
- NumInputRootOps = N->getNumChildren();
-
- if (DisablePatternForFastISel(N, CGP))
- emitCheck("OptLevel != CodeGenOpt::None");
-
- emitCheck(PredicateCheck);
- }
-
- if (N->isLeaf()) {
- if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
- emitCheck("cast<ConstantSDNode>(" + getNodeName(RootName) +
- ")->getSExtValue() == INT64_C(" +
- itostr(II->getValue()) + ")");
- return;
- } else if (!NodeIsComplexPattern(N)) {
- assert(0 && "Cannot match this as a leaf value!");
- abort();
- }
- }
-
- // If this node has a name associated with it, capture it in VariableMap. If
- // we already saw this in the pattern, emit code to verify dagness.
- if (!N->getName().empty()) {
- std::string &VarMapEntry = VariableMap[N->getName()];
- if (VarMapEntry.empty()) {
- VarMapEntry = RootName;
- } else {
- // If we get here, this is a second reference to a specific name. Since
- // we already have checked that the first reference is valid, we don't
- // have to recursively match it, just check that it's the same as the
- // previously named thing.
- emitCheck(VarMapEntry + " == " + RootName);
- return;
- }
-
- if (!N->isLeaf())
- OperatorMap[N->getName()] = N->getOperator();
- }
-
-
- // Emit code to load the child nodes and match their contents recursively.
- unsigned OpNo = 0;
- bool NodeHasChain = NodeHasProperty (N, SDNPHasChain, CGP);
- bool HasChain = PatternHasProperty(N, SDNPHasChain, CGP);
- bool EmittedUseCheck = false;
- if (HasChain) {
- if (NodeHasChain)
- OpNo = 1;
- if (!isRoot) {
- // Multiple uses of actual result?
- emitCheck(getValueName(RootName) + ".hasOneUse()");
- EmittedUseCheck = true;
- if (NodeHasChain) {
- // If the immediate use can somehow reach this node through another
- // path, then can't fold it either or it will create a cycle.
- // e.g. In the following diagram, XX can reach ld through YY. If
- // ld is folded into XX, then YY is both a predecessor and a successor
- // of XX.
- //
- // [ld]
- // ^ ^
- // | |
- // / \---
- // / [YY]
- // | ^
- // [XX]-------|
- bool NeedCheck = P != Pattern;
- if (!NeedCheck) {
- const SDNodeInfo &PInfo = CGP.getSDNodeInfo(P->getOperator());
- NeedCheck =
- P->getOperator() == CGP.get_intrinsic_void_sdnode() ||
- P->getOperator() == CGP.get_intrinsic_w_chain_sdnode() ||
- P->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() ||
- PInfo.getNumOperands() > 1 ||
- PInfo.hasProperty(SDNPHasChain) ||
- PInfo.hasProperty(SDNPInFlag) ||
- PInfo.hasProperty(SDNPOptInFlag);
- }
-
- if (NeedCheck) {
- std::string ParentName(RootName.begin(), RootName.end()-1);
- emitCheck("IsLegalAndProfitableToFold(" + getNodeName(RootName) +
- ", " + getNodeName(ParentName) + ", N)");
- }
- }
- }
-
- if (NodeHasChain) {
- if (FoundChain) {
- emitCheck("(" + ChainName + ".getNode() == " +
- getNodeName(RootName) + " || "
- "IsChainCompatible(" + ChainName + ".getNode(), " +
- getNodeName(RootName) + "))");
- OrigChains.push_back(std::make_pair(ChainName,
- getValueName(RootName)));
- } else
- FoundChain = true;
- ChainName = "Chain" + ChainSuffix;
- emitInit("SDValue " + ChainName + " = " + getNodeName(RootName) +
- "->getOperand(0);");
- }
- }
-
- // Don't fold any node which reads or writes a flag and has multiple uses.
- // FIXME: We really need to separate the concepts of flag and "glue". Those
- // real flag results, e.g. X86CMP output, can have multiple uses.
- // FIXME: If the optional incoming flag does not exist. Then it is ok to
- // fold it.
- if (!isRoot &&
- (PatternHasProperty(N, SDNPInFlag, CGP) ||
- PatternHasProperty(N, SDNPOptInFlag, CGP) ||
- PatternHasProperty(N, SDNPOutFlag, CGP))) {
- if (!EmittedUseCheck) {
- // Multiple uses of actual result?
- emitCheck(getValueName(RootName) + ".hasOneUse()");
- }
- }
-
- // If there are node predicates for this, emit the calls.
- for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
- emitCheck(N->getPredicateFns()[i] + "(" + getNodeName(RootName) + ")");
-
- // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
- // a constant without a predicate fn that has more that one bit set, handle
- // this as a special case. This is usually for targets that have special
- // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
- // handling stuff). Using these instructions is often far more efficient
- // than materializing the constant. Unfortunately, both the instcombiner
- // and the dag combiner can often infer that bits are dead, and thus drop
- // them from the mask in the dag. For example, it might turn 'AND X, 255'
- // into 'AND X, 254' if it knows the low bit is set. Emit code that checks
- // to handle this.
- if (!N->isLeaf() &&
- (N->getOperator()->getName() == "and" ||
- N->getOperator()->getName() == "or") &&
- N->getChild(1)->isLeaf() &&
- N->getChild(1)->getPredicateFns().empty()) {
- if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
- if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
- emitInit("SDValue " + RootName + "0" + " = " +
- getNodeName(RootName) + "->getOperand(" + utostr(0) + ");");
- emitInit("SDValue " + RootName + "1" + " = " +
- getNodeName(RootName) + "->getOperand(" + utostr(1) + ");");
-
- unsigned NTmp = TmpNo++;
- emitCode("ConstantSDNode *Tmp" + utostr(NTmp) +
- " = dyn_cast<ConstantSDNode>(" +
- getNodeName(RootName + "1") + ");");
- emitCheck("Tmp" + utostr(NTmp));
- const char *MaskPredicate = N->getOperator()->getName() == "or"
- ? "CheckOrMask(" : "CheckAndMask(";
- emitCheck(MaskPredicate + getValueName(RootName + "0") +
- ", Tmp" + utostr(NTmp) +
- ", INT64_C(" + itostr(II->getValue()) + "))");
-
- EmitChildMatchCode(N->getChild(0), N, RootName + utostr(0),
- ChainSuffix + utostr(0), FoundChain);
- return;
- }
- }
- }
-
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
- emitInit("SDValue " + getValueName(RootName + utostr(OpNo)) + " = " +
- getNodeName(RootName) + "->getOperand(" + utostr(OpNo) + ");");
-
- EmitChildMatchCode(N->getChild(i), N, RootName + utostr(OpNo),
- ChainSuffix + utostr(OpNo), FoundChain);
- }
-
- // Handle cases when root is a complex pattern.
- const ComplexPattern *CP;
- if (isRoot && N->isLeaf() && (CP = NodeGetComplexPattern(N, CGP))) {
- std::string Fn = CP->getSelectFunc();
- unsigned NumOps = CP->getNumOperands();
- for (unsigned i = 0; i < NumOps; ++i) {
- emitDecl("CPTmp" + RootName + "_" + utostr(i));
- emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";");
- }
- if (CP->hasProperty(SDNPHasChain)) {
- emitDecl("CPInChain");
- emitDecl("Chain" + ChainSuffix);
- emitCode("SDValue CPInChain;");
- emitCode("SDValue Chain" + ChainSuffix + ";");
- }
-
- std::string Code = Fn + "(" +
- getNodeName(RootName) + ", " +
- getValueName(RootName);
- for (unsigned i = 0; i < NumOps; i++)
- Code += ", CPTmp" + RootName + "_" + utostr(i);
- if (CP->hasProperty(SDNPHasChain)) {
- ChainName = "Chain" + ChainSuffix;
- Code += ", CPInChain, Chain" + ChainSuffix;
- }
- emitCheck(Code + ")");
- }
- }
-
- void EmitChildMatchCode(TreePatternNode *Child, TreePatternNode *Parent,
- const std::string &RootName,
- const std::string &ChainSuffix, bool &FoundChain) {
- if (!Child->isLeaf()) {
- // If it's not a leaf, recursively match.
- const SDNodeInfo &CInfo = CGP.getSDNodeInfo(Child->getOperator());
- emitCheck(getNodeName(RootName) + "->getOpcode() == " +
- CInfo.getEnumName());
- EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain);
- bool HasChain = false;
- if (NodeHasProperty(Child, SDNPHasChain, CGP)) {
- HasChain = true;
- FoldedChains.push_back(std::make_pair(getValueName(RootName),
- CInfo.getNumResults()));
- }
- if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
- assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
- "Pattern folded multiple nodes which produce flags?");
- FoldedFlag = std::make_pair(getValueName(RootName),
- CInfo.getNumResults() + (unsigned)HasChain);
- }
- } else {
- // If this child has a name associated with it, capture it in VarMap. If
- // we already saw this in the pattern, emit code to verify dagness.
- if (!Child->getName().empty()) {
- std::string &VarMapEntry = VariableMap[Child->getName()];
- if (VarMapEntry.empty()) {
- VarMapEntry = getValueName(RootName);
- } else {
- // If we get here, this is a second reference to a specific name.
- // Since we already have checked that the first reference is valid,
- // we don't have to recursively match it, just check that it's the
- // same as the previously named thing.
- emitCheck(VarMapEntry + " == " + getValueName(RootName));
- Duplicates.insert(getValueName(RootName));
- return;
- }
- }
-
- // Handle leaves of various types.
- if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
- Record *LeafRec = DI->getDef();
- if (LeafRec->isSubClassOf("RegisterClass") ||
- LeafRec->isSubClassOf("PointerLikeRegClass")) {
- // Handle register references. Nothing to do here.
- } else if (LeafRec->isSubClassOf("Register")) {
- // Handle register references.
- } else if (LeafRec->isSubClassOf("ComplexPattern")) {
- // Handle complex pattern.
- const ComplexPattern *CP = NodeGetComplexPattern(Child, CGP);
- std::string Fn = CP->getSelectFunc();
- unsigned NumOps = CP->getNumOperands();
- for (unsigned i = 0; i < NumOps; ++i) {
- emitDecl("CPTmp" + RootName + "_" + utostr(i));
- emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";");
- }
- if (CP->hasProperty(SDNPHasChain)) {
- const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Parent->getOperator());
- FoldedChains.push_back(std::make_pair("CPInChain",
- PInfo.getNumResults()));
- ChainName = "Chain" + ChainSuffix;
- emitDecl("CPInChain");
- emitDecl(ChainName);
- emitCode("SDValue CPInChain;");
- emitCode("SDValue " + ChainName + ";");
- }
-
- std::string Code = Fn + "(N, ";
- if (CP->hasProperty(SDNPHasChain)) {
- std::string ParentName(RootName.begin(), RootName.end()-1);
- Code += getValueName(ParentName) + ", ";
- }
- Code += getValueName(RootName);
- for (unsigned i = 0; i < NumOps; i++)
- Code += ", CPTmp" + RootName + "_" + utostr(i);
- if (CP->hasProperty(SDNPHasChain))
- Code += ", CPInChain, Chain" + ChainSuffix;
- emitCheck(Code + ")");
- } else if (LeafRec->getName() == "srcvalue") {
- // Place holder for SRCVALUE nodes. Nothing to do here.
- } else if (LeafRec->isSubClassOf("ValueType")) {
- // Make sure this is the specified value type.
- emitCheck("cast<VTSDNode>(" + getNodeName(RootName) +
- ")->getVT() == MVT::" + LeafRec->getName());
- } else if (LeafRec->isSubClassOf("CondCode")) {
- // Make sure this is the specified cond code.
- emitCheck("cast<CondCodeSDNode>(" + getNodeName(RootName) +
- ")->get() == ISD::" + LeafRec->getName());
- } else {
-#ifndef NDEBUG
- Child->dump();
- errs() << " ";
-#endif
- assert(0 && "Unknown leaf type!");
- }
-
- // If there are node predicates for this, emit the calls.
- for (unsigned i = 0, e = Child->getPredicateFns().size(); i != e; ++i)
- emitCheck(Child->getPredicateFns()[i] + "(" + getNodeName(RootName) +
- ")");
- } else if (IntInit *II =
- dynamic_cast<IntInit*>(Child->getLeafValue())) {
- unsigned NTmp = TmpNo++;
- emitCode("ConstantSDNode *Tmp"+ utostr(NTmp) +
- " = dyn_cast<ConstantSDNode>("+
- getNodeName(RootName) + ");");
- emitCheck("Tmp" + utostr(NTmp));
- unsigned CTmp = TmpNo++;
- emitCode("int64_t CN"+ utostr(CTmp) +
- " = Tmp" + utostr(NTmp) + "->getSExtValue();");
- emitCheck("CN" + utostr(CTmp) + " == "
- "INT64_C(" +itostr(II->getValue()) + ")");
- } else {
-#ifndef NDEBUG
- Child->dump();
-#endif
- assert(0 && "Unknown leaf type!");
- }
- }
- }
-
- /// EmitResultCode - Emit the action for a pattern. Now that it has matched
- /// we actually have to build a DAG!
- std::vector<std::string>
- EmitResultCode(TreePatternNode *N, std::vector<Record*> DstRegs,
- bool InFlagDecled, bool ResNodeDecled,
- bool LikeLeaf = false, bool isRoot = false) {
- // List of arguments of getMachineNode() or SelectNodeTo().
- std::vector<std::string> NodeOps;
- // This is something selected from the pattern we matched.
- if (!N->getName().empty()) {
- const std::string &VarName = N->getName();
- std::string Val = VariableMap[VarName];
- bool ModifiedVal = false;
- if (Val.empty()) {
- errs() << "Variable '" << VarName << " referenced but not defined "
- << "and not caught earlier!\n";
- abort();
- }
- if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') {
- // Already selected this operand, just return the tmpval.
- NodeOps.push_back(getValueName(Val));
- return NodeOps;
- }
-
- const ComplexPattern *CP;
- unsigned ResNo = TmpNo++;
- if (!N->isLeaf() && N->getOperator()->getName() == "imm") {
- assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
- std::string CastType;
- std::string TmpVar = "Tmp" + utostr(ResNo);
- switch (N->getTypeNum(0)) {
- default:
- errs() << "Cannot handle " << getEnumName(N->getTypeNum(0))
- << " type as an immediate constant. Aborting\n";
- abort();
- case MVT::i1: CastType = "bool"; break;
- case MVT::i8: CastType = "unsigned char"; break;
- case MVT::i16: CastType = "unsigned short"; break;
- case MVT::i32: CastType = "unsigned"; break;
- case MVT::i64: CastType = "uint64_t"; break;
- }
- emitCode("SDValue " + TmpVar +
- " = CurDAG->getTargetConstant(((" + CastType +
- ") cast<ConstantSDNode>(" + Val + ")->getZExtValue()), " +
- getEnumName(N->getTypeNum(0)) + ");");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
- // value if used multiple times by this pattern result.
- Val = TmpVar;
- ModifiedVal = true;
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf() && N->getOperator()->getName() == "fpimm") {
- assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
- std::string TmpVar = "Tmp" + utostr(ResNo);
- emitCode("SDValue " + TmpVar +
- " = CurDAG->getTargetConstantFP(*cast<ConstantFPSDNode>(" +
- Val + ")->getConstantFPValue(), cast<ConstantFPSDNode>(" +
- Val + ")->getValueType(0));");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
- // value if used multiple times by this pattern result.
- Val = TmpVar;
- ModifiedVal = true;
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
- Record *Op = OperatorMap[N->getName()];
- // Transform ExternalSymbol to TargetExternalSymbol
- if (Op && Op->getName() == "externalsym") {
- std::string TmpVar = "Tmp"+utostr(ResNo);
- emitCode("SDValue " + TmpVar + " = CurDAG->getTarget"
- "ExternalSymbol(cast<ExternalSymbolSDNode>(" +
- Val + ")->getSymbol(), " +
- getEnumName(N->getTypeNum(0)) + ");");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select
- // this value if used multiple times by this pattern result.
- Val = TmpVar;
- ModifiedVal = true;
- }
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf() && (N->getOperator()->getName() == "tglobaladdr"
- || N->getOperator()->getName() == "tglobaltlsaddr")) {
- Record *Op = OperatorMap[N->getName()];
- // Transform GlobalAddress to TargetGlobalAddress
- if (Op && (Op->getName() == "globaladdr" ||
- Op->getName() == "globaltlsaddr")) {
- std::string TmpVar = "Tmp" + utostr(ResNo);
- emitCode("SDValue " + TmpVar + " = CurDAG->getTarget"
- "GlobalAddress(cast<GlobalAddressSDNode>(" + Val +
- ")->getGlobal(), " + getEnumName(N->getTypeNum(0)) +
- ");");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select
- // this value if used multiple times by this pattern result.
- Val = TmpVar;
- ModifiedVal = true;
- }
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf()
- && (N->getOperator()->getName() == "texternalsym"
- || N->getOperator()->getName() == "tconstpool")) {
- // Do not rewrite the variable name, since we don't generate a new
- // temporary.
- NodeOps.push_back(getValueName(Val));
- } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, CGP))) {
- for (unsigned i = 0; i < CP->getNumOperands(); ++i) {
- NodeOps.push_back(getValueName("CPTmp" + Val + "_" + utostr(i)));
- }
- } else {
- // This node, probably wrapped in a SDNodeXForm, behaves like a leaf
- // node even if it isn't one. Don't select it.
- if (!LikeLeaf) {
- if (isRoot && N->isLeaf()) {
- emitCode("ReplaceUses(SDValue(N, 0), " + Val + ");");
- emitCode("return NULL;");
- }
- }
- NodeOps.push_back(getValueName(Val));
- }
-
- if (ModifiedVal) {
- VariableMap[VarName] = Val;
- }
- return NodeOps;
- }
- if (N->isLeaf()) {
- // If this is an explicit register reference, handle it.
- if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
- unsigned ResNo = TmpNo++;
- if (DI->getDef()->isSubClassOf("Register")) {
- emitCode("SDValue Tmp" + utostr(ResNo) + " = CurDAG->getRegister(" +
- getQualifiedName(DI->getDef()) + ", " +
- getEnumName(N->getTypeNum(0)) + ");");
- NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
- return NodeOps;
- } else if (DI->getDef()->getName() == "zero_reg") {
- emitCode("SDValue Tmp" + utostr(ResNo) +
- " = CurDAG->getRegister(0, " +
- getEnumName(N->getTypeNum(0)) + ");");
- NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
- return NodeOps;
- } else if (DI->getDef()->isSubClassOf("RegisterClass")) {
- // Handle a reference to a register class. This is used
- // in COPY_TO_SUBREG instructions.
- emitCode("SDValue Tmp" + utostr(ResNo) +
- " = CurDAG->getTargetConstant(" +
- getQualifiedName(DI->getDef()) + "RegClassID, " +
- "MVT::i32);");
- NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
- return NodeOps;
- }
- } else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
- unsigned ResNo = TmpNo++;
- assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
- emitCode("SDValue Tmp" + utostr(ResNo) +
- " = CurDAG->getTargetConstant(0x" +
- utohexstr((uint64_t) II->getValue()) +
- "ULL, " + getEnumName(N->getTypeNum(0)) + ");");
- NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
- return NodeOps;
- }
-
-#ifndef NDEBUG
- N->dump();
-#endif
- assert(0 && "Unknown leaf type!");
- return NodeOps;
- }
-
- Record *Op = N->getOperator();
- if (Op->isSubClassOf("Instruction")) {
- const CodeGenTarget &CGT = CGP.getTargetInfo();
- CodeGenInstruction &II = CGT.getInstruction(Op->getName());
- const DAGInstruction &Inst = CGP.getInstruction(Op);
- const TreePattern *InstPat = Inst.getPattern();
- // FIXME: Assume actual pattern comes before "implicit".
- TreePatternNode *InstPatNode =
- isRoot ? (InstPat ? InstPat->getTree(0) : Pattern)
- : (InstPat ? InstPat->getTree(0) : NULL);
- if (InstPatNode && !InstPatNode->isLeaf() &&
- InstPatNode->getOperator()->getName() == "set") {
- InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
- }
- bool IsVariadic = isRoot && II.isVariadic;
- // FIXME: fix how we deal with physical register operands.
- bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
- bool HasImpResults = isRoot && DstRegs.size() > 0;
- bool NodeHasOptInFlag = isRoot &&
- PatternHasProperty(Pattern, SDNPOptInFlag, CGP);
- bool NodeHasInFlag = isRoot &&
- PatternHasProperty(Pattern, SDNPInFlag, CGP);
- bool NodeHasOutFlag = isRoot &&
- PatternHasProperty(Pattern, SDNPOutFlag, CGP);
- bool NodeHasChain = InstPatNode &&
- PatternHasProperty(InstPatNode, SDNPHasChain, CGP);
- bool InputHasChain = isRoot &&
- NodeHasProperty(Pattern, SDNPHasChain, CGP);
- unsigned NumResults = Inst.getNumResults();
- unsigned NumDstRegs = HasImpResults ? DstRegs.size() : 0;
-
- // Record output varargs info.
- OutputIsVariadic = IsVariadic;
-
- if (NodeHasOptInFlag) {
- emitCode("bool HasInFlag = "
- "(N->getOperand(N->getNumOperands()-1).getValueType() == "
- "MVT::Flag);");
- }
- if (IsVariadic)
- emitCode("SmallVector<SDValue, 8> Ops" + utostr(OpcNo) + ";");
-
- // How many results is this pattern expected to produce?
- unsigned NumPatResults = 0;
- for (unsigned i = 0, e = Pattern->getExtTypes().size(); i != e; i++) {
- MVT::SimpleValueType VT = Pattern->getTypeNum(i);
- if (VT != MVT::isVoid && VT != MVT::Flag)
- NumPatResults++;
- }
-
- if (OrigChains.size() > 0) {
- // The original input chain is being ignored. If it is not just
- // pointing to the op that's being folded, we should create a
- // TokenFactor with it and the chain of the folded op as the new chain.
- // We could potentially be doing multiple levels of folding, in that
- // case, the TokenFactor can have more operands.
- emitCode("SmallVector<SDValue, 8> InChains;");
- for (unsigned i = 0, e = OrigChains.size(); i < e; ++i) {
- emitCode("if (" + OrigChains[i].first + ".getNode() != " +
- OrigChains[i].second + ".getNode()) {");
- emitCode(" InChains.push_back(" + OrigChains[i].first + ");");
- emitCode("}");
- }
- emitCode("InChains.push_back(" + ChainName + ");");
- emitCode(ChainName + " = CurDAG->getNode(ISD::TokenFactor, "
- "N->getDebugLoc(), MVT::Other, "
- "&InChains[0], InChains.size());");
- if (GenDebug) {
- emitCode("CurDAG->setSubgraphColor(" + ChainName +".getNode(), \"yellow\");");
- emitCode("CurDAG->setSubgraphColor(" + ChainName +".getNode(), \"black\");");
- }
- }
-
- // Loop over all of the operands of the instruction pattern, emitting code
- // to fill them all in. The node 'N' usually has number children equal to
- // the number of input operands of the instruction. However, in cases
- // where there are predicate operands for an instruction, we need to fill
- // in the 'execute always' values. Match up the node operands to the
- // instruction operands to do this.
- std::vector<std::string> AllOps;
- for (unsigned ChildNo = 0, InstOpNo = NumResults;
- InstOpNo != II.OperandList.size(); ++InstOpNo) {
- std::vector<std::string> Ops;
-
- // Determine what to emit for this operand.
- Record *OperandNode = II.OperandList[InstOpNo].Rec;
- if ((OperandNode->isSubClassOf("PredicateOperand") ||
- OperandNode->isSubClassOf("OptionalDefOperand")) &&
- !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
- // This is a predicate or optional def operand; emit the
- // 'default ops' operands.
- const DAGDefaultOperand &DefaultOp =
- CGP.getDefaultOperand(II.OperandList[InstOpNo].Rec);
- for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i) {
- Ops = EmitResultCode(DefaultOp.DefaultOps[i], DstRegs,
- InFlagDecled, ResNodeDecled);
- AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
- }
- } else {
- // Otherwise this is a normal operand or a predicate operand without
- // 'execute always'; emit it.
- Ops = EmitResultCode(N->getChild(ChildNo), DstRegs,
- InFlagDecled, ResNodeDecled);
- AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
- ++ChildNo;
- }
- }
-
- // Emit all the chain and CopyToReg stuff.
- bool ChainEmitted = NodeHasChain;
- if (NodeHasInFlag || HasImpInputs)
- EmitInFlagSelectCode(Pattern, "N", ChainEmitted,
- InFlagDecled, ResNodeDecled, true);
- if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs) {
- if (!InFlagDecled) {
- emitCode("SDValue InFlag(0, 0);");
- InFlagDecled = true;
- }
- if (NodeHasOptInFlag) {
- emitCode("if (HasInFlag) {");
- emitCode(" InFlag = N->getOperand(N->getNumOperands()-1);");
- emitCode("}");
- }
- }
-
- unsigned ResNo = TmpNo++;
-
- unsigned OpsNo = OpcNo;
- std::string CodePrefix;
- bool ChainAssignmentNeeded = NodeHasChain && !isRoot;
- std::deque<std::string> After;
- std::string NodeName;
- if (!isRoot) {
- NodeName = "Tmp" + utostr(ResNo);
- CodePrefix = "SDValue " + NodeName + "(";
- } else {
- NodeName = "ResNode";
- if (!ResNodeDecled) {
- CodePrefix = "SDNode *" + NodeName + " = ";
- ResNodeDecled = true;
- } else
- CodePrefix = NodeName + " = ";
- }
-
- std::string Code = "Opc" + utostr(OpcNo);
-
- if (!isRoot || (InputHasChain && !NodeHasChain))
- // For call to "getMachineNode()".
- Code += ", N->getDebugLoc()";
-
- emitOpcode(II.Namespace + "::" + II.TheDef->getName());
-
- // Output order: results, chain, flags
- // Result types.
- if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) {
- Code += ", VT" + utostr(VTNo);
- emitVT(getEnumName(N->getTypeNum(0)));
- }
- // Add types for implicit results in physical registers, scheduler will
- // care of adding copyfromreg nodes.
- for (unsigned i = 0; i < NumDstRegs; i++) {
- Record *RR = DstRegs[i];
- if (RR->isSubClassOf("Register")) {
- MVT::SimpleValueType RVT = getRegisterValueType(RR, CGT);
- Code += ", " + getEnumName(RVT);
- }
- }
- if (NodeHasChain)
- Code += ", MVT::Other";
- if (NodeHasOutFlag)
- Code += ", MVT::Flag";
-
- // Inputs.
- if (IsVariadic) {
- for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
- emitCode("Ops" + utostr(OpsNo) + ".push_back(" + AllOps[i] + ");");
- AllOps.clear();
-
- // Figure out whether any operands at the end of the op list are not
- // part of the variable section.
- std::string EndAdjust;
- if (NodeHasInFlag || HasImpInputs)
- EndAdjust = "-1"; // Always has one flag.
- else if (NodeHasOptInFlag)
- EndAdjust = "-(HasInFlag?1:0)"; // May have a flag.
-
- emitCode("for (unsigned i = NumInputRootOps + " + utostr(NodeHasChain) +
- ", e = N->getNumOperands()" + EndAdjust + "; i != e; ++i) {");
-
- emitCode(" Ops" + utostr(OpsNo) + ".push_back(N->getOperand(i));");
- emitCode("}");
- }
-
- // Populate MemRefs with entries for each memory accesses covered by
- // this pattern.
- if (isRoot && !LSI.empty()) {
- std::string MemRefs = "MemRefs" + utostr(OpsNo);
- emitCode("MachineSDNode::mmo_iterator " + MemRefs + " = "
- "MF->allocateMemRefsArray(" + utostr(LSI.size()) + ");");
- for (unsigned i = 0, e = LSI.size(); i != e; ++i)
- emitCode(MemRefs + "[" + utostr(i) + "] = "
- "cast<MemSDNode>(" + LSI[i] + ")->getMemOperand();");
- After.push_back("cast<MachineSDNode>(ResNode)->setMemRefs(" +
- MemRefs + ", " + MemRefs + " + " + utostr(LSI.size()) +
- ");");
- }
-
- if (NodeHasChain) {
- if (IsVariadic)
- emitCode("Ops" + utostr(OpsNo) + ".push_back(" + ChainName + ");");
- else
- AllOps.push_back(ChainName);
- }
-
- if (IsVariadic) {
- if (NodeHasInFlag || HasImpInputs)
- emitCode("Ops" + utostr(OpsNo) + ".push_back(InFlag);");
- else if (NodeHasOptInFlag) {
- emitCode("if (HasInFlag)");
- emitCode(" Ops" + utostr(OpsNo) + ".push_back(InFlag);");
- }
- Code += ", &Ops" + utostr(OpsNo) + "[0], Ops" + utostr(OpsNo) +
- ".size()";
- } else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs)
- AllOps.push_back("InFlag");
-
- unsigned NumOps = AllOps.size();
- if (NumOps) {
- if (!NodeHasOptInFlag && NumOps < 4) {
- for (unsigned i = 0; i != NumOps; ++i)
- Code += ", " + AllOps[i];
- } else {
- std::string OpsCode = "SDValue Ops" + utostr(OpsNo) + "[] = { ";
- for (unsigned i = 0; i != NumOps; ++i) {
- OpsCode += AllOps[i];
- if (i != NumOps-1)
- OpsCode += ", ";
- }
- emitCode(OpsCode + " };");
- Code += ", Ops" + utostr(OpsNo) + ", ";
- if (NodeHasOptInFlag) {
- Code += "HasInFlag ? ";
- Code += utostr(NumOps) + " : " + utostr(NumOps-1);
- } else
- Code += utostr(NumOps);
- }
- }
-
- if (!isRoot)
- Code += "), 0";
-
- std::vector<std::string> ReplaceFroms;
- std::vector<std::string> ReplaceTos;
- if (!isRoot) {
- NodeOps.push_back("Tmp" + utostr(ResNo));
- } else {
-
- if (NodeHasOutFlag) {
- if (!InFlagDecled) {
- After.push_back("SDValue InFlag(ResNode, " +
- utostr(NumResults+NumDstRegs+(unsigned)NodeHasChain) +
- ");");
- InFlagDecled = true;
- } else
- After.push_back("InFlag = SDValue(ResNode, " +
- utostr(NumResults+NumDstRegs+(unsigned)NodeHasChain) +
- ");");
- }
-
- for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) {
- ReplaceFroms.push_back("SDValue(" +
- FoldedChains[j].first + ".getNode(), " +
- utostr(FoldedChains[j].second) +
- ")");
- ReplaceTos.push_back("SDValue(ResNode, " +
- utostr(NumResults+NumDstRegs) + ")");
- }
-
- if (NodeHasOutFlag) {
- if (FoldedFlag.first != "") {
- ReplaceFroms.push_back("SDValue(" + FoldedFlag.first + ".getNode(), " +
- utostr(FoldedFlag.second) + ")");
- ReplaceTos.push_back("InFlag");
- } else {
- assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP));
- ReplaceFroms.push_back("SDValue(N, " +
- utostr(NumPatResults + (unsigned)InputHasChain)
- + ")");
- ReplaceTos.push_back("InFlag");
- }
- }
-
- if (!ReplaceFroms.empty() && InputHasChain) {
- ReplaceFroms.push_back("SDValue(N, " +
- utostr(NumPatResults) + ")");
- ReplaceTos.push_back("SDValue(" + ChainName + ".getNode(), " +
- ChainName + ".getResNo()" + ")");
- ChainAssignmentNeeded |= NodeHasChain;
- }
-
- // User does not expect the instruction would produce a chain!
- if ((!InputHasChain && NodeHasChain) && NodeHasOutFlag) {
- ;
- } else if (InputHasChain && !NodeHasChain) {
- // One of the inner node produces a chain.
- assert(!NodeHasOutFlag && "Node has flag but not chain!");
- ReplaceFroms.push_back("SDValue(N, " +
- utostr(NumPatResults) + ")");
- ReplaceTos.push_back(ChainName);
- }
- }
-
- if (ChainAssignmentNeeded) {
- // Remember which op produces the chain.
- std::string ChainAssign;
- if (!isRoot)
- ChainAssign = ChainName + " = SDValue(" + NodeName +
- ".getNode(), " + utostr(NumResults+NumDstRegs) + ");";
- else
- ChainAssign = ChainName + " = SDValue(" + NodeName +
- ", " + utostr(NumResults+NumDstRegs) + ");";
-
- After.push_front(ChainAssign);
- }
-
- if (ReplaceFroms.size() == 1) {
- After.push_back("ReplaceUses(" + ReplaceFroms[0] + ", " +
- ReplaceTos[0] + ");");
- } else if (!ReplaceFroms.empty()) {
- After.push_back("const SDValue Froms[] = {");
- for (unsigned i = 0, e = ReplaceFroms.size(); i != e; ++i)
- After.push_back(" " + ReplaceFroms[i] + (i + 1 != e ? "," : ""));
- After.push_back("};");
- After.push_back("const SDValue Tos[] = {");
- for (unsigned i = 0, e = ReplaceFroms.size(); i != e; ++i)
- After.push_back(" " + ReplaceTos[i] + (i + 1 != e ? "," : ""));
- After.push_back("};");
- After.push_back("ReplaceUses(Froms, Tos, " +
- itostr(ReplaceFroms.size()) + ");");
- }
-
- // We prefer to use SelectNodeTo since it avoids allocation when
- // possible and it avoids CSE map recalculation for the node's
- // users, however it's tricky to use in a non-root context.
- //
- // We also don't use SelectNodeTo if the pattern replacement is being
- // used to jettison a chain result, since morphing the node in place
- // would leave users of the chain dangling.
- //
- if (!isRoot || (InputHasChain && !NodeHasChain)) {
- Code = "CurDAG->getMachineNode(" + Code;
- } else {
- Code = "CurDAG->SelectNodeTo(N, " + Code;
- }
- if (isRoot) {
- if (After.empty())
- CodePrefix = "return ";
- else
- After.push_back("return ResNode;");
- }
-
- emitCode(CodePrefix + Code + ");");
-
- if (GenDebug) {
- if (!isRoot) {
- emitCode("CurDAG->setSubgraphColor(" + NodeName +".getNode(), \"yellow\");");
- emitCode("CurDAG->setSubgraphColor(" + NodeName +".getNode(), \"black\");");
- }
- else {
- emitCode("CurDAG->setSubgraphColor(" + NodeName +", \"yellow\");");
- emitCode("CurDAG->setSubgraphColor(" + NodeName +", \"black\");");
- }
- }
-
- for (unsigned i = 0, e = After.size(); i != e; ++i)
- emitCode(After[i]);
-
- return NodeOps;
- }
- if (Op->isSubClassOf("SDNodeXForm")) {
- assert(N->getNumChildren() == 1 && "node xform should have one child!");
- // PatLeaf node - the operand may or may not be a leaf node. But it should
- // behave like one.
- std::vector<std::string> Ops =
- EmitResultCode(N->getChild(0), DstRegs, InFlagDecled,
- ResNodeDecled, true);
- unsigned ResNo = TmpNo++;
- emitCode("SDValue Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
- + "(" + Ops.back() + ".getNode());");
- NodeOps.push_back("Tmp" + utostr(ResNo));
- if (isRoot)
- emitCode("return Tmp" + utostr(ResNo) + ".getNode();");
- return NodeOps;
- }
-
- N->dump();
- errs() << "\n";
- throw std::string("Unknown node in result pattern!");
- }
-
- /// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat'
- /// and add it to the tree. 'Pat' and 'Other' are isomorphic trees except that
- /// 'Pat' may be missing types. If we find an unresolved type to add a check
- /// for, this returns true otherwise false if Pat has all types.
- bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other,
- const std::string &Prefix, bool isRoot = false) {
- // Did we find one?
- if (Pat->getExtTypes() != Other->getExtTypes()) {
- // Move a type over from 'other' to 'pat'.
- Pat->setTypes(Other->getExtTypes());
- // The top level node type is checked outside of the select function.
- if (!isRoot)
- emitCheck(Prefix + ".getValueType() == " +
- getName(Pat->getTypeNum(0)));
- return true;
- }
-
- unsigned OpNo =
- (unsigned) NodeHasProperty(Pat, SDNPHasChain, CGP);
- for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo)
- if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i),
- Prefix + utostr(OpNo)))
- return true;
- return false;
- }
-
-private:
- /// EmitInFlagSelectCode - Emit the flag operands for the DAG that is
- /// being built.
- void EmitInFlagSelectCode(TreePatternNode *N, const std::string &RootName,
- bool &ChainEmitted, bool &InFlagDecled,
- bool &ResNodeDecled, bool isRoot = false) {
- const CodeGenTarget &T = CGP.getTargetInfo();
- unsigned OpNo =
- (unsigned) NodeHasProperty(N, SDNPHasChain, CGP);
- bool HasInFlag = NodeHasProperty(N, SDNPInFlag, CGP);
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
- TreePatternNode *Child = N->getChild(i);
- if (!Child->isLeaf()) {
- EmitInFlagSelectCode(Child, RootName + utostr(OpNo), ChainEmitted,
- InFlagDecled, ResNodeDecled);
- } else {
- if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
- if (!Child->getName().empty()) {
- std::string Name = RootName + utostr(OpNo);
- if (Duplicates.find(Name) != Duplicates.end())
- // A duplicate! Do not emit a copy for this node.
- continue;
- }
-
- Record *RR = DI->getDef();
- if (RR->isSubClassOf("Register")) {
- MVT::SimpleValueType RVT = getRegisterValueType(RR, T);
- if (RVT == MVT::Flag) {
- if (!InFlagDecled) {
- emitCode("SDValue InFlag = " +
- getValueName(RootName + utostr(OpNo)) + ";");
- InFlagDecled = true;
- } else
- emitCode("InFlag = " +
- getValueName(RootName + utostr(OpNo)) + ";");
- } else {
- if (!ChainEmitted) {
- emitCode("SDValue Chain = CurDAG->getEntryNode();");
- ChainName = "Chain";
- ChainEmitted = true;
- }
- if (!InFlagDecled) {
- emitCode("SDValue InFlag(0, 0);");
- InFlagDecled = true;
- }
- std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
- emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" + ChainName +
- ", " + getNodeName(RootName) + "->getDebugLoc()" +
- ", " + getQualifiedName(RR) +
- ", " + getValueName(RootName + utostr(OpNo)) +
- ", InFlag).getNode();");
- ResNodeDecled = true;
- emitCode(ChainName + " = SDValue(ResNode, 0);");
- emitCode("InFlag = SDValue(ResNode, 1);");
- }
- }
- }
- }
- }
-
- if (HasInFlag) {
- if (!InFlagDecled) {
- emitCode("SDValue InFlag = " + getNodeName(RootName) +
- "->getOperand(" + utostr(OpNo) + ");");
- InFlagDecled = true;
- } else
- emitCode("InFlag = " + getNodeName(RootName) +
- "->getOperand(" + utostr(OpNo) + ");");
- }
- }
-};
-
-/// EmitCodeForPattern - Given a pattern to match, emit code to the specified
-/// stream to match the pattern, and generate the code for the match if it
-/// succeeds. Returns true if the pattern is not guaranteed to match.
-void DAGISelEmitter::GenerateCodeForPattern(const PatternToMatch &Pattern,
- std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
- std::set<std::string> &GeneratedDecl,
- std::vector<std::string> &TargetOpcodes,
- std::vector<std::string> &TargetVTs,
- bool &OutputIsVariadic,
- unsigned &NumInputRootOps) {
- OutputIsVariadic = false;
- NumInputRootOps = 0;
-
- PatternCodeEmitter Emitter(CGP, Pattern.getPredicateCheck(),
- Pattern.getSrcPattern(), Pattern.getDstPattern(),
- GeneratedCode, GeneratedDecl,
- TargetOpcodes, TargetVTs,
- OutputIsVariadic, NumInputRootOps);
-
- // Emit the matcher, capturing named arguments in VariableMap.
- bool FoundChain = false;
- Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", FoundChain);
-
- // TP - Get *SOME* tree pattern, we don't care which.
- TreePattern &TP = *CGP.pf_begin()->second;
-
- // At this point, we know that we structurally match the pattern, but the
- // types of the nodes may not match. Figure out the fewest number of type
- // comparisons we need to emit. For example, if there is only one integer
- // type supported by a target, there should be no type comparisons at all for
- // integer patterns!
- //
- // To figure out the fewest number of type checks needed, clone the pattern,
- // remove the types, then perform type inference on the pattern as a whole.
- // If there are unresolved types, emit an explicit check for those types,
- // apply the type to the tree, then rerun type inference. Iterate until all
- // types are resolved.
- //
- TreePatternNode *Pat = Pattern.getSrcPattern()->clone();
- RemoveAllTypes(Pat);
-
- do {
- // Resolve/propagate as many types as possible.
- try {
- bool MadeChange = true;
- while (MadeChange)
- MadeChange = Pat->ApplyTypeConstraints(TP,
- true/*Ignore reg constraints*/);
- } catch (...) {
- assert(0 && "Error: could not find consistent types for something we"
- " already decided was ok!");
- abort();
- }
-
- // Insert a check for an unresolved type and add it to the tree. If we find
- // an unresolved type to add a check for, this returns true and we iterate,
- // otherwise we are done.
- } while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N", true));
-
- Emitter.EmitResultCode(Pattern.getDstPattern(), Pattern.getDstRegs(),
- false, false, false, true);
- delete Pat;
-}
-
-/// EraseCodeLine - Erase one code line from all of the patterns. If removing
-/// a line causes any of them to be empty, remove them and return true when
-/// done.
-static bool EraseCodeLine(std::vector<std::pair<const PatternToMatch*,
- std::vector<std::pair<unsigned, std::string> > > >
- &Patterns) {
- bool ErasedPatterns = false;
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
- Patterns[i].second.pop_back();
- if (Patterns[i].second.empty()) {
- Patterns.erase(Patterns.begin()+i);
- --i; --e;
- ErasedPatterns = true;
- }
- }
- return ErasedPatterns;
-}
-
-/// EmitPatterns - Emit code for at least one pattern, but try to group common
-/// code together between the patterns.
-void DAGISelEmitter::EmitPatterns(std::vector<std::pair<const PatternToMatch*,
- std::vector<std::pair<unsigned, std::string> > > >
- &Patterns, unsigned Indent,
- raw_ostream &OS) {
- typedef std::pair<unsigned, std::string> CodeLine;
- typedef std::vector<CodeLine> CodeList;
- typedef std::vector<std::pair<const PatternToMatch*, CodeList> > PatternList;
-
- if (Patterns.empty()) return;
-
- // Figure out how many patterns share the next code line. Explicitly copy
- // FirstCodeLine so that we don't invalidate a reference when changing
- // Patterns.
- const CodeLine FirstCodeLine = Patterns.back().second.back();
- unsigned LastMatch = Patterns.size()-1;
- while (LastMatch != 0 && Patterns[LastMatch-1].second.back() == FirstCodeLine)
- --LastMatch;
-
- // If not all patterns share this line, split the list into two pieces. The
- // first chunk will use this line, the second chunk won't.
- if (LastMatch != 0) {
- PatternList Shared(Patterns.begin()+LastMatch, Patterns.end());
- PatternList Other(Patterns.begin(), Patterns.begin()+LastMatch);
-
- // FIXME: Emit braces?
- if (Shared.size() == 1) {
- const PatternToMatch &Pattern = *Shared.back().first;
- OS << "\n" << std::string(Indent, ' ') << "// Pattern: ";
- Pattern.getSrcPattern()->print(OS);
- OS << "\n" << std::string(Indent, ' ') << "// Emits: ";
- Pattern.getDstPattern()->print(OS);
- OS << "\n";
- unsigned AddedComplexity = Pattern.getAddedComplexity();
- OS << std::string(Indent, ' ') << "// Pattern complexity = "
- << getPatternSize(Pattern.getSrcPattern(), CGP) + AddedComplexity
- << " cost = "
- << getResultPatternCost(Pattern.getDstPattern(), CGP)
- << " size = "
- << getResultPatternSize(Pattern.getDstPattern(), CGP) << "\n";
- }
- if (FirstCodeLine.first != 1) {
- OS << std::string(Indent, ' ') << "{\n";
- Indent += 2;
- }
- EmitPatterns(Shared, Indent, OS);
- if (FirstCodeLine.first != 1) {
- Indent -= 2;
- OS << std::string(Indent, ' ') << "}\n";
- }
+ bool operator()(const PatternToMatch *LHS,
+ const PatternToMatch *RHS) {
+ unsigned LHSSize = getPatternSize(LHS->getSrcPattern(), CGP);
+ unsigned RHSSize = getPatternSize(RHS->getSrcPattern(), CGP);
+ LHSSize += LHS->getAddedComplexity();
+ RHSSize += RHS->getAddedComplexity();
+ if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost
+ if (LHSSize < RHSSize) return false;
- if (Other.size() == 1) {
- const PatternToMatch &Pattern = *Other.back().first;
- OS << "\n" << std::string(Indent, ' ') << "// Pattern: ";
- Pattern.getSrcPattern()->print(OS);
- OS << "\n" << std::string(Indent, ' ') << "// Emits: ";
- Pattern.getDstPattern()->print(OS);
- OS << "\n";
- unsigned AddedComplexity = Pattern.getAddedComplexity();
- OS << std::string(Indent, ' ') << "// Pattern complexity = "
- << getPatternSize(Pattern.getSrcPattern(), CGP) + AddedComplexity
- << " cost = "
- << getResultPatternCost(Pattern.getDstPattern(), CGP)
- << " size = "
- << getResultPatternSize(Pattern.getDstPattern(), CGP) << "\n";
- }
- EmitPatterns(Other, Indent, OS);
- return;
- }
-
- // Remove this code from all of the patterns that share it.
- bool ErasedPatterns = EraseCodeLine(Patterns);
-
- bool isPredicate = FirstCodeLine.first == 1;
-
- // Otherwise, every pattern in the list has this line. Emit it.
- if (!isPredicate) {
- // Normal code.
- OS << std::string(Indent, ' ') << FirstCodeLine.second << "\n";
- } else {
- OS << std::string(Indent, ' ') << "if (" << FirstCodeLine.second;
+ // If the patterns have equal complexity, compare generated instruction cost
+ unsigned LHSCost = getResultPatternCost(LHS->getDstPattern(), CGP);
+ unsigned RHSCost = getResultPatternCost(RHS->getDstPattern(), CGP);
+ if (LHSCost < RHSCost) return true;
+ if (LHSCost > RHSCost) return false;
- // If the next code line is another predicate, and if all of the pattern
- // in this group share the same next line, emit it inline now. Do this
- // until we run out of common predicates.
- while (!ErasedPatterns && Patterns.back().second.back().first == 1) {
- // Check that all of the patterns in Patterns end with the same predicate.
- bool AllEndWithSamePredicate = true;
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i)
- if (Patterns[i].second.back() != Patterns.back().second.back()) {
- AllEndWithSamePredicate = false;
- break;
- }
- // If all of the predicates aren't the same, we can't share them.
- if (!AllEndWithSamePredicate) break;
-
- // Otherwise we can. Emit it shared now.
- OS << " &&\n" << std::string(Indent+4, ' ')
- << Patterns.back().second.back().second;
- ErasedPatterns = EraseCodeLine(Patterns);
- }
+ unsigned LHSPatSize = getResultPatternSize(LHS->getDstPattern(), CGP);
+ unsigned RHSPatSize = getResultPatternSize(RHS->getDstPattern(), CGP);
+ if (LHSPatSize < RHSPatSize) return true;
+ if (LHSPatSize > RHSPatSize) return false;
- OS << ") {\n";
- Indent += 2;
+ // Sort based on the UID of the pattern, giving us a deterministic ordering.
+ assert(LHS == RHS || LHS->ID != RHS->ID);
+ return LHS->ID < RHS->ID;
}
-
- EmitPatterns(Patterns, Indent, OS);
-
- if (isPredicate)
- OS << std::string(Indent-2, ' ') << "}\n";
-}
-
-static std::string getLegalCName(std::string OpName) {
- std::string::size_type pos = OpName.find("::");
- if (pos != std::string::npos)
- OpName.replace(pos, 2, "_");
- return OpName;
+};
}
-void DAGISelEmitter::EmitInstructionSelector(raw_ostream &OS) {
- const CodeGenTarget &Target = CGP.getTargetInfo();
-
- // Get the namespace to insert instructions into.
- std::string InstNS = Target.getInstNamespace();
- if (!InstNS.empty()) InstNS += "::";
-
- // Group the patterns by their top-level opcodes.
- std::map<std::string, std::vector<const PatternToMatch*> > PatternsByOpcode;
- // All unique target node emission functions.
- std::map<std::string, unsigned> EmitFunctions;
- for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
- E = CGP.ptm_end(); I != E; ++I) {
- const PatternToMatch &Pattern = *I;
-
- TreePatternNode *Node = Pattern.getSrcPattern();
- if (!Node->isLeaf()) {
- PatternsByOpcode[getOpcodeName(Node->getOperator(), CGP)].
- push_back(&Pattern);
- } else {
- const ComplexPattern *CP;
- if (dynamic_cast<IntInit*>(Node->getLeafValue())) {
- PatternsByOpcode[getOpcodeName(CGP.getSDNodeNamed("imm"), CGP)].
- push_back(&Pattern);
- } else if ((CP = NodeGetComplexPattern(Node, CGP))) {
- std::vector<Record*> OpNodes = CP->getRootNodes();
- for (unsigned j = 0, e = OpNodes.size(); j != e; j++) {
- PatternsByOpcode[getOpcodeName(OpNodes[j], CGP)]
- .insert(PatternsByOpcode[getOpcodeName(OpNodes[j], CGP)].begin(),
- &Pattern);
- }
- } else {
- errs() << "Unrecognized opcode '";
- Node->dump();
- errs() << "' on tree pattern '";
- errs() << Pattern.getDstPattern()->getOperator()->getName() << "'!\n";
- exit(1);
- }
- }
- }
-
- // For each opcode, there might be multiple select functions, one per
- // ValueType of the node (or its first operand if it doesn't produce a
- // non-chain result.
- std::map<std::string, std::vector<std::string> > OpcodeVTMap;
-
- // Emit one Select_* method for each top-level opcode. We do this instead of
- // emitting one giant switch statement to support compilers where this will
- // result in the recursive functions taking less stack space.
- for (std::map<std::string, std::vector<const PatternToMatch*> >::iterator
- PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end();
- PBOI != E; ++PBOI) {
- const std::string &OpName = PBOI->first;
- std::vector<const PatternToMatch*> &PatternsOfOp = PBOI->second;
- assert(!PatternsOfOp.empty() && "No patterns but map has entry?");
-
- // Split them into groups by type.
- std::map<MVT::SimpleValueType,
- std::vector<const PatternToMatch*> > PatternsByType;
- for (unsigned i = 0, e = PatternsOfOp.size(); i != e; ++i) {
- const PatternToMatch *Pat = PatternsOfOp[i];
- TreePatternNode *SrcPat = Pat->getSrcPattern();
- PatternsByType[SrcPat->getTypeNum(0)].push_back(Pat);
- }
-
- for (std::map<MVT::SimpleValueType,
- std::vector<const PatternToMatch*> >::iterator
- II = PatternsByType.begin(), EE = PatternsByType.end(); II != EE;
- ++II) {
- MVT::SimpleValueType OpVT = II->first;
- std::vector<const PatternToMatch*> &Patterns = II->second;
- typedef std::pair<unsigned, std::string> CodeLine;
- typedef std::vector<CodeLine> CodeList;
- typedef CodeList::iterator CodeListI;
-
- std::vector<std::pair<const PatternToMatch*, CodeList> > CodeForPatterns;
- std::vector<std::vector<std::string> > PatternOpcodes;
- std::vector<std::vector<std::string> > PatternVTs;
- std::vector<std::set<std::string> > PatternDecls;
- std::vector<bool> OutputIsVariadicFlags;
- std::vector<unsigned> NumInputRootOpsCounts;
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
- CodeList GeneratedCode;
- std::set<std::string> GeneratedDecl;
- std::vector<std::string> TargetOpcodes;
- std::vector<std::string> TargetVTs;
- bool OutputIsVariadic;
- unsigned NumInputRootOps;
- GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl,
- TargetOpcodes, TargetVTs,
- OutputIsVariadic, NumInputRootOps);
- CodeForPatterns.push_back(std::make_pair(Patterns[i], GeneratedCode));
- PatternDecls.push_back(GeneratedDecl);
- PatternOpcodes.push_back(TargetOpcodes);
- PatternVTs.push_back(TargetVTs);
- OutputIsVariadicFlags.push_back(OutputIsVariadic);
- NumInputRootOpsCounts.push_back(NumInputRootOps);
- }
-
- // Factor target node emission code (emitted by EmitResultCode) into
- // separate functions. Uniquing and share them among all instruction
- // selection routines.
- for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) {
- CodeList &GeneratedCode = CodeForPatterns[i].second;
- std::vector<std::string> &TargetOpcodes = PatternOpcodes[i];
- std::vector<std::string> &TargetVTs = PatternVTs[i];
- std::set<std::string> Decls = PatternDecls[i];
- bool OutputIsVariadic = OutputIsVariadicFlags[i];
- unsigned NumInputRootOps = NumInputRootOpsCounts[i];
- std::vector<std::string> AddedInits;
- int CodeSize = (int)GeneratedCode.size();
- int LastPred = -1;
- for (int j = CodeSize-1; j >= 0; --j) {
- if (LastPred == -1 && GeneratedCode[j].first == 1)
- LastPred = j;
- else if (LastPred != -1 && GeneratedCode[j].first == 2)
- AddedInits.push_back(GeneratedCode[j].second);
- }
-
- std::string CalleeCode = "(SDNode *N";
- std::string CallerCode = "(N";
- for (unsigned j = 0, e = TargetOpcodes.size(); j != e; ++j) {
- CalleeCode += ", unsigned Opc" + utostr(j);
- CallerCode += ", " + TargetOpcodes[j];
- }
- for (unsigned j = 0, e = TargetVTs.size(); j != e; ++j) {
- CalleeCode += ", MVT::SimpleValueType VT" + utostr(j);
- CallerCode += ", " + TargetVTs[j];
- }
- for (std::set<std::string>::iterator
- I = Decls.begin(), E = Decls.end(); I != E; ++I) {
- std::string Name = *I;
- CalleeCode += ", SDValue &" + Name;
- CallerCode += ", " + Name;
- }
-
- if (OutputIsVariadic) {
- CalleeCode += ", unsigned NumInputRootOps";
- CallerCode += ", " + utostr(NumInputRootOps);
- }
-
- CallerCode += ");";
- CalleeCode += ") {\n";
-
- for (std::vector<std::string>::const_reverse_iterator
- I = AddedInits.rbegin(), E = AddedInits.rend(); I != E; ++I)
- CalleeCode += " " + *I + "\n";
-
- for (int j = LastPred+1; j < CodeSize; ++j)
- CalleeCode += " " + GeneratedCode[j].second + "\n";
- for (int j = LastPred+1; j < CodeSize; ++j)
- GeneratedCode.pop_back();
- CalleeCode += "}\n";
-
- // Uniquing the emission routines.
- unsigned EmitFuncNum;
- std::map<std::string, unsigned>::iterator EFI =
- EmitFunctions.find(CalleeCode);
- if (EFI != EmitFunctions.end()) {
- EmitFuncNum = EFI->second;
- } else {
- EmitFuncNum = EmitFunctions.size();
- EmitFunctions.insert(std::make_pair(CalleeCode, EmitFuncNum));
- // Prevent emission routines from being inlined to reduce selection
- // routines stack frame sizes.
- OS << "DISABLE_INLINE ";
- OS << "SDNode *Emit_" << utostr(EmitFuncNum) << CalleeCode;
- }
-
- // Replace the emission code within selection routines with calls to the
- // emission functions.
- if (GenDebug) {
- GeneratedCode.push_back(std::make_pair(0, "CurDAG->setSubgraphColor(N, \"red\");"));
- }
- CallerCode = "SDNode *Result = Emit_" + utostr(EmitFuncNum) + CallerCode;
- GeneratedCode.push_back(std::make_pair(3, CallerCode));
- if (GenDebug) {
- GeneratedCode.push_back(std::make_pair(0, "if(Result) {"));
- GeneratedCode.push_back(std::make_pair(0, " CurDAG->setSubgraphColor(Result, \"yellow\");"));
- GeneratedCode.push_back(std::make_pair(0, " CurDAG->setSubgraphColor(Result, \"black\");"));
- GeneratedCode.push_back(std::make_pair(0, "}"));
- //GeneratedCode.push_back(std::make_pair(0, "CurDAG->setSubgraphColor(N, \"black\");"));
- }
- GeneratedCode.push_back(std::make_pair(0, "return Result;"));
- }
-
- // Print function.
- std::string OpVTStr;
- if (OpVT == MVT::iPTR) {
- OpVTStr = "_iPTR";
- } else if (OpVT == MVT::iPTRAny) {
- OpVTStr = "_iPTRAny";
- } else if (OpVT == MVT::isVoid) {
- // Nodes with a void result actually have a first result type of either
- // Other (a chain) or Flag. Since there is no one-to-one mapping from
- // void to this case, we handle it specially here.
- } else {
- OpVTStr = "_" + getEnumName(OpVT).substr(5); // Skip 'MVT::'
- }
- std::map<std::string, std::vector<std::string> >::iterator OpVTI =
- OpcodeVTMap.find(OpName);
- if (OpVTI == OpcodeVTMap.end()) {
- std::vector<std::string> VTSet;
- VTSet.push_back(OpVTStr);
- OpcodeVTMap.insert(std::make_pair(OpName, VTSet));
- } else
- OpVTI->second.push_back(OpVTStr);
-
- // We want to emit all of the matching code now. However, we want to emit
- // the matches in order of minimal cost. Sort the patterns so the least
- // cost one is at the start.
- std::stable_sort(CodeForPatterns.begin(), CodeForPatterns.end(),
- PatternSortingPredicate(CGP));
-
- // Scan the code to see if all of the patterns are reachable and if it is
- // possible that the last one might not match.
- bool mightNotMatch = true;
- for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) {
- CodeList &GeneratedCode = CodeForPatterns[i].second;
- mightNotMatch = false;
-
- for (unsigned j = 0, e = GeneratedCode.size(); j != e; ++j) {
- if (GeneratedCode[j].first == 1) { // predicate.
- mightNotMatch = true;
- break;
- }
- }
-
- // If this pattern definitely matches, and if it isn't the last one, the
- // patterns after it CANNOT ever match. Error out.
- if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
- errs() << "Pattern '";
- CodeForPatterns[i].first->getSrcPattern()->print(errs());
- errs() << "' is impossible to select!\n";
- exit(1);
- }
- }
-
- // Loop through and reverse all of the CodeList vectors, as we will be
- // accessing them from their logical front, but accessing the end of a
- // vector is more efficient.
- for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) {
- CodeList &GeneratedCode = CodeForPatterns[i].second;
- std::reverse(GeneratedCode.begin(), GeneratedCode.end());
- }
-
- // Next, reverse the list of patterns itself for the same reason.
- std::reverse(CodeForPatterns.begin(), CodeForPatterns.end());
-
- OS << "SDNode *Select_" << getLegalCName(OpName)
- << OpVTStr << "(SDNode *N) {\n";
-
- // Emit all of the patterns now, grouped together to share code.
- EmitPatterns(CodeForPatterns, 2, OS);
-
- // If the last pattern has predicates (which could fail) emit code to
- // catch the case where nothing handles a pattern.
- if (mightNotMatch) {
- OS << "\n";
- if (OpName != "ISD::INTRINSIC_W_CHAIN" &&
- OpName != "ISD::INTRINSIC_WO_CHAIN" &&
- OpName != "ISD::INTRINSIC_VOID")
- OS << " CannotYetSelect(N);\n";
- else
- OS << " CannotYetSelectIntrinsic(N);\n";
-
- OS << " return NULL;\n";
- }
- OS << "}\n\n";
- }
- }
-
- OS << "// The main instruction selector code.\n"
- << "SDNode *SelectCode(SDNode *N) {\n"
- << " MVT::SimpleValueType NVT = N->getValueType(0).getSimpleVT().SimpleTy;\n"
- << " switch (N->getOpcode()) {\n"
- << " default:\n"
- << " assert(!N->isMachineOpcode() && \"Node already selected!\");\n"
- << " break;\n"
- << " case ISD::EntryToken: // These nodes remain the same.\n"
- << " case ISD::BasicBlock:\n"
- << " case ISD::Register:\n"
- << " case ISD::HANDLENODE:\n"
- << " case ISD::TargetConstant:\n"
- << " case ISD::TargetConstantFP:\n"
- << " case ISD::TargetConstantPool:\n"
- << " case ISD::TargetFrameIndex:\n"
- << " case ISD::TargetExternalSymbol:\n"
- << " case ISD::TargetBlockAddress:\n"
- << " case ISD::TargetJumpTable:\n"
- << " case ISD::TargetGlobalTLSAddress:\n"
- << " case ISD::TargetGlobalAddress:\n"
- << " case ISD::TokenFactor:\n"
- << " case ISD::CopyFromReg:\n"
- << " case ISD::CopyToReg: {\n"
- << " return NULL;\n"
- << " }\n"
- << " case ISD::AssertSext:\n"
- << " case ISD::AssertZext: {\n"
- << " ReplaceUses(SDValue(N, 0), N->getOperand(0));\n"
- << " return NULL;\n"
- << " }\n"
- << " case ISD::INLINEASM: return Select_INLINEASM(N);\n"
- << " case ISD::EH_LABEL: return Select_EH_LABEL(N);\n"
- << " case ISD::UNDEF: return Select_UNDEF(N);\n";
-
- // Loop over all of the case statements, emiting a call to each method we
- // emitted above.
- for (std::map<std::string, std::vector<const PatternToMatch*> >::iterator
- PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end();
- PBOI != E; ++PBOI) {
- const std::string &OpName = PBOI->first;
- // Potentially multiple versions of select for this opcode. One for each
- // ValueType of the node (or its first true operand if it doesn't produce a
- // result.
- std::map<std::string, std::vector<std::string> >::iterator OpVTI =
- OpcodeVTMap.find(OpName);
- std::vector<std::string> &OpVTs = OpVTI->second;
- OS << " case " << OpName << ": {\n";
- // If we have only one variant and it's the default, elide the
- // switch. Marginally faster, and makes MSVC happier.
- if (OpVTs.size()==1 && OpVTs[0].empty()) {
- OS << " return Select_" << getLegalCName(OpName) << "(N);\n";
- OS << " break;\n";
- OS << " }\n";
- continue;
- }
- // Keep track of whether we see a pattern that has an iPtr result.
- bool HasPtrPattern = false;
- bool HasDefaultPattern = false;
-
- OS << " switch (NVT) {\n";
- for (unsigned i = 0, e = OpVTs.size(); i < e; ++i) {
- std::string &VTStr = OpVTs[i];
- if (VTStr.empty()) {
- HasDefaultPattern = true;
- continue;
- }
-
- // If this is a match on iPTR: don't emit it directly, we need special
- // code.
- if (VTStr == "_iPTR") {
- HasPtrPattern = true;
- continue;
- }
- OS << " case MVT::" << VTStr.substr(1) << ":\n"
- << " return Select_" << getLegalCName(OpName)
- << VTStr << "(N);\n";
- }
- OS << " default:\n";
-
- // If there is an iPTR result version of this pattern, emit it here.
- if (HasPtrPattern) {
- OS << " if (TLI.getPointerTy() == NVT)\n";
- OS << " return Select_" << getLegalCName(OpName) <<"_iPTR(N);\n";
- }
- if (HasDefaultPattern) {
- OS << " return Select_" << getLegalCName(OpName) << "(N);\n";
- }
- OS << " break;\n";
- OS << " }\n";
- OS << " break;\n";
- OS << " }\n";
- }
-
- OS << " } // end of big switch.\n\n"
- << " if (N->getOpcode() != ISD::INTRINSIC_W_CHAIN &&\n"
- << " N->getOpcode() != ISD::INTRINSIC_WO_CHAIN &&\n"
- << " N->getOpcode() != ISD::INTRINSIC_VOID) {\n"
- << " CannotYetSelect(N);\n"
- << " } else {\n"
- << " CannotYetSelectIntrinsic(N);\n"
- << " }\n"
- << " return NULL;\n"
- << "}\n\n";
-}
void DAGISelEmitter::run(raw_ostream &OS) {
EmitSourceFileHeader("DAG Instruction Selector for the " +
@@ -2045,24 +195,45 @@ void DAGISelEmitter::run(raw_ostream &OS) {
<< "// *** instruction selector class. These functions are really "
<< "methods.\n\n";
- OS << "// Include standard, target-independent definitions and methods used\n"
- << "// by the instruction selector.\n";
- OS << "#include \"llvm/CodeGen/DAGISelHeader.h\"\n\n";
-
- EmitNodeTransforms(OS);
+ DEBUG(errs() << "\n\nALL PATTERNS TO MATCH:\n\n";
+ for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
+ E = CGP.ptm_end(); I != E; ++I) {
+ errs() << "PATTERN: "; I->getSrcPattern()->dump();
+ errs() << "\nRESULT: "; I->getDstPattern()->dump();
+ errs() << "\n";
+ });
+
+ // FIXME: These are being used by hand written code, gross.
EmitPredicateFunctions(OS);
-
- DEBUG(errs() << "\n\nALL PATTERNS TO MATCH:\n\n");
+
+ // Add all the patterns to a temporary list so we can sort them.
+ std::vector<const PatternToMatch*> Patterns;
for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
- I != E; ++I) {
- DEBUG(errs() << "PATTERN: "; I->getSrcPattern()->dump());
- DEBUG(errs() << "\nRESULT: "; I->getDstPattern()->dump());
- DEBUG(errs() << "\n");
- }
+ I != E; ++I)
+ Patterns.push_back(&*I);
+
+ // We want to process the matches in order of minimal cost. Sort the patterns
+ // so the least cost one is at the start.
+ std::stable_sort(Patterns.begin(), Patterns.end(),
+ PatternSortingPredicate(CGP));
- // At this point, we have full information about the 'Patterns' we need to
- // parse, both implicitly from instructions as well as from explicit pattern
- // definitions. Emit the resultant instruction selector.
- EmitInstructionSelector(OS);
+ // Convert each variant of each pattern into a Matcher.
+ std::vector<Matcher*> PatternMatchers;
+ for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
+ for (unsigned Variant = 0; ; ++Variant) {
+ if (Matcher *M = ConvertPatternToMatcher(*Patterns[i], Variant, CGP))
+ PatternMatchers.push_back(M);
+ else
+ break;
+ }
+ }
+
+ Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
+ PatternMatchers.size());
+
+ TheMatcher = OptimizeMatcher(TheMatcher, CGP);
+ //Matcher->dump();
+ EmitMatcherTable(TheMatcher, CGP, OS);
+ delete TheMatcher;
}
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index d5b889b..5ffdde8 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -31,24 +31,8 @@ public:
// run - Output the isel, returning true on failure.
void run(raw_ostream &OS);
-
-
private:
- void EmitNodeTransforms(raw_ostream &OS);
void EmitPredicateFunctions(raw_ostream &OS);
-
- void GenerateCodeForPattern(const PatternToMatch &Pattern,
- std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
- std::set<std::string> &GeneratedDecl,
- std::vector<std::string> &TargetOpcodes,
- std::vector<std::string> &TargetVTs,
- bool &OutputIsVariadic,
- unsigned &NumInputRootOps);
- void EmitPatterns(std::vector<std::pair<const PatternToMatch*,
- std::vector<std::pair<unsigned, std::string> > > > &Patterns,
- unsigned Indent, raw_ostream &OS);
-
- void EmitInstructionSelector(raw_ostream &OS);
};
} // End llvm namespace
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
new file mode 100644
index 0000000..22d2fe8
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -0,0 +1,402 @@
+//===- DAGISelMatcher.cpp - Representation of DAG pattern matcher ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace llvm;
+
+void Matcher::dump() const {
+ print(errs(), 0);
+}
+
+void Matcher::print(raw_ostream &OS, unsigned indent) const {
+ printImpl(OS, indent);
+ if (Next)
+ return Next->print(OS, indent);
+}
+
+void Matcher::printOne(raw_ostream &OS) const {
+ printImpl(OS, 0);
+}
+
+/// unlinkNode - Unlink the specified node from this chain. If Other == this,
+/// we unlink the next pointer and return it. Otherwise we unlink Other from
+/// the list and return this.
+Matcher *Matcher::unlinkNode(Matcher *Other) {
+ if (this == Other)
+ return takeNext();
+
+ // Scan until we find the predecessor of Other.
+ Matcher *Cur = this;
+ for (; Cur && Cur->getNext() != Other; Cur = Cur->getNext())
+ /*empty*/;
+
+ if (Cur == 0) return 0;
+ Cur->takeNext();
+ Cur->setNext(Other->takeNext());
+ return this;
+}
+
+/// canMoveBefore - Return true if this matcher is the same as Other, or if
+/// we can move this matcher past all of the nodes in-between Other and this
+/// node. Other must be equal to or before this.
+bool Matcher::canMoveBefore(const Matcher *Other) const {
+ for (;; Other = Other->getNext()) {
+ assert(Other && "Other didn't come before 'this'?");
+ if (this == Other) return true;
+
+ // We have to be able to move this node across the Other node.
+ if (!canMoveBeforeNode(Other))
+ return false;
+ }
+}
+
+/// canMoveBefore - Return true if it is safe to move the current matcher
+/// across the specified one.
+bool Matcher::canMoveBeforeNode(const Matcher *Other) const {
+ // We can move simple predicates before record nodes.
+ if (isSimplePredicateNode())
+ return Other->isSimplePredicateOrRecordNode();
+
+ // We can move record nodes across simple predicates.
+ if (isSimplePredicateOrRecordNode())
+ return isSimplePredicateNode();
+
+ // We can't move record nodes across each other etc.
+ return false;
+}
+
+
+ScopeMatcher::~ScopeMatcher() {
+ for (unsigned i = 0, e = Children.size(); i != e; ++i)
+ delete Children[i];
+}
+
+
+// printImpl methods.
+
+void ScopeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "Scope\n";
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+ if (getChild(i) == 0)
+ OS.indent(indent+1) << "NULL POINTER\n";
+ else
+ getChild(i)->print(OS, indent+2);
+ }
+}
+
+void RecordMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "Record\n";
+}
+
+void RecordChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "RecordChild: " << ChildNo << '\n';
+}
+
+void RecordMemRefMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "RecordMemRef\n";
+}
+
+void CaptureFlagInputMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
+ OS.indent(indent) << "CaptureFlagInput\n";
+}
+
+void MoveChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "MoveChild " << ChildNo << '\n';
+}
+
+void MoveParentMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "MoveParent\n";
+}
+
+void CheckSameMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckSame " << MatchNumber << '\n';
+}
+
+void CheckPatternPredicateMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckPatternPredicate " << Predicate << '\n';
+}
+
+void CheckPredicateMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckPredicate " << PredName << '\n';
+}
+
+void CheckOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckOpcode " << Opcode.getEnumName() << '\n';
+}
+
+void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "SwitchOpcode: {\n";
+ for (unsigned i = 0, e = Cases.size(); i != e; ++i) {
+ OS.indent(indent) << "case " << Cases[i].first->getEnumName() << ":\n";
+ Cases[i].second->print(OS, indent+2);
+ }
+ OS.indent(indent) << "}\n";
+}
+
+
+void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
+}
+
+void SwitchTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "SwitchType: {\n";
+ for (unsigned i = 0, e = Cases.size(); i != e; ++i) {
+ OS.indent(indent) << "case " << getEnumName(Cases[i].first) << ":\n";
+ Cases[i].second->print(OS, indent+2);
+ }
+ OS.indent(indent) << "}\n";
+}
+
+void CheckChildTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckChildType " << ChildNo << " "
+ << getEnumName(Type) << '\n';
+}
+
+
+void CheckIntegerMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckInteger " << Value << '\n';
+}
+
+void CheckCondCodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckCondCode ISD::" << CondCodeName << '\n';
+}
+
+void CheckValueTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckValueType MVT::" << TypeName << '\n';
+}
+
+void CheckComplexPatMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckComplexPat " << Pattern.getSelectFunc() << '\n';
+}
+
+void CheckAndImmMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckAndImm " << Value << '\n';
+}
+
+void CheckOrImmMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckOrImm " << Value << '\n';
+}
+
+void CheckFoldableChainNodeMatcher::printImpl(raw_ostream &OS,
+ unsigned indent) const {
+ OS.indent(indent) << "CheckFoldableChainNode\n";
+}
+
+void EmitIntegerMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitInteger " << Val << " VT=" << VT << '\n';
+}
+
+void EmitStringIntegerMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitStringInteger " << Val << " VT=" << VT << '\n';
+}
+
+void EmitRegisterMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitRegister ";
+ if (Reg)
+ OS << Reg->getName();
+ else
+ OS << "zero_reg";
+ OS << " VT=" << VT << '\n';
+}
+
+void EmitConvertToTargetMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitConvertToTarget " << Slot << '\n';
+}
+
+void EmitMergeInputChainsMatcher::
+printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitMergeInputChains <todo: args>\n";
+}
+
+void EmitCopyToRegMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitCopyToReg <todo: args>\n";
+}
+
+void EmitNodeXFormMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitNodeXForm " << NodeXForm->getName()
+ << " Slot=" << Slot << '\n';
+}
+
+
+void EmitNodeMatcherCommon::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent);
+ OS << (isa<MorphNodeToMatcher>(this) ? "MorphNodeTo: " : "EmitNode: ")
+ << OpcodeName << ": <todo flags> ";
+
+ for (unsigned i = 0, e = VTs.size(); i != e; ++i)
+ OS << ' ' << getEnumName(VTs[i]);
+ OS << '(';
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ OS << Operands[i] << ' ';
+ OS << ")\n";
+}
+
+void MarkFlagResultsMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "MarkFlagResults <todo: args>\n";
+}
+
+void CompleteMatchMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CompleteMatch <todo args>\n";
+ OS.indent(indent) << "Src = " << *Pattern.getSrcPattern() << "\n";
+ OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
+}
+
+// getHashImpl Implementation.
+
+unsigned CheckPatternPredicateMatcher::getHashImpl() const {
+ return HashString(Predicate);
+}
+
+unsigned CheckPredicateMatcher::getHashImpl() const {
+ return HashString(PredName);
+}
+
+unsigned CheckOpcodeMatcher::getHashImpl() const {
+ return HashString(Opcode.getEnumName());
+}
+
+unsigned CheckCondCodeMatcher::getHashImpl() const {
+ return HashString(CondCodeName);
+}
+
+unsigned CheckValueTypeMatcher::getHashImpl() const {
+ return HashString(TypeName);
+}
+
+unsigned EmitStringIntegerMatcher::getHashImpl() const {
+ return HashString(Val) ^ VT;
+}
+
+template<typename It>
+static unsigned HashUnsigneds(It I, It E) {
+ unsigned Result = 0;
+ for (; I != E; ++I)
+ Result = (Result<<3) ^ *I;
+ return Result;
+}
+
+unsigned EmitMergeInputChainsMatcher::getHashImpl() const {
+ return HashUnsigneds(ChainNodes.begin(), ChainNodes.end());
+}
+
+bool CheckOpcodeMatcher::isEqualImpl(const Matcher *M) const {
+ // Note: pointer equality isn't enough here, we have to check the enum names
+ // to ensure that the nodes are for the same opcode.
+ return cast<CheckOpcodeMatcher>(M)->Opcode.getEnumName() ==
+ Opcode.getEnumName();
+}
+
+
+bool EmitNodeMatcherCommon::isEqualImpl(const Matcher *m) const {
+ const EmitNodeMatcherCommon *M = cast<EmitNodeMatcherCommon>(m);
+ return M->OpcodeName == OpcodeName && M->VTs == VTs &&
+ M->Operands == Operands && M->HasChain == HasChain &&
+ M->HasInFlag == HasInFlag && M->HasOutFlag == HasOutFlag &&
+ M->HasMemRefs == HasMemRefs &&
+ M->NumFixedArityOperands == NumFixedArityOperands;
+}
+
+unsigned EmitNodeMatcherCommon::getHashImpl() const {
+ return (HashString(OpcodeName) << 4) | Operands.size();
+}
+
+
+unsigned MarkFlagResultsMatcher::getHashImpl() const {
+ return HashUnsigneds(FlagResultNodes.begin(), FlagResultNodes.end());
+}
+
+unsigned CompleteMatchMatcher::getHashImpl() const {
+ return HashUnsigneds(Results.begin(), Results.end()) ^
+ ((unsigned)(intptr_t)&Pattern << 8);
+}
+
+// isContradictoryImpl Implementations.
+
+static bool TypesAreContradictory(MVT::SimpleValueType T1,
+ MVT::SimpleValueType T2) {
+ // If the two types are the same, then they are the same, so they don't
+ // contradict.
+ if (T1 == T2) return false;
+
+ // If either type is about iPtr, then they don't conflict unless the other
+ // one is not a scalar integer type.
+ if (T1 == MVT::iPTR)
+ return !MVT(T2).isInteger() || MVT(T2).isVector();
+
+ if (T2 == MVT::iPTR)
+ return !MVT(T1).isInteger() || MVT(T1).isVector();
+
+ // Otherwise, they are two different non-iPTR types, they conflict.
+ return true;
+}
+
+bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) {
+ // One node can't have two different opcodes!
+ // Note: pointer equality isn't enough here, we have to check the enum names
+ // to ensure that the nodes are for the same opcode.
+ return COM->getOpcode().getEnumName() != getOpcode().getEnumName();
+ }
+
+ // If the node has a known type, and if the type we're checking for is
+ // different, then we know they contradict. For example, a check for
+ // ISD::STORE will never be true at the same time a check for Type i32 is.
+ if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) {
+ // FIXME: What result is this referring to?
+ unsigned NodeType;
+ if (getOpcode().getNumResults() == 0)
+ NodeType = MVT::isVoid;
+ else
+ NodeType = getOpcode().getKnownType();
+ if (NodeType != EEVT::isUnknown)
+ return TypesAreContradictory((MVT::SimpleValueType)NodeType,
+ CT->getType());
+ }
+
+ return false;
+}
+
+bool CheckTypeMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M))
+ return TypesAreContradictory(getType(), CT->getType());
+ return false;
+}
+
+bool CheckChildTypeMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const CheckChildTypeMatcher *CC = dyn_cast<CheckChildTypeMatcher>(M)) {
+ // If the two checks are about different nodes, we don't know if they
+ // conflict!
+ if (CC->getChildNo() != getChildNo())
+ return false;
+
+ return TypesAreContradictory(getType(), CC->getType());
+ }
+ return false;
+}
+
+bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const CheckIntegerMatcher *CIM = dyn_cast<CheckIntegerMatcher>(M))
+ return CIM->getValue() != getValue();
+ return false;
+}
+
+bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M))
+ return CVT->getTypeName() != getTypeName();
+ return false;
+}
+
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
new file mode 100644
index 0000000..ef7ecf4
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -0,0 +1,1112 @@
+//===- DAGISelMatcher.h - Representation of DAG pattern matcher -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TBLGEN_DAGISELMATCHER_H
+#define TBLGEN_DAGISELMATCHER_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+ class CodeGenDAGPatterns;
+ class Matcher;
+ class PatternToMatch;
+ class raw_ostream;
+ class ComplexPattern;
+ class Record;
+ class SDNodeInfo;
+
+Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
+ const CodeGenDAGPatterns &CGP);
+Matcher *OptimizeMatcher(Matcher *Matcher, const CodeGenDAGPatterns &CGP);
+void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
+ raw_ostream &OS);
+
+
+/// Matcher - Base class for all the the DAG ISel Matcher representation
+/// nodes.
+class Matcher {
+ // The next matcher node that is executed after this one. Null if this is the
+ // last stage of a match.
+ OwningPtr<Matcher> Next;
+public:
+ enum KindTy {
+ // Matcher state manipulation.
+ Scope, // Push a checking scope.
+ RecordNode, // Record the current node.
+ RecordChild, // Record a child of the current node.
+ RecordMemRef, // Record the memref in the current node.
+ CaptureFlagInput, // If the current node has an input flag, save it.
+ MoveChild, // Move current node to specified child.
+ MoveParent, // Move current node to parent.
+
+ // Predicate checking.
+ CheckSame, // Fail if not same as prev match.
+ CheckPatternPredicate,
+ CheckPredicate, // Fail if node predicate fails.
+ CheckOpcode, // Fail if not opcode.
+ SwitchOpcode, // Dispatch based on opcode.
+ CheckType, // Fail if not correct type.
+ SwitchType, // Dispatch based on type.
+ CheckChildType, // Fail if child has wrong type.
+ CheckInteger, // Fail if wrong val.
+ CheckCondCode, // Fail if not condcode.
+ CheckValueType,
+ CheckComplexPat,
+ CheckAndImm,
+ CheckOrImm,
+ CheckFoldableChainNode,
+
+ // Node creation/emisssion.
+ EmitInteger, // Create a TargetConstant
+ EmitStringInteger, // Create a TargetConstant from a string.
+ EmitRegister, // Create a register.
+ EmitConvertToTarget, // Convert a imm/fpimm to target imm/fpimm
+ EmitMergeInputChains, // Merge together a chains for an input.
+ EmitCopyToReg, // Emit a copytoreg into a physreg.
+ EmitNode, // Create a DAG node
+ EmitNodeXForm, // Run a SDNodeXForm
+ MarkFlagResults, // Indicate which interior nodes have flag results.
+ CompleteMatch, // Finish a match and update the results.
+ MorphNodeTo // Build a node, finish a match and update results.
+ };
+ const KindTy Kind;
+
+protected:
+ Matcher(KindTy K) : Kind(K) {}
+public:
+ virtual ~Matcher() {}
+
+ KindTy getKind() const { return Kind; }
+
+ Matcher *getNext() { return Next.get(); }
+ const Matcher *getNext() const { return Next.get(); }
+ void setNext(Matcher *C) { Next.reset(C); }
+ Matcher *takeNext() { return Next.take(); }
+
+ OwningPtr<Matcher> &getNextPtr() { return Next; }
+
+ static inline bool classof(const Matcher *) { return true; }
+
+ bool isEqual(const Matcher *M) const {
+ if (getKind() != M->getKind()) return false;
+ return isEqualImpl(M);
+ }
+
+ unsigned getHash() const {
+ // Clear the high bit so we don't conflict with tombstones etc.
+ return ((getHashImpl() << 4) ^ getKind()) & (~0U>>1);
+ }
+
+ /// isSafeToReorderWithPatternPredicate - Return true if it is safe to sink a
+ /// PatternPredicate node past this one.
+ virtual bool isSafeToReorderWithPatternPredicate() const {
+ return false;
+ }
+
+ /// isSimplePredicateNode - Return true if this is a simple predicate that
+ /// operates on the node or its children without potential side effects or a
+ /// change of the current node.
+ bool isSimplePredicateNode() const {
+ switch (getKind()) {
+ default: return false;
+ case CheckSame:
+ case CheckPatternPredicate:
+ case CheckPredicate:
+ case CheckOpcode:
+ case CheckType:
+ case CheckChildType:
+ case CheckInteger:
+ case CheckCondCode:
+ case CheckValueType:
+ case CheckAndImm:
+ case CheckOrImm:
+ case CheckFoldableChainNode:
+ return true;
+ }
+ }
+
+ /// isSimplePredicateOrRecordNode - Return true if this is a record node or
+ /// a simple predicate.
+ bool isSimplePredicateOrRecordNode() const {
+ return isSimplePredicateNode() ||
+ getKind() == RecordNode || getKind() == RecordChild;
+ }
+
+ /// unlinkNode - Unlink the specified node from this chain. If Other == this,
+ /// we unlink the next pointer and return it. Otherwise we unlink Other from
+ /// the list and return this.
+ Matcher *unlinkNode(Matcher *Other);
+
+ /// canMoveBefore - Return true if this matcher is the same as Other, or if
+ /// we can move this matcher past all of the nodes in-between Other and this
+ /// node. Other must be equal to or before this.
+ bool canMoveBefore(const Matcher *Other) const;
+
+ /// canMoveBefore - Return true if it is safe to move the current matcher
+ /// across the specified one.
+ bool canMoveBeforeNode(const Matcher *Other) const;
+
+ /// isContradictory - Return true of these two matchers could never match on
+ /// the same node.
+ bool isContradictory(const Matcher *Other) const {
+ // Since this predicate is reflexive, we canonicalize the ordering so that
+ // we always match a node against nodes with kinds that are greater or equal
+ // to them. For example, we'll pass in a CheckType node as an argument to
+ // the CheckOpcode method, not the other way around.
+ if (getKind() < Other->getKind())
+ return isContradictoryImpl(Other);
+ return Other->isContradictoryImpl(this);
+ }
+
+ void print(raw_ostream &OS, unsigned indent = 0) const;
+ void printOne(raw_ostream &OS) const;
+ void dump() const;
+protected:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const = 0;
+ virtual bool isEqualImpl(const Matcher *M) const = 0;
+ virtual unsigned getHashImpl() const = 0;
+ virtual bool isContradictoryImpl(const Matcher *M) const { return false; }
+};
+
+/// ScopeMatcher - This attempts to match each of its children to find the first
+/// one that successfully matches. If one child fails, it tries the next child.
+/// If none of the children match then this check fails. It never has a 'next'.
+class ScopeMatcher : public Matcher {
+ SmallVector<Matcher*, 4> Children;
+public:
+ ScopeMatcher(Matcher *const *children, unsigned numchildren)
+ : Matcher(Scope), Children(children, children+numchildren) {
+ }
+ virtual ~ScopeMatcher();
+
+ unsigned getNumChildren() const { return Children.size(); }
+
+ Matcher *getChild(unsigned i) { return Children[i]; }
+ const Matcher *getChild(unsigned i) const { return Children[i]; }
+
+ void resetChild(unsigned i, Matcher *N) {
+ delete Children[i];
+ Children[i] = N;
+ }
+
+ Matcher *takeChild(unsigned i) {
+ Matcher *Res = Children[i];
+ Children[i] = 0;
+ return Res;
+ }
+
+ void setNumChildren(unsigned NC) {
+ if (NC < Children.size()) {
+ // delete any children we're about to lose pointers to.
+ for (unsigned i = NC, e = Children.size(); i != e; ++i)
+ delete Children[i];
+ }
+ Children.resize(NC);
+ }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == Scope;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return false; }
+ virtual unsigned getHashImpl() const { return 12312; }
+};
+
+/// RecordMatcher - Save the current node in the operand list.
+class RecordMatcher : public Matcher {
+ /// WhatFor - This is a string indicating why we're recording this. This
+ /// should only be used for comment generation not anything semantic.
+ std::string WhatFor;
+
+ /// ResultNo - The slot number in the RecordedNodes vector that this will be,
+ /// just printed as a comment.
+ unsigned ResultNo;
+public:
+ RecordMatcher(const std::string &whatfor, unsigned resultNo)
+ : Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {}
+
+ const std::string &getWhatFor() const { return WhatFor; }
+ unsigned getResultNo() const { return ResultNo; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == RecordNode;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return true; }
+ virtual unsigned getHashImpl() const { return 0; }
+};
+
+/// RecordChildMatcher - Save a numbered child of the current node, or fail
+/// the match if it doesn't exist. This is logically equivalent to:
+/// MoveChild N + RecordNode + MoveParent.
+class RecordChildMatcher : public Matcher {
+ unsigned ChildNo;
+
+ /// WhatFor - This is a string indicating why we're recording this. This
+ /// should only be used for comment generation not anything semantic.
+ std::string WhatFor;
+
+ /// ResultNo - The slot number in the RecordedNodes vector that this will be,
+ /// just printed as a comment.
+ unsigned ResultNo;
+public:
+ RecordChildMatcher(unsigned childno, const std::string &whatfor,
+ unsigned resultNo)
+ : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor),
+ ResultNo(resultNo) {}
+
+ unsigned getChildNo() const { return ChildNo; }
+ const std::string &getWhatFor() const { return WhatFor; }
+ unsigned getResultNo() const { return ResultNo; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == RecordChild;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<RecordChildMatcher>(M)->getChildNo() == getChildNo();
+ }
+ virtual unsigned getHashImpl() const { return getChildNo(); }
+};
+
+/// RecordMemRefMatcher - Save the current node's memref.
+class RecordMemRefMatcher : public Matcher {
+public:
+ RecordMemRefMatcher() : Matcher(RecordMemRef) {}
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == RecordMemRef;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return true; }
+ virtual unsigned getHashImpl() const { return 0; }
+};
+
+
+/// CaptureFlagInputMatcher - If the current record has a flag input, record
+/// it so that it is used as an input to the generated code.
+class CaptureFlagInputMatcher : public Matcher {
+public:
+ CaptureFlagInputMatcher() : Matcher(CaptureFlagInput) {}
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CaptureFlagInput;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return true; }
+ virtual unsigned getHashImpl() const { return 0; }
+};
+
+/// MoveChildMatcher - This tells the interpreter to move into the
+/// specified child node.
+class MoveChildMatcher : public Matcher {
+ unsigned ChildNo;
+public:
+ MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {}
+
+ unsigned getChildNo() const { return ChildNo; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == MoveChild;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<MoveChildMatcher>(M)->getChildNo() == getChildNo();
+ }
+ virtual unsigned getHashImpl() const { return getChildNo(); }
+};
+
+/// MoveParentMatcher - This tells the interpreter to move to the parent
+/// of the current node.
+class MoveParentMatcher : public Matcher {
+public:
+ MoveParentMatcher() : Matcher(MoveParent) {}
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == MoveParent;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return true; }
+ virtual unsigned getHashImpl() const { return 0; }
+};
+
+/// CheckSameMatcher - This checks to see if this node is exactly the same
+/// node as the specified match that was recorded with 'Record'. This is used
+/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
+class CheckSameMatcher : public Matcher {
+ unsigned MatchNumber;
+public:
+ CheckSameMatcher(unsigned matchnumber)
+ : Matcher(CheckSame), MatchNumber(matchnumber) {}
+
+ unsigned getMatchNumber() const { return MatchNumber; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckSame;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckSameMatcher>(M)->getMatchNumber() == getMatchNumber();
+ }
+ virtual unsigned getHashImpl() const { return getMatchNumber(); }
+};
+
+/// CheckPatternPredicateMatcher - This checks the target-specific predicate
+/// to see if the entire pattern is capable of matching. This predicate does
+/// not take a node as input. This is used for subtarget feature checks etc.
+class CheckPatternPredicateMatcher : public Matcher {
+ std::string Predicate;
+public:
+ CheckPatternPredicateMatcher(StringRef predicate)
+ : Matcher(CheckPatternPredicate), Predicate(predicate) {}
+
+ StringRef getPredicate() const { return Predicate; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckPatternPredicate;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckPatternPredicateMatcher>(M)->getPredicate() == Predicate;
+ }
+ virtual unsigned getHashImpl() const;
+};
+
+/// CheckPredicateMatcher - This checks the target-specific predicate to
+/// see if the node is acceptable.
+class CheckPredicateMatcher : public Matcher {
+ StringRef PredName;
+public:
+ CheckPredicateMatcher(StringRef predname)
+ : Matcher(CheckPredicate), PredName(predname) {}
+
+ StringRef getPredicateName() const { return PredName; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckPredicate;
+ }
+
+ // TODO: Ok?
+ //virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckPredicateMatcher>(M)->PredName == PredName;
+ }
+ virtual unsigned getHashImpl() const;
+};
+
+
+/// CheckOpcodeMatcher - This checks to see if the current node has the
+/// specified opcode, if not it fails to match.
+class CheckOpcodeMatcher : public Matcher {
+ const SDNodeInfo &Opcode;
+public:
+ CheckOpcodeMatcher(const SDNodeInfo &opcode)
+ : Matcher(CheckOpcode), Opcode(opcode) {}
+
+ const SDNodeInfo &getOpcode() const { return Opcode; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckOpcode;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const;
+ virtual unsigned getHashImpl() const;
+ virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+
+/// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching
+/// to one matcher per opcode. If the opcode doesn't match any of the cases,
+/// then the match fails. This is semantically equivalent to a Scope node where
+/// every child does a CheckOpcode, but is much faster.
+class SwitchOpcodeMatcher : public Matcher {
+ SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases;
+public:
+ SwitchOpcodeMatcher(const std::pair<const SDNodeInfo*, Matcher*> *cases,
+ unsigned numcases)
+ : Matcher(SwitchOpcode), Cases(cases, cases+numcases) {}
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == SwitchOpcode;
+ }
+
+ unsigned getNumCases() const { return Cases.size(); }
+
+ const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; }
+ Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
+ const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return false; }
+ virtual unsigned getHashImpl() const { return 4123; }
+};
+
+/// CheckTypeMatcher - This checks to see if the current node has the
+/// specified type, if not it fails to match.
+class CheckTypeMatcher : public Matcher {
+ MVT::SimpleValueType Type;
+public:
+ CheckTypeMatcher(MVT::SimpleValueType type)
+ : Matcher(CheckType), Type(type) {}
+
+ MVT::SimpleValueType getType() const { return Type; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckType;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckTypeMatcher>(M)->Type == Type;
+ }
+ virtual unsigned getHashImpl() const { return Type; }
+ virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+
+/// SwitchTypeMatcher - Switch based on the current node's type, dispatching
+/// to one matcher per case. If the type doesn't match any of the cases,
+/// then the match fails. This is semantically equivalent to a Scope node where
+/// every child does a CheckType, but is much faster.
+class SwitchTypeMatcher : public Matcher {
+ SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
+public:
+ SwitchTypeMatcher(const std::pair<MVT::SimpleValueType, Matcher*> *cases,
+ unsigned numcases)
+ : Matcher(SwitchType), Cases(cases, cases+numcases) {}
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == SwitchType;
+ }
+
+ unsigned getNumCases() const { return Cases.size(); }
+
+ MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; }
+ Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
+ const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return false; }
+ virtual unsigned getHashImpl() const { return 4123; }
+};
+
+
+/// CheckChildTypeMatcher - This checks to see if a child node has the
+/// specified type, if not it fails to match.
+class CheckChildTypeMatcher : public Matcher {
+ unsigned ChildNo;
+ MVT::SimpleValueType Type;
+public:
+ CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type)
+ : Matcher(CheckChildType), ChildNo(childno), Type(type) {}
+
+ unsigned getChildNo() const { return ChildNo; }
+ MVT::SimpleValueType getType() const { return Type; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckChildType;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckChildTypeMatcher>(M)->ChildNo == ChildNo &&
+ cast<CheckChildTypeMatcher>(M)->Type == Type;
+ }
+ virtual unsigned getHashImpl() const { return (Type << 3) | ChildNo; }
+ virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+
+
+/// CheckIntegerMatcher - This checks to see if the current node is a
+/// ConstantSDNode with the specified integer value, if not it fails to match.
+class CheckIntegerMatcher : public Matcher {
+ int64_t Value;
+public:
+ CheckIntegerMatcher(int64_t value)
+ : Matcher(CheckInteger), Value(value) {}
+
+ int64_t getValue() const { return Value; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckInteger;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckIntegerMatcher>(M)->Value == Value;
+ }
+ virtual unsigned getHashImpl() const { return Value; }
+ virtual bool isContradictoryImpl(const Matcher *M) const;
+};
+
+/// CheckCondCodeMatcher - This checks to see if the current node is a
+/// CondCodeSDNode with the specified condition, if not it fails to match.
+class CheckCondCodeMatcher : public Matcher {
+ StringRef CondCodeName;
+public:
+ CheckCondCodeMatcher(StringRef condcodename)
+ : Matcher(CheckCondCode), CondCodeName(condcodename) {}
+
+ StringRef getCondCodeName() const { return CondCodeName; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckCondCode;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckCondCodeMatcher>(M)->CondCodeName == CondCodeName;
+ }
+ virtual unsigned getHashImpl() const;
+};
+
+/// CheckValueTypeMatcher - This checks to see if the current node is a
+/// VTSDNode with the specified type, if not it fails to match.
+class CheckValueTypeMatcher : public Matcher {
+ StringRef TypeName;
+public:
+ CheckValueTypeMatcher(StringRef type_name)
+ : Matcher(CheckValueType), TypeName(type_name) {}
+
+ StringRef getTypeName() const { return TypeName; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckValueType;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckValueTypeMatcher>(M)->TypeName == TypeName;
+ }
+ virtual unsigned getHashImpl() const;
+ bool isContradictoryImpl(const Matcher *M) const;
+};
+
+
+
+/// CheckComplexPatMatcher - This node runs the specified ComplexPattern on
+/// the current node.
+class CheckComplexPatMatcher : public Matcher {
+ const ComplexPattern &Pattern;
+
+ /// MatchNumber - This is the recorded nodes slot that contains the node we want to
+ /// match against.
+ unsigned MatchNumber;
+
+ /// Name - The name of the node we're matching, for comment emission.
+ std::string Name;
+
+ /// FirstResult - This is the first slot in the RecordedNodes list that the
+ /// result of the match populates.
+ unsigned FirstResult;
+public:
+ CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber,
+ const std::string &name, unsigned firstresult)
+ : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber),
+ Name(name), FirstResult(firstresult) {}
+
+ const ComplexPattern &getPattern() const { return Pattern; }
+ unsigned getMatchNumber() const { return MatchNumber; }
+
+ const std::string getName() const { return Name; }
+ unsigned getFirstResult() const { return FirstResult; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckComplexPat;
+ }
+
+ // Not safe to move a pattern predicate past a complex pattern.
+ virtual bool isSafeToReorderWithPatternPredicate() const { return false; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern &&
+ cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber;
+ }
+ virtual unsigned getHashImpl() const {
+ return (unsigned)(intptr_t)&Pattern ^ MatchNumber;
+ }
+};
+
+/// CheckAndImmMatcher - This checks to see if the current node is an 'and'
+/// with something equivalent to the specified immediate.
+class CheckAndImmMatcher : public Matcher {
+ int64_t Value;
+public:
+ CheckAndImmMatcher(int64_t value)
+ : Matcher(CheckAndImm), Value(value) {}
+
+ int64_t getValue() const { return Value; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckAndImm;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckAndImmMatcher>(M)->Value == Value;
+ }
+ virtual unsigned getHashImpl() const { return Value; }
+};
+
+/// CheckOrImmMatcher - This checks to see if the current node is an 'and'
+/// with something equivalent to the specified immediate.
+class CheckOrImmMatcher : public Matcher {
+ int64_t Value;
+public:
+ CheckOrImmMatcher(int64_t value)
+ : Matcher(CheckOrImm), Value(value) {}
+
+ int64_t getValue() const { return Value; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckOrImm;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CheckOrImmMatcher>(M)->Value == Value;
+ }
+ virtual unsigned getHashImpl() const { return Value; }
+};
+
+/// CheckFoldableChainNodeMatcher - This checks to see if the current node
+/// (which defines a chain operand) is safe to fold into a larger pattern.
+class CheckFoldableChainNodeMatcher : public Matcher {
+public:
+ CheckFoldableChainNodeMatcher()
+ : Matcher(CheckFoldableChainNode) {}
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckFoldableChainNode;
+ }
+
+ virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return true; }
+ virtual unsigned getHashImpl() const { return 0; }
+};
+
+/// EmitIntegerMatcher - This creates a new TargetConstant.
+class EmitIntegerMatcher : public Matcher {
+ int64_t Val;
+ MVT::SimpleValueType VT;
+public:
+ EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt)
+ : Matcher(EmitInteger), Val(val), VT(vt) {}
+
+ int64_t getValue() const { return Val; }
+ MVT::SimpleValueType getVT() const { return VT; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitInteger;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<EmitIntegerMatcher>(M)->Val == Val &&
+ cast<EmitIntegerMatcher>(M)->VT == VT;
+ }
+ virtual unsigned getHashImpl() const { return (Val << 4) | VT; }
+};
+
+/// EmitStringIntegerMatcher - A target constant whose value is represented
+/// by a string.
+class EmitStringIntegerMatcher : public Matcher {
+ std::string Val;
+ MVT::SimpleValueType VT;
+public:
+ EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt)
+ : Matcher(EmitStringInteger), Val(val), VT(vt) {}
+
+ const std::string &getValue() const { return Val; }
+ MVT::SimpleValueType getVT() const { return VT; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitStringInteger;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<EmitStringIntegerMatcher>(M)->Val == Val &&
+ cast<EmitStringIntegerMatcher>(M)->VT == VT;
+ }
+ virtual unsigned getHashImpl() const;
+};
+
+/// EmitRegisterMatcher - This creates a new TargetConstant.
+class EmitRegisterMatcher : public Matcher {
+ /// Reg - The def for the register that we're emitting. If this is null, then
+ /// this is a reference to zero_reg.
+ Record *Reg;
+ MVT::SimpleValueType VT;
+public:
+ EmitRegisterMatcher(Record *reg, MVT::SimpleValueType vt)
+ : Matcher(EmitRegister), Reg(reg), VT(vt) {}
+
+ Record *getReg() const { return Reg; }
+ MVT::SimpleValueType getVT() const { return VT; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitRegister;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<EmitRegisterMatcher>(M)->Reg == Reg &&
+ cast<EmitRegisterMatcher>(M)->VT == VT;
+ }
+ virtual unsigned getHashImpl() const {
+ return ((unsigned)(intptr_t)Reg) << 4 | VT;
+ }
+};
+
+/// EmitConvertToTargetMatcher - Emit an operation that reads a specified
+/// recorded node and converts it from being a ISD::Constant to
+/// ISD::TargetConstant, likewise for ConstantFP.
+class EmitConvertToTargetMatcher : public Matcher {
+ unsigned Slot;
+public:
+ EmitConvertToTargetMatcher(unsigned slot)
+ : Matcher(EmitConvertToTarget), Slot(slot) {}
+
+ unsigned getSlot() const { return Slot; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitConvertToTarget;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<EmitConvertToTargetMatcher>(M)->Slot == Slot;
+ }
+ virtual unsigned getHashImpl() const { return Slot; }
+};
+
+/// EmitMergeInputChainsMatcher - Emit a node that merges a list of input
+/// chains together with a token factor. The list of nodes are the nodes in the
+/// matched pattern that have chain input/outputs. This node adds all input
+/// chains of these nodes if they are not themselves a node in the pattern.
+class EmitMergeInputChainsMatcher : public Matcher {
+ SmallVector<unsigned, 3> ChainNodes;
+public:
+ EmitMergeInputChainsMatcher(const unsigned *nodes, unsigned NumNodes)
+ : Matcher(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {}
+
+ unsigned getNumNodes() const { return ChainNodes.size(); }
+
+ unsigned getNode(unsigned i) const {
+ assert(i < ChainNodes.size());
+ return ChainNodes[i];
+ }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitMergeInputChains;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<EmitMergeInputChainsMatcher>(M)->ChainNodes == ChainNodes;
+ }
+ virtual unsigned getHashImpl() const;
+};
+
+/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,
+/// pushing the chain and flag results.
+///
+class EmitCopyToRegMatcher : public Matcher {
+ unsigned SrcSlot; // Value to copy into the physreg.
+ Record *DestPhysReg;
+public:
+ EmitCopyToRegMatcher(unsigned srcSlot, Record *destPhysReg)
+ : Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}
+
+ unsigned getSrcSlot() const { return SrcSlot; }
+ Record *getDestPhysReg() const { return DestPhysReg; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitCopyToReg;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<EmitCopyToRegMatcher>(M)->SrcSlot == SrcSlot &&
+ cast<EmitCopyToRegMatcher>(M)->DestPhysReg == DestPhysReg;
+ }
+ virtual unsigned getHashImpl() const {
+ return SrcSlot ^ ((unsigned)(intptr_t)DestPhysReg << 4);
+ }
+};
+
+
+
+/// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a
+/// recorded node and records the result.
+class EmitNodeXFormMatcher : public Matcher {
+ unsigned Slot;
+ Record *NodeXForm;
+public:
+ EmitNodeXFormMatcher(unsigned slot, Record *nodeXForm)
+ : Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {}
+
+ unsigned getSlot() const { return Slot; }
+ Record *getNodeXForm() const { return NodeXForm; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitNodeXForm;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<EmitNodeXFormMatcher>(M)->Slot == Slot &&
+ cast<EmitNodeXFormMatcher>(M)->NodeXForm == NodeXForm;
+ }
+ virtual unsigned getHashImpl() const {
+ return Slot ^ ((unsigned)(intptr_t)NodeXForm << 4);
+ }
+};
+
+/// EmitNodeMatcherCommon - Common class shared between EmitNode and
+/// MorphNodeTo.
+class EmitNodeMatcherCommon : public Matcher {
+ std::string OpcodeName;
+ const SmallVector<MVT::SimpleValueType, 3> VTs;
+ const SmallVector<unsigned, 6> Operands;
+ bool HasChain, HasInFlag, HasOutFlag, HasMemRefs;
+
+ /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1.
+ /// If this is a varidic node, this is set to the number of fixed arity
+ /// operands in the root of the pattern. The rest are appended to this node.
+ int NumFixedArityOperands;
+public:
+ EmitNodeMatcherCommon(const std::string &opcodeName,
+ const MVT::SimpleValueType *vts, unsigned numvts,
+ const unsigned *operands, unsigned numops,
+ bool hasChain, bool hasInFlag, bool hasOutFlag,
+ bool hasmemrefs,
+ int numfixedarityoperands, bool isMorphNodeTo)
+ : Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), OpcodeName(opcodeName),
+ VTs(vts, vts+numvts), Operands(operands, operands+numops),
+ HasChain(hasChain), HasInFlag(hasInFlag), HasOutFlag(hasOutFlag),
+ HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {}
+
+ const std::string &getOpcodeName() const { return OpcodeName; }
+
+ unsigned getNumVTs() const { return VTs.size(); }
+ MVT::SimpleValueType getVT(unsigned i) const {
+ assert(i < VTs.size());
+ return VTs[i];
+ }
+
+ unsigned getNumOperands() const { return Operands.size(); }
+ unsigned getOperand(unsigned i) const {
+ assert(i < Operands.size());
+ return Operands[i];
+ }
+
+ const SmallVectorImpl<MVT::SimpleValueType> &getVTList() const { return VTs; }
+ const SmallVectorImpl<unsigned> &getOperandList() const { return Operands; }
+
+
+ bool hasChain() const { return HasChain; }
+ bool hasInFlag() const { return HasInFlag; }
+ bool hasOutFlag() const { return HasOutFlag; }
+ bool hasMemRefs() const { return HasMemRefs; }
+ int getNumFixedArityOperands() const { return NumFixedArityOperands; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitNode || N->getKind() == MorphNodeTo;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const;
+ virtual unsigned getHashImpl() const;
+};
+
+/// EmitNodeMatcher - This signals a successful match and generates a node.
+class EmitNodeMatcher : public EmitNodeMatcherCommon {
+ unsigned FirstResultSlot;
+public:
+ EmitNodeMatcher(const std::string &opcodeName,
+ const MVT::SimpleValueType *vts, unsigned numvts,
+ const unsigned *operands, unsigned numops,
+ bool hasChain, bool hasInFlag, bool hasOutFlag,
+ bool hasmemrefs,
+ int numfixedarityoperands, unsigned firstresultslot)
+ : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
+ hasInFlag, hasOutFlag, hasmemrefs,
+ numfixedarityoperands, false),
+ FirstResultSlot(firstresultslot) {}
+
+ unsigned getFirstResultSlot() const { return FirstResultSlot; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == EmitNode;
+ }
+
+};
+
+class MorphNodeToMatcher : public EmitNodeMatcherCommon {
+ const PatternToMatch &Pattern;
+public:
+ MorphNodeToMatcher(const std::string &opcodeName,
+ const MVT::SimpleValueType *vts, unsigned numvts,
+ const unsigned *operands, unsigned numops,
+ bool hasChain, bool hasInFlag, bool hasOutFlag,
+ bool hasmemrefs,
+ int numfixedarityoperands, const PatternToMatch &pattern)
+ : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
+ hasInFlag, hasOutFlag, hasmemrefs,
+ numfixedarityoperands, true),
+ Pattern(pattern) {
+ }
+
+ const PatternToMatch &getPattern() const { return Pattern; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == MorphNodeTo;
+ }
+};
+
+/// MarkFlagResultsMatcher - This node indicates which non-root nodes in the
+/// pattern produce flags. This allows CompleteMatchMatcher to update them
+/// with the output flag of the resultant code.
+class MarkFlagResultsMatcher : public Matcher {
+ SmallVector<unsigned, 3> FlagResultNodes;
+public:
+ MarkFlagResultsMatcher(const unsigned *nodes, unsigned NumNodes)
+ : Matcher(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {}
+
+ unsigned getNumNodes() const { return FlagResultNodes.size(); }
+
+ unsigned getNode(unsigned i) const {
+ assert(i < FlagResultNodes.size());
+ return FlagResultNodes[i];
+ }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == MarkFlagResults;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<MarkFlagResultsMatcher>(M)->FlagResultNodes == FlagResultNodes;
+ }
+ virtual unsigned getHashImpl() const;
+};
+
+/// CompleteMatchMatcher - Complete a match by replacing the results of the
+/// pattern with the newly generated nodes. This also prints a comment
+/// indicating the source and dest patterns.
+class CompleteMatchMatcher : public Matcher {
+ SmallVector<unsigned, 2> Results;
+ const PatternToMatch &Pattern;
+public:
+ CompleteMatchMatcher(const unsigned *results, unsigned numresults,
+ const PatternToMatch &pattern)
+ : Matcher(CompleteMatch), Results(results, results+numresults),
+ Pattern(pattern) {}
+
+ unsigned getNumResults() const { return Results.size(); }
+ unsigned getResult(unsigned R) const { return Results[R]; }
+ const PatternToMatch &getPattern() const { return Pattern; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CompleteMatch;
+ }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const {
+ return cast<CompleteMatchMatcher>(M)->Results == Results &&
+ &cast<CompleteMatchMatcher>(M)->Pattern == &Pattern;
+ }
+ virtual unsigned getHashImpl() const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
new file mode 100644
index 0000000..cabf2d4
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -0,0 +1,779 @@
+//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains code to generate C++ code a matcher.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "Record.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormattedStream.h"
+using namespace llvm;
+
+enum {
+ CommentIndent = 30
+};
+
+// To reduce generated source code size.
+static cl::opt<bool>
+OmitComments("omit-comments", cl::desc("Do not generate comments"),
+ cl::init(false));
+
+namespace {
+class MatcherTableEmitter {
+ StringMap<unsigned> NodePredicateMap, PatternPredicateMap;
+ std::vector<std::string> NodePredicates, PatternPredicates;
+
+ DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
+ std::vector<const ComplexPattern*> ComplexPatterns;
+
+
+ DenseMap<Record*, unsigned> NodeXFormMap;
+ std::vector<Record*> NodeXForms;
+
+public:
+ MatcherTableEmitter() {}
+
+ unsigned EmitMatcherList(const Matcher *N, unsigned Indent,
+ unsigned StartIdx, formatted_raw_ostream &OS);
+
+ void EmitPredicateFunctions(const CodeGenDAGPatterns &CGP,
+ formatted_raw_ostream &OS);
+
+ void EmitHistogram(const Matcher *N, formatted_raw_ostream &OS);
+private:
+ unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
+ formatted_raw_ostream &OS);
+
+ unsigned getNodePredicate(StringRef PredName) {
+ unsigned &Entry = NodePredicateMap[PredName];
+ if (Entry == 0) {
+ NodePredicates.push_back(PredName.str());
+ Entry = NodePredicates.size();
+ }
+ return Entry-1;
+ }
+ unsigned getPatternPredicate(StringRef PredName) {
+ unsigned &Entry = PatternPredicateMap[PredName];
+ if (Entry == 0) {
+ PatternPredicates.push_back(PredName.str());
+ Entry = PatternPredicates.size();
+ }
+ return Entry-1;
+ }
+
+ unsigned getComplexPat(const ComplexPattern &P) {
+ unsigned &Entry = ComplexPatternMap[&P];
+ if (Entry == 0) {
+ ComplexPatterns.push_back(&P);
+ Entry = ComplexPatterns.size();
+ }
+ return Entry-1;
+ }
+
+ unsigned getNodeXFormID(Record *Rec) {
+ unsigned &Entry = NodeXFormMap[Rec];
+ if (Entry == 0) {
+ NodeXForms.push_back(Rec);
+ Entry = NodeXForms.size();
+ }
+ return Entry-1;
+ }
+
+};
+} // end anonymous namespace.
+
+static unsigned GetVBRSize(unsigned Val) {
+ if (Val <= 127) return 1;
+
+ unsigned NumBytes = 0;
+ while (Val >= 128) {
+ Val >>= 7;
+ ++NumBytes;
+ }
+ return NumBytes+1;
+}
+
+/// EmitVBRValue - Emit the specified value as a VBR, returning the number of
+/// bytes emitted.
+static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) {
+ if (Val <= 127) {
+ OS << Val << ", ";
+ return 1;
+ }
+
+ uint64_t InVal = Val;
+ unsigned NumBytes = 0;
+ while (Val >= 128) {
+ OS << (Val&127) << "|128,";
+ Val >>= 7;
+ ++NumBytes;
+ }
+ OS << Val;
+ if (!OmitComments)
+ OS << "/*" << InVal << "*/";
+ OS << ", ";
+ return NumBytes+1;
+}
+
+/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
+/// the number of bytes emitted.
+unsigned MatcherTableEmitter::
+EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
+ formatted_raw_ostream &OS) {
+ OS.PadToColumn(Indent*2);
+
+ switch (N->getKind()) {
+ case Matcher::Scope: {
+ const ScopeMatcher *SM = cast<ScopeMatcher>(N);
+ assert(SM->getNext() == 0 && "Shouldn't have next after scope");
+
+ unsigned StartIdx = CurrentIdx;
+
+ // Emit all of the children.
+ for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
+ if (i == 0) {
+ OS << "OPC_Scope, ";
+ ++CurrentIdx;
+ } else {
+ if (!OmitComments) {
+ OS << "/*" << CurrentIdx << "*/";
+ OS.PadToColumn(Indent*2) << "/*Scope*/ ";
+ } else
+ OS.PadToColumn(Indent*2);
+ }
+
+ // We need to encode the child and the offset of the failure code before
+ // emitting either of them. Handle this by buffering the output into a
+ // string while we get the size. Unfortunately, the offset of the
+ // children depends on the VBR size of the child, so for large children we
+ // have to iterate a bit.
+ SmallString<128> TmpBuf;
+ unsigned ChildSize = 0;
+ unsigned VBRSize = 0;
+ do {
+ VBRSize = GetVBRSize(ChildSize);
+
+ TmpBuf.clear();
+ raw_svector_ostream OS(TmpBuf);
+ formatted_raw_ostream FOS(OS);
+ ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
+ CurrentIdx+VBRSize, FOS);
+ } while (GetVBRSize(ChildSize) != VBRSize);
+
+ assert(ChildSize != 0 && "Should not have a zero-sized child!");
+
+ CurrentIdx += EmitVBRValue(ChildSize, OS);
+ if (!OmitComments) {
+ OS << "/*->" << CurrentIdx+ChildSize << "*/";
+
+ if (i == 0)
+ OS.PadToColumn(CommentIndent) << "// " << SM->getNumChildren()
+ << " children in Scope";
+ }
+
+ OS << '\n' << TmpBuf.str();
+ CurrentIdx += ChildSize;
+ }
+
+ // Emit a zero as a sentinel indicating end of 'Scope'.
+ if (!OmitComments)
+ OS << "/*" << CurrentIdx << "*/";
+ OS.PadToColumn(Indent*2) << "0, ";
+ if (!OmitComments)
+ OS << "/*End of Scope*/";
+ OS << '\n';
+ return CurrentIdx - StartIdx + 1;
+ }
+
+ case Matcher::RecordNode:
+ OS << "OPC_RecordNode,";
+ if (!OmitComments)
+ OS.PadToColumn(CommentIndent) << "// #"
+ << cast<RecordMatcher>(N)->getResultNo() << " = "
+ << cast<RecordMatcher>(N)->getWhatFor();
+ OS << '\n';
+ return 1;
+
+ case Matcher::RecordChild:
+ OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo()
+ << ',';
+ if (!OmitComments)
+ OS.PadToColumn(CommentIndent) << "// #"
+ << cast<RecordChildMatcher>(N)->getResultNo() << " = "
+ << cast<RecordChildMatcher>(N)->getWhatFor();
+ OS << '\n';
+ return 1;
+
+ case Matcher::RecordMemRef:
+ OS << "OPC_RecordMemRef,\n";
+ return 1;
+
+ case Matcher::CaptureFlagInput:
+ OS << "OPC_CaptureFlagInput,\n";
+ return 1;
+
+ case Matcher::MoveChild:
+ OS << "OPC_MoveChild, " << cast<MoveChildMatcher>(N)->getChildNo() << ",\n";
+ return 2;
+
+ case Matcher::MoveParent:
+ OS << "OPC_MoveParent,\n";
+ return 1;
+
+ case Matcher::CheckSame:
+ OS << "OPC_CheckSame, "
+ << cast<CheckSameMatcher>(N)->getMatchNumber() << ",\n";
+ return 2;
+
+ case Matcher::CheckPatternPredicate: {
+ StringRef Pred = cast<CheckPatternPredicateMatcher>(N)->getPredicate();
+ OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
+ if (!OmitComments)
+ OS.PadToColumn(CommentIndent) << "// " << Pred;
+ OS << '\n';
+ return 2;
+ }
+ case Matcher::CheckPredicate: {
+ StringRef Pred = cast<CheckPredicateMatcher>(N)->getPredicateName();
+ OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
+ if (!OmitComments)
+ OS.PadToColumn(CommentIndent) << "// " << Pred;
+ OS << '\n';
+ return 2;
+ }
+
+ case Matcher::CheckOpcode:
+ OS << "OPC_CheckOpcode, "
+ << cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << ",\n";
+ return 2;
+
+ case Matcher::SwitchOpcode:
+ case Matcher::SwitchType: {
+ unsigned StartIdx = CurrentIdx;
+
+ unsigned NumCases;
+ if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
+ OS << "OPC_SwitchOpcode ";
+ NumCases = SOM->getNumCases();
+ } else {
+ OS << "OPC_SwitchType ";
+ NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
+ }
+
+ if (!OmitComments)
+ OS << "/*" << NumCases << " cases */";
+ OS << ", ";
+ ++CurrentIdx;
+
+ // For each case we emit the size, then the opcode, then the matcher.
+ for (unsigned i = 0, e = NumCases; i != e; ++i) {
+ const Matcher *Child;
+ if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
+ Child = SOM->getCaseMatcher(i);
+ else
+ Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
+
+ // We need to encode the opcode and the offset of the case code before
+ // emitting the case code. Handle this by buffering the output into a
+ // string while we get the size. Unfortunately, the offset of the
+ // children depends on the VBR size of the child, so for large children we
+ // have to iterate a bit.
+ SmallString<128> TmpBuf;
+ unsigned ChildSize = 0;
+ unsigned VBRSize = 0;
+ do {
+ VBRSize = GetVBRSize(ChildSize);
+
+ TmpBuf.clear();
+ raw_svector_ostream OS(TmpBuf);
+ formatted_raw_ostream FOS(OS);
+ ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx+VBRSize+1, FOS);
+ } while (GetVBRSize(ChildSize) != VBRSize);
+
+ assert(ChildSize != 0 && "Should not have a zero-sized child!");
+
+ if (i != 0) {
+ OS.PadToColumn(Indent*2);
+ if (!OmitComments)
+ OS << (isa<SwitchOpcodeMatcher>(N) ?
+ "/*SwitchOpcode*/ " : "/*SwitchType*/ ");
+ }
+
+ // Emit the VBR.
+ CurrentIdx += EmitVBRValue(ChildSize, OS);
+
+ OS << ' ';
+ if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
+ OS << SOM->getCaseOpcode(i).getEnumName();
+ else
+ OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i));
+ OS << ',';
+
+ if (!OmitComments)
+ OS << "// ->" << CurrentIdx+ChildSize+1;
+ OS << '\n';
+ ++CurrentIdx;
+ OS << TmpBuf.str();
+ CurrentIdx += ChildSize;
+ }
+
+ // Emit the final zero to terminate the switch.
+ OS.PadToColumn(Indent*2) << "0, ";
+ if (!OmitComments)
+ OS << (isa<SwitchOpcodeMatcher>(N) ?
+ "// EndSwitchOpcode" : "// EndSwitchType");
+
+ OS << '\n';
+ ++CurrentIdx;
+ return CurrentIdx-StartIdx;
+ }
+
+ case Matcher::CheckType:
+ OS << "OPC_CheckType, "
+ << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
+ return 2;
+
+ case Matcher::CheckChildType:
+ OS << "OPC_CheckChild"
+ << cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, "
+ << getEnumName(cast<CheckChildTypeMatcher>(N)->getType()) << ",\n";
+ return 2;
+
+ case Matcher::CheckInteger: {
+ OS << "OPC_CheckInteger, ";
+ unsigned Bytes=1+EmitVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
+ OS << '\n';
+ return Bytes;
+ }
+ case Matcher::CheckCondCode:
+ OS << "OPC_CheckCondCode, ISD::"
+ << cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
+ return 2;
+
+ case Matcher::CheckValueType:
+ OS << "OPC_CheckValueType, MVT::"
+ << cast<CheckValueTypeMatcher>(N)->getTypeName() << ",\n";
+ return 2;
+
+ case Matcher::CheckComplexPat: {
+ const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
+ const ComplexPattern &Pattern = CCPM->getPattern();
+ OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/"
+ << CCPM->getMatchNumber() << ',';
+
+ if (!OmitComments) {
+ OS.PadToColumn(CommentIndent) << "// " << Pattern.getSelectFunc();
+ OS << ":$" << CCPM->getName();
+ for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)
+ OS << " #" << CCPM->getFirstResult()+i;
+
+ if (Pattern.hasProperty(SDNPHasChain))
+ OS << " + chain result";
+ }
+ OS << '\n';
+ return 3;
+ }
+
+ case Matcher::CheckAndImm: {
+ OS << "OPC_CheckAndImm, ";
+ unsigned Bytes=1+EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS);
+ OS << '\n';
+ return Bytes;
+ }
+
+ case Matcher::CheckOrImm: {
+ OS << "OPC_CheckOrImm, ";
+ unsigned Bytes = 1+EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS);
+ OS << '\n';
+ return Bytes;
+ }
+
+ case Matcher::CheckFoldableChainNode:
+ OS << "OPC_CheckFoldableChainNode,\n";
+ return 1;
+
+ case Matcher::EmitInteger: {
+ int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
+ OS << "OPC_EmitInteger, "
+ << getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
+ unsigned Bytes = 2+EmitVBRValue(Val, OS);
+ OS << '\n';
+ return Bytes;
+ }
+ case Matcher::EmitStringInteger: {
+ const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
+ // These should always fit into one byte.
+ OS << "OPC_EmitInteger, "
+ << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
+ << Val << ",\n";
+ return 3;
+ }
+
+ case Matcher::EmitRegister:
+ OS << "OPC_EmitRegister, "
+ << getEnumName(cast<EmitRegisterMatcher>(N)->getVT()) << ", ";
+ if (Record *R = cast<EmitRegisterMatcher>(N)->getReg())
+ OS << getQualifiedName(R) << ",\n";
+ else {
+ OS << "0 ";
+ if (!OmitComments)
+ OS << "/*zero_reg*/";
+ OS << ",\n";
+ }
+ return 3;
+
+ case Matcher::EmitConvertToTarget:
+ OS << "OPC_EmitConvertToTarget, "
+ << cast<EmitConvertToTargetMatcher>(N)->getSlot() << ",\n";
+ return 2;
+
+ case Matcher::EmitMergeInputChains: {
+ const EmitMergeInputChainsMatcher *MN =
+ cast<EmitMergeInputChainsMatcher>(N);
+ OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
+ for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
+ OS << MN->getNode(i) << ", ";
+ OS << '\n';
+ return 2+MN->getNumNodes();
+ }
+ case Matcher::EmitCopyToReg:
+ OS << "OPC_EmitCopyToReg, "
+ << cast<EmitCopyToRegMatcher>(N)->getSrcSlot() << ", "
+ << getQualifiedName(cast<EmitCopyToRegMatcher>(N)->getDestPhysReg())
+ << ",\n";
+ return 3;
+ case Matcher::EmitNodeXForm: {
+ const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);
+ OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
+ << XF->getSlot() << ',';
+ if (!OmitComments)
+ OS.PadToColumn(CommentIndent) << "// "<<XF->getNodeXForm()->getName();
+ OS <<'\n';
+ return 3;
+ }
+
+ case Matcher::EmitNode:
+ case Matcher::MorphNodeTo: {
+ const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
+ OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo");
+ OS << ", TARGET_OPCODE(" << EN->getOpcodeName() << "), 0";
+
+ if (EN->hasChain()) OS << "|OPFL_Chain";
+ if (EN->hasInFlag()) OS << "|OPFL_FlagInput";
+ if (EN->hasOutFlag()) OS << "|OPFL_FlagOutput";
+ if (EN->hasMemRefs()) OS << "|OPFL_MemRefs";
+ if (EN->getNumFixedArityOperands() != -1)
+ OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
+ OS << ",\n";
+
+ OS.PadToColumn(Indent*2+4) << EN->getNumVTs();
+ if (!OmitComments)
+ OS << "/*#VTs*/";
+ OS << ", ";
+ for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
+ OS << getEnumName(EN->getVT(i)) << ", ";
+
+ OS << EN->getNumOperands();
+ if (!OmitComments)
+ OS << "/*#Ops*/";
+ OS << ", ";
+ unsigned NumOperandBytes = 0;
+ for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
+ NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);
+
+ if (!OmitComments) {
+ // Print the result #'s for EmitNode.
+ if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) {
+ if (unsigned NumResults = EN->getNumVTs()) {
+ OS.PadToColumn(CommentIndent) << "// Results = ";
+ unsigned First = E->getFirstResultSlot();
+ for (unsigned i = 0; i != NumResults; ++i)
+ OS << "#" << First+i << " ";
+ }
+ }
+ OS << '\n';
+
+ if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
+ OS.PadToColumn(Indent*2) << "// Src: "
+ << *SNT->getPattern().getSrcPattern() << '\n';
+ OS.PadToColumn(Indent*2) << "// Dst: "
+ << *SNT->getPattern().getDstPattern() << '\n';
+ }
+ } else
+ OS << '\n';
+
+ return 6+EN->getNumVTs()+NumOperandBytes;
+ }
+ case Matcher::MarkFlagResults: {
+ const MarkFlagResultsMatcher *CFR = cast<MarkFlagResultsMatcher>(N);
+ OS << "OPC_MarkFlagResults, " << CFR->getNumNodes() << ", ";
+ unsigned NumOperandBytes = 0;
+ for (unsigned i = 0, e = CFR->getNumNodes(); i != e; ++i)
+ NumOperandBytes += EmitVBRValue(CFR->getNode(i), OS);
+ OS << '\n';
+ return 2+NumOperandBytes;
+ }
+ case Matcher::CompleteMatch: {
+ const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);
+ OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
+ unsigned NumResultBytes = 0;
+ for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
+ NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
+ OS << '\n';
+ if (!OmitComments) {
+ OS.PadToColumn(Indent*2) << "// Src: "
+ << *CM->getPattern().getSrcPattern() << '\n';
+ OS.PadToColumn(Indent*2) << "// Dst: "
+ << *CM->getPattern().getDstPattern();
+ }
+ OS << '\n';
+ return 2 + NumResultBytes;
+ }
+ }
+ assert(0 && "Unreachable");
+ return 0;
+}
+
+/// EmitMatcherList - Emit the bytes for the specified matcher subtree.
+unsigned MatcherTableEmitter::
+EmitMatcherList(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
+ formatted_raw_ostream &OS) {
+ unsigned Size = 0;
+ while (N) {
+ if (!OmitComments)
+ OS << "/*" << CurrentIdx << "*/";
+ unsigned MatcherSize = EmitMatcher(N, Indent, CurrentIdx, OS);
+ Size += MatcherSize;
+ CurrentIdx += MatcherSize;
+
+ // If there are other nodes in this list, iterate to them, otherwise we're
+ // done.
+ N = N->getNext();
+ }
+ return Size;
+}
+
+void MatcherTableEmitter::EmitPredicateFunctions(const CodeGenDAGPatterns &CGP,
+ formatted_raw_ostream &OS) {
+ // Emit pattern predicates.
+ if (!PatternPredicates.empty()) {
+ OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n";
+ OS << " switch (PredNo) {\n";
+ OS << " default: assert(0 && \"Invalid predicate in table?\");\n";
+ for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
+ OS << " case " << i << ": return " << PatternPredicates[i] << ";\n";
+ OS << " }\n";
+ OS << "}\n\n";
+ }
+
+ // Emit Node predicates.
+ // FIXME: Annoyingly, these are stored by name, which we never even emit. Yay?
+ StringMap<TreePattern*> PFsByName;
+
+ for (CodeGenDAGPatterns::pf_iterator I = CGP.pf_begin(), E = CGP.pf_end();
+ I != E; ++I)
+ PFsByName[I->first->getName()] = I->second;
+
+ if (!NodePredicates.empty()) {
+ OS << "bool CheckNodePredicate(SDNode *Node, unsigned PredNo) const {\n";
+ OS << " switch (PredNo) {\n";
+ OS << " default: assert(0 && \"Invalid predicate in table?\");\n";
+ for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
+ // FIXME: Storing this by name is horrible.
+ TreePattern *P =PFsByName[NodePredicates[i].substr(strlen("Predicate_"))];
+ assert(P && "Unknown name?");
+
+ // Emit the predicate code corresponding to this pattern.
+ std::string Code = P->getRecord()->getValueAsCode("Predicate");
+ assert(!Code.empty() && "No code in this predicate");
+ OS << " case " << i << ": { // " << NodePredicates[i] << '\n';
+ std::string ClassName;
+ if (P->getOnlyTree()->isLeaf())
+ ClassName = "SDNode";
+ else
+ ClassName =
+ CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
+ if (ClassName == "SDNode")
+ OS << " SDNode *N = Node;\n";
+ else
+ OS << " " << ClassName << "*N = cast<" << ClassName << ">(Node);\n";
+ OS << Code << "\n }\n";
+ }
+ OS << " }\n";
+ OS << "}\n\n";
+ }
+
+ // Emit CompletePattern matchers.
+ // FIXME: This should be const.
+ if (!ComplexPatterns.empty()) {
+ OS << "bool CheckComplexPattern(SDNode *Root, SDValue N,\n";
+ OS << " unsigned PatternNo, SmallVectorImpl<SDValue> &Result) {\n";
+ OS << " switch (PatternNo) {\n";
+ OS << " default: assert(0 && \"Invalid pattern # in table?\");\n";
+ for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
+ const ComplexPattern &P = *ComplexPatterns[i];
+ unsigned NumOps = P.getNumOperands();
+
+ if (P.hasProperty(SDNPHasChain))
+ ++NumOps; // Get the chained node too.
+
+ OS << " case " << i << ":\n";
+ OS << " Result.resize(Result.size()+" << NumOps << ");\n";
+ OS << " return " << P.getSelectFunc();
+
+ OS << "(Root, N";
+ for (unsigned i = 0; i != NumOps; ++i)
+ OS << ", Result[Result.size()-" << (NumOps-i) << ']';
+ OS << ");\n";
+ }
+ OS << " }\n";
+ OS << "}\n\n";
+ }
+
+
+ // Emit SDNodeXForm handlers.
+ // FIXME: This should be const.
+ if (!NodeXForms.empty()) {
+ OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {\n";
+ OS << " switch (XFormNo) {\n";
+ OS << " default: assert(0 && \"Invalid xform # in table?\");\n";
+
+ // FIXME: The node xform could take SDValue's instead of SDNode*'s.
+ for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) {
+ const CodeGenDAGPatterns::NodeXForm &Entry =
+ CGP.getSDNodeTransform(NodeXForms[i]);
+
+ Record *SDNode = Entry.first;
+ const std::string &Code = Entry.second;
+
+ OS << " case " << i << ": { ";
+ if (!OmitComments)
+ OS << "// " << NodeXForms[i]->getName();
+ OS << '\n';
+
+ std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
+ if (ClassName == "SDNode")
+ OS << " SDNode *N = V.getNode();\n";
+ else
+ OS << " " << ClassName << " *N = cast<" << ClassName
+ << ">(V.getNode());\n";
+ OS << Code << "\n }\n";
+ }
+ OS << " }\n";
+ OS << "}\n\n";
+ }
+}
+
+static void BuildHistogram(const Matcher *M, std::vector<unsigned> &OpcodeFreq){
+ for (; M != 0; M = M->getNext()) {
+ // Count this node.
+ if (unsigned(M->getKind()) >= OpcodeFreq.size())
+ OpcodeFreq.resize(M->getKind()+1);
+ OpcodeFreq[M->getKind()]++;
+
+ // Handle recursive nodes.
+ if (const ScopeMatcher *SM = dyn_cast<ScopeMatcher>(M)) {
+ for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i)
+ BuildHistogram(SM->getChild(i), OpcodeFreq);
+ } else if (const SwitchOpcodeMatcher *SOM =
+ dyn_cast<SwitchOpcodeMatcher>(M)) {
+ for (unsigned i = 0, e = SOM->getNumCases(); i != e; ++i)
+ BuildHistogram(SOM->getCaseMatcher(i), OpcodeFreq);
+ } else if (const SwitchTypeMatcher *STM = dyn_cast<SwitchTypeMatcher>(M)) {
+ for (unsigned i = 0, e = STM->getNumCases(); i != e; ++i)
+ BuildHistogram(STM->getCaseMatcher(i), OpcodeFreq);
+ }
+ }
+}
+
+void MatcherTableEmitter::EmitHistogram(const Matcher *M,
+ formatted_raw_ostream &OS) {
+ if (OmitComments)
+ return;
+
+ std::vector<unsigned> OpcodeFreq;
+ BuildHistogram(M, OpcodeFreq);
+
+ OS << " // Opcode Histogram:\n";
+ for (unsigned i = 0, e = OpcodeFreq.size(); i != e; ++i) {
+ OS << " // #";
+ switch ((Matcher::KindTy)i) {
+ case Matcher::Scope: OS << "OPC_Scope"; break;
+ case Matcher::RecordNode: OS << "OPC_RecordNode"; break;
+ case Matcher::RecordChild: OS << "OPC_RecordChild"; break;
+ case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break;
+ case Matcher::CaptureFlagInput: OS << "OPC_CaptureFlagInput"; break;
+ case Matcher::MoveChild: OS << "OPC_MoveChild"; break;
+ case Matcher::MoveParent: OS << "OPC_MoveParent"; break;
+ case Matcher::CheckSame: OS << "OPC_CheckSame"; break;
+ case Matcher::CheckPatternPredicate:
+ OS << "OPC_CheckPatternPredicate"; break;
+ case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
+ case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
+ case Matcher::SwitchOpcode: OS << "OPC_SwitchOpcode"; break;
+ case Matcher::CheckType: OS << "OPC_CheckType"; break;
+ case Matcher::SwitchType: OS << "OPC_SwitchType"; break;
+ case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
+ case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
+ case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break;
+ case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break;
+ case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
+ case Matcher::CheckAndImm: OS << "OPC_CheckAndImm"; break;
+ case Matcher::CheckOrImm: OS << "OPC_CheckOrImm"; break;
+ case Matcher::CheckFoldableChainNode:
+ OS << "OPC_CheckFoldableChainNode"; break;
+ case Matcher::EmitInteger: OS << "OPC_EmitInteger"; break;
+ case Matcher::EmitStringInteger: OS << "OPC_EmitStringInteger"; break;
+ case Matcher::EmitRegister: OS << "OPC_EmitRegister"; break;
+ case Matcher::EmitConvertToTarget: OS << "OPC_EmitConvertToTarget"; break;
+ case Matcher::EmitMergeInputChains: OS << "OPC_EmitMergeInputChains"; break;
+ case Matcher::EmitCopyToReg: OS << "OPC_EmitCopyToReg"; break;
+ case Matcher::EmitNode: OS << "OPC_EmitNode"; break;
+ case Matcher::MorphNodeTo: OS << "OPC_MorphNodeTo"; break;
+ case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break;
+ case Matcher::MarkFlagResults: OS << "OPC_MarkFlagResults"; break;
+ case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break;
+ }
+
+ OS.PadToColumn(40) << " = " << OpcodeFreq[i] << '\n';
+ }
+ OS << '\n';
+}
+
+
+void llvm::EmitMatcherTable(const Matcher *TheMatcher,
+ const CodeGenDAGPatterns &CGP, raw_ostream &O) {
+ formatted_raw_ostream OS(O);
+
+ OS << "// The main instruction selector code.\n";
+ OS << "SDNode *SelectCode(SDNode *N) {\n";
+
+ MatcherTableEmitter MatcherEmitter;
+
+ OS << " // Opcodes are emitted as 2 bytes, TARGET_OPCODE handles this.\n";
+ OS << " #define TARGET_OPCODE(X) X & 255, unsigned(X) >> 8\n";
+ OS << " static const unsigned char MatcherTable[] = {\n";
+ unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 5, 0, OS);
+ OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
+
+ MatcherEmitter.EmitHistogram(TheMatcher, OS);
+
+ OS << " #undef TARGET_OPCODE\n";
+ OS << " return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
+ OS << '\n';
+
+ // Next up, emit the function for node and pattern predicates:
+ MatcherEmitter.EmitPredicateFunctions(CGP, OS);
+}
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
new file mode 100644
index 0000000..4951a42
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -0,0 +1,882 @@
+//===- DAGISelMatcherGen.cpp - Matcher generator --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "Record.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include <utility>
+using namespace llvm;
+
+
+/// getRegisterValueType - Look up and return the ValueType of the specified
+/// register. If the register is a member of multiple register classes which
+/// have different associated types, return MVT::Other.
+static MVT::SimpleValueType getRegisterValueType(Record *R,
+ const CodeGenTarget &T) {
+ bool FoundRC = false;
+ MVT::SimpleValueType VT = MVT::Other;
+ const std::vector<CodeGenRegisterClass> &RCs = T.getRegisterClasses();
+ std::vector<Record*>::const_iterator Element;
+
+ for (unsigned rc = 0, e = RCs.size(); rc != e; ++rc) {
+ const CodeGenRegisterClass &RC = RCs[rc];
+ if (!std::count(RC.Elements.begin(), RC.Elements.end(), R))
+ continue;
+
+ if (!FoundRC) {
+ FoundRC = true;
+ VT = RC.getValueTypeNum(0);
+ continue;
+ }
+
+ // If this occurs in multiple register classes, they all have to agree.
+ assert(VT == RC.getValueTypeNum(0));
+ }
+ return VT;
+}
+
+
+namespace {
+ class MatcherGen {
+ const PatternToMatch &Pattern;
+ const CodeGenDAGPatterns &CGP;
+
+ /// PatWithNoTypes - This is a clone of Pattern.getSrcPattern() that starts
+ /// out with all of the types removed. This allows us to insert type checks
+ /// as we scan the tree.
+ TreePatternNode *PatWithNoTypes;
+
+ /// VariableMap - A map from variable names ('$dst') to the recorded operand
+ /// number that they were captured as. These are biased by 1 to make
+ /// insertion easier.
+ StringMap<unsigned> VariableMap;
+
+ /// NextRecordedOperandNo - As we emit opcodes to record matched values in
+ /// the RecordedNodes array, this keeps track of which slot will be next to
+ /// record into.
+ unsigned NextRecordedOperandNo;
+
+ /// MatchedChainNodes - This maintains the position in the recorded nodes
+ /// array of all of the recorded input nodes that have chains.
+ SmallVector<unsigned, 2> MatchedChainNodes;
+
+ /// MatchedFlagResultNodes - This maintains the position in the recorded
+ /// nodes array of all of the recorded input nodes that have flag results.
+ SmallVector<unsigned, 2> MatchedFlagResultNodes;
+
+ /// MatchedComplexPatterns - This maintains a list of all of the
+ /// ComplexPatterns that we need to check. The patterns are known to have
+ /// names which were recorded. The second element of each pair is the first
+ /// slot number that the OPC_CheckComplexPat opcode drops the matched
+ /// results into.
+ SmallVector<std::pair<const TreePatternNode*,
+ unsigned>, 2> MatchedComplexPatterns;
+
+ /// PhysRegInputs - List list has an entry for each explicitly specified
+ /// physreg input to the pattern. The first elt is the Register node, the
+ /// second is the recorded slot number the input pattern match saved it in.
+ SmallVector<std::pair<Record*, unsigned>, 2> PhysRegInputs;
+
+ /// Matcher - This is the top level of the generated matcher, the result.
+ Matcher *TheMatcher;
+
+ /// CurPredicate - As we emit matcher nodes, this points to the latest check
+ /// which should have future checks stuck into its Next position.
+ Matcher *CurPredicate;
+ public:
+ MatcherGen(const PatternToMatch &pattern, const CodeGenDAGPatterns &cgp);
+
+ ~MatcherGen() {
+ delete PatWithNoTypes;
+ }
+
+ bool EmitMatcherCode(unsigned Variant);
+ void EmitResultCode();
+
+ Matcher *GetMatcher() const { return TheMatcher; }
+ Matcher *GetCurPredicate() const { return CurPredicate; }
+ private:
+ void AddMatcher(Matcher *NewNode);
+ void InferPossibleTypes();
+
+ // Matcher Generation.
+ void EmitMatchCode(const TreePatternNode *N, TreePatternNode *NodeNoTypes);
+ void EmitLeafMatchCode(const TreePatternNode *N);
+ void EmitOperatorMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes);
+
+ // Result Code Generation.
+ unsigned getNamedArgumentSlot(StringRef Name) {
+ unsigned VarMapEntry = VariableMap[Name];
+ assert(VarMapEntry != 0 &&
+ "Variable referenced but not defined and not caught earlier!");
+ return VarMapEntry-1;
+ }
+
+ /// GetInstPatternNode - Get the pattern for an instruction.
+ const TreePatternNode *GetInstPatternNode(const DAGInstruction &Ins,
+ const TreePatternNode *N);
+
+ void EmitResultOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps);
+ void EmitResultOfNamedOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps);
+ void EmitResultLeafAsOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps);
+ void EmitResultInstructionAsOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps);
+ void EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps);
+ };
+
+} // end anon namespace.
+
+MatcherGen::MatcherGen(const PatternToMatch &pattern,
+ const CodeGenDAGPatterns &cgp)
+: Pattern(pattern), CGP(cgp), NextRecordedOperandNo(0),
+ TheMatcher(0), CurPredicate(0) {
+ // We need to produce the matcher tree for the patterns source pattern. To do
+ // this we need to match the structure as well as the types. To do the type
+ // matching, we want to figure out the fewest number of type checks we need to
+ // emit. For example, if there is only one integer type supported by a
+ // target, there should be no type comparisons at all for integer patterns!
+ //
+ // To figure out the fewest number of type checks needed, clone the pattern,
+ // remove the types, then perform type inference on the pattern as a whole.
+ // If there are unresolved types, emit an explicit check for those types,
+ // apply the type to the tree, then rerun type inference. Iterate until all
+ // types are resolved.
+ //
+ PatWithNoTypes = Pattern.getSrcPattern()->clone();
+ PatWithNoTypes->RemoveAllTypes();
+
+ // If there are types that are manifestly known, infer them.
+ InferPossibleTypes();
+}
+
+/// InferPossibleTypes - As we emit the pattern, we end up generating type
+/// checks and applying them to the 'PatWithNoTypes' tree. As we do this, we
+/// want to propagate implied types as far throughout the tree as possible so
+/// that we avoid doing redundant type checks. This does the type propagation.
+void MatcherGen::InferPossibleTypes() {
+ // TP - Get *SOME* tree pattern, we don't care which. It is only used for
+ // diagnostics, which we know are impossible at this point.
+ TreePattern &TP = *CGP.pf_begin()->second;
+
+ try {
+ bool MadeChange = true;
+ while (MadeChange)
+ MadeChange = PatWithNoTypes->ApplyTypeConstraints(TP,
+ true/*Ignore reg constraints*/);
+ } catch (...) {
+ errs() << "Type constraint application shouldn't fail!";
+ abort();
+ }
+}
+
+
+/// AddMatcher - Add a matcher node to the current graph we're building.
+void MatcherGen::AddMatcher(Matcher *NewNode) {
+ if (CurPredicate != 0)
+ CurPredicate->setNext(NewNode);
+ else
+ TheMatcher = NewNode;
+ CurPredicate = NewNode;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Pattern Match Generation
+//===----------------------------------------------------------------------===//
+
+/// EmitLeafMatchCode - Generate matching code for leaf nodes.
+void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
+ assert(N->isLeaf() && "Not a leaf?");
+
+ // Direct match against an integer constant.
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+ // If this is the root of the dag we're matching, we emit a redundant opcode
+ // check to ensure that this gets folded into the normal top-level
+ // OpcodeSwitch.
+ if (N == Pattern.getSrcPattern()) {
+ const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed("imm"));
+ AddMatcher(new CheckOpcodeMatcher(NI));
+ }
+
+ return AddMatcher(new CheckIntegerMatcher(II->getValue()));
+ }
+
+ DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue());
+ if (DI == 0) {
+ errs() << "Unknown leaf kind: " << *DI << "\n";
+ abort();
+ }
+
+ Record *LeafRec = DI->getDef();
+ if (// Handle register references. Nothing to do here, they always match.
+ LeafRec->isSubClassOf("RegisterClass") ||
+ LeafRec->isSubClassOf("PointerLikeRegClass") ||
+ // Place holder for SRCVALUE nodes. Nothing to do here.
+ LeafRec->getName() == "srcvalue")
+ return;
+
+ // If we have a physreg reference like (mul gpr:$src, EAX) then we need to
+ // record the register
+ if (LeafRec->isSubClassOf("Register")) {
+ AddMatcher(new RecordMatcher("physreg input "+LeafRec->getName(),
+ NextRecordedOperandNo));
+ PhysRegInputs.push_back(std::make_pair(LeafRec, NextRecordedOperandNo++));
+ return;
+ }
+
+ if (LeafRec->isSubClassOf("ValueType"))
+ return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName()));
+
+ if (LeafRec->isSubClassOf("CondCode"))
+ return AddMatcher(new CheckCondCodeMatcher(LeafRec->getName()));
+
+ if (LeafRec->isSubClassOf("ComplexPattern")) {
+ // We can't model ComplexPattern uses that don't have their name taken yet.
+ // The OPC_CheckComplexPattern operation implicitly records the results.
+ if (N->getName().empty()) {
+ errs() << "We expect complex pattern uses to have names: " << *N << "\n";
+ exit(1);
+ }
+
+ // Remember this ComplexPattern so that we can emit it after all the other
+ // structural matches are done.
+ MatchedComplexPatterns.push_back(std::make_pair(N, 0));
+ return;
+ }
+
+ errs() << "Unknown leaf kind: " << *N << "\n";
+ abort();
+}
+
+void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes) {
+ assert(!N->isLeaf() && "Not an operator?");
+ const SDNodeInfo &CInfo = CGP.getSDNodeInfo(N->getOperator());
+
+ // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
+ // a constant without a predicate fn that has more that one bit set, handle
+ // this as a special case. This is usually for targets that have special
+ // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
+ // handling stuff). Using these instructions is often far more efficient
+ // than materializing the constant. Unfortunately, both the instcombiner
+ // and the dag combiner can often infer that bits are dead, and thus drop
+ // them from the mask in the dag. For example, it might turn 'AND X, 255'
+ // into 'AND X, 254' if it knows the low bit is set. Emit code that checks
+ // to handle this.
+ if ((N->getOperator()->getName() == "and" ||
+ N->getOperator()->getName() == "or") &&
+ N->getChild(1)->isLeaf() && N->getChild(1)->getPredicateFns().empty() &&
+ N->getPredicateFns().empty()) {
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
+ if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
+ // If this is at the root of the pattern, we emit a redundant
+ // CheckOpcode so that the following checks get factored properly under
+ // a single opcode check.
+ if (N == Pattern.getSrcPattern())
+ AddMatcher(new CheckOpcodeMatcher(CInfo));
+
+ // Emit the CheckAndImm/CheckOrImm node.
+ if (N->getOperator()->getName() == "and")
+ AddMatcher(new CheckAndImmMatcher(II->getValue()));
+ else
+ AddMatcher(new CheckOrImmMatcher(II->getValue()));
+
+ // Match the LHS of the AND as appropriate.
+ AddMatcher(new MoveChildMatcher(0));
+ EmitMatchCode(N->getChild(0), NodeNoTypes->getChild(0));
+ AddMatcher(new MoveParentMatcher());
+ return;
+ }
+ }
+ }
+
+ // Check that the current opcode lines up.
+ AddMatcher(new CheckOpcodeMatcher(CInfo));
+
+ // If this node has memory references (i.e. is a load or store), tell the
+ // interpreter to capture them in the memref array.
+ if (N->NodeHasProperty(SDNPMemOperand, CGP))
+ AddMatcher(new RecordMemRefMatcher());
+
+ // If this node has a chain, then the chain is operand #0 is the SDNode, and
+ // the child numbers of the node are all offset by one.
+ unsigned OpNo = 0;
+ if (N->NodeHasProperty(SDNPHasChain, CGP)) {
+ // Record the node and remember it in our chained nodes list.
+ AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
+ "' chained node",
+ NextRecordedOperandNo));
+ // Remember all of the input chains our pattern will match.
+ MatchedChainNodes.push_back(NextRecordedOperandNo++);
+
+ // Don't look at the input chain when matching the tree pattern to the
+ // SDNode.
+ OpNo = 1;
+
+ // If this node is not the root and the subtree underneath it produces a
+ // chain, then the result of matching the node is also produce a chain.
+ // Beyond that, this means that we're also folding (at least) the root node
+ // into the node that produce the chain (for example, matching
+ // "(add reg, (load ptr))" as a add_with_memory on X86). This is
+ // problematic, if the 'reg' node also uses the load (say, its chain).
+ // Graphically:
+ //
+ // [LD]
+ // ^ ^
+ // | \ DAG's like cheese.
+ // / |
+ // / [YY]
+ // | ^
+ // [XX]--/
+ //
+ // It would be invalid to fold XX and LD. In this case, folding the two
+ // nodes together would induce a cycle in the DAG, making it a 'cyclic DAG'
+ // To prevent this, we emit a dynamic check for legality before allowing
+ // this to be folded.
+ //
+ const TreePatternNode *Root = Pattern.getSrcPattern();
+ if (N != Root) { // Not the root of the pattern.
+ // If there is a node between the root and this node, then we definitely
+ // need to emit the check.
+ bool NeedCheck = !Root->hasChild(N);
+
+ // If it *is* an immediate child of the root, we can still need a check if
+ // the root SDNode has multiple inputs. For us, this means that it is an
+ // intrinsic, has multiple operands, or has other inputs like chain or
+ // flag).
+ if (!NeedCheck) {
+ const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Root->getOperator());
+ NeedCheck =
+ Root->getOperator() == CGP.get_intrinsic_void_sdnode() ||
+ Root->getOperator() == CGP.get_intrinsic_w_chain_sdnode() ||
+ Root->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() ||
+ PInfo.getNumOperands() > 1 ||
+ PInfo.hasProperty(SDNPHasChain) ||
+ PInfo.hasProperty(SDNPInFlag) ||
+ PInfo.hasProperty(SDNPOptInFlag);
+ }
+
+ if (NeedCheck)
+ AddMatcher(new CheckFoldableChainNodeMatcher());
+ }
+ }
+
+ // If this node has an output flag and isn't the root, remember it.
+ if (N->NodeHasProperty(SDNPOutFlag, CGP) &&
+ N != Pattern.getSrcPattern()) {
+ // TODO: This redundantly records nodes with both flags and chains.
+
+ // Record the node and remember it in our chained nodes list.
+ AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
+ "' flag output node",
+ NextRecordedOperandNo));
+ // Remember all of the nodes with output flags our pattern will match.
+ MatchedFlagResultNodes.push_back(NextRecordedOperandNo++);
+ }
+
+ // If this node is known to have an input flag or if it *might* have an input
+ // flag, capture it as the flag input of the pattern.
+ if (N->NodeHasProperty(SDNPOptInFlag, CGP) ||
+ N->NodeHasProperty(SDNPInFlag, CGP))
+ AddMatcher(new CaptureFlagInputMatcher());
+
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
+ // Get the code suitable for matching this child. Move to the child, check
+ // it then move back to the parent.
+ AddMatcher(new MoveChildMatcher(OpNo));
+ EmitMatchCode(N->getChild(i), NodeNoTypes->getChild(i));
+ AddMatcher(new MoveParentMatcher());
+ }
+}
+
+
+void MatcherGen::EmitMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes) {
+ // If N and NodeNoTypes don't agree on a type, then this is a case where we
+ // need to do a type check. Emit the check, apply the tyep to NodeNoTypes and
+ // reinfer any correlated types.
+ unsigned NodeType = EEVT::isUnknown;
+ if (NodeNoTypes->getExtTypes() != N->getExtTypes()) {
+ NodeType = N->getTypeNum(0);
+ NodeNoTypes->setTypes(N->getExtTypes());
+ InferPossibleTypes();
+ }
+
+ // If this node has a name associated with it, capture it in VariableMap. If
+ // we already saw this in the pattern, emit code to verify dagness.
+ if (!N->getName().empty()) {
+ unsigned &VarMapEntry = VariableMap[N->getName()];
+ if (VarMapEntry == 0) {
+ // If it is a named node, we must emit a 'Record' opcode.
+ AddMatcher(new RecordMatcher("$" + N->getName(), NextRecordedOperandNo));
+ VarMapEntry = ++NextRecordedOperandNo;
+ } else {
+ // If we get here, this is a second reference to a specific name. Since
+ // we already have checked that the first reference is valid, we don't
+ // have to recursively match it, just check that it's the same as the
+ // previously named thing.
+ AddMatcher(new CheckSameMatcher(VarMapEntry-1));
+ return;
+ }
+ }
+
+ if (N->isLeaf())
+ EmitLeafMatchCode(N);
+ else
+ EmitOperatorMatchCode(N, NodeNoTypes);
+
+ // If there are node predicates for this node, generate their checks.
+ for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
+ AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
+
+ if (NodeType != EEVT::isUnknown)
+ AddMatcher(new CheckTypeMatcher((MVT::SimpleValueType)NodeType));
+}
+
+/// EmitMatcherCode - Generate the code that matches the predicate of this
+/// pattern for the specified Variant. If the variant is invalid this returns
+/// true and does not generate code, if it is valid, it returns false.
+bool MatcherGen::EmitMatcherCode(unsigned Variant) {
+ // If the root of the pattern is a ComplexPattern and if it is specified to
+ // match some number of root opcodes, these are considered to be our variants.
+ // Depending on which variant we're generating code for, emit the root opcode
+ // check.
+ if (const ComplexPattern *CP =
+ Pattern.getSrcPattern()->getComplexPatternInfo(CGP)) {
+ const std::vector<Record*> &OpNodes = CP->getRootNodes();
+ assert(!OpNodes.empty() &&"Complex Pattern must specify what it can match");
+ if (Variant >= OpNodes.size()) return true;
+
+ AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant])));
+ } else {
+ if (Variant != 0) return true;
+ }
+
+ // Emit the matcher for the pattern structure and types.
+ EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
+
+ // If the pattern has a predicate on it (e.g. only enabled when a subtarget
+ // feature is around, do the check).
+ if (!Pattern.getPredicateCheck().empty())
+ AddMatcher(new CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
+
+ // Now that we've completed the structural type match, emit any ComplexPattern
+ // checks (e.g. addrmode matches). We emit this after the structural match
+ // because they are generally more expensive to evaluate and more difficult to
+ // factor.
+ for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i) {
+ const TreePatternNode *N = MatchedComplexPatterns[i].first;
+
+ // Remember where the results of this match get stuck.
+ MatchedComplexPatterns[i].second = NextRecordedOperandNo;
+
+ // Get the slot we recorded the value in from the name on the node.
+ unsigned RecNodeEntry = VariableMap[N->getName()];
+ assert(!N->getName().empty() && RecNodeEntry &&
+ "Complex pattern should have a name and slot");
+ --RecNodeEntry; // Entries in VariableMap are biased.
+
+ const ComplexPattern &CP =
+ CGP.getComplexPattern(((DefInit*)N->getLeafValue())->getDef());
+
+ // Emit a CheckComplexPat operation, which does the match (aborting if it
+ // fails) and pushes the matched operands onto the recorded nodes list.
+ AddMatcher(new CheckComplexPatMatcher(CP, RecNodeEntry,
+ N->getName(), NextRecordedOperandNo));
+
+ // Record the right number of operands.
+ NextRecordedOperandNo += CP.getNumOperands();
+ if (CP.hasProperty(SDNPHasChain)) {
+ // If the complex pattern has a chain, then we need to keep track of the
+ // fact that we just recorded a chain input. The chain input will be
+ // matched as the last operand of the predicate if it was successful.
+ ++NextRecordedOperandNo; // Chained node operand.
+
+ // It is the last operand recorded.
+ assert(NextRecordedOperandNo > 1 &&
+ "Should have recorded input/result chains at least!");
+ MatchedChainNodes.push_back(NextRecordedOperandNo-1);
+ }
+
+ // TODO: Complex patterns can't have output flags, if they did, we'd want
+ // to record them.
+ }
+
+ return false;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Node Result Generation
+//===----------------------------------------------------------------------===//
+
+void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps){
+ assert(!N->getName().empty() && "Operand not named!");
+
+ // A reference to a complex pattern gets all of the results of the complex
+ // pattern's match.
+ if (const ComplexPattern *CP = N->getComplexPatternInfo(CGP)) {
+ unsigned SlotNo = 0;
+ for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i)
+ if (MatchedComplexPatterns[i].first->getName() == N->getName()) {
+ SlotNo = MatchedComplexPatterns[i].second;
+ break;
+ }
+ assert(SlotNo != 0 && "Didn't get a slot number assigned?");
+
+ // The first slot entry is the node itself, the subsequent entries are the
+ // matched values.
+ for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
+ ResultOps.push_back(SlotNo+i);
+ return;
+ }
+
+ unsigned SlotNo = getNamedArgumentSlot(N->getName());
+
+ // If this is an 'imm' or 'fpimm' node, make sure to convert it to the target
+ // version of the immediate so that it doesn't get selected due to some other
+ // node use.
+ if (!N->isLeaf()) {
+ StringRef OperatorName = N->getOperator()->getName();
+ if (OperatorName == "imm" || OperatorName == "fpimm") {
+ AddMatcher(new EmitConvertToTargetMatcher(SlotNo));
+ ResultOps.push_back(NextRecordedOperandNo++);
+ return;
+ }
+ }
+
+ ResultOps.push_back(SlotNo);
+}
+
+void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps) {
+ assert(N->isLeaf() && "Must be a leaf");
+
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+ AddMatcher(new EmitIntegerMatcher(II->getValue(),N->getTypeNum(0)));
+ ResultOps.push_back(NextRecordedOperandNo++);
+ return;
+ }
+
+ // If this is an explicit register reference, handle it.
+ if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+ if (DI->getDef()->isSubClassOf("Register")) {
+ AddMatcher(new EmitRegisterMatcher(DI->getDef(),
+ N->getTypeNum(0)));
+ ResultOps.push_back(NextRecordedOperandNo++);
+ return;
+ }
+
+ if (DI->getDef()->getName() == "zero_reg") {
+ AddMatcher(new EmitRegisterMatcher(0, N->getTypeNum(0)));
+ ResultOps.push_back(NextRecordedOperandNo++);
+ return;
+ }
+
+ // Handle a reference to a register class. This is used
+ // in COPY_TO_SUBREG instructions.
+ if (DI->getDef()->isSubClassOf("RegisterClass")) {
+ std::string Value = getQualifiedName(DI->getDef()) + "RegClassID";
+ AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
+ ResultOps.push_back(NextRecordedOperandNo++);
+ return;
+ }
+ }
+
+ errs() << "unhandled leaf node: \n";
+ N->dump();
+}
+
+/// GetInstPatternNode - Get the pattern for an instruction.
+///
+const TreePatternNode *MatcherGen::
+GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode *N) {
+ const TreePattern *InstPat = Inst.getPattern();
+
+ // FIXME2?: Assume actual pattern comes before "implicit".
+ TreePatternNode *InstPatNode;
+ if (InstPat)
+ InstPatNode = InstPat->getTree(0);
+ else if (/*isRoot*/ N == Pattern.getDstPattern())
+ InstPatNode = Pattern.getSrcPattern();
+ else
+ return 0;
+
+ if (InstPatNode && !InstPatNode->isLeaf() &&
+ InstPatNode->getOperator()->getName() == "set")
+ InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
+
+ return InstPatNode;
+}
+
+void MatcherGen::
+EmitResultInstructionAsOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &OutputOps) {
+ Record *Op = N->getOperator();
+ const CodeGenTarget &CGT = CGP.getTargetInfo();
+ CodeGenInstruction &II = CGT.getInstruction(Op->getName());
+ const DAGInstruction &Inst = CGP.getInstruction(Op);
+
+ // If we can, get the pattern for the instruction we're generating. We derive
+ // a variety of information from this pattern, such as whether it has a chain.
+ //
+ // FIXME2: This is extremely dubious for several reasons, not the least of
+ // which it gives special status to instructions with patterns that Pat<>
+ // nodes can't duplicate.
+ const TreePatternNode *InstPatNode = GetInstPatternNode(Inst, N);
+
+ // NodeHasChain - Whether the instruction node we're creating takes chains.
+ bool NodeHasChain = InstPatNode &&
+ InstPatNode->TreeHasProperty(SDNPHasChain, CGP);
+
+ bool isRoot = N == Pattern.getDstPattern();
+
+ // TreeHasOutFlag - True if this tree has a flag.
+ bool TreeHasInFlag = false, TreeHasOutFlag = false;
+ if (isRoot) {
+ const TreePatternNode *SrcPat = Pattern.getSrcPattern();
+ TreeHasInFlag = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) ||
+ SrcPat->TreeHasProperty(SDNPInFlag, CGP);
+
+ // FIXME2: this is checking the entire pattern, not just the node in
+ // question, doing this just for the root seems like a total hack.
+ TreeHasOutFlag = SrcPat->TreeHasProperty(SDNPOutFlag, CGP);
+ }
+
+ // NumResults - This is the number of results produced by the instruction in
+ // the "outs" list.
+ unsigned NumResults = Inst.getNumResults();
+
+ // Loop over all of the operands of the instruction pattern, emitting code
+ // to fill them all in. The node 'N' usually has number children equal to
+ // the number of input operands of the instruction. However, in cases
+ // where there are predicate operands for an instruction, we need to fill
+ // in the 'execute always' values. Match up the node operands to the
+ // instruction operands to do this.
+ SmallVector<unsigned, 8> InstOps;
+ for (unsigned ChildNo = 0, InstOpNo = NumResults, e = II.OperandList.size();
+ InstOpNo != e; ++InstOpNo) {
+
+ // Determine what to emit for this operand.
+ Record *OperandNode = II.OperandList[InstOpNo].Rec;
+ if ((OperandNode->isSubClassOf("PredicateOperand") ||
+ OperandNode->isSubClassOf("OptionalDefOperand")) &&
+ !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
+ // This is a predicate or optional def operand; emit the
+ // 'default ops' operands.
+ const DAGDefaultOperand &DefaultOp =
+ CGP.getDefaultOperand(II.OperandList[InstOpNo].Rec);
+ for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i)
+ EmitResultOperand(DefaultOp.DefaultOps[i], InstOps);
+ continue;
+ }
+
+ // Otherwise this is a normal operand or a predicate operand without
+ // 'execute always'; emit it.
+ EmitResultOperand(N->getChild(ChildNo), InstOps);
+ ++ChildNo;
+ }
+
+ // If this node has an input flag or explicitly specified input physregs, we
+ // need to add chained and flagged copyfromreg nodes and materialize the flag
+ // input.
+ if (isRoot && !PhysRegInputs.empty()) {
+ // Emit all of the CopyToReg nodes for the input physical registers. These
+ // occur in patterns like (mul:i8 AL:i8, GR8:i8:$src).
+ for (unsigned i = 0, e = PhysRegInputs.size(); i != e; ++i)
+ AddMatcher(new EmitCopyToRegMatcher(PhysRegInputs[i].second,
+ PhysRegInputs[i].first));
+ // Even if the node has no other flag inputs, the resultant node must be
+ // flagged to the CopyFromReg nodes we just generated.
+ TreeHasInFlag = true;
+ }
+
+ // Result order: node results, chain, flags
+
+ // Determine the result types.
+ SmallVector<MVT::SimpleValueType, 4> ResultVTs;
+ if (NumResults != 0 && N->getTypeNum(0) != MVT::isVoid) {
+ // FIXME2: If the node has multiple results, we should add them. For now,
+ // preserve existing behavior?!
+ ResultVTs.push_back(N->getTypeNum(0));
+ }
+
+
+ // If this is the root instruction of a pattern that has physical registers in
+ // its result pattern, add output VTs for them. For example, X86 has:
+ // (set AL, (mul ...))
+ // This also handles implicit results like:
+ // (implicit EFLAGS)
+ if (isRoot && Pattern.getDstRegs().size() != 0) {
+ for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i)
+ if (Pattern.getDstRegs()[i]->isSubClassOf("Register"))
+ ResultVTs.push_back(getRegisterValueType(Pattern.getDstRegs()[i], CGT));
+ }
+
+ // FIXME2: Instead of using the isVariadic flag on the instruction, we should
+ // have an SDNP that indicates variadicism. The TargetInstrInfo isVariadic
+ // property should be inferred from this when an instruction has a pattern.
+ int NumFixedArityOperands = -1;
+ if (isRoot && II.isVariadic)
+ NumFixedArityOperands = Pattern.getSrcPattern()->getNumChildren();
+
+ // If this is the root node and any of the nodes matched nodes in the input
+ // pattern have MemRefs in them, have the interpreter collect them and plop
+ // them onto this node.
+ //
+ // FIXME3: This is actively incorrect for result patterns where the root of
+ // the pattern is not the memory reference and is also incorrect when the
+ // result pattern has multiple memory-referencing instructions. For example,
+ // in the X86 backend, this pattern causes the memrefs to get attached to the
+ // CVTSS2SDrr instead of the MOVSSrm:
+ //
+ // def : Pat<(extloadf32 addr:$src),
+ // (CVTSS2SDrr (MOVSSrm addr:$src))>;
+ //
+ bool NodeHasMemRefs =
+ isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP);
+
+ AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
+ ResultVTs.data(), ResultVTs.size(),
+ InstOps.data(), InstOps.size(),
+ NodeHasChain, TreeHasInFlag, TreeHasOutFlag,
+ NodeHasMemRefs, NumFixedArityOperands,
+ NextRecordedOperandNo));
+
+ // The non-chain and non-flag results of the newly emitted node get recorded.
+ for (unsigned i = 0, e = ResultVTs.size(); i != e; ++i) {
+ if (ResultVTs[i] == MVT::Other || ResultVTs[i] == MVT::Flag) break;
+ OutputOps.push_back(NextRecordedOperandNo++);
+ }
+}
+
+void MatcherGen::
+EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps) {
+ assert(N->getOperator()->isSubClassOf("SDNodeXForm") && "Not SDNodeXForm?");
+
+ // Emit the operand.
+ SmallVector<unsigned, 8> InputOps;
+
+ // FIXME2: Could easily generalize this to support multiple inputs and outputs
+ // to the SDNodeXForm. For now we just support one input and one output like
+ // the old instruction selector.
+ assert(N->getNumChildren() == 1);
+ EmitResultOperand(N->getChild(0), InputOps);
+
+ // The input currently must have produced exactly one result.
+ assert(InputOps.size() == 1 && "Unexpected input to SDNodeXForm");
+
+ AddMatcher(new EmitNodeXFormMatcher(InputOps[0], N->getOperator()));
+ ResultOps.push_back(NextRecordedOperandNo++);
+}
+
+void MatcherGen::EmitResultOperand(const TreePatternNode *N,
+ SmallVectorImpl<unsigned> &ResultOps) {
+ // This is something selected from the pattern we matched.
+ if (!N->getName().empty())
+ return EmitResultOfNamedOperand(N, ResultOps);
+
+ if (N->isLeaf())
+ return EmitResultLeafAsOperand(N, ResultOps);
+
+ Record *OpRec = N->getOperator();
+ if (OpRec->isSubClassOf("Instruction"))
+ return EmitResultInstructionAsOperand(N, ResultOps);
+ if (OpRec->isSubClassOf("SDNodeXForm"))
+ return EmitResultSDNodeXFormAsOperand(N, ResultOps);
+ errs() << "Unknown result node to emit code for: " << *N << '\n';
+ throw std::string("Unknown node in result pattern!");
+}
+
+void MatcherGen::EmitResultCode() {
+ // Patterns that match nodes with (potentially multiple) chain inputs have to
+ // merge them together into a token factor. This informs the generated code
+ // what all the chained nodes are.
+ if (!MatchedChainNodes.empty())
+ AddMatcher(new EmitMergeInputChainsMatcher
+ (MatchedChainNodes.data(), MatchedChainNodes.size()));
+
+ // Codegen the root of the result pattern, capturing the resulting values.
+ SmallVector<unsigned, 8> Ops;
+ EmitResultOperand(Pattern.getDstPattern(), Ops);
+
+ // At this point, we have however many values the result pattern produces.
+ // However, the input pattern might not need all of these. If there are
+ // excess values at the end (such as condition codes etc) just lop them off.
+ // This doesn't need to worry about flags or chains, just explicit results.
+ //
+ // FIXME2: This doesn't work because there is currently no way to get an
+ // accurate count of the # results the source pattern sets. This is because
+ // of the "parallel" construct in X86 land, which looks like this:
+ //
+ //def : Pat<(parallel (X86and_flag GR8:$src1, GR8:$src2),
+ // (implicit EFLAGS)),
+ // (AND8rr GR8:$src1, GR8:$src2)>;
+ //
+ // This idiom means to match the two-result node X86and_flag (which is
+ // declared as returning a single result, because we can't match multi-result
+ // nodes yet). In this case, we would have to know that the input has two
+ // results. However, mul8r is modelled exactly the same way, but without
+ // implicit defs included. The fix is to support multiple results directly
+ // and eliminate 'parallel'.
+ //
+ // FIXME2: When this is fixed, we should revert the terrible hack in the
+ // OPC_EmitNode code in the interpreter.
+#if 0
+ const TreePatternNode *Src = Pattern.getSrcPattern();
+ unsigned NumSrcResults = Src->getTypeNum(0) != MVT::isVoid ? 1 : 0;
+ NumSrcResults += Pattern.getDstRegs().size();
+ assert(Ops.size() >= NumSrcResults && "Didn't provide enough results");
+ Ops.resize(NumSrcResults);
+#endif
+
+ // If the matched pattern covers nodes which define a flag result, emit a node
+ // that tells the matcher about them so that it can update their results.
+ if (!MatchedFlagResultNodes.empty())
+ AddMatcher(new MarkFlagResultsMatcher(MatchedFlagResultNodes.data(),
+ MatchedFlagResultNodes.size()));
+
+ AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern));
+}
+
+
+/// ConvertPatternToMatcher - Create the matcher for the specified pattern with
+/// the specified variant. If the variant number is invalid, this returns null.
+Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
+ unsigned Variant,
+ const CodeGenDAGPatterns &CGP) {
+ MatcherGen Gen(Pattern, CGP);
+
+ // Generate the code for the matcher.
+ if (Gen.EmitMatcherCode(Variant))
+ return 0;
+
+ // FIXME2: Kill extra MoveParent commands at the end of the matcher sequence.
+ // FIXME2: Split result code out to another table, and make the matcher end
+ // with an "Emit <index>" command. This allows result generation stuff to be
+ // shared and factored?
+
+ // If the match succeeds, then we generate Pattern.
+ Gen.EmitResultCode();
+
+ // Unconditional match.
+ return Gen.GetMatcher();
+}
+
+
+
diff --git a/utils/TableGen/DAGISelMatcherOpt.cpp b/utils/TableGen/DAGISelMatcherOpt.cpp
new file mode 100644
index 0000000..910c4c5
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -0,0 +1,509 @@
+//===- DAGISelMatcherOpt.cpp - Optimize a DAG Matcher ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the DAG Matcher optimizer.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "isel-opt"
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
+using namespace llvm;
+
+/// ContractNodes - Turn multiple matcher node patterns like 'MoveChild+Record'
+/// into single compound nodes like RecordChild.
+static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
+ const CodeGenDAGPatterns &CGP) {
+ // If we reached the end of the chain, we're done.
+ Matcher *N = MatcherPtr.get();
+ if (N == 0) return;
+
+ // If we have a scope node, walk down all of the children.
+ if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
+ for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
+ OwningPtr<Matcher> Child(Scope->takeChild(i));
+ ContractNodes(Child, CGP);
+ Scope->resetChild(i, Child.take());
+ }
+ return;
+ }
+
+ // If we found a movechild node with a node that comes in a 'foochild' form,
+ // transform it.
+ if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N)) {
+ Matcher *New = 0;
+ if (RecordMatcher *RM = dyn_cast<RecordMatcher>(MC->getNext()))
+ New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor(),
+ RM->getResultNo());
+
+ if (CheckTypeMatcher *CT= dyn_cast<CheckTypeMatcher>(MC->getNext()))
+ New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType());
+
+ if (New) {
+ // Insert the new node.
+ New->setNext(MatcherPtr.take());
+ MatcherPtr.reset(New);
+ // Remove the old one.
+ MC->setNext(MC->getNext()->takeNext());
+ return ContractNodes(MatcherPtr, CGP);
+ }
+ }
+
+ // Zap movechild -> moveparent.
+ if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N))
+ if (MoveParentMatcher *MP =
+ dyn_cast<MoveParentMatcher>(MC->getNext())) {
+ MatcherPtr.reset(MP->takeNext());
+ return ContractNodes(MatcherPtr, CGP);
+ }
+
+ // Turn EmitNode->MarkFlagResults->CompleteMatch into
+ // MarkFlagResults->EmitNode->CompleteMatch when we can to encourage
+ // MorphNodeTo formation. This is safe because MarkFlagResults never refers
+ // to the root of the pattern.
+ if (isa<EmitNodeMatcher>(N) && isa<MarkFlagResultsMatcher>(N->getNext()) &&
+ isa<CompleteMatchMatcher>(N->getNext()->getNext())) {
+ // Unlink the two nodes from the list.
+ Matcher *EmitNode = MatcherPtr.take();
+ Matcher *MFR = EmitNode->takeNext();
+ Matcher *Tail = MFR->takeNext();
+
+ // Relink them.
+ MatcherPtr.reset(MFR);
+ MFR->setNext(EmitNode);
+ EmitNode->setNext(Tail);
+ return ContractNodes(MatcherPtr, CGP);
+ }
+
+ // Turn EmitNode->CompleteMatch into MorphNodeTo if we can.
+ if (EmitNodeMatcher *EN = dyn_cast<EmitNodeMatcher>(N))
+ if (CompleteMatchMatcher *CM =
+ dyn_cast<CompleteMatchMatcher>(EN->getNext())) {
+ // We can only use MorphNodeTo if the result values match up.
+ unsigned RootResultFirst = EN->getFirstResultSlot();
+ bool ResultsMatch = true;
+ for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
+ if (CM->getResult(i) != RootResultFirst+i)
+ ResultsMatch = false;
+
+ // If the selected node defines a subset of the flag/chain results, we
+ // can't use MorphNodeTo. For example, we can't use MorphNodeTo if the
+ // matched pattern has a chain but the root node doesn't.
+ const PatternToMatch &Pattern = CM->getPattern();
+
+ if (!EN->hasChain() &&
+ Pattern.getSrcPattern()->NodeHasProperty(SDNPHasChain, CGP))
+ ResultsMatch = false;
+
+ // If the matched node has a flag and the output root doesn't, we can't
+ // use MorphNodeTo.
+ //
+ // NOTE: Strictly speaking, we don't have to check for the flag here
+ // because the code in the pattern generator doesn't handle it right. We
+ // do it anyway for thoroughness.
+ if (!EN->hasOutFlag() &&
+ Pattern.getSrcPattern()->NodeHasProperty(SDNPOutFlag, CGP))
+ ResultsMatch = false;
+
+
+ // If the root result node defines more results than the source root node
+ // *and* has a chain or flag input, then we can't match it because it
+ // would end up replacing the extra result with the chain/flag.
+#if 0
+ if ((EN->hasFlag() || EN->hasChain()) &&
+ EN->getNumNonChainFlagVTs() > ... need to get no results reliably ...)
+ ResultMatch = false;
+#endif
+
+ if (ResultsMatch) {
+ const SmallVectorImpl<MVT::SimpleValueType> &VTs = EN->getVTList();
+ const SmallVectorImpl<unsigned> &Operands = EN->getOperandList();
+ MatcherPtr.reset(new MorphNodeToMatcher(EN->getOpcodeName(),
+ VTs.data(), VTs.size(),
+ Operands.data(),Operands.size(),
+ EN->hasChain(), EN->hasInFlag(),
+ EN->hasOutFlag(),
+ EN->hasMemRefs(),
+ EN->getNumFixedArityOperands(),
+ Pattern));
+ return;
+ }
+
+ // FIXME2: Kill off all the SelectionDAG::SelectNodeTo and getMachineNode
+ // variants.
+ }
+
+ ContractNodes(N->getNextPtr(), CGP);
+
+
+ // If we have a CheckType/CheckChildType/Record node followed by a
+ // CheckOpcode, invert the two nodes. We prefer to do structural checks
+ // before type checks, as this opens opportunities for factoring on targets
+ // like X86 where many operations are valid on multiple types.
+ if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
+ isa<RecordMatcher>(N)) &&
+ isa<CheckOpcodeMatcher>(N->getNext())) {
+ // Unlink the two nodes from the list.
+ Matcher *CheckType = MatcherPtr.take();
+ Matcher *CheckOpcode = CheckType->takeNext();
+ Matcher *Tail = CheckOpcode->takeNext();
+
+ // Relink them.
+ MatcherPtr.reset(CheckOpcode);
+ CheckOpcode->setNext(CheckType);
+ CheckType->setNext(Tail);
+ return ContractNodes(MatcherPtr, CGP);
+ }
+}
+
+/// SinkPatternPredicates - Pattern predicates can be checked at any level of
+/// the matching tree. The generator dumps them at the top level of the pattern
+/// though, which prevents factoring from being able to see past them. This
+/// optimization sinks them as far down into the pattern as possible.
+///
+/// Conceptually, we'd like to sink these predicates all the way to the last
+/// matcher predicate in the series. However, it turns out that some
+/// ComplexPatterns have side effects on the graph, so we really don't want to
+/// run a the complex pattern if the pattern predicate will fail. For this
+/// reason, we refuse to sink the pattern predicate past a ComplexPattern.
+///
+static void SinkPatternPredicates(OwningPtr<Matcher> &MatcherPtr) {
+ // Recursively scan for a PatternPredicate.
+ // If we reached the end of the chain, we're done.
+ Matcher *N = MatcherPtr.get();
+ if (N == 0) return;
+
+ // Walk down all members of a scope node.
+ if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
+ for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
+ OwningPtr<Matcher> Child(Scope->takeChild(i));
+ SinkPatternPredicates(Child);
+ Scope->resetChild(i, Child.take());
+ }
+ return;
+ }
+
+ // If this node isn't a CheckPatternPredicateMatcher we keep scanning until
+ // we find one.
+ CheckPatternPredicateMatcher *CPPM =dyn_cast<CheckPatternPredicateMatcher>(N);
+ if (CPPM == 0)
+ return SinkPatternPredicates(N->getNextPtr());
+
+ // Ok, we found one, lets try to sink it. Check if we can sink it past the
+ // next node in the chain. If not, we won't be able to change anything and
+ // might as well bail.
+ if (!CPPM->getNext()->isSafeToReorderWithPatternPredicate())
+ return;
+
+ // Okay, we know we can sink it past at least one node. Unlink it from the
+ // chain and scan for the new insertion point.
+ MatcherPtr.take(); // Don't delete CPPM.
+ MatcherPtr.reset(CPPM->takeNext());
+
+ N = MatcherPtr.get();
+ while (N->getNext()->isSafeToReorderWithPatternPredicate())
+ N = N->getNext();
+
+ // At this point, we want to insert CPPM after N.
+ CPPM->setNext(N->takeNext());
+ N->setNext(CPPM);
+}
+
+/// FindNodeWithKind - Scan a series of matchers looking for a matcher with a
+/// specified kind. Return null if we didn't find one otherwise return the
+/// matcher.
+static Matcher *FindNodeWithKind(Matcher *M, Matcher::KindTy Kind) {
+ for (; M; M = M->getNext())
+ if (M->getKind() == Kind)
+ return M;
+ return 0;
+}
+
+
+/// FactorNodes - Turn matches like this:
+/// Scope
+/// OPC_CheckType i32
+/// ABC
+/// OPC_CheckType i32
+/// XYZ
+/// into:
+/// OPC_CheckType i32
+/// Scope
+/// ABC
+/// XYZ
+///
+static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
+ // If we reached the end of the chain, we're done.
+ Matcher *N = MatcherPtr.get();
+ if (N == 0) return;
+
+ // If this is not a push node, just scan for one.
+ ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N);
+ if (Scope == 0)
+ return FactorNodes(N->getNextPtr());
+
+ // Okay, pull together the children of the scope node into a vector so we can
+ // inspect it more easily. While we're at it, bucket them up by the hash
+ // code of their first predicate.
+ SmallVector<Matcher*, 32> OptionsToMatch;
+
+ for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
+ // Factor the subexpression.
+ OwningPtr<Matcher> Child(Scope->takeChild(i));
+ FactorNodes(Child);
+
+ if (Matcher *N = Child.take())
+ OptionsToMatch.push_back(N);
+ }
+
+ SmallVector<Matcher*, 32> NewOptionsToMatch;
+
+ // Loop over options to match, merging neighboring patterns with identical
+ // starting nodes into a shared matcher.
+ for (unsigned OptionIdx = 0, e = OptionsToMatch.size(); OptionIdx != e;) {
+ // Find the set of matchers that start with this node.
+ Matcher *Optn = OptionsToMatch[OptionIdx++];
+
+ if (OptionIdx == e) {
+ NewOptionsToMatch.push_back(Optn);
+ continue;
+ }
+
+ // See if the next option starts with the same matcher. If the two
+ // neighbors *do* start with the same matcher, we can factor the matcher out
+ // of at least these two patterns. See what the maximal set we can merge
+ // together is.
+ SmallVector<Matcher*, 8> EqualMatchers;
+ EqualMatchers.push_back(Optn);
+
+ // Factor all of the known-equal matchers after this one into the same
+ // group.
+ while (OptionIdx != e && OptionsToMatch[OptionIdx]->isEqual(Optn))
+ EqualMatchers.push_back(OptionsToMatch[OptionIdx++]);
+
+ // If we found a non-equal matcher, see if it is contradictory with the
+ // current node. If so, we know that the ordering relation between the
+ // current sets of nodes and this node don't matter. Look past it to see if
+ // we can merge anything else into this matching group.
+ unsigned Scan = OptionIdx;
+ while (1) {
+ // If we ran out of stuff to scan, we're done.
+ if (Scan == e) break;
+
+ Matcher *ScanMatcher = OptionsToMatch[Scan];
+
+ // If we found an entry that matches out matcher, merge it into the set to
+ // handle.
+ if (Optn->isEqual(ScanMatcher)) {
+ // If is equal after all, add the option to EqualMatchers and remove it
+ // from OptionsToMatch.
+ EqualMatchers.push_back(ScanMatcher);
+ OptionsToMatch.erase(OptionsToMatch.begin()+Scan);
+ --e;
+ continue;
+ }
+
+ // If the option we're checking for contradicts the start of the list,
+ // skip over it.
+ if (Optn->isContradictory(ScanMatcher)) {
+ ++Scan;
+ continue;
+ }
+
+ // If we're scanning for a simple node, see if it occurs later in the
+ // sequence. If so, and if we can move it up, it might be contradictory
+ // or the same as what we're looking for. If so, reorder it.
+ if (Optn->isSimplePredicateOrRecordNode()) {
+ Matcher *M2 = FindNodeWithKind(ScanMatcher, Optn->getKind());
+ if (M2 != 0 && M2 != ScanMatcher &&
+ M2->canMoveBefore(ScanMatcher) &&
+ (M2->isEqual(Optn) || M2->isContradictory(Optn))) {
+ Matcher *MatcherWithoutM2 = ScanMatcher->unlinkNode(M2);
+ M2->setNext(MatcherWithoutM2);
+ OptionsToMatch[Scan] = M2;
+ continue;
+ }
+ }
+
+ // Otherwise, we don't know how to handle this entry, we have to bail.
+ break;
+ }
+
+ if (Scan != e &&
+ // Don't print it's obvious nothing extra could be merged anyway.
+ Scan+1 != e) {
+ DEBUG(errs() << "Couldn't merge this:\n";
+ Optn->print(errs(), 4);
+ errs() << "into this:\n";
+ OptionsToMatch[Scan]->print(errs(), 4);
+ if (Scan+1 != e)
+ OptionsToMatch[Scan+1]->printOne(errs());
+ if (Scan+2 < e)
+ OptionsToMatch[Scan+2]->printOne(errs());
+ errs() << "\n");
+ }
+
+ // If we only found one option starting with this matcher, no factoring is
+ // possible.
+ if (EqualMatchers.size() == 1) {
+ NewOptionsToMatch.push_back(EqualMatchers[0]);
+ continue;
+ }
+
+ // Factor these checks by pulling the first node off each entry and
+ // discarding it. Take the first one off the first entry to reuse.
+ Matcher *Shared = Optn;
+ Optn = Optn->takeNext();
+ EqualMatchers[0] = Optn;
+
+ // Remove and delete the first node from the other matchers we're factoring.
+ for (unsigned i = 1, e = EqualMatchers.size(); i != e; ++i) {
+ Matcher *Tmp = EqualMatchers[i]->takeNext();
+ delete EqualMatchers[i];
+ EqualMatchers[i] = Tmp;
+ }
+
+ Shared->setNext(new ScopeMatcher(&EqualMatchers[0], EqualMatchers.size()));
+
+ // Recursively factor the newly created node.
+ FactorNodes(Shared->getNextPtr());
+
+ NewOptionsToMatch.push_back(Shared);
+ }
+
+ // If we're down to a single pattern to match, then we don't need this scope
+ // anymore.
+ if (NewOptionsToMatch.size() == 1) {
+ MatcherPtr.reset(NewOptionsToMatch[0]);
+ return;
+ }
+
+ if (NewOptionsToMatch.empty()) {
+ MatcherPtr.reset(0);
+ return;
+ }
+
+ // If our factoring failed (didn't achieve anything) see if we can simplify in
+ // other ways.
+
+ // Check to see if all of the leading entries are now opcode checks. If so,
+ // we can convert this Scope to be a OpcodeSwitch instead.
+ bool AllOpcodeChecks = true, AllTypeChecks = true;
+ for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
+ // Check to see if this breaks a series of CheckOpcodeMatchers.
+ if (AllOpcodeChecks &&
+ !isa<CheckOpcodeMatcher>(NewOptionsToMatch[i])) {
+#if 0
+ if (i > 3) {
+ errs() << "FAILING OPC #" << i << "\n";
+ NewOptionsToMatch[i]->dump();
+ }
+#endif
+ AllOpcodeChecks = false;
+ }
+
+ // Check to see if this breaks a series of CheckTypeMatcher's.
+ if (AllTypeChecks) {
+ CheckTypeMatcher *CTM =
+ cast_or_null<CheckTypeMatcher>(FindNodeWithKind(NewOptionsToMatch[i],
+ Matcher::CheckType));
+ if (CTM == 0 ||
+ // iPTR checks could alias any other case without us knowing, don't
+ // bother with them.
+ CTM->getType() == MVT::iPTR ||
+ // If the CheckType isn't at the start of the list, see if we can move
+ // it there.
+ !CTM->canMoveBefore(NewOptionsToMatch[i])) {
+#if 0
+ if (i > 3 && AllTypeChecks) {
+ errs() << "FAILING TYPE #" << i << "\n";
+ NewOptionsToMatch[i]->dump();
+ }
+#endif
+ AllTypeChecks = false;
+ }
+ }
+ }
+
+ // If all the options are CheckOpcode's, we can form the SwitchOpcode, woot.
+ if (AllOpcodeChecks) {
+ StringSet<> Opcodes;
+ SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases;
+ for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
+ CheckOpcodeMatcher *COM = cast<CheckOpcodeMatcher>(NewOptionsToMatch[i]);
+ assert(Opcodes.insert(COM->getOpcode().getEnumName()) &&
+ "Duplicate opcodes not factored?");
+ Cases.push_back(std::make_pair(&COM->getOpcode(), COM->getNext()));
+ }
+
+ MatcherPtr.reset(new SwitchOpcodeMatcher(&Cases[0], Cases.size()));
+ return;
+ }
+
+ // If all the options are CheckType's, we can form the SwitchType, woot.
+ if (AllTypeChecks) {
+ DenseMap<unsigned, unsigned> TypeEntry;
+ SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
+ for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
+ CheckTypeMatcher *CTM =
+ cast_or_null<CheckTypeMatcher>(FindNodeWithKind(NewOptionsToMatch[i],
+ Matcher::CheckType));
+ Matcher *MatcherWithoutCTM = NewOptionsToMatch[i]->unlinkNode(CTM);
+ MVT::SimpleValueType CTMTy = CTM->getType();
+ delete CTM;
+
+ unsigned &Entry = TypeEntry[CTMTy];
+ if (Entry != 0) {
+ // If we have unfactored duplicate types, then we should factor them.
+ Matcher *PrevMatcher = Cases[Entry-1].second;
+ if (ScopeMatcher *SM = dyn_cast<ScopeMatcher>(PrevMatcher)) {
+ SM->setNumChildren(SM->getNumChildren()+1);
+ SM->resetChild(SM->getNumChildren()-1, MatcherWithoutCTM);
+ continue;
+ }
+
+ Matcher *Entries[2] = { PrevMatcher, MatcherWithoutCTM };
+ Cases[Entry-1].second = new ScopeMatcher(Entries, 2);
+ continue;
+ }
+
+ Entry = Cases.size()+1;
+ Cases.push_back(std::make_pair(CTMTy, MatcherWithoutCTM));
+ }
+
+ if (Cases.size() != 1) {
+ MatcherPtr.reset(new SwitchTypeMatcher(&Cases[0], Cases.size()));
+ } else {
+ // If we factored and ended up with one case, create it now.
+ MatcherPtr.reset(new CheckTypeMatcher(Cases[0].first));
+ MatcherPtr->setNext(Cases[0].second);
+ }
+ return;
+ }
+
+
+ // Reassemble the Scope node with the adjusted children.
+ Scope->setNumChildren(NewOptionsToMatch.size());
+ for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i)
+ Scope->resetChild(i, NewOptionsToMatch[i]);
+}
+
+Matcher *llvm::OptimizeMatcher(Matcher *TheMatcher,
+ const CodeGenDAGPatterns &CGP) {
+ OwningPtr<Matcher> MatcherPtr(TheMatcher);
+ ContractNodes(MatcherPtr, CGP);
+ SinkPatternPredicates(MatcherPtr);
+ FactorNodes(MatcherPtr);
+ return MatcherPtr.take();
+}
diff --git a/utils/TableGen/InstrEnumEmitter.cpp b/utils/TableGen/InstrEnumEmitter.cpp
index f382d34..d1e7f3d 100644
--- a/utils/TableGen/InstrEnumEmitter.cpp
+++ b/utils/TableGen/InstrEnumEmitter.cpp
@@ -29,7 +29,7 @@ void InstrEnumEmitter::run(raw_ostream &OS) {
std::string Namespace;
for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
E = Target.inst_end(); II != E; ++II) {
- if (II->second.Namespace != "TargetInstrInfo") {
+ if (II->second.Namespace != "TargetOpcode") {
Namespace = II->second.Namespace;
break;
}
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index 2abc94b..da2d54f 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -43,6 +43,7 @@ const unsigned TabWidth = 4;
const unsigned Indent1 = TabWidth*1;
const unsigned Indent2 = TabWidth*2;
const unsigned Indent3 = TabWidth*3;
+const unsigned Indent4 = TabWidth*4;
// Default help string.
const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED";
@@ -229,7 +230,8 @@ namespace OptionDescriptionFlags {
enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
ReallyHidden = 0x4, Extern = 0x8,
OneOrMore = 0x10, Optional = 0x20,
- CommaSeparated = 0x40 };
+ CommaSeparated = 0x40, ForwardNotSplit = 0x80,
+ ZeroOrMore = 0x100 };
}
/// OptionDescription - Represents data contained in a single
@@ -259,6 +261,9 @@ struct OptionDescription {
/// Merge - Merge two option descriptions.
void Merge (const OptionDescription& other);
+ /// CheckConsistency - Check that the flags are consistent.
+ void CheckConsistency() const;
+
// Misc convenient getters/setters.
bool isAlias() const;
@@ -271,12 +276,18 @@ struct OptionDescription {
bool isExtern() const;
void setExtern();
+ bool isForwardNotSplit() const;
+ void setForwardNotSplit();
+
bool isRequired() const;
void setRequired();
bool isOneOrMore() const;
void setOneOrMore();
+ bool isZeroOrMore() const;
+ void setZeroOrMore();
+
bool isOptional() const;
void setOptional();
@@ -297,6 +308,20 @@ struct OptionDescription {
};
+void OptionDescription::CheckConsistency() const {
+ unsigned i = 0;
+
+ i += this->isRequired();
+ i += this->isOptional();
+ i += this->isOneOrMore();
+ i += this->isZeroOrMore();
+
+ if (i > 1) {
+ throw "Only one of (required), (optional), (one_or_more) or "
+ "(zero_or_more) properties is allowed!";
+ }
+}
+
void OptionDescription::Merge (const OptionDescription& other)
{
if (other.Type != Type)
@@ -327,6 +352,13 @@ void OptionDescription::setCommaSeparated() {
Flags |= OptionDescriptionFlags::CommaSeparated;
}
+bool OptionDescription::isForwardNotSplit() const {
+ return Flags & OptionDescriptionFlags::ForwardNotSplit;
+}
+void OptionDescription::setForwardNotSplit() {
+ Flags |= OptionDescriptionFlags::ForwardNotSplit;
+}
+
bool OptionDescription::isExtern() const {
return Flags & OptionDescriptionFlags::Extern;
}
@@ -348,6 +380,13 @@ void OptionDescription::setOneOrMore() {
Flags |= OptionDescriptionFlags::OneOrMore;
}
+bool OptionDescription::isZeroOrMore() const {
+ return Flags & OptionDescriptionFlags::ZeroOrMore;
+}
+void OptionDescription::setZeroOrMore() {
+ Flags |= OptionDescriptionFlags::ZeroOrMore;
+}
+
bool OptionDescription::isOptional() const {
return Flags & OptionDescriptionFlags::Optional;
}
@@ -582,10 +621,13 @@ public:
AddHandler("init", &CollectOptionProperties::onInit);
AddHandler("multi_val", &CollectOptionProperties::onMultiVal);
AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore);
+ AddHandler("zero_or_more", &CollectOptionProperties::onZeroOrMore);
AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
AddHandler("required", &CollectOptionProperties::onRequired);
AddHandler("optional", &CollectOptionProperties::onOptional);
AddHandler("comma_separated", &CollectOptionProperties::onCommaSeparated);
+ AddHandler("forward_not_split",
+ &CollectOptionProperties::onForwardNotSplit);
staticMembersInitialized_ = true;
}
@@ -629,12 +671,18 @@ private:
optDesc_.setCommaSeparated();
}
+ void onForwardNotSplit (const DagInit& d) {
+ CheckNumberOfArguments(d, 0);
+ if (!optDesc_.isParameter())
+ throw "'forward_not_split' is valid only for parameter options!";
+ optDesc_.setForwardNotSplit();
+ }
+
void onRequired (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (optDesc_.isOneOrMore() || optDesc_.isOptional())
- throw "Only one of (required), (optional) or "
- "(one_or_more) properties is allowed!";
+
optDesc_.setRequired();
+ optDesc_.CheckConsistency();
}
void onInit (const DagInit& d) {
@@ -653,24 +701,31 @@ private:
void onOneOrMore (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (optDesc_.isRequired() || optDesc_.isOptional())
- throw "Only one of (required), (optional) or "
- "(one_or_more) properties is allowed!";
- if (!OptionType::IsList(optDesc_.Type))
- llvm::errs() << "Warning: specifying the 'one_or_more' property "
- "on a non-list option will have no effect.\n";
+
optDesc_.setOneOrMore();
+ optDesc_.CheckConsistency();
+ }
+
+ void onZeroOrMore (const DagInit& d) {
+ CheckNumberOfArguments(d, 0);
+
+ if (OptionType::IsList(optDesc_.Type))
+ llvm::errs() << "Warning: specifying the 'zero_or_more' property "
+ "on a list option has no effect.\n";
+
+ optDesc_.setZeroOrMore();
+ optDesc_.CheckConsistency();
}
void onOptional (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (optDesc_.isRequired() || optDesc_.isOneOrMore())
- throw "Only one of (required), (optional) or "
- "(one_or_more) properties is allowed!";
+
if (!OptionType::IsList(optDesc_.Type))
llvm::errs() << "Warning: specifying the 'optional' property"
- "on a non-list option will have no effect.\n";
+ "on a non-list option has no effect.\n";
+
optDesc_.setOptional();
+ optDesc_.CheckConsistency();
}
void onMultiVal (const DagInit& d) {
@@ -761,9 +816,12 @@ struct ToolDescription : public RefCountedBase<ToolDescription> {
Init* CmdLine;
Init* Actions;
StrVector InLanguage;
+ std::string InFileOption;
+ std::string OutFileOption;
std::string OutLanguage;
std::string OutputSuffix;
unsigned Flags;
+ const Init* OnEmpty;
// Various boolean properties
void setSink() { Flags |= ToolFlags::Sink; }
@@ -773,9 +831,13 @@ struct ToolDescription : public RefCountedBase<ToolDescription> {
// Default ctor here is needed because StringMap can only store
// DefaultConstructible objects
- ToolDescription() : CmdLine(0), Actions(0), Flags(0) {}
+ ToolDescription ()
+ : CmdLine(0), Actions(0), OutFileOption("-o"),
+ Flags(0), OnEmpty(0)
+ {}
ToolDescription (const std::string& n)
- : Name(n), CmdLine(0), Actions(0), Flags(0)
+ : Name(n), CmdLine(0), Actions(0), OutFileOption("-o"),
+ Flags(0), OnEmpty(0)
{}
};
@@ -806,12 +868,17 @@ public:
if (!staticMembersInitialized_) {
AddHandler("actions", &CollectToolProperties::onActions);
- AddHandler("cmd_line", &CollectToolProperties::onCmdLine);
+ AddHandler("command", &CollectToolProperties::onCommand);
AddHandler("in_language", &CollectToolProperties::onInLanguage);
AddHandler("join", &CollectToolProperties::onJoin);
AddHandler("out_language", &CollectToolProperties::onOutLanguage);
+
+ AddHandler("out_file_option", &CollectToolProperties::onOutFileOption);
+ AddHandler("in_file_option", &CollectToolProperties::onInFileOption);
+
AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix);
AddHandler("sink", &CollectToolProperties::onSink);
+ AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty);
staticMembersInitialized_ = true;
}
@@ -836,7 +903,7 @@ private:
toolDesc_.Actions = Case;
}
- void onCmdLine (const DagInit& d) {
+ void onCommand (const DagInit& d) {
CheckNumberOfArguments(d, 1);
toolDesc_.CmdLine = d.getArg(0);
}
@@ -878,6 +945,16 @@ private:
toolDesc_.OutLanguage = InitPtrToString(d.getArg(0));
}
+ void onOutFileOption (const DagInit& d) {
+ CheckNumberOfArguments(d, 1);
+ toolDesc_.OutFileOption = InitPtrToString(d.getArg(0));
+ }
+
+ void onInFileOption (const DagInit& d) {
+ CheckNumberOfArguments(d, 1);
+ toolDesc_.InFileOption = InitPtrToString(d.getArg(0));
+ }
+
void onOutputSuffix (const DagInit& d) {
CheckNumberOfArguments(d, 1);
toolDesc_.OutputSuffix = InitPtrToString(d.getArg(0));
@@ -888,6 +965,10 @@ private:
toolDesc_.setSink();
}
+ void onWorksOnEmpty (const DagInit& d) {
+ toolDesc_.OnEmpty = d.getArg(0);
+ }
+
};
/// CollectToolDescriptions - Gather information about tool properties
@@ -1490,7 +1571,7 @@ public:
/// EmitCaseConstructHandler - Emit code that handles the 'case'
/// construct. Takes a function object that should emit code for every case
/// clause. Implemented on top of WalkCase.
-/// Callback's type is void F(Init* Statement, unsigned IndentLevel,
+/// Callback's type is void F(const Init* Statement, unsigned IndentLevel,
/// raw_ostream& O).
/// EmitElseIf parameter controls the type of condition that is emitted ('if
/// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..) {..}
@@ -1699,82 +1780,41 @@ void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
if (StrVec.empty())
throw "Tool '" + ToolName + "' has empty command line!";
- StrVector::const_iterator I = StrVec.begin(), E = StrVec.end();
+ StrVector::const_iterator B = StrVec.begin(), E = StrVec.end();
- // If there is a hook invocation on the place of the first command, skip it.
+ // Emit the command itself.
assert(!StrVec[0].empty());
+ O.indent(IndentLevel) << "cmd = ";
if (StrVec[0][0] == '$') {
- while (I != E && (*I)[0] != ')' )
- ++I;
-
- // Skip the ')' symbol.
- ++I;
+ B = SubstituteSpecialCommands(B, E, IsJoin, O);
+ ++B;
}
else {
- ++I;
+ O << '"' << StrVec[0] << '"';
+ ++B;
}
+ O << ";\n";
- bool hasINFILE = false;
+ // Go through the command arguments.
+ assert(B <= E);
+ for (; B != E; ++B) {
+ const std::string& cmd = *B;
- for (; I != E; ++I) {
- const std::string& cmd = *I;
assert(!cmd.empty());
O.indent(IndentLevel);
+
if (cmd.at(0) == '$') {
- if (cmd == "$INFILE") {
- hasINFILE = true;
- if (IsJoin) {
- O << "for (PathVector::const_iterator B = inFiles.begin()"
- << ", E = inFiles.end();\n";
- O.indent(IndentLevel) << "B != E; ++B)\n";
- O.indent(IndentLevel + Indent1) << "vec.push_back(B->str());\n";
- }
- else {
- O << "vec.push_back(inFile.str());\n";
- }
- }
- else if (cmd == "$OUTFILE") {
- O << "vec.push_back(\"\");\n";
- O.indent(IndentLevel) << "out_file_index = vec.size()-1;\n";
- }
- else {
- O << "vec.push_back(";
- I = SubstituteSpecialCommands(I, E, IsJoin, O);
- O << ");\n";
- }
+ O << "vec.push_back(std::make_pair(0, ";
+ B = SubstituteSpecialCommands(B, E, IsJoin, O);
+ O << "));\n";
}
else {
- O << "vec.push_back(\"" << cmd << "\");\n";
+ O << "vec.push_back(std::make_pair(0, \"" << cmd << "\"));\n";
}
}
- if (!hasINFILE)
- throw "Tool '" + ToolName + "' doesn't take any input!";
- O.indent(IndentLevel) << "cmd = ";
- if (StrVec[0][0] == '$')
- SubstituteSpecialCommands(StrVec.begin(), StrVec.end(), IsJoin, O);
- else
- O << '"' << StrVec[0] << '"';
- O << ";\n";
}
-/// EmitCmdLineVecFillCallback - A function object wrapper around
-/// EmitCmdLineVecFill(). Used by EmitGenerateActionMethod() as an
-/// argument to EmitCaseConstructHandler().
-class EmitCmdLineVecFillCallback {
- bool IsJoin;
- const std::string& ToolName;
- public:
- EmitCmdLineVecFillCallback(bool J, const std::string& TN)
- : IsJoin(J), ToolName(TN) {}
-
- void operator()(const Init* Statement, unsigned IndentLevel,
- raw_ostream& O) const
- {
- EmitCmdLineVecFill(Statement, ToolName, IsJoin, IndentLevel, O);
- }
-};
-
/// EmitForwardOptionPropertyHandlingCode - Helper function used to
/// implement EmitActionHandler. Emits code for
/// handling the (forward) and (forward_as) option properties.
@@ -1789,15 +1829,30 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
switch (D.Type) {
case OptionType::Switch:
- O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\");\n";
+ O.indent(IndentLevel)
+ << "vec.push_back(std::make_pair(" << D.GenVariableName()
+ << ".getPosition(), \"" << Name << "\"));\n";
break;
case OptionType::Parameter:
- O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\");\n";
- O.indent(IndentLevel) << "vec.push_back(" << D.GenVariableName() << ");\n";
+ O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+ << D.GenVariableName()
+ <<".getPosition(), \"" << Name;
+
+ if (!D.isForwardNotSplit()) {
+ O << "\"));\n";
+ O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+ << D.GenVariableName() << ".getPosition(), "
+ << D.GenVariableName() << "));\n";
+ }
+ else {
+ O << "=\" + " << D.GenVariableName() << "));\n";
+ }
break;
case OptionType::Prefix:
- O.indent(IndentLevel) << "vec.push_back(\"" << Name << "\" + "
- << D.GenVariableName() << ");\n";
+ O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+ << D.GenVariableName() << ".getPosition(), \""
+ << Name << "\" + "
+ << D.GenVariableName() << "));\n";
break;
case OptionType::PrefixList:
O.indent(IndentLevel)
@@ -1805,11 +1860,15 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
<< "::iterator B = " << D.GenVariableName() << ".begin(),\n";
O.indent(IndentLevel)
<< "E = " << D.GenVariableName() << ".end(); B != E;) {\n";
- O.indent(IndentLevel1) << "vec.push_back(\"" << Name << "\" + " << "*B);\n";
+ O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
+ << ".getPosition(B - " << D.GenVariableName()
+ << ".begin());\n";
+ O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
+ << Name << "\" + " << "*B));\n";
O.indent(IndentLevel1) << "++B;\n";
for (int i = 1, j = D.MultiVal; i < j; ++i) {
- O.indent(IndentLevel1) << "vec.push_back(*B);\n";
+ O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
O.indent(IndentLevel1) << "++B;\n";
}
@@ -1821,10 +1880,14 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
<< D.GenVariableName() << ".begin(),\n";
O.indent(IndentLevel) << "E = " << D.GenVariableName()
<< ".end() ; B != E;) {\n";
- O.indent(IndentLevel1) << "vec.push_back(\"" << Name << "\");\n";
+ O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
+ << ".getPosition(B - " << D.GenVariableName()
+ << ".begin());\n";
+ O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
+ << Name << "\"));\n";
for (int i = 0, j = D.MultiVal; i < j; ++i) {
- O.indent(IndentLevel1) << "vec.push_back(*B);\n";
+ O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n";
O.indent(IndentLevel1) << "++B;\n";
}
@@ -1906,7 +1969,8 @@ class EmitActionHandlersCallback :
{
CheckNumberOfArguments(Dag, 1);
this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)),
- "vec.push_back(", ");\n", IndentLevel, O);
+ "vec.push_back(std::make_pair(65536, ", "));\n",
+ IndentLevel, O);
}
void onForward (const DagInit& Dag,
@@ -1936,13 +2000,23 @@ class EmitActionHandlersCallback :
const OptionDescription& D = OptDescs.FindListOrParameter(Name);
if (D.isParameter()) {
- O.indent(IndentLevel) << "vec.push_back("
- << D.GenVariableName() << ");\n";
+ O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+ << D.GenVariableName() << ".getPosition(), "
+ << D.GenVariableName() << "));\n";
}
else {
- O.indent(IndentLevel) << "std::copy(" << D.GenVariableName()
- << ".begin(), " << D.GenVariableName()
- << ".end(), std::back_inserter(vec));\n";
+ O.indent(IndentLevel) << "for (cl::list<std::string>::iterator B = "
+ << D.GenVariableName() << ".begin(), \n";
+ O.indent(IndentLevel + Indent1) << " E = " << D.GenVariableName()
+ << ".end(); B != E; ++B)\n";
+ O.indent(IndentLevel) << "{\n";
+ O.indent(IndentLevel + Indent1)
+ << "unsigned pos = " << D.GenVariableName()
+ << ".getPosition(B - " << D.GenVariableName()
+ << ".begin());\n";
+ O.indent(IndentLevel + Indent1)
+ << "vec.push_back(std::make_pair(pos, *B));\n";
+ O.indent(IndentLevel) << "}\n";
}
}
@@ -1954,9 +2028,18 @@ class EmitActionHandlersCallback :
const std::string& Hook = InitPtrToString(Dag.getArg(1));
const OptionDescription& D = OptDescs.FindListOrParameter(Name);
- O.indent(IndentLevel) << "vec.push_back(" << "hooks::"
- << Hook << "(" << D.GenVariableName()
- << (D.isParameter() ? ".c_str()" : "") << "));\n";
+ O.indent(IndentLevel) << "vec.push_back(std::make_pair("
+ << D.GenVariableName() << ".getPosition("
+ << (D.isList() ? "0" : "") << "), "
+ << "hooks::" << Hook << "(" << D.GenVariableName()
+ << (D.isParameter() ? ".c_str()" : "") << ")));\n";
+ }
+
+ void onNoOutFile (const DagInit& Dag,
+ unsigned IndentLevel, raw_ostream& O) const
+ {
+ CheckNumberOfArguments(Dag, 0);
+ O.indent(IndentLevel) << "no_out_file = true;\n";
}
void onOutputSuffix (const DagInit& Dag,
@@ -1995,12 +2078,15 @@ class EmitActionHandlersCallback :
AddHandler("forward_value", &EmitActionHandlersCallback::onForwardValue);
AddHandler("forward_transformed_value",
&EmitActionHandlersCallback::onForwardTransformedValue);
+ AddHandler("no_out_file",
+ &EmitActionHandlersCallback::onNoOutFile);
AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix);
AddHandler("stop_compilation",
&EmitActionHandlersCallback::onStopCompilation);
AddHandler("unpack_values",
&EmitActionHandlersCallback::onUnpackValues);
+
staticMembersInitialized_ = true;
}
}
@@ -2012,58 +2098,6 @@ class EmitActionHandlersCallback :
}
};
-bool IsOutFileIndexCheckRequiredStr (const Init* CmdLine) {
- StrVector StrVec;
- TokenizeCmdLine(InitPtrToString(CmdLine), StrVec);
-
- for (StrVector::const_iterator I = StrVec.begin(), E = StrVec.end();
- I != E; ++I) {
- if (*I == "$OUTFILE")
- return false;
- }
-
- return true;
-}
-
-class IsOutFileIndexCheckRequiredStrCallback {
- bool* ret_;
-
-public:
- IsOutFileIndexCheckRequiredStrCallback(bool* ret) : ret_(ret)
- {}
-
- void operator()(const Init* CmdLine) {
- // Ignore nested 'case' DAG.
- if (typeid(*CmdLine) == typeid(DagInit))
- return;
-
- if (IsOutFileIndexCheckRequiredStr(CmdLine))
- *ret_ = true;
- }
-
- void operator()(const DagInit* Test, unsigned, bool) {
- this->operator()(Test);
- }
- void operator()(const Init* Statement, unsigned) {
- this->operator()(Statement);
- }
-};
-
-bool IsOutFileIndexCheckRequiredCase (Init* CmdLine) {
- bool ret = false;
- WalkCase(CmdLine, Id(), IsOutFileIndexCheckRequiredStrCallback(&ret));
- return ret;
-}
-
-/// IsOutFileIndexCheckRequired - Should we emit an "out_file_index != -1" check
-/// in EmitGenerateActionMethod() ?
-bool IsOutFileIndexCheckRequired (Init* CmdLine) {
- if (typeid(*CmdLine) == typeid(StringInit))
- return IsOutFileIndexCheckRequiredStr(CmdLine);
- else
- return IsOutFileIndexCheckRequiredCase(CmdLine);
-}
-
void EmitGenerateActionMethodHeader(const ToolDescription& D,
bool IsJoin, raw_ostream& O)
{
@@ -2078,8 +2112,10 @@ void EmitGenerateActionMethodHeader(const ToolDescription& D,
O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
O.indent(Indent1) << "{\n";
O.indent(Indent2) << "std::string cmd;\n";
- O.indent(Indent2) << "std::vector<std::string> vec;\n";
+ O.indent(Indent2) << "std::string out_file;\n";
+ O.indent(Indent2) << "std::vector<std::pair<unsigned, std::string> > vec;\n";
O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n";
+ O.indent(Indent2) << "bool no_out_file = false;\n";
O.indent(Indent2) << "const char* output_suffix = \""
<< D.OutputSuffix << "\";\n";
}
@@ -2095,46 +2131,67 @@ void EmitGenerateActionMethod (const ToolDescription& D,
if (!D.CmdLine)
throw "Tool " + D.Name + " has no cmd_line property!";
- bool IndexCheckRequired = IsOutFileIndexCheckRequired(D.CmdLine);
- O.indent(Indent2) << "int out_file_index"
- << (IndexCheckRequired ? " = -1" : "")
- << ";\n\n";
-
- // Process the cmd_line property.
- if (typeid(*D.CmdLine) == typeid(StringInit))
- EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O);
- else
- EmitCaseConstructHandler(D.CmdLine, Indent2,
- EmitCmdLineVecFillCallback(IsJoin, D.Name),
- true, OptDescs, O);
+ // Process the 'command' property.
+ O << '\n';
+ EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O);
+ O << '\n';
- // For every understood option, emit handling code.
+ // Process the 'actions' list of this tool.
if (D.Actions)
EmitCaseConstructHandler(D.Actions, Indent2,
EmitActionHandlersCallback(OptDescs),
false, OptDescs, O);
-
O << '\n';
- O.indent(Indent2)
- << "std::string out_file = OutFilename("
- << (IsJoin ? "sys::Path(),\n" : "inFile,\n");
- O.indent(Indent3) << "TempDir, stop_compilation, output_suffix).str();\n\n";
- if (IndexCheckRequired)
- O.indent(Indent2) << "if (out_file_index != -1)\n";
- O.indent(IndexCheckRequired ? Indent3 : Indent2)
- << "vec[out_file_index] = out_file;\n";
+ // Input file (s)
+ if (!D.InFileOption.empty()) {
+ O.indent(Indent2)
+ << "vec.push_back(std::make_pair(InputFilenames.getPosition(0), \""
+ << D.InFileOption << "\");\n";
+ }
+
+ if (IsJoin) {
+ O.indent(Indent2)
+ << "for (PathVector::const_iterator B = inFiles.begin(),\n";
+ O.indent(Indent3) << "E = inFiles.end(); B != E; ++B)\n";
+ O.indent(Indent2) << "{\n";
+ O.indent(Indent3) << "vec.push_back(std::make_pair("
+ << "InputFilenames.getPosition(B - inFiles.begin()), "
+ << "B->str()));\n";
+ O.indent(Indent2) << "}\n";
+ }
+ else {
+ O.indent(Indent2) << "vec.push_back(std::make_pair("
+ << "InputFilenames.getPosition(0), inFile.str()));\n";
+ }
+
+ // Output file
+ O.indent(Indent2) << "if (!no_out_file) {\n";
+ if (!D.OutFileOption.empty())
+ O.indent(Indent3) << "vec.push_back(std::make_pair(65536, \""
+ << D.OutFileOption << "\"));\n";
+
+ O.indent(Indent3) << "out_file = this->OutFilename("
+ << (IsJoin ? "sys::Path(),\n" : "inFile,\n");
+ O.indent(Indent4) << "TempDir, stop_compilation, output_suffix).str();\n\n";
+ O.indent(Indent3) << "vec.push_back(std::make_pair(65536, out_file));\n";
+
+ O.indent(Indent2) << "}\n\n";
// Handle the Sink property.
if (D.isSink()) {
O.indent(Indent2) << "if (!" << SinkOptionName << ".empty()) {\n";
- O.indent(Indent3) << "vec.insert(vec.end(), "
- << SinkOptionName << ".begin(), " << SinkOptionName
- << ".end());\n";
+ O.indent(Indent3) << "for (cl::list<std::string>::iterator B = "
+ << SinkOptionName << ".begin(), E = " << SinkOptionName
+ << ".end(); B != E; ++B)\n";
+ O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOptionName
+ << ".getPosition(B - " << SinkOptionName
+ << ".begin()), *B));\n";
O.indent(Indent2) << "}\n";
}
- O.indent(Indent2) << "return Action(cmd, vec, stop_compilation, out_file);\n";
+ O.indent(Indent2) << "return Action(cmd, this->SortArgs(vec), "
+ << "stop_compilation, out_file);\n";
O.indent(Indent1) << "}\n\n";
}
@@ -2194,6 +2251,29 @@ void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) {
O.indent(Indent1) << "}\n\n";
}
+/// EmitWorksOnEmptyCallback - Callback used by EmitWorksOnEmptyMethod in
+/// conjunction with EmitCaseConstructHandler.
+void EmitWorksOnEmptyCallback (const Init* Value,
+ unsigned IndentLevel, raw_ostream& O) {
+ CheckBooleanConstant(Value);
+ O.indent(IndentLevel) << "return " << Value->getAsString() << ";\n";
+}
+
+/// EmitWorksOnEmptyMethod - Emit the WorksOnEmpty() method for a given Tool
+/// class.
+void EmitWorksOnEmptyMethod (const ToolDescription& D,
+ const OptionDescriptions& OptDescs,
+ raw_ostream& O)
+{
+ O.indent(Indent1) << "bool WorksOnEmpty() const {\n";
+ if (D.OnEmpty == 0)
+ O.indent(Indent2) << "return false;\n";
+ else
+ EmitCaseConstructHandler(D.OnEmpty, Indent2, EmitWorksOnEmptyCallback,
+ /*EmitElseIf = */ true, OptDescs, O);
+ O.indent(Indent1) << "}\n\n";
+}
+
/// EmitStaticMemberDefinitions - Emit static member definitions for a
/// given Tool class.
void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) {
@@ -2228,6 +2308,7 @@ void EmitToolClassDefinition (const ToolDescription& D,
EmitNameMethod(D, O);
EmitInOutLanguageMethods(D, O);
EmitIsJoinMethod(D, O);
+ EmitWorksOnEmptyMethod(D, OptDescs, O);
EmitGenerateActionMethods(D, OptDescs, O);
// Close class definition
@@ -2277,12 +2358,15 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
else
O << ", cl::Required";
}
- else if (val.isOneOrMore() && val.isList()) {
- O << ", cl::OneOrMore";
- }
- else if (val.isOptional() && val.isList()) {
+
+ if (val.isOptional())
O << ", cl::Optional";
- }
+
+ if (val.isOneOrMore())
+ O << ", cl::OneOrMore";
+
+ if (val.isZeroOrMore())
+ O << ", cl::ZeroOrMore";
if (val.isReallyHidden())
O << ", cl::ReallyHidden";
@@ -2981,7 +3065,7 @@ void LLVMCConfigurationEmitter::run (raw_ostream &O) {
CollectPluginData(Records, Data);
CheckPluginData(Data);
- EmitSourceFileHeader("LLVMC Configuration Library", O);
+ this->EmitSourceFileHeader("LLVMC Configuration Library", O);
EmitPluginCode(Data, O);
} catch (std::exception& Error) {
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 45f3072..90096e9 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -1225,6 +1225,10 @@ public:
ID(LastID++), Name(N), Loc(loc) {}
~Record() {}
+
+ static unsigned getNewUID() { return LastID++; }
+
+
unsigned getID() const { return ID; }
const std::string &getName() const { return Name; }
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index da2de6b..ea78d41 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -24,6 +24,18 @@
using namespace llvm;
+#define MRM_MAPPING \
+ MAP(C1, 33) \
+ MAP(C2, 34) \
+ MAP(C3, 35) \
+ MAP(C4, 36) \
+ MAP(C8, 37) \
+ MAP(C9, 38) \
+ MAP(E8, 39) \
+ MAP(F0, 40) \
+ MAP(F8, 41) \
+ MAP(F9, 42)
+
// A clone of X86 since we can't depend on something that is generated.
namespace X86Local {
enum {
@@ -38,7 +50,12 @@ namespace X86Local {
MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
- MRMInitReg = 32
+ MRMInitReg = 32,
+
+#define MAP(from, to) MRM_##from = to,
+ MRM_MAPPING
+#undef MAP
+ lastMRM
};
enum {
@@ -47,10 +64,28 @@ namespace X86Local {
D8 = 3, D9 = 4, DA = 5, DB = 6,
DC = 7, DD = 8, DE = 9, DF = 10,
XD = 11, XS = 12,
- T8 = 13, TA = 14
+ T8 = 13, P_TA = 14,
+ P_0F_AE = 16, P_0F_01 = 17
};
}
-
+
+// If rows are added to the opcode extension tables, then corresponding entries
+// must be added here.
+//
+// If the row corresponds to a single byte (i.e., 8f), then add an entry for
+// that byte to ONE_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to two bytes where the first is 0f, add an entry for
+// the second byte to TWO_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to some other set of bytes, you will need to modify
+// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
+// to the X86 TD files, except in two cases: if the first two bytes of such a
+// new combination are 0f 38 or 0f 3a, you just have to add maps called
+// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
+// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
+// in RecognizableInstr::emitDecodePath().
+
#define ONE_BYTE_EXTENSION_TABLES \
EXTENSION_TABLE(80) \
EXTENSION_TABLE(81) \
@@ -81,10 +116,6 @@ namespace X86Local {
EXTENSION_TABLE(b9) \
EXTENSION_TABLE(ba) \
EXTENSION_TABLE(c7)
-
-#define TWO_BYTE_FULL_EXTENSION_TABLES \
- EXTENSION_TABLE(01)
-
using namespace X86Disassembler;
@@ -251,6 +282,10 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const {
IsCodeGenOnly)
return FILTER_STRONG;
+ if (Form == X86Local::MRMInitReg)
+ return FILTER_STRONG;
+
+
// Filter out instructions with a LOCK prefix;
// prefer forms that do not have the prefix
if (HasLockPrefix)
@@ -322,9 +357,6 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const {
if (AsmString.find("subreg") != AsmString.npos)
return FILTER_STRONG;
- assert(Form != X86Local::MRMInitReg &&
- "FORMAT_MRMINITREG instruction not skipped");
-
if (HasFROperands && Name.find("MOV") != Name.npos &&
((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
(Name.find("to") != Name.npos)))
@@ -549,36 +581,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
// Special cases where the LLVM tables are not complete
-#define EXACTCASE(class, name, lastbyte) \
- if (Name == name) { \
- tables.setTableFields(class, \
- insnContext(), \
- Opcode, \
- ExactFilter(lastbyte), \
- UID); \
- Spec->modifierBase = Opcode; \
- return; \
- }
-
- EXACTCASE(TWOBYTE, "MONITOR", 0xc8)
- EXACTCASE(TWOBYTE, "MWAIT", 0xc9)
- EXACTCASE(TWOBYTE, "SWPGS", 0xf8)
- EXACTCASE(TWOBYTE, "INVEPT", 0x80)
- EXACTCASE(TWOBYTE, "INVVPID", 0x81)
- EXACTCASE(TWOBYTE, "VMCALL", 0xc1)
- EXACTCASE(TWOBYTE, "VMLAUNCH", 0xc2)
- EXACTCASE(TWOBYTE, "VMRESUME", 0xc3)
- EXACTCASE(TWOBYTE, "VMXOFF", 0xc4)
-
- if (Name == "INVLPG") {
- tables.setTableFields(TWOBYTE,
- insnContext(),
- Opcode,
- ExtendedFilter(false, 7),
- UID);
- Spec->modifierBase = Opcode;
- return;
- }
+#define MAP(from, to) \
+ case X86Local::MRM_##from: \
+ filter = new ExactFilter(0x##from); \
+ break;
OpcodeType opcodeType = (OpcodeType)-1;
@@ -593,6 +599,12 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
opcodeType = TWOBYTE;
switch (Opcode) {
+ default:
+ if (needsModRMForDecode(Form))
+ filter = new ModFilter(isRegFormat(Form));
+ else
+ filter = new DumbFilter();
+ break;
#define EXTENSION_TABLE(n) case 0x##n:
TWO_BYTE_EXTENSION_TABLES
#undef EXTENSION_TABLE
@@ -619,16 +631,10 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::MRM7m:
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
+ MRM_MAPPING
} // switch (Form)
break;
- default:
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
-
- break;
- } // switch (opcode)
+ } // switch (Opcode)
opcodeToSet = Opcode;
break;
case X86Local::T8:
@@ -639,7 +645,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
filter = new DumbFilter();
opcodeToSet = Opcode;
break;
- case X86Local::TA:
+ case X86Local::P_TA:
opcodeType = THREEBYTE_3A;
if (needsModRMForDecode(Form))
filter = new ModFilter(isRegFormat(Form));
@@ -696,6 +702,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::MRM7m:
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
+ MRM_MAPPING
} // switch (Form)
break;
case 0xd8:
@@ -760,6 +767,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
}
delete filter;
+
+#undef MAP
}
#define TYPE(str, type) if (s == str) return type;
diff --git a/utils/buildit/GNUmakefile b/utils/buildit/GNUmakefile
index 57aac43..8d8504c 100644
--- a/utils/buildit/GNUmakefile
+++ b/utils/buildit/GNUmakefile
@@ -34,9 +34,9 @@ DSTROOT = $(OBJROOT)/../dst
PREFIX = /usr/local
-# Unless assertions are forced on in the GMAKE command line, enable them.
+# Unless assertions are forced on in the GMAKE command line, disable them.
ifndef ENABLE_ASSERTIONS
-ENABLE_ASSERTIONS := yes
+ENABLE_ASSERTIONS := no
endif
# Default is optimized build.
diff --git a/utils/git/find-rev b/utils/git/find-rev
new file mode 100755
index 0000000..a6161db
--- /dev/null
+++ b/utils/git/find-rev
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+import os, sys, subprocess
+
+def main():
+ from optparse import OptionParser, OptionGroup
+ parser = OptionParser("usage: %prog [options] <repo> <revision>")
+ parser.add_option("", "--dump-section-data", dest="dumpSectionData",
+ help="Dump the contents of sections",
+ action="store_true", default=False)
+ (opts, args) = parser.parse_args()
+
+ if len(args) != 2:
+ parser.error("invalid number of arguments")
+
+ repo,rev = args
+
+ try:
+ rev = int(rev)
+ except:
+ parser.error("invalid revision argument (not an integer)")
+
+ os.chdir(repo)
+ p = subprocess.Popen(['git', 'rev-list', 'git-svn', '--pretty'],
+ stdout=subprocess.PIPE)
+
+ bestRev = bestCommit = None
+ lastCommit = None
+ for ln in p.stdout:
+ if ln.startswith('commit '):
+ lastCommit = ln.split(' ',2)[1]
+ elif ln.startswith(' git-svn-id: '):
+ _,repo,_ = ln.strip().split(' ')
+ _,lrev = repo.rsplit('@',1)
+ lrev = int(lrev)
+ if lrev<=rev:
+ if bestRev is None or lrev>bestRev:
+ assert lastCommit
+ bestCommit = lastCommit
+ bestRev = lrev
+ if lrev == rev:
+ break
+
+ if bestCommit is not None:
+ print bestCommit
+ sys.exit(0)
+ sys.exit(1)
+
+if __name__=='__main__':
+ main()
diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp b/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp
index 1d9c743..efa839e 100644
--- a/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp
+++ b/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp
@@ -4,7 +4,6 @@
set target_triplet "x86_64-apple-darwin10"
set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend"
set llvmgcc_langs "c,c++,objc,obj-c++"
-set llvmgcc_version "4.2.1"
set prcontext "/usr/bin/tclsh8.4 /Volumes/Data/ddunbar/llvm/test/Scripts/prcontext.tcl"
set llvmtoolsdir "/Users/ddunbar/llvm.obj.64/Debug/bin"
set llvmlibsdir "/Users/ddunbar/llvm.obj.64/Debug/lib"
@@ -19,7 +18,6 @@ set compile_cxx " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include
set link " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -g -L/Users/ddunbar/llvm.obj.64/Debug/lib -L/Volumes/Data/ddunbar/llvm.obj.64/Debug/lib "
set llvmgcc "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
set llvmgxx "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
-set llvmgccmajvers "4"
set bugpoint_topts "-gcc-tool-args -m64"
set shlibext ".dylib"
set ocamlopt "/sw/bin/ocamlopt -cc \"g++ -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT\" -I /Users/ddunbar/llvm.obj.64/Debug/lib/ocaml"
diff --git a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp
index 1d9c743..efa839e 100644
--- a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp
+++ b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp
@@ -4,7 +4,6 @@
set target_triplet "x86_64-apple-darwin10"
set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend"
set llvmgcc_langs "c,c++,objc,obj-c++"
-set llvmgcc_version "4.2.1"
set prcontext "/usr/bin/tclsh8.4 /Volumes/Data/ddunbar/llvm/test/Scripts/prcontext.tcl"
set llvmtoolsdir "/Users/ddunbar/llvm.obj.64/Debug/bin"
set llvmlibsdir "/Users/ddunbar/llvm.obj.64/Debug/lib"
@@ -19,7 +18,6 @@ set compile_cxx " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include
set link " /usr/bin/g++ -arch x86_64 -I/Users/ddunbar/llvm.obj.64/include -I/Users/ddunbar/llvm.obj.64/test -I/Volumes/Data/ddunbar/llvm.obj.64/include -I/Volumes/Data/ddunbar/llvm/include -I/Volumes/Data/ddunbar/llvm/test -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -g -fno-exceptions -fno-common -Woverloaded-virtual -m64 -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -g -L/Users/ddunbar/llvm.obj.64/Debug/lib -L/Volumes/Data/ddunbar/llvm.obj.64/Debug/lib "
set llvmgcc "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
set llvmgxx "/Users/ddunbar/llvm-gcc/install/bin/llvm-gcc -m64 "
-set llvmgccmajvers "4"
set bugpoint_topts "-gcc-tool-args -m64"
set shlibext ".dylib"
set ocamlopt "/sw/bin/ocamlopt -cc \"g++ -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT\" -I /Users/ddunbar/llvm.obj.64/Debug/lib/ocaml"
diff --git a/utils/lit/lit/TestFormats.py b/utils/lit/lit/TestFormats.py
index fba0ce2..d87a467 100644
--- a/utils/lit/lit/TestFormats.py
+++ b/utils/lit/lit/TestFormats.py
@@ -87,6 +87,10 @@ class FileBasedTest(object):
litConfig, localConfig):
source_path = testSuite.getSourcePath(path_in_suite)
for filename in os.listdir(source_path):
+ # Ignore dot files.
+ if filename.startswith('.'):
+ continue
+
filepath = os.path.join(source_path, filename)
if not os.path.isdir(filepath):
base,ext = os.path.splitext(filename)
@@ -137,7 +141,8 @@ class OneCommandPerFileTest:
d not in localConfig.excludes)]
for filename in filenames:
- if (not self.pattern.match(filename) or
+ if (filename.startswith('.') or
+ not self.pattern.match(filename) or
filename in localConfig.excludes):
continue
diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py
index 20fbc6c..a7de2b7 100644
--- a/utils/lit/lit/TestRunner.py
+++ b/utils/lit/lit/TestRunner.py
@@ -353,6 +353,8 @@ def isExpectedFail(xfails, xtargets, target_triple):
return True
+import re
+
def parseIntegratedTestScript(test):
"""parseIntegratedTestScript - Scan an LLVM/Clang style integrated test
script and extract the lines to 'RUN' as well as 'XFAIL' and 'XTARGET'
@@ -385,7 +387,21 @@ def parseIntegratedTestScript(test):
script = []
xfails = []
xtargets = []
+ ignoredAny = False
for ln in open(sourcepath):
+ conditional = re.search('IF\((.+?)\((.+?)\)\):', ln)
+ if conditional:
+ ln = ln[conditional.end():]
+ condition = conditional.group(1)
+ value = conditional.group(2)
+
+ # Actually test the condition.
+ if condition not in test.config.conditions:
+ return (Test.UNRESOLVED, "unknown condition '"+condition+"'")
+ if not test.config.conditions[condition](value):
+ ignoredAny = True
+ continue
+
if 'RUN:' in ln:
# Isolate the command to run.
index = ln.index('RUN:')
@@ -422,6 +438,8 @@ def parseIntegratedTestScript(test):
# Verify the script contains a run line.
if not script:
+ if ignoredAny:
+ return (Test.UNSUPPORTED, "Test has only ignored run lines")
return (Test.UNRESOLVED, "Test has no run line!")
if script[-1][-1] == '\\':
diff --git a/utils/lit/lit/TestingConfig.py b/utils/lit/lit/TestingConfig.py
index 1f5067c..d6f2a4d 100644
--- a/utils/lit/lit/TestingConfig.py
+++ b/utils/lit/lit/TestingConfig.py
@@ -10,6 +10,7 @@ class TestingConfig:
if config is None:
# Set the environment based on the command line arguments.
environment = {
+ 'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH',''),
'PATH' : os.pathsep.join(litConfig.path +
[os.environ.get('PATH','')]),
'PATHEXT' : os.environ.get('PATHEXT',''),
@@ -27,7 +28,8 @@ class TestingConfig:
on_clone = None,
test_exec_root = None,
test_source_root = None,
- excludes = [])
+ excludes = [],
+ conditions = {})
if os.path.exists(path):
# FIXME: Improve detection and error reporting of errors in the
@@ -53,7 +55,7 @@ class TestingConfig:
def __init__(self, parent, name, suffixes, test_format,
environment, substitutions, unsupported, on_clone,
- test_exec_root, test_source_root, excludes):
+ test_exec_root, test_source_root, excludes, conditions):
self.parent = parent
self.name = str(name)
self.suffixes = set(suffixes)
@@ -65,6 +67,7 @@ class TestingConfig:
self.test_exec_root = test_exec_root
self.test_source_root = test_source_root
self.excludes = set(excludes)
+ self.conditions = dict(conditions)
def clone(self, path):
# FIXME: Chain implementations?
@@ -74,7 +77,7 @@ class TestingConfig:
self.environment, self.substitutions,
self.unsupported, self.on_clone,
self.test_exec_root, self.test_source_root,
- self.excludes)
+ self.excludes, self.conditions)
if cfg.on_clone:
cfg.on_clone(self, cfg, path)
return cfg
diff --git a/utils/llvm.grm b/utils/llvm.grm
index 86a707a..d391e2a 100644
--- a/utils/llvm.grm
+++ b/utils/llvm.grm
@@ -162,6 +162,7 @@ FuncAttr ::= noreturn
| readnone
| readonly
| inlinehint
+ | alignstack
| noinline
| alwaysinline
| optsize
diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim
index 6e4a207..518aa04 100644
--- a/utils/vim/llvm.vim
+++ b/utils/vim/llvm.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: llvm
" Maintainer: The LLVM team, http://llvm.org/
-" Updated: 2003-06-02
+" Version: $Revision: 97271 $
if version < 600
syntax clear
@@ -52,11 +52,12 @@ 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 noredzone noimplicitfloat naked
+syn keyword llvmKeyword noredzone noimplicitfloat naked alignstack
syn keyword llvmKeyword module asm align tail to
syn keyword llvmKeyword addrspace section alias sideeffect c gc
syn keyword llvmKeyword target datalayout triple
syn keyword llvmKeyword blockaddress
+syn keyword llvmKeyword union
" Obsolete keywords.
syn keyword llvmError uninitialized implementation
diff --git a/utils/vim/tablegen.vim b/utils/vim/tablegen.vim
index ad35872..11a4d80 100644
--- a/utils/vim/tablegen.vim
+++ b/utils/vim/tablegen.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: TableGen
" Maintainer: The LLVM team, http://llvm.org/
-" Updated: 2003-08-11
+" Version: $Revision: 97271 $
if version < 600
syntax clear
diff --git a/utils/vim/vimrc b/utils/vim/vimrc
index 4909f60..63108f2 100644
--- a/utils/vim/vimrc
+++ b/utils/vim/vimrc
@@ -1,4 +1,5 @@
" LLVM coding guidelines conformance for VIM
+" $Revision: 97273 $
"
" Maintainer: The LLVM Team, http://llvm.org
" WARNING: Read before you source in all these commands and macros! Some
@@ -10,17 +11,30 @@
" It's VIM, not VI
set nocompatible
-" Wrap text at 80 cols
-set textwidth=80
-
" A tab produces a 2-space indentation
set softtabstop=2
set shiftwidth=2
set expandtab
-" Highlight trailing whitespace
+" Highlight trailing whitespace and lines longer than 80 columns.
+highlight LongLine ctermbg=DarkYellow guibg=DarkYellow
highlight WhitespaceEOL ctermbg=DarkYellow guibg=DarkYellow
-match WhitespaceEOL /\s\+$/
+if v:version >= 702
+ " Lines longer than 80 columns.
+ au BufWinEnter * let w:m0=matchadd('LongLine', '\%>80v.\+', -1)
+
+ " Whitespace at the end of a line. This little dance suppresses
+ " whitespace that has just been typed.
+ au BufWinEnter * let w:m1=matchadd('WhitespaceEOL', '\s\+$', -1)
+ au InsertEnter * call matchdelete(w:m1)
+ au InsertEnter * let w:m2=matchadd('WhitespaceEOL', '\s\+\%#\@<!$', -1)
+ au InsertLeave * call matchdelete(w:m2)
+ au InsertLeave * let w:m1=matchadd('WhitespaceEOL', '\s\+$', -1)
+else
+ au BufRead,BufNewFile * syntax match LongLine /\%>80v.\+/
+ au InsertEnter * syntax match WhitespaceEOL /\s\+\%#\@<!$/
+ au InsertLeave * syntax match WhitespaceEOL /\s\+$/
+endif
" Enable filetype detection
filetype on
@@ -70,3 +84,10 @@ augroup END
augroup filetype
au! BufRead,BufNewFile *.td set filetype=tablegen
augroup END
+
+" Additional vim features to optionally uncomment.
+"set showcmd
+"set showmatch
+"set showmode
+"set incsearch
+"set ruler