summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanya Lattner <tonic@nondot.org>2009-02-03 05:07:10 +0000
committerTanya Lattner <tonic@nondot.org>2009-02-03 05:07:10 +0000
commit682ae9aa345df80fab3180fd494c99853e7de436 (patch)
treeff9e30cb68f18ffd4e6a5061fd8c1b64da01a298
parent254a6e0c63b22de9ddca2fadbeb335abd9735920 (diff)
parentdac5c4b10b387b55c2394cd98a64f3f1394df2e8 (diff)
downloadllvm-682ae9aa345df80fab3180fd494c99853e7de436.tar.gz
Create 2.5 branch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_25@63604 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--CMakeLists.txt3
-rw-r--r--Makefile.rules7
-rw-r--r--ModuleInfo.txt4
-rw-r--r--autoconf/configure.ac2
-rwxr-xr-xbuild-for-llvm-top.sh18
-rwxr-xr-xconfigure18
-rw-r--r--docs/CodeGenerator.html23
-rw-r--r--docs/CommandLine.html16
-rw-r--r--docs/CompilerDriver.html75
-rw-r--r--docs/FAQ.html34
-rw-r--r--docs/LangRef.html196
-rw-r--r--docs/SourceLevelDebugging.html9
-rw-r--r--docs/WritingAnLLVMBackend.html28
-rw-r--r--docs/WritingAnLLVMPass.html12
-rw-r--r--include/llvm/ADT/APSInt.h12
-rw-r--r--include/llvm/ADT/BitVector.h6
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h13
-rw-r--r--include/llvm/Analysis/DebugInfo.h104
-rw-r--r--include/llvm/Analysis/EscapeAnalysis.h55
-rw-r--r--include/llvm/Analysis/LoopInfo.h3
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h13
-rw-r--r--include/llvm/CodeGen/DAGISelHeader.h4
-rw-r--r--include/llvm/CodeGen/DebugLoc.h94
-rw-r--r--include/llvm/CodeGen/DwarfWriter.h5
-rw-r--r--include/llvm/CodeGen/FastISel.h21
-rw-r--r--include/llvm/CodeGen/LiveInterval.h8
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h4
-rw-r--r--include/llvm/CodeGen/MachineFunction.h16
-rw-r--r--include/llvm/CodeGen/MachineInstr.h32
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h59
-rw-r--r--include/llvm/CodeGen/ScheduleDAGSDNodes.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h188
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h511
-rw-r--r--include/llvm/CodeGen/ValueTypes.h15
-rw-r--r--include/llvm/CompilerDriver/Common.td5
-rw-r--r--include/llvm/Config/config.h.cmake2
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h8
-rw-r--r--include/llvm/Instructions.h8
-rw-r--r--include/llvm/LinkAllPasses.h2
-rw-r--r--include/llvm/Pass.h24
-rw-r--r--include/llvm/PassAnalysisSupport.h22
-rw-r--r--include/llvm/Support/CallSite.h4
-rw-r--r--include/llvm/Support/CommandLine.h26
-rw-r--r--include/llvm/Support/Dwarf.h6
-rw-r--r--include/llvm/Support/raw_ostream.h6
-rw-r--r--include/llvm/System/Host.h14
-rw-r--r--include/llvm/Target/TargetAsmInfo.h54
-rw-r--r--include/llvm/Target/TargetLowering.h21
-rw-r--r--include/llvm/Target/TargetOptions.h4
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h33
-rw-r--r--include/llvm/User.h9
-rw-r--r--lib/Analysis/AliasAnalysis.cpp24
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp24
-rw-r--r--lib/Analysis/CMakeLists.txt1
-rw-r--r--lib/Analysis/DebugInfo.cpp161
-rw-r--r--lib/Analysis/EscapeAnalysis.cpp158
-rw-r--r--lib/Analysis/IPA/CallGraph.cpp3
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp26
-rw-r--r--lib/Analysis/ScalarEvolution.cpp12
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp5
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp3
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp13
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp125
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp177
-rw-r--r--lib/CodeGen/BranchFolding.cpp2
-rw-r--r--lib/CodeGen/GCMetadata.cpp2
-rw-r--r--lib/CodeGen/GCStrategy.cpp5
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp2
-rw-r--r--lib/CodeGen/LiveInterval.cpp16
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp14
-rw-r--r--lib/CodeGen/MachineFunction.cpp22
-rw-r--r--lib/CodeGen/MachineInstr.cpp53
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp2
-rw-r--r--lib/CodeGen/PHIElimination.cpp4
-rw-r--r--lib/CodeGen/PreAllocSplitting.cpp913
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp2
-rw-r--r--lib/CodeGen/RegAllocLocal.cpp134
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp101
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp1674
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp63
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp1767
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp217
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp598
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp110
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h18
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp106
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp420
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp24
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp50
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp1298
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp1127
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.h15
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp265
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp214
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.h23
-rw-r--r--lib/CodeGen/TargetInstrInfoImpl.cpp2
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp170
-rw-r--r--lib/CodeGen/UnreachableBlockElim.cpp2
-rw-r--r--lib/CodeGen/VirtRegMap.cpp3
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp28
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp19
-rw-r--r--lib/ExecutionEngine/JIT/JIT.h9
-rw-r--r--lib/Support/APInt.cpp8
-rw-r--r--lib/Support/CommandLine.cpp12
-rw-r--r--lib/Support/Dwarf.cpp2
-rw-r--r--lib/Support/raw_ostream.cpp6
-rw-r--r--lib/System/DynamicLibrary.cpp11
-rw-r--r--lib/System/Unix/Host.inc4
-rw-r--r--lib/System/Win32/DynamicLibrary.inc4
-rw-r--r--lib/System/Win32/Host.inc4
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp2
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp10
-rw-r--r--lib/Target/ARM/ARMInstrInfo.cpp2
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp4
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp18
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.h3
-rw-r--r--lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp42
-rw-r--r--lib/Target/CellSPU/SPU64InstrInfo.td4
-rw-r--r--lib/Target/CellSPU/SPUISelDAGToDAG.cpp185
-rw-r--r--lib/Target/CellSPU/SPUISelLowering.cpp498
-rw-r--r--lib/Target/CellSPU/SPUISelLowering.h4
-rw-r--r--lib/Target/CellSPU/SPUInstrFormats.td3
-rw-r--r--lib/Target/CellSPU/SPUInstrInfo.cpp28
-rw-r--r--lib/Target/CellSPU/SPUInstrInfo.h8
-rw-r--r--lib/Target/CellSPU/SPUInstrInfo.td61
-rw-r--r--lib/Target/CellSPU/SPUMathInstr.td28
-rw-r--r--lib/Target/CellSPU/SPUTargetAsmInfo.cpp24
-rw-r--r--lib/Target/DarwinTargetAsmInfo.cpp4
-rw-r--r--lib/Target/ELFTargetAsmInfo.cpp3
-rw-r--r--lib/Target/IA64/IA64ISelLowering.cpp36
-rw-r--r--lib/Target/IA64/IA64ISelLowering.h6
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp5
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.cpp41
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.h1
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp27
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.h2
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.td2
-rw-r--r--lib/Target/PIC16/PIC16TargetAsmInfo.cpp29
-rw-r--r--lib/Target/PIC16/PIC16TargetAsmInfo.h7
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp10
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp3
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp3
-rw-r--r--lib/Target/README.txt16
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp3
-rw-r--r--lib/Target/Sparc/SparcISelLowering.h3
-rw-r--r--lib/Target/TargetAsmInfo.cpp24
-rw-r--r--lib/Target/TargetMachine.cpp7
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp13
-rw-r--r--lib/Target/X86/README-SSE.txt5
-rw-r--r--lib/Target/X86/X86.td20
-rw-r--r--lib/Target/X86/X86CallingConv.td8
-rw-r--r--lib/Target/X86/X86FastISel.cpp3
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp74
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp264
-rw-r--r--lib/Target/X86/X86ISelLowering.h2
-rw-r--r--lib/Target/X86/X86Instr64bit.td5
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp11
-rw-r--r--lib/Target/X86/X86InstrInfo.td26
-rw-r--r--lib/Target/X86/X86InstrSSE.td34
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp15
-rw-r--r--lib/Target/X86/X86RegisterInfo.td99
-rw-r--r--lib/Target/X86/X86Subtarget.cpp18
-rw-r--r--lib/Target/XCore/XCoreAsmPrinter.cpp4
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp2
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp6
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp3
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp7
-rw-r--r--lib/Transforms/IPO/IndMemRemoval.cpp11
-rw-r--r--lib/Transforms/IPO/Internalize.cpp2
-rw-r--r--lib/Transforms/IPO/StructRetPromotion.cpp5
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp3
-rw-r--r--lib/Transforms/Scalar/CondPropagate.cpp8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp626
-rw-r--r--lib/Transforms/Scalar/LoopRotation.cpp117
-rw-r--r--lib/Transforms/Scalar/LoopUnroll.cpp4
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp4
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp709
-rw-r--r--lib/Transforms/Utils/BasicBlockUtils.cpp14
-rw-r--r--lib/Transforms/Utils/BreakCriticalEdges.cpp6
-rw-r--r--lib/Transforms/Utils/CloneLoop.cpp4
-rw-r--r--lib/Transforms/Utils/InlineCost.cpp2
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp11
-rw-r--r--lib/Transforms/Utils/LCSSA.cpp6
-rw-r--r--lib/Transforms/Utils/Local.cpp4
-rw-r--r--lib/Transforms/Utils/LoopSimplify.cpp4
-rw-r--r--lib/VMCore/Instruction.cpp3
-rw-r--r--lib/VMCore/Pass.cpp2
-rw-r--r--lib/VMCore/PassManager.cpp8
-rw-r--r--lib/VMCore/Verifier.cpp10
-rw-r--r--test/Assembler/2009-02-01-UnnamedForwardRef.ll6
-rw-r--r--test/Assembler/vector-cmp.ll16
-rw-r--r--test/Bitcode/extractelement.ll8
-rw-r--r--test/CodeGen/CellSPU/fcmp32.ll (renamed from test/CodeGen/CellSPU/fcmp.ll)15
-rw-r--r--test/CodeGen/CellSPU/fcmp64.ll7
-rw-r--r--test/CodeGen/CellSPU/fneg-fabs.ll11
-rw-r--r--test/CodeGen/CellSPU/select_bits.ll114
-rw-r--r--test/CodeGen/CellSPU/shift_ops.ll6
-rw-r--r--test/CodeGen/CellSPU/sp_farith.ll2
-rw-r--r--test/CodeGen/PowerPC/private.ll5
-rw-r--r--test/CodeGen/X86/2006-07-19-ATTAsm.ll2
-rw-r--r--test/CodeGen/X86/2008-02-22-ReMatBug.ll2
-rw-r--r--test/CodeGen/X86/2008-07-19-movups-spills.ll2
-rw-r--r--test/CodeGen/X86/2008-07-23-VSetCC.ll30
-rw-r--r--test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll4
-rw-r--r--test/CodeGen/X86/2009-01-25-NoSSE.ll20
-rw-r--r--test/CodeGen/X86/2009-01-26-WrongCheck.ll16
-rw-r--r--test/CodeGen/X86/2009-01-27-NullStrings.ll38
-rw-r--r--test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll38
-rw-r--r--test/CodeGen/X86/2009-01-31-BigShift.ll9
-rw-r--r--test/CodeGen/X86/2009-01-31-BigShift2.ll11
-rw-r--r--test/CodeGen/X86/2009-01-31-BigShift3.ll31
-rw-r--r--test/CodeGen/X86/2009-02-01-LargeMask.ll32
-rw-r--r--test/CodeGen/X86/bt.ll424
-rw-r--r--test/CodeGen/X86/commute-cmov.ll17
-rw-r--r--test/CodeGen/X86/dag-rauw-cse.ll (renamed from test/CodeGen/X86/pr3018.ll)1
-rw-r--r--test/CodeGen/X86/extractelement-load.ll2
-rw-r--r--test/CodeGen/X86/fold-call-3.ll45
-rw-r--r--test/CodeGen/X86/illegal-asm.ll32
-rw-r--r--test/CodeGen/X86/movgs.ll8
-rw-r--r--test/CodeGen/X86/neg_fp.ll12
-rw-r--r--test/CodeGen/X86/nosse-error1.ll33
-rw-r--r--test/CodeGen/X86/nosse-error2.ll33
-rw-r--r--test/CodeGen/X86/nosse-varargs.ll46
-rw-r--r--test/CodeGen/X86/pmul.ll2
-rw-r--r--test/CodeGen/X86/pre-split1.ll1
-rw-r--r--test/CodeGen/X86/red-zone.ll13
-rw-r--r--test/CodeGen/X86/smul-with-overflow-2.ll20
-rw-r--r--test/CodeGen/X86/smul-with-overflow-3.ll23
-rw-r--r--test/CodeGen/X86/subclass-coalesce.ll2
-rw-r--r--test/CodeGen/X86/swizzle.ll19
-rw-r--r--test/CodeGen/X86/twoaddr-coalesce.ll25
-rw-r--r--test/CodeGen/X86/vec_ins_extract-1.ll25
-rw-r--r--test/CodeGen/X86/vec_shuffle-29.ll14
-rw-r--r--test/CodeGen/X86/vfcmp.ll13
-rw-r--r--test/CodeGen/X86/vshift-1.ll65
-rw-r--r--test/CodeGen/X86/vshift-2.ll64
-rw-r--r--test/CodeGen/X86/vshift-3.ll54
-rw-r--r--test/CodeGen/X86/vshift-4.ll71
-rw-r--r--test/DebugInfo/2009-01-15-RecordVariableCrash.ll20
-rw-r--r--test/DebugInfo/2009-01-15-member.ll2
-rw-r--r--test/DebugInfo/2009-01-28-ArrayType.ll23
-rw-r--r--test/DebugInfo/2009-01-29-HeaderLocation.ll46
-rw-r--r--test/DebugInfo/2009-01-29-MethodDeclaration.ll32
-rw-r--r--test/DebugInfo/2009-01-30-Method.ll103
-rw-r--r--test/ExecutionEngine/2009-01-29-PartSet.ll17
-rw-r--r--test/FrontendC++/2006-11-06-StackTrace.cpp3
-rw-r--r--test/FrontendC++/2006-11-30-Pubnames.cpp2
-rw-r--r--test/FrontendC/always-inline.c12
-rw-r--r--test/FrontendC/implicit-arg.c10
-rw-r--r--test/FrontendC/union-align.c17
-rw-r--r--test/FrontendObjC/2009-01-26-WriteBarrier-2.m14
-rw-r--r--test/LLVMC/ExternOptions.td3
-rw-r--r--test/LLVMC/MultiValuedOption.td21
-rw-r--r--test/LLVMC/OneOrMore.td22
-rw-r--r--test/Makefile8
-rw-r--r--test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll37
-rw-r--r--test/Transforms/ConstProp/2008-07-07-VectorCompare.ll28
-rw-r--r--test/Transforms/GVN/2009-01-22-SortInvalidation.ll100
-rw-r--r--test/Transforms/IndMemRem/2009-01-24-Noalias.ll11
-rw-r--r--test/Transforms/IndMemRem/dg.exp3
-rw-r--r--test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll32
-rw-r--r--test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll1
-rw-r--r--test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll18
-rw-r--r--test/Transforms/InstCombine/2009-01-31-InfIterate.ll22
-rw-r--r--test/Transforms/InstCombine/2009-01-31-Pressure.ll22
-rw-r--r--test/Transforms/InstCombine/cast-sext-zext.ll1
-rw-r--r--test/Transforms/InstCombine/cast-store-gep.ll17
-rw-r--r--test/Transforms/InstCombine/dce-iterate.ll24
-rw-r--r--test/Transforms/InstCombine/multi-use-or.ll24
-rw-r--r--test/Transforms/InstCombine/vec_shuffle2.ll19
-rw-r--r--test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll21
-rw-r--r--test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll7
-rw-r--r--test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll5
-rw-r--r--test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll16
-rw-r--r--test/Transforms/ScalarRepl/badarray.ll2
-rw-r--r--test/Transforms/ScalarRepl/bitfield-sroa.ll16
-rw-r--r--test/Transforms/ScalarRepl/memset-aggregate.ll18
-rw-r--r--test/Transforms/ScalarRepl/vector_promote.ll15
-rw-r--r--test/Transforms/ScalarRepl/volatile.ll12
-rw-r--r--test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll3
-rw-r--r--test/lib/llvm.exp4
-rw-r--r--tools/Makefile7
-rw-r--r--tools/llvmc/doc/LLVMC-Reference.rst57
-rw-r--r--tools/llvmc/driver/CompilationGraph.cpp6
-rw-r--r--tools/lto/Makefile8
-rw-r--r--unittests/ADT/APInt.cpp79
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp2
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp10
-rw-r--r--utils/TableGen/FastISelEmitter.cpp5
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp148
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp78
-rw-r--r--utils/TableGen/TGParser.h4
-rw-r--r--win32/Analysis/Analysis.vcproj8
-rw-r--r--win32/AsmParser/AsmParser.vcproj76
-rw-r--r--win32/CodeGen/CodeGen.vcproj30
-rw-r--r--win32/Transforms/Transforms.vcproj12
-rw-r--r--win32/config.h1
299 files changed, 11743 insertions, 6592 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2072c703715d..3dcc5e4f7ff0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,8 @@ project(LLVM)
cmake_minimum_required(VERSION 2.6.1)
set(PACKAGE_NAME llvm)
-set(PACKAGE_VERSION svn)
+set(PACKAGE_VERSION 2.6svn)
+set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu")
if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
diff --git a/Makefile.rules b/Makefile.rules
index 0d4a0c8aedf2..5bddff8e8a22 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -613,6 +613,13 @@ $(RecursiveTargets)::
endif
#-----------------------------------------------------------
+# Handle the OPTIONAL_PARALLEL_DIRS options for optional parallel construction
+#-----------------------------------------------------------
+ifdef OPTIONAL_PARALLEL_DIRS
+ PARALLEL_DIRS += $(foreach T,$(OPTIONAL_PARALLEL_DIRS),$(shell test -d $(PROJ_SRC_DIR)/$(T) && echo "$(T)"))
+endif
+
+#-----------------------------------------------------------
# Handle the PARALLEL_DIRS options for parallel construction
#-----------------------------------------------------------
ifdef PARALLEL_DIRS
diff --git a/ModuleInfo.txt b/ModuleInfo.txt
index ec9da652cb8f..5a1d8b85ad0b 100644
--- a/ModuleInfo.txt
+++ b/ModuleInfo.txt
@@ -1,4 +1,4 @@
DepModule:
BuildCmd: ./build-for-llvm-top.sh
-CleanCmd: make clean
-InstallCmd: make install
+CleanCmd: make clean -C ../build.llvm
+InstallCmd: make install -C ../build.llvm
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 7e488361d4b7..3a218eaeb9c6 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -31,7 +31,7 @@ dnl===
dnl===-----------------------------------------------------------------------===
dnl Initialize autoconf and define the package name, version number and
dnl email address for reporting bugs.
-AC_INIT([[llvm]],[[2.5]],[llvmbugs@cs.uiuc.edu])
+AC_INIT([[llvm]],[[2.6svn]],[llvmbugs@cs.uiuc.edu])
dnl Provide a copyright substitution and ensure the copyright notice is included
dnl in the output of --version option of the generated configure script.
diff --git a/build-for-llvm-top.sh b/build-for-llvm-top.sh
index 2a68c79965b8..78e3ed87f092 100755
--- a/build-for-llvm-top.sh
+++ b/build-for-llvm-top.sh
@@ -9,9 +9,16 @@
# variables.
process_arguments "$@"
+# First, see if the build directory is there. If not, create it.
+build_dir="$LLVM_TOP/build.llvm"
+if test ! -d "$build_dir" ; then
+ mkdir -p "$build_dir"
+fi
+
# See if we have previously been configured by sensing the presence
# of the config.status scripts
-if test ! -x "config.status" ; then
+config_status="$build_dir/config.status"
+if test ! -f "$config_status" -o "$config_status" -ot "$0" ; then
# We must configure so build a list of configure options
config_options="--prefix=$PREFIX --with-llvmgccdir=$PREFIX"
if test "$OPTIMIZED" -eq 1 ; then
@@ -45,12 +52,15 @@ if test ! -x "config.status" ; then
config_options="$config_options --disable-threads"
fi
config_options="$config_options $OPTIONS_DASH $OPTIONS_DASH_DASH"
+ src_dir=`pwd`
+ cd "$build_dir"
msg 0 Configuring $module with:
- msg 0 " ./configure" $config_options
- $LLVM_TOP/llvm/configure $config_options || \
- die $? "Configuring llvm module failed"
+ msg 0 " $src_dir/configure" $config_options
+ $src_dir/configure $config_options || \
+ die $? "Configuring $module module failed"
else
msg 0 Module $module already configured, ignoring configure options.
+ cd "$build_dir"
fi
msg 0 Building $module with:
diff --git a/configure b/configure
index d88a48e6c0b3..19dfdf679923 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.60 for llvm 2.5.
+# Generated by GNU Autoconf 2.60 for llvm 2.6svn.
#
# Report bugs to <llvmbugs@cs.uiuc.edu>.
#
@@ -715,8 +715,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='llvm'
PACKAGE_TARNAME='-llvm-'
-PACKAGE_VERSION='2.5'
-PACKAGE_STRING='llvm 2.5'
+PACKAGE_VERSION='2.6svn'
+PACKAGE_STRING='llvm 2.6svn'
PACKAGE_BUGREPORT='llvmbugs@cs.uiuc.edu'
ac_unique_file="lib/VMCore/Module.cpp"
@@ -1463,7 +1463,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures llvm 2.5 to adapt to many kinds of systems.
+\`configure' configures llvm 2.6svn to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1529,7 +1529,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of llvm 2.5:";;
+ short | recursive ) echo "Configuration of llvm 2.6svn:";;
esac
cat <<\_ACEOF
@@ -1664,7 +1664,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-llvm configure 2.5
+llvm configure 2.6svn
generated by GNU Autoconf 2.60
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1680,7 +1680,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by llvm $as_me 2.5, which was
+It was created by llvm $as_me 2.6svn, which was
generated by GNU Autoconf 2.60. Invocation command line was
$ $0 $@
@@ -35005,7 +35005,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by llvm $as_me 2.5, which was
+This file was extended by llvm $as_me 2.6svn, which was
generated by GNU Autoconf 2.60. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -35058,7 +35058,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-llvm config.status 2.5
+llvm config.status 2.6svn
configured by $0, generated by GNU Autoconf 2.60,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/docs/CodeGenerator.html b/docs/CodeGenerator.html
index 009ecd676788..66d793dfa03c 100644
--- a/docs/CodeGenerator.html
+++ b/docs/CodeGenerator.html
@@ -1718,7 +1718,7 @@ processors, and includes support for ISA extensions such as MMX and SSE.
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
- <a name="x86_tt">X86 Target Triples Supported</a>
+ <a name="x86_tt">X86 Target Triples supported</a>
</div>
<div class="doc_text">
@@ -1791,6 +1791,27 @@ same way and in the same order.</p>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
+ <a name="x86_memory">X86 address spaces supported</a>
+</div>
+
+<div class="doc_text">
+
+<p>x86 has the ability to perform loads and stores to different address spaces
+via the x86 segment registers. A segment override prefix byte on an instruction
+causes the instruction's memory access to go to the specified segment. LLVM
+address space 0 is the default address space, which includes the stack, and
+any unqualified memory accesses in a program. Address spaces 1-255 are
+currently reserved for user-defined code. The GS-segment is represented by
+address space 256. Other x86 segments have yet to be allocated address space
+numbers.
+
+<p>Some operating systems use the GS-segment to implement TLS, so care should be
+taken when reading and writing to address space 256 on these platforms.
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
<a name="x86_names">Instruction naming</a>
</div>
diff --git a/docs/CommandLine.html b/docs/CommandLine.html
index 97df9f787cdc..013ff27d1921 100644
--- a/docs/CommandLine.html
+++ b/docs/CommandLine.html
@@ -1447,6 +1447,16 @@ unrecognized option strings to it as values instead of signaling an
error. As with <b><tt>cl::CommaSeparated</tt></b></a>, this modifier
only makes sense with a <a href="#cl::list">cl::list</a> option.</li>
+<li><a name="cl::AllowInverse">The <b><tt>cl::AllowInverse</tt></b></a>
+modifier can be used on options that have the form <tt>-fopt</tt> to
+automatically create a corresponding
+<tt>-fno-opt</tt> option. The <tt>f</tt> can be any single
+character, and the <tt>opt</tt> can be any one or more characters.
+The value of the created option is the logical complement of the value
+that would have been used if the base form of the option was used.
+This modifier only makes sense with an option that uses
+a <a href="#boolparser">bool parser</a>.</li>
+
</ul>
@@ -1745,7 +1755,11 @@ for any data type.</li>
<li><a name="boolparser">The <b><tt>parser&lt;bool&gt;</tt> specialization</b></a>
is used to convert boolean strings to a boolean value. Currently accepted
strings are "<tt>true</tt>", "<tt>TRUE</tt>", "<tt>True</tt>", "<tt>1</tt>",
-"<tt>false</tt>", "<tt>FALSE</tt>", "<tt>False</tt>", and "<tt>0</tt>".</li>
+"<tt>false</tt>", "<tt>FALSE</tt>", "<tt>False</tt>", and "<tt>0</tt>". The
+<b><tt>cl::AllowInverse</tt></b> modifier can be used on an option of the form
+<tt>-fopt</tt> that uses the <tt>parser&lt;bool&gt;</tt> specialization
+to create a corresponding option with the form <tt>-fno-opt</tt>. See
+<a href="#cl::AllowInverse"><tt>cl::AllowInverse</tt></a> for details.</li>
<li><a name="boolOrDefaultparser">The <b><tt>parser&lt;boolOrDefault&gt;</tt>
specialization</b></a> is used for cases where the value is boolean,
diff --git a/docs/CompilerDriver.html b/docs/CompilerDriver.html
index 977bd470c682..6338dd247696 100644
--- a/docs/CompilerDriver.html
+++ b/docs/CompilerDriver.html
@@ -263,38 +263,50 @@ separate option groups syntactically.</p>
<li><p class="first">Possible option types:</p>
<blockquote>
<ul class="simple">
-<li><tt class="docutils literal"><span class="pre">switch_option</span></tt> - a simple boolean switch without arguments,
-for example <tt class="docutils literal"><span class="pre">-O2</span></tt> or <tt class="docutils literal"><span class="pre">-time</span></tt>.</li>
-<li><tt class="docutils literal"><span class="pre">parameter_option</span></tt> - option that takes one argument, for
-example <tt class="docutils literal"><span class="pre">-std=c99</span></tt>. It is also allowed to use spaces instead of
-the equality sign: <tt class="docutils literal"><span class="pre">-std</span> <span class="pre">c99</span></tt>.</li>
-<li><tt class="docutils literal"><span class="pre">parameter_list_option</span></tt> - same as the above, but more than one
-option occurence is allowed.</li>
-<li><tt class="docutils literal"><span class="pre">prefix_option</span></tt> - same as the parameter_option, but the option
-name and argument do not have to be separated. Example:
-<tt class="docutils literal"><span class="pre">-ofile</span></tt>. This can be also specified as <tt class="docutils literal"><span class="pre">-o</span> <span class="pre">file</span></tt>; however,
-<tt class="docutils literal"><span class="pre">-o=file</span></tt> will be parsed incorrectly (<tt class="docutils literal"><span class="pre">=file</span></tt> will be
-interpreted as option value).</li>
-<li><tt class="docutils literal"><span class="pre">prefix_list_option</span></tt> - same as the above, but more than one
-occurence of the option is allowed; example: <tt class="docutils literal"><span class="pre">-lm</span> <span class="pre">-lpthread</span></tt>.</li>
-<li><tt class="docutils literal"><span class="pre">alias_option</span></tt> - a special option type for creating
-aliases. Unlike other option types, aliases are not allowed to
-have any properties besides the aliased option name. Usage
-example: <tt class="docutils literal"><span class="pre">(alias_option</span> <span class="pre">&quot;preprocess&quot;,</span> <span class="pre">&quot;E&quot;)</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">switch_option</span></tt> - a simple boolean switch without arguments, for example
+<tt class="docutils literal"><span class="pre">-O2</span></tt> or <tt class="docutils literal"><span class="pre">-time</span></tt>. At most one occurrence is allowed.</li>
+<li><tt class="docutils literal"><span class="pre">parameter_option</span></tt> - option that takes one argument, for example
+<tt class="docutils literal"><span class="pre">-std=c99</span></tt>. It is also allowed to use spaces instead of the equality
+sign: <tt class="docutils literal"><span class="pre">-std</span> <span class="pre">c99</span></tt>. At most one occurrence is allowed.</li>
+<li><tt class="docutils literal"><span class="pre">parameter_list_option</span></tt> - same as the above, but more than one option
+occurence is allowed.</li>
+<li><tt class="docutils literal"><span class="pre">prefix_option</span></tt> - same as the parameter_option, but the option name and
+argument do not have to be separated. Example: <tt class="docutils literal"><span class="pre">-ofile</span></tt>. This can be also
+specified as <tt class="docutils literal"><span class="pre">-o</span> <span class="pre">file</span></tt>; however, <tt class="docutils literal"><span class="pre">-o=file</span></tt> will be parsed incorrectly
+(<tt class="docutils literal"><span class="pre">=file</span></tt> will be interpreted as option value). At most one occurrence is
+allowed.</li>
+<li><tt class="docutils literal"><span class="pre">prefix_list_option</span></tt> - same as the above, but more than one occurence of
+the option is allowed; example: <tt class="docutils literal"><span class="pre">-lm</span> <span class="pre">-lpthread</span></tt>.</li>
+<li><tt class="docutils literal"><span class="pre">alias_option</span></tt> - a special option type for creating aliases. Unlike other
+option types, aliases are not allowed to have any properties besides the
+aliased option name. Usage example: <tt class="docutils literal"><span class="pre">(alias_option</span> <span class="pre">&quot;preprocess&quot;,</span> <span class="pre">&quot;E&quot;)</span></tt></li>
</ul>
</blockquote>
</li>
<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> output.</li>
-<li><tt class="docutils literal"><span class="pre">required</span></tt> - this option is obligatory.</li>
+<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
+once). Incompatible with <tt class="docutils literal"><span class="pre">zero_or_one</span></tt> and <tt class="docutils literal"><span class="pre">one_or_more</span></tt>.</li>
+<li><tt class="docutils literal"><span class="pre">one_or_more</span></tt> - the option must be specified at least one time. Useful
+only for list options in conjunction with <tt class="docutils literal"><span class="pre">multi_val</span></tt>; for ordinary lists
+it is synonymous with <tt class="docutils literal"><span class="pre">required</span></tt>. Incompatible with <tt class="docutils literal"><span class="pre">required</span></tt> and
+<tt class="docutils literal"><span class="pre">zero_or_one</span></tt>.</li>
+<li><tt class="docutils literal"><span class="pre">zero_or_one</span></tt> - the option can be specified zero or one times. Useful
+only 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>
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>
+<li><tt class="docutils literal"><span class="pre">multi_val</span> <span class="pre">n</span></tt> - this option takes <em>n</em> arguments (can be useful in some
+special cases). Usage example: <tt class="docutils literal"><span class="pre">(parameter_list_option</span> <span class="pre">&quot;foo&quot;,</span> <span class="pre">(multi_val</span>
+<span class="pre">3))</span></tt>. Only list options can have this attribute; you can, however, use
+the <tt class="docutils literal"><span class="pre">one_or_more</span></tt> and <tt class="docutils literal"><span class="pre">zero_or_one</span></tt> properties.</li>
<li><tt class="docutils literal"><span class="pre">extern</span></tt> - this option is defined in some other plugin, see below.</li>
</ul>
</blockquote>
@@ -526,16 +538,21 @@ output languages should match. This is enforced at compile-time.</p>
<div class="section">
<h2><a class="toc-backref" href="#id16" id="hooks-and-environment-variables" name="hooks-and-environment-variables"><span id="hooks"></span>Hooks and environment variables</a></h2>
<p>Normally, LLVMC executes programs from the system <tt class="docutils literal"><span class="pre">PATH</span></tt>. Sometimes,
-this is not sufficient: for example, we may want to specify tool names
-in the configuration file. This can be achieved via the mechanism of
-hooks - to write your own hooks, just add their definitions to the
-<tt class="docutils literal"><span class="pre">PluginMain.cpp</span></tt> or drop a <tt class="docutils literal"><span class="pre">.cpp</span></tt> file into the
-<tt class="docutils literal"><span class="pre">$LLVMC_DIR/driver</span></tt> directory. Hooks should live in the <tt class="docutils literal"><span class="pre">hooks</span></tt>
-namespace and have the signature <tt class="docutils literal"><span class="pre">std::string</span> <span class="pre">hooks::MyHookName</span>
-<span class="pre">(void)</span></tt>. They can be used from the <tt class="docutils literal"><span class="pre">cmd_line</span></tt> tool property:</p>
+this is not sufficient: for example, we may want to specify tool paths
+or names in the configuration file. This can be easily achieved via
+the hooks mechanism. To write your own hooks, just add their
+definitions to the <tt class="docutils literal"><span class="pre">PluginMain.cpp</span></tt> or drop a <tt class="docutils literal"><span class="pre">.cpp</span></tt> file into the
+your plugin directory. Hooks should live in the <tt class="docutils literal"><span class="pre">hooks</span></tt> namespace
+and have the signature <tt class="docutils literal"><span class="pre">std::string</span> <span class="pre">hooks::MyHookName</span> <span class="pre">([const</span> <span class="pre">char*</span>
+<span class="pre">Arg0</span> <span class="pre">[</span> <span class="pre">const</span> <span class="pre">char*</span> <span class="pre">Arg2</span> <span class="pre">[,</span> <span class="pre">...]]])</span></tt>. They can be used from the
+<tt class="docutils literal"><span class="pre">cmd_line</span></tt> tool property:</p>
<pre class="literal-block">
(cmd_line &quot;$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)&quot;)
</pre>
+<p>To pass arguments to hooks, use the following syntax:</p>
+<pre class="literal-block">
+(cmd_line &quot;$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2&quot;)
+</pre>
<p>It is also possible to use environment variables in the same manner:</p>
<pre class="literal-block">
(cmd_line &quot;$ENV(VAR1)/path/to/file -o $ENV(VAR2)&quot;)
@@ -594,7 +611,7 @@ errors as its status code.</p>
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
-Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $
+Last modified: $Date$
</address></div>
</div>
</div>
diff --git a/docs/FAQ.html b/docs/FAQ.html
index 753331269f51..ad08f10cfa29 100644
--- a/docs/FAQ.html
+++ b/docs/FAQ.html
@@ -564,9 +564,8 @@ code that you desire.
Note that the generated C code will be very low level (all loops are lowered
to gotos, etc) and not very pretty (comments are stripped, original source
formatting is totally lost, variables are renamed, expressions are regrouped),
-so this may not be what you're looking for. However, this is a good way to add
-C++ support for a processor that does not otherwise have a C++ compiler.
-</p>
+so this may not be what you're looking for. Also, there are several
+limitations noted below.<p>
<p>Use commands like this:</p>
@@ -603,20 +602,31 @@ C++ support for a processor that does not otherwise have a C++ compiler.
</ol>
-<p>Note that, by default, the C backend does not support exception handling. If
-you want/need it for a certain program, you can enable it by passing
-"-enable-correct-eh-support" to the llc program. The resultant code will use
-setjmp/longjmp to implement exception support that is correct but relatively
-slow.</p>
+<p>Using LLVM does not eliminate the need for C++ library support.
+If you use the llvm-g++ front-end, the generated code will depend on
+g++'s C++ support libraries in the same way that code generated from
+g++ would. If you use another C++ front-end, the generated code will
+depend on whatever library that front-end would normally require.</p>
-<p>Also note: this specific sequence of commands won't work if you use a
-function defined in the C++ runtime library (or any other C++ library). To
-access an external C++ library, you must manually compile libstdc++ to LLVM
+<p>If you are working on a platform that does not provide any C++
+libraries, you may be able to manually compile libstdc++ to LLVM
bitcode, statically link it into your program, then use the commands above to
-convert the whole result into C code. Alternatively, you can compile the
+convert the whole result into C code. Alternatively, you might compile the
libraries and your application into two different chunks of C code and link
them.</p>
+<p>Note that, by default, the C back end does not support exception handling. If
+you want/need it for a certain program, you can enable it by passing
+"-enable-correct-eh-support" to the llc program. The resultant code will use
+setjmp/longjmp to implement exception support that is relatively slow, and
+not C++-ABI-conforming on most platforms, but otherwise correct.</p>
+
+<p>Also, there are a number of other limitations of the C backend that
+cause it to produce code that does not fully conform to the C++ ABI on
+most platforms. Some of the C++ programs in LLVM's test suite are known
+to fail when compiled with the C back end because of ABI incompatiblities
+with standard C++ libraries.</p>
+
</div>
<!-- *********************************************************************** -->
diff --git a/docs/LangRef.html b/docs/LangRef.html
index df970807fe98..88970f971eca 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -55,6 +55,7 @@
<li><a href="#t_opaque">Opaque Type</a></li>
</ol>
</li>
+ <li><a href="#t_uprefs">Type Up-references</a></li>
</ol>
</li>
<li><a href="#constants">Constants</a>
@@ -149,6 +150,8 @@
<ol>
<li><a href="#i_icmp">'<tt>icmp</tt>' Instruction</a></li>
<li><a href="#i_fcmp">'<tt>fcmp</tt>' Instruction</a></li>
+ <li><a href="#i_vicmp">'<tt>vicmp</tt>' Instruction</a></li>
+ <li><a href="#i_vfcmp">'<tt>vfcmp</tt>' Instruction</a></li>
<li><a href="#i_phi">'<tt>phi</tt>' Instruction</a></li>
<li><a href="#i_select">'<tt>select</tt>' Instruction</a></li>
<li><a href="#i_call">'<tt>call</tt>' Instruction</a></li>
@@ -720,7 +723,6 @@ change.</p>
</div>
-
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="globalvars">Global Variables</a>
@@ -1342,6 +1344,13 @@ value.</p>
</tr>
</tbody>
</table>
+
+<p>Note that the code generator does not yet support large integer types
+to be used as function return types. The specific limit on how large a
+return type the code generator can currently handle is target-dependent;
+currently it's often 64 bits for 32-bit targets and 128 bits for 64-bit
+targets.</p>
+
</div>
<!-- _______________________________________________________________________ -->
@@ -1402,6 +1411,11 @@ As a special case, however, zero length arrays are recognized to be variable
length. This allows implementation of 'pascal style arrays' with the LLVM
type "{ i32, [0 x float]}", for example.</p>
+<p>Note that the code generator does not yet support large aggregate types
+to be used as function return types. The specific limit on how large an
+aggregate return type the code generator can currently handle is
+target-dependent, and also dependent on the aggregate element types.</p>
+
</div>
<!-- _______________________________________________________________________ -->
@@ -1487,6 +1501,12 @@ instruction.</p>
an <tt>i32</tt>.</td>
</tr>
</table>
+
+<p>Note that the code generator does not yet support large aggregate types
+to be used as function return types. The specific limit on how large an
+aggregate return type the code generator can currently handle is
+target-dependent, and also dependent on the aggregate element types.</p>
+
</div>
<!-- _______________________________________________________________________ -->
@@ -1591,6 +1611,12 @@ be any integer or floating point type.</p>
<td class="left">Vector of 2 64-bit integer values.</td>
</tr>
</table>
+
+<p>Note that the code generator does not yet support large vector types
+to be used as function return types. The specific limit on how large a
+vector return type codegen can currently handle is target-dependent;
+currently it's often a few times longer than a hardware vector register.</p>
+
</div>
<!-- _______________________________________________________________________ -->
@@ -1620,6 +1646,56 @@ structure type).</p>
</table>
</div>
+<!-- ======================================================================= -->
+<div class="doc_subsection">
+ <a name="t_uprefs">Type Up-references</a>
+</div>
+
+<div class="doc_text">
+<h5>Overview:</h5>
+<p>
+An "up reference" allows you to refer to a lexically enclosing type without
+requiring it to have a name. For instance, a structure declaration may contain a
+pointer to any of the types it is lexically a member of. Example of up
+references (with their equivalent as named type declarations) include:</p>
+
+<pre>
+ { \2 * } %x = type { %t* }
+ { \2 }* %y = type { %y }*
+ \1* %z = type %z*
+</pre>
+
+<p>
+An up reference is needed by the asmprinter for printing out cyclic types when
+there is no declared name for a type in the cycle. Because the asmprinter does
+not want to print out an infinite type string, it needs a syntax to handle
+recursive types that have no names (all names are optional in llvm IR).
+</p>
+
+<h5>Syntax:</h5>
+<pre>
+ \&lt;level&gt;
+</pre>
+
+<p>
+The level is the count of the lexical type that is being referred to.
+</p>
+
+<h5>Examples:</h5>
+
+<table class="layout">
+ <tr class="layout">
+ <td class="left"><tt>\1*</tt></td>
+ <td class="left">Self-referential pointer.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt>{ { \3*, i8 }, i32 }</tt></td>
+ <td class="left">Recursive structure where the upref refers to the out-most
+ structure.</td>
+ </tr>
+</table>
+</div>
+
<!-- *********************************************************************** -->
<div class="doc_section"> <a name="constants">Constants</a> </div>
@@ -1866,6 +1942,12 @@ following is the syntax for constant expressions:</p>
<dt><b><tt>fcmp COND ( VAL1, VAL2 )</tt></b></dt>
<dd>Performs the <a href="#i_fcmp">fcmp operation</a> on constants.</dd>
+ <dt><b><tt>vicmp COND ( VAL1, VAL2 )</tt></b></dt>
+ <dd>Performs the <a href="#i_vicmp">vicmp operation</a> on constants.</dd>
+
+ <dt><b><tt>vfcmp COND ( VAL1, VAL2 )</tt></b></dt>
+ <dd>Performs the <a href="#i_vfcmp">vfcmp operation</a> on constants.</dd>
+
<dt><b><tt>extractelement ( VAL, IDX )</tt></b></dt>
<dd>Perform the <a href="#i_extractelement">extractelement
@@ -2034,8 +2116,13 @@ return value.</p>
ret { i32, i8 } { i32 4, i8 2 } <i>; Return an aggregate of values 4 and 2</i>
</pre>
-<p>Note that the code generator does not yet fully support larger
- aggregate return values.</p>
+<p>Note that the code generator does not yet fully support large
+ return values. The specific sizes that are currently supported are
+ dependent on the target. For integers, on 32-bit targets the limit
+ is often 64 bits, and on 64-bit targets the limit is often 128 bits.
+ For aggregate types, the current limits are dependent on the element
+ types; for example targets are often limited to 2 total integer
+ elements and 2 total floating-point elements.</p>
</div>
<!-- _______________________________________________________________________ -->
@@ -4167,6 +4254,109 @@ always yields an <a href="#t_primitive">i1</a> result, as follows:</p>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
+ <a name="i_vicmp">'<tt>vicmp</tt>' Instruction</a>
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+<pre> &lt;result&gt; = vicmp &lt;cond&gt; &lt;ty&gt; &lt;op1&gt;, &lt;op2&gt; <i>; yields {ty}:result</i>
+</pre>
+<h5>Overview:</h5>
+<p>The '<tt>vicmp</tt>' instruction returns an integer vector value based on
+element-wise comparison of its two integer vector operands.</p>
+<h5>Arguments:</h5>
+<p>The '<tt>vicmp</tt>' instruction takes three operands. The first operand is
+the condition code indicating the kind of comparison to perform. It is not
+a value, just a keyword. The possible condition code are:</p>
+<ol>
+ <li><tt>eq</tt>: equal</li>
+ <li><tt>ne</tt>: not equal </li>
+ <li><tt>ugt</tt>: unsigned greater than</li>
+ <li><tt>uge</tt>: unsigned greater or equal</li>
+ <li><tt>ult</tt>: unsigned less than</li>
+ <li><tt>ule</tt>: unsigned less or equal</li>
+ <li><tt>sgt</tt>: signed greater than</li>
+ <li><tt>sge</tt>: signed greater or equal</li>
+ <li><tt>slt</tt>: signed less than</li>
+ <li><tt>sle</tt>: signed less or equal</li>
+</ol>
+<p>The remaining two arguments must be <a href="#t_vector">vector</a> or
+<a href="#t_integer">integer</a> typed. They must also be identical types.</p>
+<h5>Semantics:</h5>
+<p>The '<tt>vicmp</tt>' instruction compares <tt>op1</tt> and <tt>op2</tt>
+according to the condition code given as <tt>cond</tt>. The comparison yields a
+<a href="#t_vector">vector</a> of <a href="#t_integer">integer</a> result, of
+identical type as the values being compared. The most significant bit in each
+element is 1 if the element-wise comparison evaluates to true, and is 0
+otherwise. All other bits of the result are undefined. The condition codes
+are evaluated identically to the <a href="#i_icmp">'<tt>icmp</tt>'
+instruction</a>.</p>
+
+<h5>Example:</h5>
+<pre>
+ &lt;result&gt; = vicmp eq &lt;2 x i32&gt; &lt; i32 4, i32 0&gt;, &lt; i32 5, i32 0&gt; <i>; yields: result=&lt;2 x i32&gt; &lt; i32 0, i32 -1 &gt;</i>
+ &lt;result&gt; = vicmp ult &lt;2 x i8 &gt; &lt; i8 1, i8 2&gt;, &lt; i8 2, i8 2 &gt; <i>; yields: result=&lt;2 x i8&gt; &lt; i8 -1, i8 0 &gt;</i>
+</pre>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="i_vfcmp">'<tt>vfcmp</tt>' Instruction</a>
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+<pre> &lt;result&gt; = vfcmp &lt;cond&gt; &lt;ty&gt; &lt;op1&gt;, &lt;op2&gt;</pre>
+<h5>Overview:</h5>
+<p>The '<tt>vfcmp</tt>' instruction returns an integer vector value based on
+element-wise comparison of its two floating point vector operands. The output
+elements have the same width as the input elements.</p>
+<h5>Arguments:</h5>
+<p>The '<tt>vfcmp</tt>' instruction takes three operands. The first operand is
+the condition code indicating the kind of comparison to perform. It is not
+a value, just a keyword. The possible condition code are:</p>
+<ol>
+ <li><tt>false</tt>: no comparison, always returns false</li>
+ <li><tt>oeq</tt>: ordered and equal</li>
+ <li><tt>ogt</tt>: ordered and greater than </li>
+ <li><tt>oge</tt>: ordered and greater than or equal</li>
+ <li><tt>olt</tt>: ordered and less than </li>
+ <li><tt>ole</tt>: ordered and less than or equal</li>
+ <li><tt>one</tt>: ordered and not equal</li>
+ <li><tt>ord</tt>: ordered (no nans)</li>
+ <li><tt>ueq</tt>: unordered or equal</li>
+ <li><tt>ugt</tt>: unordered or greater than </li>
+ <li><tt>uge</tt>: unordered or greater than or equal</li>
+ <li><tt>ult</tt>: unordered or less than </li>
+ <li><tt>ule</tt>: unordered or less than or equal</li>
+ <li><tt>une</tt>: unordered or not equal</li>
+ <li><tt>uno</tt>: unordered (either nans)</li>
+ <li><tt>true</tt>: no comparison, always returns true</li>
+</ol>
+<p>The remaining two arguments must be <a href="#t_vector">vector</a> of
+<a href="#t_floating">floating point</a> typed. They must also be identical
+types.</p>
+<h5>Semantics:</h5>
+<p>The '<tt>vfcmp</tt>' instruction compares <tt>op1</tt> and <tt>op2</tt>
+according to the condition code given as <tt>cond</tt>. The comparison yields a
+<a href="#t_vector">vector</a> of <a href="#t_integer">integer</a> result, with
+an identical number of elements as the values being compared, and each element
+having identical with to the width of the floating point elements. The most
+significant bit in each element is 1 if the element-wise comparison evaluates to
+true, and is 0 otherwise. All other bits of the result are undefined. The
+condition codes are evaluated identically to the
+<a href="#i_fcmp">'<tt>fcmp</tt>' instruction</a>.</p>
+
+<h5>Example:</h5>
+<pre>
+ <i>; yields: result=&lt;2 x i32&gt; &lt; i32 0, i32 -1 &gt;</i>
+ &lt;result&gt; = vfcmp oeq &lt;2 x float&gt; &lt; float 4, float 0 &gt;, &lt; float 5, float 0 &gt;
+
+ <i>; yields: result=&lt;2 x i64&gt; &lt; i64 -1, i64 0 &gt;</i>
+ &lt;result&gt; = vfcmp ult &lt;2 x double&gt; &lt; double 1, double 2 &gt;, &lt; double 2, double 2&gt;
+</pre>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
<a name="i_phi">'<tt>phi</tt>' Instruction</a>
</div>
diff --git a/docs/SourceLevelDebugging.html b/docs/SourceLevelDebugging.html
index 4a55a1c1a2ad..263f40c6ebc0 100644
--- a/docs/SourceLevelDebugging.html
+++ b/docs/SourceLevelDebugging.html
@@ -378,6 +378,7 @@ deleted.</p>
sbyte*, ;; Source file name
sbyte*, ;; Source file directory (includes trailing slash)
sbyte* ;; Producer (ex. "4.0.1 LLVM (LLVM research group)")
+ bool ;; True if this is a main compile unit.
}
</pre>
@@ -392,6 +393,14 @@ specific source file. Global variables and top level functions would be defined
using this context. Compile unit descriptors also provide context for source
line correspondence.</p>
+<p> Each input file is encoded as a separate compile unit in LLVM debugging
+information output. However, many target specific tool chains prefer to encode
+only one compile unit in an object file. In this situation, the LLVM code
+generator will include debugging information entities in the compile unit
+that is marked as main compile unit. The code generator accepts maximum one main
+compile unit per module. If a module does not contain any main compile unit
+then the code generator will emit multiple compile units in the output object
+file.
</div>
<!-- ======================================================================= -->
diff --git a/docs/WritingAnLLVMBackend.html b/docs/WritingAnLLVMBackend.html
index 0f38955f4eef..08da132028d0 100644
--- a/docs/WritingAnLLVMBackend.html
+++ b/docs/WritingAnLLVMBackend.html
@@ -1349,9 +1349,9 @@ ISD::STORE opcode.</p>
</div>
<div class="doc_code">
-<pre>SDNode *SelectCode(SDOperand N) {
+<pre>SDNode *SelectCode(SDValue N) {
...
- MVT::ValueType NVT = N.Val-&gt;getValueType(0);
+ MVT::ValueType NVT = N.getNode()-&gt;getValueType(0);
switch (N.getOpcode()) {
case ISD::STORE: {
switch (NVT) {
@@ -1372,21 +1372,21 @@ instruction. </p>
</div>
<div class="doc_code">
-<pre>SDNode *Select_ISD_STORE(const SDOperand &amp;N) {
- SDOperand Chain = N.getOperand(0);
- if (Predicate_store(N.Val)) {
- SDOperand N1 = N.getOperand(1);
- SDOperand N2 = N.getOperand(2);
- SDOperand CPTmp0;
- SDOperand CPTmp1;
+<pre>SDNode *Select_ISD_STORE(const SDValue &amp;N) {
+ SDValue Chain = N.getOperand(0);
+ if (Predicate_store(N.getNode())) {
+ SDValue N1 = N.getOperand(1);
+ SDValue N2 = N.getOperand(2);
+ SDValue CPTmp0;
+ SDValue CPTmp1;
&nbsp;
// Pattern: (st:void IntRegs:i32:$src,
// ADDRrr:i32:$addr)&lt;&lt;P:Predicate_store&gt;&gt;
// Emits: (STrr:void ADDRrr:i32:$addr, IntRegs:i32:$src)
// Pattern complexity = 13 cost = 1 size = 0
if (SelectADDRrr(N, N2, CPTmp0, CPTmp1) &amp;&amp;
- N1.Val-&gt;getValueType(0) == MVT::i32 &amp;&amp;
- N2.Val-&gt;getValueType(0) == MVT::i32) {
+ N1.getNode()-&gt;getValueType(0) == MVT::i32 &amp;&amp;
+ N2.getNode()-&gt;getValueType(0) == MVT::i32) {
return Emit_22(N, SP::STrr, CPTmp0, CPTmp1);
}
...
@@ -1520,8 +1520,8 @@ code, an FP_TO_SINT opcode will call the <tt>LowerFP_TO_SINT</tt> method:</p>
</div>
<div class="doc_code">
-<pre>SDOperand SparcTargetLowering::LowerOperation(
- SDOperand Op, SelectionDAG &amp;DAG) {
+<pre>SDValue SparcTargetLowering::LowerOperation(
+ SDValue Op, SelectionDAG &amp;DAG) {
switch (Op.getOpcode()) {
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
...
@@ -1535,7 +1535,7 @@ register to convert the floating-point value to an integer.</p>
</div>
<div class="doc_code">
-<pre>static SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &amp;DAG) {
+<pre>static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &amp;DAG) {
assert(Op.getValueType() == MVT::i32);
Op = DAG.getNode(SPISD::FTOI, MVT::f32, Op.getOperand(0));
return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
diff --git a/docs/WritingAnLLVMPass.html b/docs/WritingAnLLVMPass.html
index 0f37ec276c45..04bd9266118b 100644
--- a/docs/WritingAnLLVMPass.html
+++ b/docs/WritingAnLLVMPass.html
@@ -78,7 +78,8 @@
<li><a href="#AU::addRequired">The <tt>AnalysisUsage::addRequired&lt;&gt;</tt> and <tt>AnalysisUsage::addRequiredTransitive&lt;&gt;</tt> methods</a></li>
<li><a href="#AU::addPreserved">The <tt>AnalysisUsage::addPreserved&lt;&gt;</tt> method</a></li>
<li><a href="#AU::examples">Example implementations of <tt>getAnalysisUsage</tt></a></li>
- <li><a href="#getAnalysis">The <tt>getAnalysis&lt;&gt;</tt> and <tt>getAnalysisToUpdate&lt;&gt;</tt> methods</a></li>
+ <li><a href="#getAnalysis">The <tt>getAnalysis&lt;&gt;</tt> and
+<tt>getAnalysisIfAvailable&lt;&gt;</tt> methods</a></li>
</ul></li>
<li><a href="#analysisgroup">Implementing Analysis Groups</a>
<ul>
@@ -1131,7 +1132,8 @@ the fact that it hacks on the CFG.
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
- <a name="getAnalysis">The <tt>getAnalysis&lt;&gt;</tt> and <tt>getAnalysisToUpdate&lt;&gt;</tt> methods</a>
+ <a name="getAnalysis">The <tt>getAnalysis&lt;&gt;</tt> and
+<tt>getAnalysisIfAvailable&lt;&gt;</tt> methods</a>
</div>
<div class="doc_text">
@@ -1173,12 +1175,12 @@ before returning a reference to the desired pass.</p>
<p>
If your pass is capable of updating analyses if they exist (e.g.,
<tt>BreakCriticalEdges</tt>, as described above), you can use the
-<tt>getAnalysisToUpdate</tt> method, which returns a pointer to the analysis if
-it is active. For example:</p>
+<tt>getAnalysisIfAvailable</tt> method, which returns a pointer to the analysis
+if it is active. For example:</p>
<div class="doc_code"><pre>
...
- if (DominatorSet *DS = getAnalysisToUpdate&lt;DominatorSet&gt;()) {
+ if (DominatorSet *DS = getAnalysisIfAvailable&lt;DominatorSet&gt;()) {
<i>// A DominatorSet is active. This code will update it.</i>
}
...
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 386a8ad18df2..6fef4c7a0d0c 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -236,16 +236,16 @@ public:
/// getMaxValue - Return the APSInt representing the maximum integer value
/// with the given bit width and signedness.
- static APSInt getMaxValue(uint32_t numBits, bool Signed) {
- return APSInt(Signed ? APInt::getSignedMaxValue(numBits)
- : APInt::getMaxValue(numBits), Signed);
+ static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
+ return APSInt(Unsigned ? APInt::getMaxValue(numBits)
+ : APInt::getSignedMaxValue(numBits), Unsigned);
}
/// getMinValue - Return the APSInt representing the minimum integer value
/// with the given bit width and signedness.
- static APSInt getMinValue(uint32_t numBits, bool Signed) {
- return APSInt(Signed ? APInt::getSignedMinValue(numBits)
- : APInt::getMinValue(numBits), Signed);
+ static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
+ return APSInt(Unsigned ? APInt::getMinValue(numBits)
+ : APInt::getSignedMinValue(numBits), Unsigned);
}
/// Profile - Used to insert APSInt objects, or objects that contain APSInt
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index d92605b8193f..23fde26e142d 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -286,7 +286,7 @@ public:
}
// Intersection, union, disjoint union.
- BitVector operator&=(const BitVector &RHS) {
+ BitVector &operator&=(const BitVector &RHS) {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
unsigned i;
@@ -302,14 +302,14 @@ public:
return *this;
}
- BitVector operator|=(const BitVector &RHS) {
+ BitVector &operator|=(const BitVector &RHS) {
assert(Size == RHS.Size && "Illegal operation!");
for (unsigned i = 0; i < NumBitWords(size()); ++i)
Bits[i] |= RHS.Bits[i];
return *this;
}
- BitVector operator^=(const BitVector &RHS) {
+ BitVector &operator^=(const BitVector &RHS) {
assert(Size == RHS.Size && "Illegal operation!");
for (unsigned i = 0; i < NumBitWords(size()); ++i)
Bits[i] ^= RHS.Bits[i];
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index c705bccca4d3..1b38baf48c57 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -345,6 +345,19 @@ public:
}
};
+/// isNoAliasCall - Return true if this pointer is returned by a noalias
+/// function.
+bool isNoAliasCall(const Value *V);
+
+/// isIdentifiedObject - Return true if this pointer refers to a distinct and
+/// identifiable object. This returns true for:
+/// Global Variables and Functions
+/// Allocas and Mallocs
+/// ByVal and NoAlias Arguments
+/// NoAlias returns
+///
+bool isIdentifiedObject(const Value *V);
+
} // End llvm namespace
// Because of the way .a files work, we must force the BasicAA implementation to
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index 63206ea6fca5..5113d5f77370 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_DEBUGINFO_H
-#define LLVM_SUPPORT_DEBUGINFO_H
+#ifndef LLVM_ANALYSIS_DEBUGINFO_H
+#define LLVM_ANALYSIS_DEBUGINFO_H
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/DenseMap.h"
@@ -109,9 +109,24 @@ namespace llvm {
std::string getFilename() const { return getStringField(3); }
std::string getDirectory() const { return getStringField(4); }
std::string getProducer() const { return getStringField(5); }
+
+ /// isMain - Each input file is encoded as a separate compile unit in LLVM
+ /// debugging information output. However, many target specific tool chains
+ /// prefer to encode only one compile unit in an object file. In this
+ /// situation, the LLVM code generator will include debugging information
+ /// entities in the compile unit that is marked as main compile unit. The
+ /// code generator accepts maximum one main compile unit per module. If a
+ /// module does not contain any main compile unit then the code generator
+ /// will emit multiple compile units in the output object file.
+ bool isMain() const { return getUnsignedField(6); }
+ bool isOptimized() const { return getUnsignedField(7); }
+ std::string getFlags() const { return getStringField(8); }
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
+
+ /// dump - print compile unit.
+ void dump() const;
};
/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
@@ -178,25 +193,18 @@ namespace llvm {
bool isProtected() const { return (getFlags() & FlagProtected) != 0; }
bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; }
- virtual std::string getFilename() const {
- assert (0 && "Invalid DIDescriptor");
- return "";
- }
-
- virtual std::string getDirectory() const {
- assert (0 && "Invalid DIDescriptor");
- return "";
- }
+ /// dump - print type.
+ void dump() const;
};
/// DIBasicType - A basic type, like 'int' or 'float'.
class DIBasicType : public DIType {
public:
explicit DIBasicType(GlobalVariable *GV);
-
unsigned getEncoding() const { return getUnsignedField(9); }
- std::string getFilename() const { return getStringField(10); }
- std::string getDirectory() const { return getStringField(11); }
+
+ /// dump - print basic type.
+ void dump() const;
};
/// DIDerivedType - A simple derived type, like a const qualified type,
@@ -207,10 +215,10 @@ namespace llvm {
: DIType(GV, true, true) {}
public:
explicit DIDerivedType(GlobalVariable *GV);
-
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
- std::string getFilename() const { return getStringField(10); }
- std::string getDirectory() const { return getStringField(11); }
+
+ /// dump - print derived type.
+ void dump() const;
};
/// DICompositeType - This descriptor holds a type that can refer to multiple
@@ -219,13 +227,13 @@ namespace llvm {
class DICompositeType : public DIDerivedType {
public:
explicit DICompositeType(GlobalVariable *GV);
-
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
- std::string getFilename() const { return getStringField(11); }
- std::string getDirectory() const { return getStringField(12); }
/// Verify - Verify that a composite type descriptor is well formed.
bool Verify() const;
+
+ /// dump - print composite type.
+ void dump() const;
};
/// DIGlobal - This is a common class for global variables and subprograms.
@@ -262,40 +270,34 @@ namespace llvm {
unsigned isLocalToUnit() const { return getUnsignedField(9); }
unsigned isDefinition() const { return getUnsignedField(10); }
- virtual std::string getFilename() const {
- assert (0 && "Invalid DIDescriptor");
- return "";
- }
-
- virtual std::string getDirectory() const {
- assert (0 && "Invalid DIDescriptor");
- return "";
- }
+ /// dump - print global.
+ void dump() const;
};
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIGlobal {
public:
explicit DISubprogram(GlobalVariable *GV = 0);
- std::string getFilename() const { return getStringField(11); }
- std::string getDirectory() const { return getStringField(12); }
DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
/// Verify - Verify that a subprogram descriptor is well formed.
bool Verify() const;
+
+ /// dump - print subprogram.
+ void dump() const;
};
/// DIGlobalVariable - This is a wrapper for a global variable.
class DIGlobalVariable : public DIGlobal {
public:
explicit DIGlobalVariable(GlobalVariable *GV = 0);
-
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
- std::string getFilename() const { return getStringField(12); }
- std::string getDirectory() const { return getStringField(13); }
/// Verify - Verify that a global variable descriptor is well formed.
bool Verify() const;
+
+ /// dump - print global variable.
+ void dump() const;
};
/// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
@@ -309,14 +311,15 @@ namespace llvm {
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
unsigned getLineNumber() const { return getUnsignedField(4); }
DIType getType() const { return getFieldAs<DIType>(5); }
- std::string getFilename() const { return getStringField(6); }
- std::string getDirectory() const { return getStringField(7); }
/// isVariable - Return true if the specified tag is legal for DIVariable.
static bool isVariable(unsigned Tag);
/// Verify - Verify that a variable descriptor is well formed.
bool Verify() const;
+
+ /// dump - print variable.
+ void dump() const;
};
/// DIBlock - This is a wrapper for a block (e.g. a function, scope, etc).
@@ -372,7 +375,10 @@ namespace llvm {
DICompileUnit CreateCompileUnit(unsigned LangID,
const std::string &Filename,
const std::string &Directory,
- const std::string &Producer);
+ const std::string &Producer,
+ bool isMain = false,
+ bool isOptimized = false,
+ const char *Flags = "");
/// CreateEnumerator - Create a single enumerator value.
DIEnumerator CreateEnumerator(const std::string &Name, uint64_t Val);
@@ -382,9 +388,7 @@ namespace llvm {
DICompileUnit CompileUnit, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
- unsigned Encoding,
- const std::string *FileName = 0,
- const std::string *Directory = 0);
+ unsigned Encoding);
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
@@ -394,9 +398,7 @@ namespace llvm {
unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
- DIType DerivedFrom,
- const std::string *FileName = 0,
- const std::string *Directory = 0);
+ DIType DerivedFrom);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
@@ -407,9 +409,7 @@ namespace llvm {
uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType DerivedFrom,
- DIArray Elements,
- const std::string *FileName = 0,
- const std::string *Directory = 0);
+ DIArray Elements);
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields.
@@ -418,9 +418,7 @@ namespace llvm {
const std::string &LinkageName,
DICompileUnit CompileUnit, unsigned LineNo,
DIType Type, bool isLocalToUnit,
- bool isDefinition,
- const std::string *FileName = 0,
- const std::string *Directory = 0);
+ bool isDefinition);
/// CreateGlobalVariable - Create a new descriptor for the specified global.
DIGlobalVariable
@@ -429,17 +427,13 @@ namespace llvm {
const std::string &LinkageName,
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type, bool isLocalToUnit,
- bool isDefinition, llvm::GlobalVariable *GV,
- const std::string *FileName = 0,
- const std::string *Directory = 0);
+ bool isDefinition, llvm::GlobalVariable *GV);
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type,
- const std::string *FileName = 0,
- const std::string *Directory = 0);
+ DIType Type);
/// CreateBlock - This creates a descriptor for a lexical block with the
/// specified parent context.
diff --git a/include/llvm/Analysis/EscapeAnalysis.h b/include/llvm/Analysis/EscapeAnalysis.h
deleted file mode 100644
index 3f4da25310d7..000000000000
--- a/include/llvm/Analysis/EscapeAnalysis.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===------------- EscapeAnalysis.h - Pointer escape 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 the interface for the pointer escape analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_ESCAPEANALYSIS_H
-#define LLVM_ANALYSIS_ESCAPEANALYSIS_H
-
-#include "llvm/Pass.h"
-#include <set>
-
-namespace llvm {
-
-class Instruction;
-class Value;
-
-/// EscapeAnalysis - This class determines whether an allocation (a MallocInst
-/// or an AllocaInst) can escape from the current function. It performs some
-/// precomputation, with the rest of the work happening on-demand.
-class EscapeAnalysis : public FunctionPass {
-private:
- std::set<Instruction*> EscapePoints;
-
-public:
- static char ID; // Class identification, replacement for typeinfo
-
- EscapeAnalysis() : FunctionPass(intptr_t(&ID)) {}
-
- bool runOnFunction(Function &F);
-
- void releaseMemory() {
- EscapePoints.clear();
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const;
-
- //===---------------------------------------------------------------------
- // Client API
-
- /// escapes - returns true if the value, which must have a pointer type,
- /// can escape.
- bool escapes(Value* A);
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 7aa325a9d1d8..a1bac6639077 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -482,8 +482,7 @@ public:
++UI) {
BlockT *UserBB = cast<Instruction>(*UI)->getParent();
if (PHINode *P = dyn_cast<PHINode>(*UI)) {
- unsigned OperandNo = UI.getOperandNo();
- UserBB = P->getIncomingBlock(OperandNo/2);
+ UserBB = P->getIncomingBlock(UI);
}
// Check the current block, as a fast-path. Most values are used in
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index cdc795162579..d63b06d954e2 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -309,7 +309,7 @@ namespace llvm {
protected:
/// EmitZeros - Emit a block of zeros.
///
- void EmitZeros(uint64_t NumZeros) const;
+ void EmitZeros(uint64_t NumZeros, unsigned AddrSpace = 0) const;
/// EmitString - Emit a zero-byte-terminated string constant.
///
@@ -320,7 +320,7 @@ namespace llvm {
void EmitConstantValueOnly(const Constant *CV);
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
- void EmitGlobalConstant(const Constant* CV);
+ void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0);
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
@@ -351,7 +351,7 @@ namespace llvm {
/// printDataDirective - This method prints the asm directive for the
/// specified type.
- void printDataDirective(const Type *type);
+ void printDataDirective(const Type *type, unsigned AddrSpace = 0);
/// printSuffixedName - This prints a name with preceding
/// getPrivateGlobalPrefix and the specified suffix, handling quoted names
@@ -371,11 +371,12 @@ namespace llvm {
const GlobalValue *findGlobalValue(const Constant* CV);
void EmitLLVMUsedList(Constant *List);
void EmitXXStructorList(Constant *List);
- void EmitGlobalConstantStruct(const ConstantStruct* CVS);
+ void EmitGlobalConstantStruct(const ConstantStruct* CVS,
+ unsigned AddrSpace);
void EmitGlobalConstantArray(const ConstantArray* CVA);
void EmitGlobalConstantVector(const ConstantVector* CP);
- void EmitGlobalConstantFP(const ConstantFP* CFP);
- void EmitGlobalConstantLargeInt(const ConstantInt* CI);
+ void EmitGlobalConstantFP(const ConstantFP* CFP, unsigned AddrSpace);
+ void EmitGlobalConstantLargeInt(const ConstantInt* CI, unsigned AddrSpace);
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
};
}
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h
index 28b227772a51..6c040f47f60a 100644
--- a/include/llvm/CodeGen/DAGISelHeader.h
+++ b/include/llvm/CodeGen/DAGISelHeader.h
@@ -31,9 +31,9 @@ SelectionDAG::allnodes_iterator ISelPosition;
static bool IsChainCompatible(SDNode *Chain, SDNode *Op) {
if (Chain->getOpcode() == ISD::EntryToken)
return true;
- else if (Chain->getOpcode() == ISD::TokenFactor)
+ if (Chain->getOpcode() == ISD::TokenFactor)
return false;
- else if (Chain->getNumOperands() > 0) {
+ if (Chain->getNumOperands() > 0) {
SDValue C0 = Chain->getOperand(0);
if (C0.getValueType() == MVT::Other)
return C0.getNode() != Op && IsChainCompatible(C0.getNode(), Op);
diff --git a/include/llvm/CodeGen/DebugLoc.h b/include/llvm/CodeGen/DebugLoc.h
new file mode 100644
index 000000000000..b89bf6302a08
--- /dev/null
+++ b/include/llvm/CodeGen/DebugLoc.h
@@ -0,0 +1,94 @@
+//===---- llvm/CodeGen/DebugLoc.h - Debug Location 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 defines a number of light weight data structures used by the code
+// generator to describe and track debug location information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DEBUGLOC_H
+#define LLVM_CODEGEN_DEBUGLOC_H
+
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+
+namespace llvm {
+
+ /// DebugLocTuple - Debug location tuple of filename id, line and column.
+ ///
+ struct DebugLocTuple {
+ unsigned Src, Line, Col;
+
+ DebugLocTuple(unsigned s, unsigned l, unsigned c)
+ : Src(s), Line(l), Col(c) {};
+ };
+
+ /// DebugLoc - Debug location id. This is carried by SDNode and MachineInstr
+ /// to index into a vector of unique debug location tuples.
+ class DebugLoc {
+ unsigned Idx;
+
+ public:
+ DebugLoc() : Idx(~0U) {} // Defaults to invalid.
+
+ static DebugLoc getUnknownLoc() { DebugLoc L; L.Idx = 0; return L; }
+ static DebugLoc get(unsigned idx) { DebugLoc L; L.Idx = idx; return L; }
+
+ /// isInvalid - Return true if the DebugLoc is invalid.
+ bool isInvalid() const { return Idx == ~0U; }
+
+ /// isUnknown - Return true if there is no debug info for the SDNode /
+ /// MachineInstr.
+ bool isUnknown() const { return Idx == 0; }
+ };
+
+ // Partially specialize DenseMapInfo for DebugLocTyple.
+ template<> struct DenseMapInfo<DebugLocTuple> {
+ static inline DebugLocTuple getEmptyKey() {
+ return DebugLocTuple(~0U, ~0U, ~0U);
+ }
+ static inline DebugLocTuple getTombstoneKey() {
+ return DebugLocTuple(~1U, ~1U, ~1U);
+ }
+ static unsigned getHashValue(const DebugLocTuple &Val) {
+ return DenseMapInfo<unsigned>::getHashValue(Val.Src) ^
+ DenseMapInfo<unsigned>::getHashValue(Val.Line) ^
+ DenseMapInfo<unsigned>::getHashValue(Val.Col);
+ }
+ static bool isEqual(const DebugLocTuple &LHS, const DebugLocTuple &RHS) {
+ return LHS.Src == RHS.Src &&
+ LHS.Line == RHS.Line &&
+ LHS.Col == RHS.Col;
+ }
+
+ static bool isPod() { return true; }
+ };
+
+ /// DebugLocTracker - This class tracks debug location information.
+ ///
+ struct DebugLocTracker {
+ /// DebugLocations - A vector of unique DebugLocTuple's.
+ ///
+ std::vector<DebugLocTuple> DebugLocations;
+
+ /// DebugIdsMap - This maps DebugLocTuple's to indices into DebugLocations
+ /// vector.
+ DenseMap<DebugLocTuple, unsigned> DebugIdMap;
+
+ DebugLocTracker() {}
+
+ ~DebugLocTracker() {
+ DebugLocations.clear();
+ DebugIdMap.clear();
+ }
+ };
+
+} // end namespace llvm
+
+#endif /* LLVM_CODEGEN_DEBUGLOC_H */
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
index 1616dfa4e90b..58a2fa742373 100644
--- a/include/llvm/CodeGen/DwarfWriter.h
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -79,8 +79,9 @@ public:
/// ValidDebugInfo - Return true if V represents valid debug info value.
bool ValidDebugInfo(Value *V);
- /// label. Returns a unique label ID used to generate a label and provide
- /// correspondence to the source line list.
+ /// RecordSourceLine - Register a source line with debug info. Returns a
+ /// unique label ID used to generate a label and provide correspondence to
+ /// the source line list.
unsigned RecordSourceLine(unsigned Line, unsigned Col, unsigned Src);
/// RecordSource - Register a source file with debug info. Returns an source
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 0b8d67bfcdb4..1c26b3fd763b 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/CodeGen/DebugLoc.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
namespace llvm {
@@ -55,28 +56,33 @@ protected:
MachineRegisterInfo &MRI;
MachineFrameInfo &MFI;
MachineConstantPool &MCP;
+ DebugLoc DL;
const TargetMachine &TM;
const TargetData &TD;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
public:
- /// startNewBlock - Set the current block, to which generated
- /// machine instructions will be appended, and clear the local
- /// CSE map.
+ /// startNewBlock - Set the current block to which generated machine
+ /// instructions will be appended, and clear the local CSE map.
///
void startNewBlock(MachineBasicBlock *mbb) {
setCurrentBlock(mbb);
LocalValueMap.clear();
}
- /// setCurrentBlock - Set the current block, to which generated
- /// machine instructions will be appended.
+ /// setCurrentBlock - Set the current block to which generated machine
+ /// instructions will be appended.
///
void setCurrentBlock(MachineBasicBlock *mbb) {
MBB = mbb;
}
+ /// setCurDebugLoc - Set the current debug location information, which is used
+ /// when creating a machine instruction.
+ ///
+ void setCurDebugLoc(DebugLoc dl) { DL = dl; }
+
/// SelectInstruction - Do "fast" instruction selection for the given
/// LLVM IR instruction, and append generated machine instructions to
/// the current block. Return true if selection was successful.
@@ -259,8 +265,9 @@ protected:
uint64_t Imm);
/// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg
- /// from a specified index of a superregister.
- unsigned FastEmitInst_extractsubreg(unsigned Op0, uint32_t Idx);
+ /// from a specified index of a superregister to a specified type.
+ unsigned FastEmitInst_extractsubreg(MVT::SimpleValueType RetVT,
+ unsigned Op0, uint32_t Idx);
/// FastEmitBranch - Emit an unconditional branch to the given block,
/// unless it is the immediate (fall-through) successor, and update
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 86aada3b80a7..fb7448635711 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -276,7 +276,7 @@ namespace llvm {
/// are found to be equivalent. This eliminates V1, replacing all
/// LiveRanges with the V1 value number with the V2 value number. This can
/// cause merging of V1/V2 values numbers and compaction of the value space.
- void MergeValueNumberInto(VNInfo *V1, VNInfo *V2);
+ VNInfo* MergeValueNumberInto(VNInfo *V1, VNInfo *V2);
/// MergeInClobberRanges - For any live ranges that are not defined in the
/// current interval, but are defined in the Clobbers interval, mark them
@@ -377,8 +377,12 @@ namespace llvm {
const int *RHSValNoAssignments,
SmallVector<VNInfo*, 16> &NewVNInfo);
+ /// isInOneLiveRange - Return true if the range specified is entirely in the
+ /// a single LiveRange of the live interval.
+ bool isInOneLiveRange(unsigned Start, unsigned End);
+
/// removeRange - Remove the specified range from this interval. Note that
- /// the range must already be in this interval in its entirety.
+ /// the range must be a single LiveRange in its entirety.
void removeRange(unsigned Start, unsigned End, bool RemoveDeadValNo = false);
void removeRange(LiveRange LR, bool RemoveDeadValNo = false) {
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
index 6b5235a5d1dd..7cb4151e8705 100644
--- a/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -64,8 +64,8 @@ namespace llvm {
return I->second;
}
- bool hasInterval(unsigned reg) const {
- return s2iMap.count(reg);
+ bool hasInterval(unsigned Slot) const {
+ return s2iMap.count(Slot);
}
BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 835c8a37c56e..6abedb50b3c2 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -19,6 +19,7 @@
#define LLVM_CODEGEN_MACHINEFUNCTION_H
#include "llvm/ADT/ilist.h"
+#include "llvm/CodeGen/DebugLoc.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Support/Annotation.h"
#include "llvm/Support/Allocator.h"
@@ -27,11 +28,11 @@
namespace llvm {
class Function;
-class TargetMachine;
class MachineRegisterInfo;
class MachineFrameInfo;
class MachineConstantPool;
class MachineJumpTableInfo;
+class TargetMachine;
template <>
struct ilist_traits<MachineBasicBlock>
@@ -94,6 +95,9 @@ class MachineFunction : private Annotation {
typedef ilist<MachineBasicBlock> BasicBlockListType;
BasicBlockListType BasicBlocks;
+ // Tracks debug locations.
+ DebugLocTracker DebugLocInfo;
+
public:
MachineFunction(const Function *Fn, const TargetMachine &TM);
~MachineFunction();
@@ -282,6 +286,7 @@ public:
/// of `new MachineInstr'.
///
MachineInstr *CreateMachineInstr(const TargetInstrDesc &TID,
+ DebugLoc DL,
bool NoImp = false);
/// CloneMachineInstr - Create a new MachineInstr which is a copy of the
@@ -302,6 +307,15 @@ public:
/// DeleteMachineBasicBlock - Delete the given MachineBasicBlock.
///
void DeleteMachineBasicBlock(MachineBasicBlock *MBB);
+
+ //===--------------------------------------------------------------------===//
+ // Debug location.
+ //
+
+ /// getOrCreateDebugLocID - Look up the DebugLocTuple index with the given
+ /// source file, line, and column. If none currently exists, create add a new
+ /// new DebugLocTuple and insert it into the DebugIdMap.
+ unsigned getOrCreateDebugLocID(unsigned Src, unsigned Line, unsigned Col);
};
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 379cf8fbd340..2a3f98dbc5bd 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -22,6 +22,7 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/Target/TargetInstrDesc.h"
+#include "llvm/CodeGen/DebugLoc.h"
#include <list>
#include <vector>
@@ -43,6 +44,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
std::vector<MachineOperand> Operands; // the operands
std::list<MachineMemOperand> MemOperands; // information on memory references
MachineBasicBlock *Parent; // Pointer to the owning basic block.
+ DebugLoc debugLoc; // Source line information.
// OperandComplete - Return true if it's illegal to add a new operand
bool OperandsComplete() const;
@@ -64,17 +66,34 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// TID NULL and no operands.
MachineInstr();
+ // The next two constructors have DebugLoc and non-DebugLoc versions;
+ // over time, the non-DebugLoc versions should be phased out and eventually
+ // removed.
+
/// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by
- /// TargetInstrDesc.
+ /// TargetInstrDesc. The version with a DebugLoc should be preferred.
explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic
- /// block.
+ /// block. The version with a DebugLoc should be preferred.
///
MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID);
+ /// MachineInstr ctor - This constructor create a MachineInstr and add the
+ /// implicit operands. It reserves space for number of operands specified by
+ /// TargetInstrDesc. An explicit DebugLoc is supplied.
+ explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl,
+ bool NoImp = false);
+
+ /// MachineInstr ctor - Work exactly the same as the ctor above, except that
+ /// the MachineInstr is created and added to the end of the specified basic
+ /// block.
+ ///
+ MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
+ const TargetInstrDesc &TID);
+
~MachineInstr();
// MachineInstrs are pool-allocated and owned by MachineFunction.
@@ -83,6 +102,10 @@ class MachineInstr : public ilist_node<MachineInstr> {
public:
const MachineBasicBlock* getParent() const { return Parent; }
MachineBasicBlock* getParent() { return Parent; }
+
+ /// getDebugLoc - Returns the debug location id of this MachineInstr.
+ ///
+ const DebugLoc getDebugLoc() const { return debugLoc; }
/// getDesc - Returns the target instruction descriptor of this
/// MachineInstr.
@@ -289,6 +312,11 @@ public:
///
void setDesc(const TargetInstrDesc &tid) { TID = &tid; }
+ /// setDebugLoc - Replace current source information with new such.
+ /// Avoid using this, the constructor argument is preferable.
+ ///
+ void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+
/// RemoveOperand - Erase an operand from an instruction, leaving it with one
/// fewer operand than it started with.
///
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index d097362a5582..54fbe27eec73 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -100,16 +100,31 @@ public:
///
inline MachineInstrBuilder BuildMI(MachineFunction &MF,
const TargetInstrDesc &TID) {
- return MachineInstrBuilder(MF.CreateMachineInstr(TID));
+ return MachineInstrBuilder(MF.CreateMachineInstr(TID,
+ DebugLoc::getUnknownLoc()));
+}
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+ DebugLoc DL,
+ const TargetInstrDesc &TID) {
+ return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL));
}
/// BuildMI - This version of the builder sets up the first operand as a
/// destination virtual register.
///
-inline MachineInstrBuilder BuildMI(MachineFunction &MF,
- const TargetInstrDesc &TID,
- unsigned DestReg) {
- return MachineInstrBuilder(MF.CreateMachineInstr(TID)).addReg(DestReg, true);
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+ const TargetInstrDesc &TID,
+ unsigned DestReg) {
+ return MachineInstrBuilder(MF.CreateMachineInstr(TID,
+ DebugLoc::getUnknownLoc()))
+ .addReg(DestReg, true);
+}
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+ DebugLoc DL,
+ const TargetInstrDesc &TID,
+ unsigned DestReg) {
+ return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL))
+ .addReg(DestReg, true);
}
/// BuildMI - This version of the builder inserts the newly-built
@@ -120,7 +135,17 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
const TargetInstrDesc &TID,
unsigned DestReg) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID);
+ MachineInstr *MI =
+ BB.getParent()->CreateMachineInstr(TID, DebugLoc::getUnknownLoc());
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI).addReg(DestReg, true);
+}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ DebugLoc DL,
+ const TargetInstrDesc &TID,
+ unsigned DestReg) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
BB.insert(I, MI);
return MachineInstrBuilder(MI).addReg(DestReg, true);
}
@@ -132,7 +157,16 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
const TargetInstrDesc &TID) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID);
+ MachineInstr *MI =
+ BB.getParent()->CreateMachineInstr(TID, DebugLoc::getUnknownLoc());
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI);
+}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ DebugLoc DL,
+ const TargetInstrDesc &TID) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
BB.insert(I, MI);
return MachineInstrBuilder(MI);
}
@@ -145,6 +179,11 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
const TargetInstrDesc &TID) {
return BuildMI(*BB, BB->end(), TID);
}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ DebugLoc DL,
+ const TargetInstrDesc &TID) {
+ return BuildMI(*BB, BB->end(), DL, TID);
+}
/// BuildMI - This version of the builder inserts the newly-built
/// instruction at the end of the given MachineBasicBlock, and sets up the first
@@ -155,6 +194,12 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
unsigned DestReg) {
return BuildMI(*BB, BB->end(), TID, DestReg);
}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ DebugLoc DL,
+ const TargetInstrDesc &TID,
+ unsigned DestReg) {
+ return BuildMI(*BB, BB->end(), DL, TID, DestReg);
+}
} // End llvm namespace
diff --git a/include/llvm/CodeGen/ScheduleDAGSDNodes.h b/include/llvm/CodeGen/ScheduleDAGSDNodes.h
index 52cf4eb998b7..8950433062f5 100644
--- a/include/llvm/CodeGen/ScheduleDAGSDNodes.h
+++ b/include/llvm/CodeGen/ScheduleDAGSDNodes.h
@@ -61,7 +61,7 @@ namespace llvm {
SUnit *NewSUnit(SDNode *N) {
#ifndef NDEBUG
const SUnit *Addr = 0;
- if (SUnits.size() > 0)
+ if (!SUnits.empty())
Addr = &SUnits[0];
#endif
SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index f93b6207b8f9..5f226e83d5c7 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -307,14 +307,19 @@ public:
return getConstantPool(C, VT, Align, Offset, true);
}
SDValue getBasicBlock(MachineBasicBlock *MBB);
+ SDValue getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl);
SDValue getExternalSymbol(const char *Sym, MVT VT);
+ SDValue getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
SDValue getTargetExternalSymbol(const char *Sym, MVT VT);
+ SDValue getTargetExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
SDValue getArgFlags(ISD::ArgFlagsTy Flags);
SDValue getValueType(MVT);
SDValue getRegister(unsigned Reg, MVT VT);
SDValue getDbgStopPoint(SDValue Root, unsigned Line, unsigned Col,
Value *CU);
SDValue getLabel(unsigned Opcode, SDValue Root, unsigned LabelID);
+ SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root,
+ unsigned LabelID);
SDValue getCopyToReg(SDValue Chain, unsigned Reg, SDValue N) {
return getNode(ISD::CopyToReg, MVT::Other, Chain,
@@ -365,7 +370,11 @@ public:
/// getZeroExtendInReg - Return the expression required to zero extend the Op
/// value assuming it was the smaller SrcTy value.
SDValue getZeroExtendInReg(SDValue Op, MVT SrcTy);
+ SDValue getZeroExtendInReg(SDValue Op, DebugLoc DL, MVT SrcTy);
+ /// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
+ SDValue getNOT(DebugLoc DL, SDValue Val, MVT VT);
+
/// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
/// a flag result (to ensure it's not CSE'd).
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) {
@@ -391,35 +400,68 @@ public:
/// getNode - Gets or creates the specified node.
///
SDValue getNode(unsigned Opcode, MVT VT);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT);
SDValue getNode(unsigned Opcode, MVT VT, SDValue N);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue N);
SDValue getNode(unsigned Opcode, MVT VT, SDValue N1, SDValue N2);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue N1, SDValue N2);
SDValue getNode(unsigned Opcode, MVT VT,
- SDValue N1, SDValue N2, SDValue N3);
+ SDValue N1, SDValue N2, SDValue N3);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ SDValue N1, SDValue N2, SDValue N3);
SDValue getNode(unsigned Opcode, MVT VT,
- SDValue N1, SDValue N2, SDValue N3, SDValue N4);
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4);
SDValue getNode(unsigned Opcode, MVT VT,
- SDValue N1, SDValue N2, SDValue N3, SDValue N4,
- SDValue N5);
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4,
+ SDValue N5);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4,
+ SDValue N5);
SDValue getNode(unsigned Opcode, MVT VT,
- const SDValue *Ops, unsigned NumOps);
+ const SDUse *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ const SDUse *Ops, unsigned NumOps);
SDValue getNode(unsigned Opcode, MVT VT,
- const SDUse *Ops, unsigned NumOps);
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ const SDValue *Ops, unsigned NumOps);
SDValue getNode(unsigned Opcode, const std::vector<MVT> &ResultTys,
- const SDValue *Ops, unsigned NumOps);
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL,
+ const std::vector<MVT> &ResultTys,
+ const SDValue *Ops, unsigned NumOps);
SDValue getNode(unsigned Opcode, const MVT *VTs, unsigned NumVTs,
- const SDValue *Ops, unsigned NumOps);
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, const MVT *VTs, unsigned NumVTs,
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps);
+
SDValue getNode(unsigned Opcode, SDVTList VTs);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs);
SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, SDValue N);
SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N1, SDValue N2);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2);
SDValue getNode(unsigned Opcode, SDVTList VTs,
SDValue N1, SDValue N2, SDValue N3);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2, SDValue N3);
SDValue getNode(unsigned Opcode, SDVTList VTs,
SDValue N1, SDValue N2, SDValue N3, SDValue N4);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4);
SDValue getNode(unsigned Opcode, SDVTList VTs,
SDValue N1, SDValue N2, SDValue N3, SDValue N4,
SDValue N5);
- SDValue getNode(unsigned Opcode, SDVTList VTs,
- const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4,
+ SDValue N5);
SDValue getMemcpy(SDValue Chain, SDValue Dst, SDValue Src,
SDValue Size, unsigned Align, bool AlwaysInline,
@@ -440,7 +482,12 @@ public:
///
SDValue getSetCC(MVT VT, SDValue LHS, SDValue RHS,
ISD::CondCode Cond) {
- return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond));
+ return getNode(ISD::SETCC, DebugLoc::getUnknownLoc(), VT,
+ LHS, RHS, getCondCode(Cond));
+ }
+ SDValue getSetCC(DebugLoc DL, MVT VT, SDValue LHS, SDValue RHS,
+ ISD::CondCode Cond) {
+ return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
/// getVSetCC - Helper function to make it easier to build VSetCC's nodes
@@ -448,7 +495,12 @@ public:
///
SDValue getVSetCC(MVT VT, SDValue LHS, SDValue RHS,
ISD::CondCode Cond) {
- return getNode(ISD::VSETCC, VT, LHS, RHS, getCondCode(Cond));
+ return getNode(ISD::VSETCC, DebugLoc::getUnknownLoc(), VT,
+ LHS, RHS, getCondCode(Cond));
+ }
+ SDValue getVSetCC(DebugLoc DL, MVT VT, SDValue LHS, SDValue RHS,
+ ISD::CondCode Cond) {
+ return getNode(ISD::VSETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
/// getSelectCC - Helper function to make it easier to build SelectCC's if you
@@ -456,8 +508,13 @@ public:
///
SDValue getSelectCC(SDValue LHS, SDValue RHS,
SDValue True, SDValue False, ISD::CondCode Cond) {
- return getNode(ISD::SELECT_CC, True.getValueType(), LHS, RHS, True, False,
- getCondCode(Cond));
+ return getNode(ISD::SELECT_CC, DebugLoc::getUnknownLoc(), True.getValueType(),
+ LHS, RHS, True, False, getCondCode(Cond));
+ }
+ SDValue getSelectCC(DebugLoc DL, SDValue LHS, SDValue RHS,
+ SDValue True, SDValue False, ISD::CondCode Cond) {
+ return getNode(ISD::SELECT_CC, DL, True.getValueType(),
+ LHS, RHS, True, False, getCondCode(Cond));
}
/// getVAArg - VAArg produces a result and token chain, and takes a pointer
@@ -470,12 +527,18 @@ public:
SDValue getAtomic(unsigned Opcode, MVT MemVT, SDValue Chain, SDValue Ptr,
SDValue Cmp, SDValue Swp, const Value* PtrVal,
unsigned Alignment=0);
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDValue Chain,
+ SDValue Ptr, SDValue Cmp, SDValue Swp, const Value* PtrVal,
+ unsigned Alignment=0);
/// getAtomic - Gets a node for an atomic op, produces result and chain and
/// takes 2 operands.
SDValue getAtomic(unsigned Opcode, MVT MemVT, SDValue Chain, SDValue Ptr,
SDValue Val, const Value* PtrVal,
unsigned Alignment = 0);
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDValue Chain,
+ SDValue Ptr, SDValue Val, const Value* PtrVal,
+ unsigned Alignment = 0);
/// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
/// result and takes a list of operands.
@@ -485,21 +548,36 @@ public:
MVT MemVT, const Value *srcValue, int SVOff,
unsigned Align = 0, bool Vol = false,
bool ReadMem = true, bool WriteMem = true);
+ SDValue getMemIntrinsicNode(unsigned Opcode, DebugLoc dl,
+ const MVT *VTs, unsigned NumVTs,
+ const SDValue *Ops, unsigned NumOps,
+ MVT MemVT, const Value *srcValue, int SVOff,
+ unsigned Align = 0, bool Vol = false,
+ bool ReadMem = true, bool WriteMem = true);
SDValue getMemIntrinsicNode(unsigned Opcode, SDVTList VTList,
const SDValue *Ops, unsigned NumOps,
MVT MemVT, const Value *srcValue, int SVOff,
unsigned Align = 0, bool Vol = false,
bool ReadMem = true, bool WriteMem = true);
+ SDValue getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
+ const SDValue *Ops, unsigned NumOps,
+ MVT MemVT, const Value *srcValue, int SVOff,
+ unsigned Align = 0, bool Vol = false,
+ bool ReadMem = true, bool WriteMem = true);
/// getMergeValues - Create a MERGE_VALUES node from the given operands.
SDValue getMergeValues(const SDValue *Ops, unsigned NumOps);
+ SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, DebugLoc dl);
/// getCall - Create a CALL node from the given information.
///
SDValue getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
bool isInreg, SDVTList VTs, const SDValue *Operands,
unsigned NumOperands);
+ SDValue getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
+ bool IsTailCall, bool isInreg, SDVTList VTs,
+ const SDValue *Operands, unsigned NumOperands);
/// getLoad - Loads are not normal binary operators: their result type is not
/// determined by their operands, and they produce a value AND a token chain.
@@ -507,36 +585,62 @@ public:
SDValue getLoad(MVT VT, SDValue Chain, SDValue Ptr,
const Value *SV, int SVOffset, bool isVolatile=false,
unsigned Alignment=0);
+ SDValue getLoad(MVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
+ const Value *SV, int SVOffset, bool isVolatile=false,
+ unsigned Alignment=0);
SDValue getExtLoad(ISD::LoadExtType ExtType, MVT VT,
SDValue Chain, SDValue Ptr, const Value *SV,
int SVOffset, MVT EVT, bool isVolatile=false,
unsigned Alignment=0);
+ SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, MVT VT,
+ SDValue Chain, SDValue Ptr, const Value *SV,
+ int SVOffset, MVT EVT, bool isVolatile=false,
+ unsigned Alignment=0);
SDValue getIndexedLoad(SDValue OrigLoad, SDValue Base,
SDValue Offset, ISD::MemIndexedMode AM);
+ SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
+ SDValue Offset, ISD::MemIndexedMode AM);
SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
MVT VT, SDValue Chain,
SDValue Ptr, SDValue Offset,
const Value *SV, int SVOffset, MVT EVT,
bool isVolatile=false, unsigned Alignment=0);
+ SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
+ MVT VT, SDValue Chain,
+ SDValue Ptr, SDValue Offset,
+ const Value *SV, int SVOffset, MVT EVT,
+ bool isVolatile=false, unsigned Alignment=0);
/// getStore - Helper function to build ISD::STORE nodes.
///
SDValue getStore(SDValue Chain, SDValue Val, SDValue Ptr,
const Value *SV, int SVOffset, bool isVolatile=false,
unsigned Alignment=0);
+ SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
+ const Value *SV, int SVOffset, bool isVolatile=false,
+ unsigned Alignment=0);
SDValue getTruncStore(SDValue Chain, SDValue Val, SDValue Ptr,
const Value *SV, int SVOffset, MVT TVT,
bool isVolatile=false, unsigned Alignment=0);
+ SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
+ const Value *SV, int SVOffset, MVT TVT,
+ bool isVolatile=false, unsigned Alignment=0);
SDValue getIndexedStore(SDValue OrigStoe, SDValue Base,
SDValue Offset, ISD::MemIndexedMode AM);
+ SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base,
+ SDValue Offset, ISD::MemIndexedMode AM);
- // getSrcValue - Construct a node to track a Value* through the backend.
+ /// getSrcValue - Construct a node to track a Value* through the backend.
SDValue getSrcValue(const Value *v);
- // getMemOperand - Construct a node to track a memory reference
- // through the backend.
+ /// getMemOperand - Construct a node to track a memory reference
+ /// through the backend.
SDValue getMemOperand(const MachineMemOperand &MO);
+ /// getShiftAmountOperand - Return the specified value casted to
+ /// the target's desired shift amount type.
+ SDValue getShiftAmountOperand(SDValue Op);
+
/// UpdateNodeOperands - *Mutate* the specified node in-place to have the
/// specified operands. If the resultant node already exists in the DAG,
/// this does not modify the specified node, instead it returns the node that
@@ -616,30 +720,72 @@ public:
/// node of the specified opcode and operands, it returns that node instead of
/// the current one.
SDNode *getTargetNode(unsigned Opcode, MVT VT);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1, SDValue Op2);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1,
+ SDValue Op2);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT,
SDValue Op1, SDValue Op2, SDValue Op3);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
+ SDValue Op1, SDValue Op2, SDValue Op3);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT,
const SDValue *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
+ const SDValue *Ops, unsigned NumOps);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, SDValue Op1);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
+ SDValue Op1);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1,
MVT VT2, SDValue Op1, SDValue Op2);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
+ MVT VT2, SDValue Op1, SDValue Op2);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1,
MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
+ MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
const SDValue *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
+ const SDValue *Ops, unsigned NumOps);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
SDValue Op1, SDValue Op2);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
+ SDValue Op1, SDValue Op2);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
SDValue Op1, SDValue Op2, SDValue Op3);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
+ SDValue Op1, SDValue Op2, SDValue Op3);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
const SDValue *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
+ const SDValue *Ops, unsigned NumOps);
+
SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, MVT VT4,
const SDValue *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
+ MVT VT4, const SDValue *Ops, unsigned NumOps);
+
SDNode *getTargetNode(unsigned Opcode, const std::vector<MVT> &ResultTys,
const SDValue *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl,
+ const std::vector<MVT> &ResultTys, const SDValue *Ops,
+ unsigned NumOps);
/// getNodeIfExists - Get the specified node if it's already available, or
/// else return NULL.
@@ -758,7 +904,7 @@ public:
/// FoldSetCC - Constant fold a setcc to true or false.
SDValue FoldSetCC(MVT VT, SDValue N1,
- SDValue N2, ISD::CondCode Cond);
+ SDValue N2, ISD::CondCode Cond, DebugLoc dl);
/// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
/// use this predicate to simplify operations downstream.
@@ -797,7 +943,7 @@ public:
private:
bool RemoveNodeFromCSEMaps(SDNode *N);
- SDNode *AddNonLeafNodeToCSEMaps(SDNode *N);
+ void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener);
SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos);
SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2,
void *&InsertPos);
@@ -811,10 +957,10 @@ private:
void allnodes_clear();
- // List of non-single value types.
+ /// VTList - List of non-single value types.
std::vector<SDVTList> VTList;
- // Maps to auto-CSE operations.
+ /// CondCodeNodes - Maps to auto-CSE operations.
std::vector<CondCodeSDNode*> CondCodeNodes;
std::vector<SDNode*> ValueTypeNodes;
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index a429855a9d21..fafc78181853 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -30,6 +30,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/RecyclingAllocator.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/CodeGen/DebugLoc.h"
#include <cassert>
namespace llvm {
@@ -59,8 +60,19 @@ struct SDVTList {
namespace ISD {
//===--------------------------------------------------------------------===//
- /// ISD::NodeType enum - This enum defines all of the operators valid in a
- /// SelectionDAG.
+ /// ISD::NodeType enum - This enum defines the target-independent operators
+ /// for a SelectionDAG.
+ ///
+ /// Targets may also define target-dependent operator codes for SDNodes. For
+ /// example, on x86, these are the enum values in the X86ISD namespace.
+ /// Targets should aim to use target-independent operators to model their
+ /// instruction sets as much as possible, and only use target-dependent
+ /// operators when they have special requirements.
+ ///
+ /// Finally, during and after selection proper, SNodes may use special
+ /// operator codes that correspond directly with MachineInstr opcodes. These
+ /// are used to represent selected instructions. See the isMachineOpcode()
+ /// and getMachineOpcode() member functions of SDNode.
///
enum NodeType {
// DELETED_NODE - This is an illegal flag value that is used to catch
@@ -901,6 +913,7 @@ public:
inline bool isTargetOpcode() const;
inline bool isMachineOpcode() const;
inline unsigned getMachineOpcode() const;
+ inline const DebugLoc getDebugLoc() const;
/// reachesChainWithoutSideEffects - Return true if this operand (which must
@@ -955,63 +968,77 @@ template<> struct simplify_type<const SDValue> {
}
};
-/// SDUse - Represents a use of the SDNode referred by
-/// the SDValue.
+/// SDUse - Represents a use of a SDNode. This class holds an SDValue,
+/// which records the SDNode being used and the result number, a
+/// pointer to the SDNode using the value, and Next and Prev pointers,
+/// which link together all the uses of an SDNode.
+///
class SDUse {
- SDValue Operand;
- /// User - Parent node of this operand.
- SDNode *User;
- /// Prev, next - Pointers to the uses list of the SDNode referred by
+ /// Val - The value being used.
+ SDValue Val;
+ /// User - The user of this value.
+ SDNode *User;
+ /// Prev, Next - Pointers to the uses list of the SDNode referred by
/// this operand.
SDUse **Prev, *Next;
-public:
- friend class SDNode;
- SDUse(): Operand(), User(NULL), Prev(NULL), Next(NULL) {}
- SDUse(SDNode *val, unsigned resno) :
- Operand(val,resno), User(NULL), Prev(NULL), Next(NULL) {}
+ SDUse(const SDUse &U); // Do not implement
+ void operator=(const SDUse &U); // Do not implement
- SDUse& operator= (const SDValue& Op) {
- Operand = Op;
- Next = NULL;
- Prev = NULL;
- return *this;
- }
-
- SDUse& operator= (const SDUse& Op) {
- Operand = Op;
- Next = NULL;
- Prev = NULL;
- return *this;
- }
+public:
+ SDUse() : Val(), User(NULL), Prev(NULL), Next(NULL) {}
- SDUse *getNext() { return Next; }
+ /// Normally SDUse will just implicitly convert to an SDValue that it holds.
+ operator const SDValue&() const { return Val; }
+ /// If implicit conversion to SDValue doesn't work, the get() method returns
+ /// the SDValue.
+ const SDValue &get() const { return Val; }
+
+ /// getUser - This returns the SDNode that contains this Use.
SDNode *getUser() { return User; }
- void setUser(SDNode *p) { User = p; }
-
- operator SDValue() const { return Operand; }
-
- const SDValue& getSDValue() const { return Operand; }
+ /// getNext - Get the next SDUse in the use list.
+ SDUse *getNext() const { return Next; }
- SDValue &getSDValue() { return Operand; }
- SDNode *getVal() { return Operand.getNode(); }
- SDNode *getVal() const { return Operand.getNode(); } // FIXME: const correct?
+ /// getNode - Convenience function for get().getNode().
+ SDNode *getNode() const { return Val.getNode(); }
+ /// getResNo - Convenience function for get().getResNo().
+ unsigned getResNo() const { return Val.getResNo(); }
+ /// getValueType - Convenience function for get().getValueType().
+ MVT getValueType() const { return Val.getValueType(); }
- bool operator==(const SDValue &O) const {
- return Operand == O;
+ /// operator== - Convenience function for get().operator==
+ bool operator==(const SDValue &V) const {
+ return Val == V;
}
-
- bool operator!=(const SDValue &O) const {
- return !(Operand == O);
+
+ /// operator!= - Convenience function for get().operator!=
+ bool operator!=(const SDValue &V) const {
+ return Val != V;
}
- bool operator<(const SDValue &O) const {
- return Operand < O;
+ /// operator< - Convenience function for get().operator<
+ bool operator<(const SDValue &V) const {
+ return Val < V;
}
-protected:
+private:
+ friend class SelectionDAG;
+ friend class SDNode;
+
+ void setUser(SDNode *p) { User = p; }
+
+ /// set - Remove this use from its existing use list, assign it the
+ /// given value, and add it to the new value's node's use list.
+ inline void set(const SDValue &V);
+ /// setInitial - like set, but only supports initializing a newly-allocated
+ /// SDUse with a non-null value.
+ inline void setInitial(const SDValue &V);
+ /// setNode - like set, but only sets the Node portion of the value,
+ /// leaving the ResNo portion unmodified.
+ inline void setNode(SDNode *N);
+
void addToList(SDUse **List) {
Next = *List;
if (Next) Next->Prev = &Next;
@@ -1025,61 +1052,22 @@ protected:
}
};
-
/// simplify_type specializations - Allow casting operators to work directly on
/// SDValues as if they were SDNode*'s.
template<> struct simplify_type<SDUse> {
typedef SDNode* SimpleType;
static SimpleType getSimplifiedValue(const SDUse &Val) {
- return static_cast<SimpleType>(Val.getVal());
+ return static_cast<SimpleType>(Val.getNode());
}
};
template<> struct simplify_type<const SDUse> {
typedef SDNode* SimpleType;
static SimpleType getSimplifiedValue(const SDUse &Val) {
- return static_cast<SimpleType>(Val.getVal());
+ return static_cast<SimpleType>(Val.getNode());
}
};
-/// SDOperandPtr - A helper SDValue pointer class, that can handle
-/// arrays of SDUse and arrays of SDValue objects. This is required
-/// in many places inside the SelectionDAG.
-///
-class SDOperandPtr {
- const SDValue *ptr; // The pointer to the SDValue object
- int object_size; // The size of the object containg the SDValue
-public:
- SDOperandPtr() : ptr(0), object_size(0) {}
-
- SDOperandPtr(SDUse * use_ptr) {
- ptr = &use_ptr->getSDValue();
- object_size = (int)sizeof(SDUse);
- }
-
- SDOperandPtr(const SDValue * op_ptr) {
- ptr = op_ptr;
- object_size = (int)sizeof(SDValue);
- }
-
- const SDValue operator *() { return *ptr; }
- const SDValue *operator ->() { return ptr; }
- SDOperandPtr operator ++ () {
- ptr = (SDValue*)((char *)ptr + object_size);
- return *this;
- }
-
- SDOperandPtr operator ++ (int) {
- SDOperandPtr tmp = *this;
- ptr = (SDValue*)((char *)ptr + object_size);
- return tmp;
- }
-
- SDValue operator[] (int idx) const {
- return *(SDValue*)((char*) ptr + object_size * idx);
- }
-};
-
/// SDNode - Represents one node in the SelectionDAG.
///
class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
@@ -1110,14 +1098,20 @@ private:
/// define multiple values simultaneously.
const MVT *ValueList;
+ /// UseList - List of uses for this SDNode.
+ SDUse *UseList;
+
/// NumOperands/NumValues - The number of entries in the Operand/Value list.
unsigned short NumOperands, NumValues;
-
- /// Uses - List of uses for this SDNode.
- SDUse *Uses;
- /// addUse - add SDUse to the list of uses.
- void addUse(SDUse &U) { U.addToList(&Uses); }
+ /// debugLoc - source line information.
+ DebugLoc debugLoc;
+
+ /// getValueTypeList - Return a pointer to the specified value type.
+ static const MVT *getValueTypeList(MVT VT);
+
+ friend class SelectionDAG;
+ friend struct ilist_traits<SDNode>;
public:
//===--------------------------------------------------------------------===//
@@ -1148,7 +1142,7 @@ public:
/// use_empty - Return true if there are no uses of this node.
///
- bool use_empty() const { return Uses == NULL; }
+ bool use_empty() const { return UseList == NULL; }
/// hasOneUse - Return true if there is exactly one use of this node.
///
@@ -1168,6 +1162,13 @@ public:
/// setNodeId - Set unique node id.
void setNodeId(int Id) { NodeId = Id; }
+ /// getDebugLoc - Return the source location info.
+ const DebugLoc getDebugLoc() const { return debugLoc; }
+
+ /// setDebugLoc - Set source location info. Try to avoid this, putting
+ /// it in the constructor is preferable.
+ void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+
/// use_iterator - This class provides iterator support for SDUse
/// operands that use a specific SDNode.
class use_iterator
@@ -1226,7 +1227,7 @@ public:
/// of an SDNode.
use_iterator use_begin() const {
- return use_iterator(Uses);
+ return use_iterator(UseList);
}
static use_iterator use_end() { return use_iterator(0); }
@@ -1265,14 +1266,13 @@ public:
const SDValue &getOperand(unsigned Num) const {
assert(Num < NumOperands && "Invalid child # of SDNode!");
- return OperandList[Num].getSDValue();
+ return OperandList[Num];
}
typedef SDUse* op_iterator;
op_iterator op_begin() const { return OperandList; }
op_iterator op_end() const { return OperandList+NumOperands; }
-
SDVTList getVTList() const {
SDVTList X = { ValueList, NumValues };
return X;
@@ -1339,91 +1339,124 @@ public:
///
void Profile(FoldingSetNodeID &ID) const;
-protected:
- friend class SelectionDAG;
- friend struct ilist_traits<SDNode>;
-
- /// getValueTypeList - Return a pointer to the specified value type.
+ /// addUse - This method should only be used by the SDUse class.
///
- static const MVT *getValueTypeList(MVT VT);
+ void addUse(SDUse &U) { U.addToList(&UseList); }
+
+protected:
static SDVTList getSDVTList(MVT VT) {
SDVTList Ret = { getValueTypeList(VT), 1 };
return Ret;
}
+ /// The constructors that supply DebugLoc explicitly should be preferred
+ /// for new code.
SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps)
: NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
- NodeId(-1), Uses(NULL) {
- NumOperands = NumOps;
- OperandList = NumOps ? new SDUse[NumOperands] : 0;
-
+ NodeId(-1),
+ OperandList(NumOps ? new SDUse[NumOps] : 0),
+ ValueList(VTs.VTs),
+ UseList(NULL),
+ NumOperands(NumOps), NumValues(VTs.NumVTs),
+ debugLoc(DebugLoc::getUnknownLoc()) {
for (unsigned i = 0; i != NumOps; ++i) {
- OperandList[i] = Ops[i];
OperandList[i].setUser(this);
- Ops[i].getNode()->addUse(OperandList[i]);
+ OperandList[i].setInitial(Ops[i]);
}
-
- ValueList = VTs.VTs;
- NumValues = VTs.NumVTs;
}
- SDNode(unsigned Opc, SDVTList VTs, const SDUse *Ops, unsigned NumOps)
+ /// This constructor adds no operands itself; operands can be
+ /// set later with InitOperands.
+ SDNode(unsigned Opc, SDVTList VTs)
+ : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0),
+ NodeId(-1), OperandList(0), ValueList(VTs.VTs), UseList(NULL),
+ NumOperands(0), NumValues(VTs.NumVTs),
+ debugLoc(DebugLoc::getUnknownLoc()) {}
+
+ /// The next two constructors specify DebugLoc explicitly; the intent
+ /// is that they will replace the above two over time, and eventually
+ /// the ones above can be removed.
+ SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops,
+ unsigned NumOps)
: NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
- NodeId(-1), Uses(NULL) {
- OperandsNeedDelete = true;
- NumOperands = NumOps;
- OperandList = NumOps ? new SDUse[NumOperands] : 0;
-
+ NodeId(-1),
+ OperandList(NumOps ? new SDUse[NumOps] : 0),
+ ValueList(VTs.VTs), UseList(NULL),
+ NumOperands(NumOps), NumValues(VTs.NumVTs),
+ debugLoc(dl) {
for (unsigned i = 0; i != NumOps; ++i) {
- OperandList[i] = Ops[i];
OperandList[i].setUser(this);
- Ops[i].getVal()->addUse(OperandList[i]);
+ OperandList[i].setInitial(Ops[i]);
}
-
- ValueList = VTs.VTs;
- NumValues = VTs.NumVTs;
}
/// This constructor adds no operands itself; operands can be
/// set later with InitOperands.
- SDNode(unsigned Opc, SDVTList VTs)
+ SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs)
: NodeType(Opc), OperandsNeedDelete(false), SubclassData(0),
- NodeId(-1), Uses(NULL) {
- NumOperands = 0;
- OperandList = 0;
- ValueList = VTs.VTs;
- NumValues = VTs.NumVTs;
- }
+ NodeId(-1), OperandList(0), ValueList(VTs.VTs), UseList(NULL),
+ NumOperands(0), NumValues(VTs.NumVTs),
+ debugLoc(dl) {}
- /// InitOperands - Initialize the operands list of this node with the
- /// specified values, which are part of the node (thus they don't need to be
- /// copied in or allocated).
- void InitOperands(SDUse *Ops, unsigned NumOps) {
- assert(OperandList == 0 && "Operands already set!");
- NumOperands = NumOps;
+ /// InitOperands - Initialize the operands list of this with 1 operand.
+ void InitOperands(SDUse *Ops, const SDValue &Op0) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ NumOperands = 1;
OperandList = Ops;
- Uses = NULL;
-
- for (unsigned i = 0; i != NumOps; ++i) {
- OperandList[i].setUser(this);
- Ops[i].getVal()->addUse(OperandList[i]);
+ }
+
+ /// InitOperands - Initialize the operands list of this with 2 operands.
+ void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ Ops[1].setUser(this);
+ Ops[1].setInitial(Op1);
+ NumOperands = 2;
+ OperandList = Ops;
+ }
+
+ /// InitOperands - Initialize the operands list of this with 3 operands.
+ void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+ const SDValue &Op2) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ Ops[1].setUser(this);
+ Ops[1].setInitial(Op1);
+ Ops[2].setUser(this);
+ Ops[2].setInitial(Op2);
+ NumOperands = 3;
+ OperandList = Ops;
+ }
+
+ /// InitOperands - Initialize the operands list of this with 4 operands.
+ void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+ const SDValue &Op2, const SDValue &Op3) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ Ops[1].setUser(this);
+ Ops[1].setInitial(Op1);
+ Ops[2].setUser(this);
+ Ops[2].setInitial(Op2);
+ Ops[3].setUser(this);
+ Ops[3].setInitial(Op3);
+ NumOperands = 4;
+ OperandList = Ops;
+ }
+
+ /// InitOperands - Initialize the operands list of this with N operands.
+ void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) {
+ for (unsigned i = 0; i != N; ++i) {
+ Ops[i].setUser(this);
+ Ops[i].setInitial(Vals[i]);
}
+ NumOperands = N;
+ OperandList = Ops;
}
/// DropOperands - Release the operands and set this node to have
/// zero operands.
void DropOperands();
-
- void addUser(unsigned i, SDNode *User) {
- assert(User->OperandList[i].getUser() && "Node without parent");
- addUse(User->OperandList[i]);
- }
-
- void removeUser(unsigned i, SDNode *User) {
- assert(User->OperandList[i].getUser() && "Node without parent");
- SDUse &Op = User->OperandList[i];
- Op.removeFromList();
- }
};
@@ -1459,6 +1492,28 @@ inline bool SDValue::use_empty() const {
inline bool SDValue::hasOneUse() const {
return Node->hasNUsesOfValue(1, ResNo);
}
+inline const DebugLoc SDValue::getDebugLoc() const {
+ return Node->getDebugLoc();
+}
+
+// Define inline functions from the SDUse class.
+
+inline void SDUse::set(const SDValue &V) {
+ if (Val.getNode()) removeFromList();
+ Val = V;
+ if (V.getNode()) V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setInitial(const SDValue &V) {
+ Val = V;
+ V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setNode(SDNode *N) {
+ if (Val.getNode()) removeFromList();
+ Val.setNode(N);
+ if (N) N->addUse(*this);
+}
/// UnarySDNode - This class is used for single-operand SDNodes. This is solely
/// to allow co-allocation of node operands with the node itself.
@@ -1467,8 +1522,11 @@ class UnarySDNode : public SDNode {
public:
UnarySDNode(unsigned Opc, SDVTList VTs, SDValue X)
: SDNode(Opc, VTs) {
- Op = X;
- InitOperands(&Op, 1);
+ InitOperands(&Op, X);
+ }
+ UnarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X)
+ : SDNode(Opc, dl, VTs) {
+ InitOperands(&Op, X);
}
};
@@ -1479,9 +1537,11 @@ class BinarySDNode : public SDNode {
public:
BinarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y)
: SDNode(Opc, VTs) {
- Ops[0] = X;
- Ops[1] = Y;
- InitOperands(Ops, 2);
+ InitOperands(Ops, X, Y);
+ }
+ BinarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y)
+ : SDNode(Opc, dl, VTs) {
+ InitOperands(Ops, X, Y);
}
};
@@ -1493,10 +1553,12 @@ public:
TernarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y,
SDValue Z)
: SDNode(Opc, VTs) {
- Ops[0] = X;
- Ops[1] = Y;
- Ops[2] = Z;
- InitOperands(Ops, 3);
+ InitOperands(Ops, X, Y, Z);
+ }
+ TernarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y,
+ SDValue Z)
+ : SDNode(Opc, dl, VTs) {
+ InitOperands(Ops, X, Y, Z);
}
};
@@ -1516,11 +1578,10 @@ public:
explicit HandleSDNode(SDValue X)
#endif
: SDNode(ISD::HANDLENODE, getSDVTList(MVT::Other)) {
- Op = X;
- InitOperands(&Op, 1);
+ InitOperands(&Op, X);
}
~HandleSDNode();
- const SDValue &getValue() const { return Op.getSDValue(); }
+ const SDValue &getValue() const { return Op; }
};
/// Abstact virtual class for operations for memory operations
@@ -1535,10 +1596,6 @@ private:
//! SVOffset - Memory location offset. Note that base is defined in MemSDNode
int SVOffset;
- /// Flags - the low bit indicates whether this is a volatile reference;
- /// the remainder is a log2 encoding of the alignment in bytes.
- unsigned Flags;
-
public:
MemSDNode(unsigned Opc, SDVTList VTs, MVT MemoryVT,
const Value *srcValue, int SVOff,
@@ -1548,10 +1605,26 @@ public:
MVT MemoryVT, const Value *srcValue, int SVOff,
unsigned alignment, bool isvolatile);
+ MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT MemoryVT,
+ const Value *srcValue, int SVOff,
+ unsigned alignment, bool isvolatile);
+
+ MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, const SDValue *Ops,
+ unsigned NumOps, MVT MemoryVT, const Value *srcValue, int SVOff,
+ unsigned alignment, bool isvolatile);
+
/// Returns alignment and volatility of the memory access
- unsigned getAlignment() const { return (1u << (Flags >> 1)) >> 1; }
- bool isVolatile() const { return Flags & 1; }
+ unsigned getAlignment() const { return (1u << (SubclassData >> 6)) >> 1; }
+ bool isVolatile() const { return (SubclassData >> 5) & 1; }
+ /// getRawSubclassData - Return the SubclassData value, which contains an
+ /// encoding of the alignment and volatile information, as well as bits
+ /// used by subclasses. This function should only be used to compute a
+ /// FoldingSetNodeID value.
+ unsigned getRawSubclassData() const {
+ return SubclassData;
+ }
+
/// Returns the SrcValue and offset that describes the location of the access
const Value *getSrcValue() const { return SrcValue; }
int getSrcValueOffset() const { return SVOffset; }
@@ -1568,10 +1641,6 @@ public:
return getOperand(getOpcode() == ISD::STORE ? 2 : 1);
}
- /// getRawFlags - Represent the flags as a bunch of bits.
- ///
- unsigned getRawFlags() const { return Flags; }
-
// Methods to support isa and dyn_cast
static bool classof(const MemSDNode *) { return true; }
static bool classof(const SDNode *N) {
@@ -1617,21 +1686,29 @@ public:
unsigned Align=0)
: MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0,
Align, /*isVolatile=*/true) {
- Ops[0] = Chain;
- Ops[1] = Ptr;
- Ops[2] = Cmp;
- Ops[3] = Swp;
- InitOperands(Ops, 4);
+ InitOperands(Ops, Chain, Ptr, Cmp, Swp);
}
AtomicSDNode(unsigned Opc, SDVTList VTL, MVT MemVT,
SDValue Chain, SDValue Ptr,
SDValue Val, const Value* SrcVal, unsigned Align=0)
: MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0,
Align, /*isVolatile=*/true) {
- Ops[0] = Chain;
- Ops[1] = Ptr;
- Ops[2] = Val;
- InitOperands(Ops, 3);
+ InitOperands(Ops, Chain, Ptr, Val);
+ }
+ AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT,
+ SDValue Chain, SDValue Ptr,
+ SDValue Cmp, SDValue Swp, const Value* SrcVal,
+ unsigned Align=0)
+ : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0,
+ Align, /*isVolatile=*/true) {
+ InitOperands(Ops, Chain, Ptr, Cmp, Swp);
+ }
+ AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT,
+ SDValue Chain, SDValue Ptr,
+ SDValue Val, const Value* SrcVal, unsigned Align=0)
+ : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0,
+ Align, /*isVolatile=*/true) {
+ InitOperands(Ops, Chain, Ptr, Val);
}
const SDValue &getBasePtr() const { return getOperand(1); }
@@ -1674,6 +1751,13 @@ public:
: MemSDNode(Opc, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol),
ReadMem(ReadMem), WriteMem(WriteMem) {
}
+ MemIntrinsicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps,
+ MVT MemoryVT, const Value *srcValue, int SVO,
+ unsigned Align, bool Vol, bool ReadMem, bool WriteMem)
+ : MemSDNode(Opc, dl, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol),
+ ReadMem(ReadMem), WriteMem(WriteMem) {
+ }
bool readMem() const { return ReadMem; }
bool writeMem() const { return WriteMem; }
@@ -1892,6 +1976,9 @@ protected:
explicit BasicBlockSDNode(MachineBasicBlock *mbb)
: SDNode(ISD::BasicBlock, getSDVTList(MVT::Other)), MBB(mbb) {
}
+ explicit BasicBlockSDNode(MachineBasicBlock *mbb, DebugLoc dl)
+ : SDNode(ISD::BasicBlock, dl, getSDVTList(MVT::Other)), MBB(mbb) {
+ }
public:
MachineBasicBlock *getBasicBlock() const { return MBB; }
@@ -1979,8 +2066,7 @@ protected:
Value *cu)
: SDNode(ISD::DBG_STOPPOINT, getSDVTList(MVT::Other)),
Line(l), Column(c), CU(cu) {
- Chain = ch;
- InitOperands(&Chain, 1);
+ InitOperands(&Chain, ch);
}
public:
unsigned getLine() const { return Line; }
@@ -2000,8 +2086,11 @@ protected:
friend class SelectionDAG;
LabelSDNode(unsigned NodeTy, SDValue ch, unsigned id)
: SDNode(NodeTy, getSDVTList(MVT::Other)), LabelID(id) {
- Chain = ch;
- InitOperands(&Chain, 1);
+ InitOperands(&Chain, ch);
+ }
+ LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
+ : SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) {
+ InitOperands(&Chain, ch);
}
public:
unsigned getLabelID() const { return LabelID; }
@@ -2021,6 +2110,10 @@ protected:
: SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
getSDVTList(VT)), Symbol(Sym) {
}
+ ExternalSymbolSDNode(bool isTarget, DebugLoc dl, const char *Sym, MVT VT)
+ : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, dl,
+ getSDVTList(VT)), Symbol(Sym) {
+ }
public:
const char *getSymbol() const { return Symbol; }
@@ -2187,6 +2280,12 @@ protected:
: SDNode(ISD::CALL, VTs, Operands, numOperands),
CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
Inreg(isinreg) {}
+ CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall,
+ bool isinreg, SDVTList VTs, const SDValue *Operands,
+ unsigned numOperands)
+ : SDNode(ISD::CALL, dl, VTs, Operands, numOperands),
+ CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
+ Inreg(isinreg) {}
public:
unsigned getCallingConv() const { return CallingConv; }
unsigned isVarArg() const { return IsVarArg; }
@@ -2255,11 +2354,21 @@ public:
SDVTList VTs, ISD::MemIndexedMode AM, MVT VT,
const Value *SV, int SVO, unsigned Align, bool Vol)
: MemSDNode(NodeTy, VTs, VT, SV, SVO, Align, Vol) {
- SubclassData = AM;
- for (unsigned i = 0; i != numOperands; ++i)
- Ops[i] = Operands[i];
- InitOperands(Ops, numOperands);
assert(Align != 0 && "Loads and stores should have non-zero aligment");
+ SubclassData |= AM << 2;
+ assert(getAddressingMode() == AM && "MemIndexedMode encoding error!");
+ InitOperands(Ops, Operands, numOperands);
+ assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
+ "Only indexed loads and stores have a non-undef offset operand");
+ }
+ LSBaseSDNode(ISD::NodeType NodeTy, DebugLoc dl, SDValue *Operands,
+ unsigned numOperands, SDVTList VTs, ISD::MemIndexedMode AM,
+ MVT VT, const Value *SV, int SVO, unsigned Align, bool Vol)
+ : MemSDNode(NodeTy, dl, VTs, VT, SV, SVO, Align, Vol) {
+ assert(Align != 0 && "Loads and stores should have non-zero aligment");
+ SubclassData |= AM << 2;
+ assert(getAddressingMode() == AM && "MemIndexedMode encoding error!");
+ InitOperands(Ops, Operands, numOperands);
assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
"Only indexed loads and stores have a non-undef offset operand");
}
@@ -2271,7 +2380,7 @@ public:
/// getAddressingMode - Return the addressing mode for this load or store:
/// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
ISD::MemIndexedMode getAddressingMode() const {
- return ISD::MemIndexedMode(SubclassData & 7);
+ return ISD::MemIndexedMode((SubclassData >> 2) & 7);
}
/// isIndexed - Return true if this is a pre/post inc/dec load/store.
@@ -2297,14 +2406,23 @@ protected:
const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
: LSBaseSDNode(ISD::LOAD, ChainPtrOff, 3,
VTs, AM, LVT, SV, O, Align, Vol) {
- SubclassData |= (unsigned short)ETy << 3;
+ SubclassData |= (unsigned short)ETy;
+ assert(getExtensionType() == ETy && "LoadExtType encoding error!");
+ }
+ LoadSDNode(SDValue *ChainPtrOff, DebugLoc dl, SDVTList VTs,
+ ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT LVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : LSBaseSDNode(ISD::LOAD, dl, ChainPtrOff, 3,
+ VTs, AM, LVT, SV, O, Align, Vol) {
+ SubclassData |= (unsigned short)ETy;
+ assert(getExtensionType() == ETy && "LoadExtType encoding error!");
}
public:
/// getExtensionType - Return whether this is a plain node,
/// or one of the varieties of value-extending loads.
ISD::LoadExtType getExtensionType() const {
- return ISD::LoadExtType((SubclassData >> 3) & 3);
+ return ISD::LoadExtType(SubclassData & 3);
}
const SDValue &getBasePtr() const { return getOperand(1); }
@@ -2326,14 +2444,23 @@ protected:
const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
: LSBaseSDNode(ISD::STORE, ChainValuePtrOff, 4,
VTs, AM, SVT, SV, O, Align, Vol) {
- SubclassData |= (unsigned short)isTrunc << 3;
+ SubclassData |= (unsigned short)isTrunc;
+ assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!");
+ }
+ StoreSDNode(SDValue *ChainValuePtrOff, DebugLoc dl, SDVTList VTs,
+ ISD::MemIndexedMode AM, bool isTrunc, MVT SVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : LSBaseSDNode(ISD::STORE, dl, ChainValuePtrOff, 4,
+ VTs, AM, SVT, SV, O, Align, Vol) {
+ SubclassData |= (unsigned short)isTrunc;
+ assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!");
}
public:
/// isTruncatingStore - Return true if the op does a truncation before store.
/// For integers this is the same as doing a TRUNCATE and storing the result.
/// For floats, it is the same as doing an FP_ROUND and storing the result.
- bool isTruncatingStore() const { return (SubclassData >> 3) & 1; }
+ bool isTruncatingStore() const { return SubclassData & 1; }
const SDValue &getValue() const { return getOperand(1); }
const SDValue &getBasePtr() const { return getOperand(2); }
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index 1a08f4d6086e..3c6f04253633 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -439,21 +439,6 @@ namespace llvm {
else {
return *this;
}
- }
-
- /// getIntegerVTBitMask - Return an integer with 1's every place there are
- /// bits in the specified integer value type. FIXME: Should return an apint.
- uint64_t getIntegerVTBitMask() const {
- assert(isInteger() && !isVector() && "Only applies to int scalars!");
- return ~uint64_t(0UL) >> (64-getSizeInBits());
- }
-
- /// getIntegerVTSignBit - Return an integer with a 1 in the position of the
- /// sign bit for the specified integer value type. FIXME: Should return an
- /// apint.
- uint64_t getIntegerVTSignBit() const {
- assert(isInteger() && !isVector() && "Only applies to int scalars!");
- return uint64_t(1UL) << (getSizeInBits()-1);
}
/// getMVTString - This function returns value type as a string,
diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td
index 097dd4f38ee9..1f6bacc787bc 100644
--- a/include/llvm/CompilerDriver/Common.td
+++ b/include/llvm/CompilerDriver/Common.td
@@ -36,11 +36,14 @@ def prefix_list_option;
// Possible option properties.
+def extern;
def help;
def hidden;
+def multi_val;
+def one_or_more;
def really_hidden;
def required;
-def extern;
+def zero_or_one;
// Empty DAG marker.
def empty;
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index d5e286b7dc98..12846fe8649a 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -507,7 +507,7 @@
#cmakedefine PACKAGE_NAME "${PACKAGE_NAME}"
/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
+#cmakedefine PACKAGE_STRING "${PACKAGE_STRING}"
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index a26c755ee76a..3559ede31c34 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -143,10 +143,16 @@ public:
/// removeModuleProvider - Remove a ModuleProvider from the list of modules.
- /// Release module from ModuleProvider.
+ /// Relases the Module from the ModuleProvider, materializing it in the
+ /// process, and returns the materialized Module.
virtual Module* removeModuleProvider(ModuleProvider *P,
std::string *ErrInfo = 0);
+ /// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
+ /// and deletes the ModuleProvider and owned Module. Avoids materializing
+ /// the underlying module.
+ virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0);
+
/// FindFunctionNamed - Search all of the active modules to find the one that
/// defines FnName. This is very slow operation and shouldn't be used for
/// general code.
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 841cf9cff27f..fbf376afd5d4 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -1943,6 +1943,14 @@ public:
return i*2;
}
+ /// getIncomingBlock - Return incoming basic block corresponding
+ /// to value use iterator
+ ///
+ template <typename U>
+ BasicBlock *getIncomingBlock(value_use_iterator<U> I) const {
+ assert(this == *I && "Iterator doesn't point to PHI's Uses?");
+ return static_cast<BasicBlock*>((&I.getUse() + 1)->get());
+ }
/// getIncomingBlock - Return incoming basic block number x
///
BasicBlock *getIncomingBlock(unsigned i) const {
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 4113b16dfffc..18f72ac457b4 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -16,7 +16,6 @@
#define LLVM_LINKALLPASSES_H
#include "llvm/Analysis/AliasSetTracker.h"
-#include "llvm/Analysis/EscapeAnalysis.h"
#include "llvm/Analysis/FindUsedTypes.h"
#include "llvm/Analysis/IntervalPartition.h"
#include "llvm/Analysis/LoopVR.h"
@@ -132,7 +131,6 @@ namespace {
(void)new llvm::FindUsedTypes();
(void)new llvm::ScalarEvolution();
(void)new llvm::LoopVR();
- (void)new llvm::EscapeAnalysis();
((llvm::Function*)0)->viewCFGOnly();
llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0);
X.add((llvm::Value*)0, 0); // for -print-alias-sets
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index dd012da93cfa..0527e0cdbbe4 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -169,22 +169,22 @@ public:
// or null if it is not known.
static const PassInfo *lookupPassInfo(intptr_t TI);
- /// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
- /// to get to the analysis information that might be around that needs to be
- /// updated. This is different than getAnalysis in that it can fail (ie the
- /// analysis results haven't been computed), so should only be used if you
- /// provide the capability to update an analysis that exists. This method is
- /// often used by transformation APIs to update analysis results for a pass
- /// automatically as the transform is performed.
+ /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+ /// get analysis information that might be around, for example to update it.
+ /// This is different than getAnalysis in that it can fail (if the analysis
+ /// results haven't been computed), so should only be used if you can handle
+ /// the case when the analysis is not available. This method is often used by
+ /// transformation APIs to update analysis results for a pass automatically as
+ /// the transform is performed.
///
- template<typename AnalysisType>
- AnalysisType *getAnalysisToUpdate() const; // Defined in PassAnalysisSupport.h
+ template<typename AnalysisType> AnalysisType *
+ getAnalysisIfAvailable() const; // Defined in PassAnalysisSupport.h
/// mustPreserveAnalysisID - This method serves the same function as
- /// getAnalysisToUpdate, but works if you just have an AnalysisID. This
+ /// getAnalysisIfAvailable, but works if you just have an AnalysisID. This
/// obviously cannot give you a properly typed instance of the class if you
- /// don't have the class name available (use getAnalysisToUpdate if you do),
- /// but it can tell you if you need to preserve the pass at least.
+ /// don't have the class name available (use getAnalysisIfAvailable if you
+ /// do), but it can tell you if you need to preserve the pass at least.
///
bool mustPreserveAnalysisID(const PassInfo *AnalysisID) const;
diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h
index c6ed179af61f..f8b139ecb1a5 100644
--- a/include/llvm/PassAnalysisSupport.h
+++ b/include/llvm/PassAnalysisSupport.h
@@ -143,8 +143,8 @@ public:
AnalysisImpls.push_back(pir);
}
- // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
- Pass *getAnalysisToUpdate(AnalysisID ID, bool Direction) const;
+ // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist
+ Pass *getAnalysisIfAvailable(AnalysisID ID, bool Direction) const;
// AnalysisImpls - This keeps track of which passes implements the interfaces
// that are required by the current pass (to implement getAnalysis()).
@@ -157,22 +157,22 @@ private:
PMDataManager &PM;
};
-/// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
-/// to get to the analysis information that might be around that needs to be
-/// updated. This is different than getAnalysis in that it can fail (ie the
-/// analysis results haven't been computed), so should only be used if you
-/// provide the capability to update an analysis that exists. This method is
-/// often used by transformation APIs to update analysis results for a pass
-/// automatically as the transform is performed.
+/// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+/// get analysis information that might be around, for example to update it.
+/// This is different than getAnalysis in that it can fail (if the analysis
+/// results haven't been computed), so should only be used if you can handle
+/// the case when the analysis is not available. This method is often used by
+/// transformation APIs to update analysis results for a pass automatically as
+/// the transform is performed.
///
template<typename AnalysisType>
-AnalysisType *Pass::getAnalysisToUpdate() const {
+AnalysisType *Pass::getAnalysisIfAvailable() const {
assert(Resolver && "Pass not resident in a PassManager object!");
const PassInfo *PI = getClassPassInfo<AnalysisType>();
if (PI == 0) return 0;
return dynamic_cast<AnalysisType*>
- (Resolver->getAnalysisToUpdate(PI, true));
+ (Resolver->getAnalysisIfAvailable(PI, true));
}
/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 520f8de79fb5..dc41590fb8a5 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -180,6 +180,10 @@ public:
return getInstruction() < CS.getInstruction();
}
+ bool isCallee(Value::use_iterator UI) const {
+ return getInstruction()->op_begin() == &UI.getUse();
+ }
+
private:
/// Returns the operand number of the first argument
unsigned getArgumentOffset() const {
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index e7f5a02b77d7..def5ce750140 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -126,7 +126,8 @@ enum MiscFlags { // Miscellaneous flags to adjust argument
CommaSeparated = 0x200, // Should this cl::list split between commas?
PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
Sink = 0x800, // Should this cl::list eat all unknown options?
- MiscMask = 0xE00 // Union of the above flags.
+ AllowInverse = 0x1000, // Can this option take a -Xno- form?
+ MiscMask = 0x1E00 // Union of the above flags.
};
@@ -536,10 +537,33 @@ struct basic_parser : public basic_parser_impl {
//
template<>
class parser<bool> : public basic_parser<bool> {
+ bool IsInvertable; // Should we synthezise a -xno- style option?
+ const char *ArgStr;
public:
+ void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ if (IsInvertable) {
+ char *s = new char [strlen(ArgStr) + 3 + 1];
+ s[0] = ArgStr[0];
+ s[1] = 'n';
+ s[2] = 'o';
+ s[3] = '-';
+ strcpy(&s[4], ArgStr+1);
+ OptionNames.push_back(s);
+ }
+ }
+
// parse - Return true on error.
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
+ template <class Opt>
+ void initialize(Opt &O) {
+ if (O.getMiscFlags() & llvm::cl::AllowInverse)
+ IsInvertable = true;
+ else
+ IsInvertable = false;
+ ArgStr = O.ArgStr;
+ }
+
enum ValueExpected getValueExpectedFlagDefault() const {
return ValueOptional;
}
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 23ab9bf29e57..c24274354cf6 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -221,7 +221,11 @@ enum dwarf_constants {
DW_AT_GNU_vector = 0x2107,
DW_AT_lo_user = 0x2000,
DW_AT_hi_user = 0x3fff,
-
+
+ // Apple extensions.
+ DW_AT_APPLE_optimized = 0x3fe1,
+ DW_AT_APPLE_flags = 0x3fe2,
+
// Attribute form encodings
DW_FORM_addr = 0x01,
DW_FORM_block2 = 0x03,
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 1a4f6bf6f471..030412169d8a 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -181,7 +181,11 @@ public:
/// tell - Return the current offset with the file.
uint64_t tell() {
return pos + (OutBufCur - OutBufStart);
- }
+ }
+
+ /// seek - Flushes the stream and repositions the underlying file descriptor
+ /// positition to the offset specified from the beginning of the file.
+ uint64_t seek(uint64_t off);
};
/// raw_stdout_ostream - This is a stream that always prints to stdout.
diff --git a/include/llvm/System/Host.h b/include/llvm/System/Host.h
index 711959325d98..22e36e7ba7b5 100644
--- a/include/llvm/System/Host.h
+++ b/include/llvm/System/Host.h
@@ -19,7 +19,7 @@
namespace llvm {
namespace sys {
- inline bool littleEndianHost() {
+ inline bool isLittleEndianHost() {
union {
int i;
char c;
@@ -28,17 +28,17 @@ namespace sys {
return c;
}
- inline bool bigEndianHost() {
- return !littleEndianHost();
+ inline bool isBigEndianHost() {
+ return !isLittleEndianHost();
}
- /// osName() - Return the name of the host operating system or "" if
+ /// getOSName() - Return the name of the host operating system or "" if
/// unknown.
- std::string osName();
+ std::string getOSName();
- /// osVersion() - Return the operating system version as a string or
+ /// getOSVersion() - Return the operating system version as a string or
/// "" if unknown.
- std::string osVersion();
+ std::string getOSVersion();
}
}
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index 0de74103adcf..0e44666e5c12 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -298,6 +298,15 @@ namespace llvm {
const char *Data32bitsDirective; // Defaults to "\t.long\t"
const char *Data64bitsDirective; // Defaults to "\t.quad\t"
+ /// getASDirective - Targets can override it to provide different data
+ /// directives for various sizes and non-default address spaces.
+ virtual const char *getASDirective(unsigned size,
+ unsigned AS) const {
+ assert (AS > 0
+ && "Dont know the directives for default addr space");
+ return NULL;
+ }
+
//===--- Alignment Information ----------------------------------------===//
/// AlignDirective - The directive used to emit round up to an alignment
@@ -429,27 +438,31 @@ namespace llvm {
/// HasLEB128 - True if target asm supports leb128 directives.
///
bool HasLEB128; // Defaults to false.
-
+
/// hasDotLocAndDotFile - True if target asm supports .loc and .file
/// directives for emitting debugging information.
///
bool HasDotLocAndDotFile; // Defaults to false.
-
+
/// SupportsDebugInformation - True if target supports emission of debugging
/// information.
bool SupportsDebugInformation;
-
+
/// SupportsExceptionHandling - True if target supports
/// exception handling.
///
bool SupportsExceptionHandling; // Defaults to false.
-
+
/// RequiresFrameSection - true if the Dwarf2 output needs a frame section
///
bool DwarfRequiresFrameSection; // Defaults to true.
+ /// SupportsMacInfo - true if the Dwarf output supports macro information
+ ///
+ bool SupportsMacInfoSection; // Defaults to true
+
/// NonLocalEHFrameLabel - If set, the EH_frame label needs to be non-local.
- ///
+ ///
bool NonLocalEHFrameLabel; // Defaults to false.
/// GlobalEHDirective - This is the directive used to make exception frame
@@ -594,6 +607,22 @@ namespace llvm {
static unsigned getULEB128Size(unsigned Value);
+ // Data directive accessors
+ //
+ const char *getData8bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data8bitsDirective : getASDirective(8, AS);
+ }
+ const char *getData16bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data16bitsDirective : getASDirective(16, AS);
+ }
+ const char *getData32bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data32bitsDirective : getASDirective(32, AS);
+ }
+ const char *getData64bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data64bitsDirective : getASDirective(64, AS);
+ }
+
+
// Accessors.
//
const Section *getTextSection() const {
@@ -707,18 +736,6 @@ namespace llvm {
const char *getAscizDirective() const {
return AscizDirective;
}
- const char *getData8bitsDirective() const {
- return Data8bitsDirective;
- }
- const char *getData16bitsDirective() const {
- return Data16bitsDirective;
- }
- const char *getData32bitsDirective() const {
- return Data32bitsDirective;
- }
- const char *getData64bitsDirective() const {
- return Data64bitsDirective;
- }
const char *getJumpTableDirective() const {
return JumpTableDirective;
}
@@ -818,6 +835,9 @@ namespace llvm {
bool doesDwarfRequireFrameSection() const {
return DwarfRequiresFrameSection;
}
+ bool doesSupportMacInfoSection() const {
+ return SupportsMacInfoSection;
+ }
bool doesRequireNonLocalEHFrameLabel() const {
return NonLocalEHFrameLabel;
}
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 23238ad9e053..6639db1e00ed 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -29,6 +29,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/DebugLoc.h"
#include <climits>
#include <map>
#include <vector>
@@ -340,12 +341,20 @@ public:
return (LegalizeAction)((OpActions[Op] >> (2*VT.getSimpleVT())) & 3);
}
+ /// isOperationLegalOrCustom - Return true if the specified operation is
+ /// legal on this target or can be made legal with custom lowering. This
+ /// is used to help guide high-level lowering decisions.
+ bool isOperationLegalOrCustom(unsigned Op, MVT VT) const {
+ return (VT == MVT::Other || isTypeLegal(VT)) &&
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Custom);
+ }
+
/// isOperationLegal - Return true if the specified operation is legal on this
/// target.
bool isOperationLegal(unsigned Op, MVT VT) const {
return (VT == MVT::Other || isTypeLegal(VT)) &&
- (getOperationAction(Op, VT) == Legal ||
- getOperationAction(Op, VT) == Custom);
+ getOperationAction(Op, VT) == Legal;
}
/// getLoadExtAction - Return how this load with extension should be treated:
@@ -772,13 +781,15 @@ public:
SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To);
SDValue CombineTo(SDNode *N, SDValue Res);
SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1);
+
+ void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
};
/// SimplifySetCC - Try to simplify a setcc built with the specified operands
/// and cc. If it is unable to simplify it, return a null SDValue.
SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
ISD::CondCode Cond, bool foldBooleans,
- DAGCombinerInfo &DCI) const;
+ DAGCombinerInfo &DCI, DebugLoc dl) const;
/// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
/// node is a GlobalAddress + offset.
@@ -1049,7 +1060,7 @@ public:
/// lower the arguments for the specified function, into the specified DAG.
virtual void
LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue>& ArgValues);
+ SmallVectorImpl<SDValue>& ArgValues, DebugLoc dl);
/// LowerCallTo - This hook lowers an abstract call to a function into an
/// actual call. This returns a pair of operands. The first element is the
@@ -1074,7 +1085,7 @@ public:
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
bool isVarArg, bool isInreg, unsigned CallingConv,
bool isTailCall, SDValue Callee, ArgListTy &Args,
- SelectionDAG &DAG);
+ SelectionDAG &DAG, DebugLoc dl);
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
/// memcpy. This can be used by targets to provide code sequences for cases
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 2419376c5396..d53e399b8593 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -107,6 +107,10 @@ namespace llvm {
/// wth earlier copy coalescing.
extern bool StrongPHIElim;
+ /// DisableRedZone - This flag disables use of the "Red Zone" on
+ /// targets which would otherwise have one.
+ extern bool DisableRedZone;
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index fbc0bbc6f404..54fc00dd84ce 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -60,8 +60,6 @@ private:
const vt_iterator VTs;
const sc_iterator SubClasses;
const sc_iterator SuperClasses;
- const sc_iterator SubRegClasses;
- const sc_iterator SuperRegClasses;
const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
const int CopyCost;
const iterator RegsBegin, RegsEnd;
@@ -70,12 +68,9 @@ public:
const MVT *vts,
const TargetRegisterClass * const *subcs,
const TargetRegisterClass * const *supcs,
- const TargetRegisterClass * const *subregcs,
- const TargetRegisterClass * const *superregcs,
unsigned RS, unsigned Al, int CC,
iterator RB, iterator RE)
: ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs),
- SubRegClasses(subregcs), SuperRegClasses(superregcs),
RegSize(RS), Alignment(Al), CopyCost(CC), RegsBegin(RB), RegsEnd(RE) {}
virtual ~TargetRegisterClass() {} // Allow subclasses
@@ -169,29 +164,11 @@ public:
while (*I != NULL) ++I;
return I;
}
-
- /// subregclasses_begin / subregclasses_end - Loop over all of
- /// the subregister classes of this register class.
- sc_iterator subregclasses_begin() const {
- return SubRegClasses;
- }
-
- sc_iterator subregclasses_end() const {
- sc_iterator I = SubRegClasses;
- while (*I != NULL) ++I;
- return I;
- }
-
- /// superregclasses_begin / superregclasses_end - Loop over all of
- /// the superregister classes of this register class.
- sc_iterator superregclasses_begin() const {
- return SuperRegClasses;
- }
-
- sc_iterator superregclasses_end() const {
- sc_iterator I = SuperRegClasses;
- while (*I != NULL) ++I;
- return I;
+
+ /// isASubClass - return true if this TargetRegisterClass is a sub-class of at
+ /// least one other TargetRegisterClass.
+ bool isASubClass() const {
+ return SuperClasses[0] != 0;
}
/// allocation_order_begin/end - These methods define a range of registers
diff --git a/include/llvm/User.h b/include/llvm/User.h
index 919693e08292..e25d19b563fe 100644
--- a/include/llvm/User.h
+++ b/include/llvm/User.h
@@ -100,6 +100,15 @@ public:
"Cannot mutate a constant with setOperand!");
OperandList[i] = Val;
}
+ const Use &getOperandUse(unsigned i) const {
+ assert(i < NumOperands && "getOperand() out of range!");
+ return OperandList[i];
+ }
+ Use &getOperandUse(unsigned i) {
+ assert(i < NumOperands && "getOperand() out of range!");
+ return OperandList[i];
+ }
+
unsigned getNumOperands() const { return NumOperands; }
// ---------------------------------------------------------------------------
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp
index c8c43a69ef74..d5de2fe616ac 100644
--- a/lib/Analysis/AliasAnalysis.cpp
+++ b/lib/Analysis/AliasAnalysis.cpp
@@ -207,6 +207,30 @@ bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
return false;
}
+/// isNoAliasCall - Return true if this pointer is returned by a noalias
+/// function.
+bool llvm::isNoAliasCall(const Value *V) {
+ if (isa<CallInst>(V) || isa<InvokeInst>(V))
+ return CallSite(const_cast<Instruction*>(cast<Instruction>(V)))
+ .paramHasAttr(0, Attribute::NoAlias);
+ return false;
+}
+
+/// isIdentifiedObject - Return true if this pointer refers to a distinct and
+/// identifiable object. This returns true for:
+/// Global Variables and Functions
+/// Allocas and Mallocs
+/// ByVal and NoAlias Arguments
+/// NoAlias returns
+///
+bool llvm::isIdentifiedObject(const Value *V) {
+ if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isNoAliasCall(V))
+ return true;
+ if (const Argument *A = dyn_cast<Argument>(V))
+ return A->hasNoAliasAttr() || A->hasByValAttr();
+ return false;
+}
+
// Because of the way .a files work, we must force the BasicAA implementation to
// be pulled in if the AliasAnalysis classes are pulled in. Otherwise we run
// the risk of AliasAnalysis being used, but the default implementation not
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 82514400b826..ccbe338585df 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -64,30 +64,6 @@ static const Value *GetGEPOperands(const Value *V,
return V;
}
-/// isNoAliasCall - Return true if this pointer is returned by a noalias
-/// function.
-static bool isNoAliasCall(const Value *V) {
- if (isa<CallInst>(V) || isa<InvokeInst>(V))
- return CallSite(const_cast<Instruction*>(cast<Instruction>(V)))
- .paramHasAttr(0, Attribute::NoAlias);
- return false;
-}
-
-/// isIdentifiedObject - Return true if this pointer refers to a distinct and
-/// identifiable object. This returns true for:
-/// Global Variables and Functions
-/// Allocas and Mallocs
-/// ByVal and NoAlias Arguments
-/// NoAlias returns
-///
-static bool isIdentifiedObject(const Value *V) {
- if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isNoAliasCall(V))
- return true;
- if (const Argument *A = dyn_cast<Argument>(V))
- return A->hasNoAliasAttr() || A->hasByValAttr();
- return false;
-}
-
/// isKnownNonNull - Return true if we know that the specified value is never
/// null.
static bool isKnownNonNull(const Value *V) {
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index c5dc2cdf0a9b..f63054b60ed0 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -11,7 +11,6 @@ add_llvm_library(LLVMAnalysis
ConstantFolding.cpp
DbgInfoPrinter.cpp
DebugInfo.cpp
- EscapeAnalysis.cpp
InstCount.cpp
Interval.cpp
IntervalPartition.cpp
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index 34ccd0a97cf9..0ec80894f11c 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -20,6 +20,7 @@
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Support/Streams.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -440,14 +441,20 @@ DISubrange DIFactory::GetOrCreateSubrange(int64_t Lo, int64_t Hi) {
DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
const std::string &Filename,
const std::string &Directory,
- const std::string &Producer) {
+ const std::string &Producer,
+ bool isMain,
+ bool isOptimized,
+ const char *Flags) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_compile_unit),
getCastToEmpty(GetOrCreateCompileUnitAnchor()),
ConstantInt::get(Type::Int32Ty, LangID),
GetStringConstant(Filename),
GetStringConstant(Directory),
- GetStringConstant(Producer)
+ GetStringConstant(Producer),
+ ConstantInt::get(Type::Int1Ty, isMain),
+ ConstantInt::get(Type::Int1Ty, isOptimized),
+ GetStringConstant(Flags)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -487,9 +494,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
uint64_t SizeInBits,
uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
- unsigned Encoding,
- const std::string *FileName,
- const std::string *Directory) {
+ unsigned Encoding) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_base_type),
getCastToEmpty(Context),
@@ -500,9 +505,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
ConstantInt::get(Type::Int64Ty, AlignInBits),
ConstantInt::get(Type::Int64Ty, OffsetInBits),
ConstantInt::get(Type::Int32Ty, Flags),
- ConstantInt::get(Type::Int32Ty, Encoding),
- GetStringConstant(FileName ? FileName->c_str() : ""),
- GetStringConstant(Directory ? Directory->c_str() : "")
+ ConstantInt::get(Type::Int32Ty, Encoding)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -526,9 +529,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
uint64_t AlignInBits,
uint64_t OffsetInBits,
unsigned Flags,
- DIType DerivedFrom,
- const std::string *FileName,
- const std::string *Directory) {
+ DIType DerivedFrom) {
Constant *Elts[] = {
GetTagConstant(Tag),
getCastToEmpty(Context),
@@ -539,9 +540,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
ConstantInt::get(Type::Int64Ty, AlignInBits),
ConstantInt::get(Type::Int64Ty, OffsetInBits),
ConstantInt::get(Type::Int32Ty, Flags),
- getCastToEmpty(DerivedFrom),
- GetStringConstant(FileName ? FileName->c_str() : ""),
- GetStringConstant(Directory ? Directory->c_str() : "")
+ getCastToEmpty(DerivedFrom)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -565,9 +564,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
uint64_t OffsetInBits,
unsigned Flags,
DIType DerivedFrom,
- DIArray Elements,
- const std::string *FileName,
- const std::string *Directory) {
+ DIArray Elements) {
Constant *Elts[] = {
GetTagConstant(Tag),
@@ -580,9 +577,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
ConstantInt::get(Type::Int64Ty, OffsetInBits),
ConstantInt::get(Type::Int32Ty, Flags),
getCastToEmpty(DerivedFrom),
- getCastToEmpty(Elements),
- GetStringConstant(FileName ? FileName->c_str() : ""),
- GetStringConstant(Directory ? Directory->c_str() : "")
+ getCastToEmpty(Elements)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -606,9 +601,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type,
bool isLocalToUnit,
- bool isDefinition,
- const std::string *FileName,
- const std::string *Directory) {
+ bool isDefinition) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_subprogram),
@@ -621,9 +614,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
ConstantInt::get(Type::Int32Ty, LineNo),
getCastToEmpty(Type),
ConstantInt::get(Type::Int1Ty, isLocalToUnit),
- ConstantInt::get(Type::Int1Ty, isDefinition),
- GetStringConstant(FileName ? FileName->c_str() : ""),
- GetStringConstant(Directory ? Directory->c_str() : "")
+ ConstantInt::get(Type::Int1Ty, isDefinition)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -643,9 +634,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
const std::string &LinkageName,
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type,bool isLocalToUnit,
- bool isDefinition, llvm::GlobalVariable *Val,
- const std::string *FileName,
- const std::string *Directory) {
+ bool isDefinition, llvm::GlobalVariable *Val) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_variable),
getCastToEmpty(GetOrCreateGlobalVariableAnchor()),
@@ -658,9 +647,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
getCastToEmpty(Type),
ConstantInt::get(Type::Int1Ty, isLocalToUnit),
ConstantInt::get(Type::Int1Ty, isDefinition),
- ConstantExpr::getBitCast(Val, EmptyStructPtr),
- GetStringConstant(FileName ? FileName->c_str() : ""),
- GetStringConstant(Directory ? Directory->c_str() : "")
+ ConstantExpr::getBitCast(Val, EmptyStructPtr)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -678,20 +665,14 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type,
- const std::string *FileName,
- const std::string *Directory) {
-
-
+ DIType Type) {
Constant *Elts[] = {
GetTagConstant(Tag),
getCastToEmpty(Context),
GetStringConstant(Name),
getCastToEmpty(CompileUnit),
ConstantInt::get(Type::Int32Ty, LineNo),
- getCastToEmpty(Type),
- GetStringConstant(FileName ? FileName->c_str() : ""),
- GetStringConstant(Directory ? Directory->c_str() : "")
+ getCastToEmpty(Type)
};
Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -866,3 +847,103 @@ namespace llvm {
}
}
+/// dump - print compile unit.
+void DICompileUnit::dump() const {
+ cerr << " [" << dwarf::LanguageString(getLanguage()) << "] ";
+ cerr << " [" << getDirectory() << "/" << getFilename() << " ]";
+}
+
+/// dump - print type.
+void DIType::dump() const {
+ if (isNull()) return;
+ if (!getName().empty())
+ cerr << " [" << getName() << "] ";
+ unsigned Tag = getTag();
+ cerr << " [" << dwarf::TagString(Tag) << "] ";
+ // TODO : Print context
+ getCompileUnit().dump();
+ cerr << " ["
+ << getLineNumber() << ", "
+ << getSizeInBits() << ", "
+ << getAlignInBits() << ", "
+ << getOffsetInBits()
+ << "] ";
+ if (isPrivate())
+ cerr << " [private] ";
+ else if (isProtected())
+ cerr << " [protected] ";
+ if (isForwardDecl())
+ cerr << " [fwd] ";
+
+ if (isBasicType(Tag))
+ DIBasicType(GV).dump();
+ else if (isDerivedType(Tag))
+ DIDerivedType(GV).dump();
+ else if (isCompositeType(Tag))
+ DICompositeType(GV).dump();
+ else {
+ cerr << "Invalid DIType\n";
+ return;
+ }
+ cerr << "\n";
+}
+
+/// dump - print basic type.
+void DIBasicType::dump() const {
+ cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] ";
+
+}
+
+/// dump - print derived type.
+void DIDerivedType::dump() const {
+ cerr << "\n\t Derived From: "; getTypeDerivedFrom().dump();
+}
+
+/// dump - print composite type.
+void DICompositeType::dump() const {
+ DIArray A = getTypeArray();
+ if (A.isNull())
+ return;
+ cerr << " [" << A.getNumElements() << " elements]";
+}
+
+/// dump - print global.
+void DIGlobal::dump() const {
+
+ if (!getName().empty())
+ cerr << " [" << getName() << "] ";
+ unsigned Tag = getTag();
+ cerr << " [" << dwarf::TagString(Tag) << "] ";
+ // TODO : Print context
+ getCompileUnit().dump();
+ cerr << " [" << getLineNumber() << "] ";
+ if (isLocalToUnit())
+ cerr << " [local] ";
+ if (isDefinition())
+ cerr << " [def] ";
+
+ if (isGlobalVariable(Tag))
+ DIGlobalVariable(GV).dump();
+
+ cerr << "\n";
+}
+
+/// dump - print subprogram.
+void DISubprogram::dump() const {
+ DIGlobal::dump();
+}
+
+/// dump - print global variable.
+void DIGlobalVariable::dump() const {
+ cerr << " ["; getGlobal()->dump(); cerr << "] ";
+}
+
+/// dump - print variable.
+void DIVariable::dump() const {
+ if (!getName().empty())
+ cerr << " [" << getName() << "] ";
+ getCompileUnit().dump();
+ cerr << " [" << getLineNumber() << "] ";
+ getType().dump();
+ cerr << "\n";
+}
diff --git a/lib/Analysis/EscapeAnalysis.cpp b/lib/Analysis/EscapeAnalysis.cpp
deleted file mode 100644
index c621c9f9abc2..000000000000
--- a/lib/Analysis/EscapeAnalysis.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-//===------------- EscapeAnalysis.h - Pointer escape analysis -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the implementation of the pointer escape analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "escape-analysis"
-#include "llvm/Analysis/EscapeAnalysis.h"
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include <vector>
-using namespace llvm;
-
-char EscapeAnalysis::ID = 0;
-static RegisterPass<EscapeAnalysis> X("escape-analysis",
- "Pointer Escape Analysis", true, true);
-
-
-void EscapeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredTransitive<TargetData>();
- AU.addRequiredTransitive<AliasAnalysis>();
- AU.setPreservesAll();
-}
-
-/// runOnFunction - Precomputation for escape analysis. This collects all know
-/// "escape points" in the def-use graph of the function. These are
-/// instructions which allow their inputs to escape from the current function.
-bool EscapeAnalysis::runOnFunction(Function& F) {
- EscapePoints.clear();
-
- TargetData& TD = getAnalysis<TargetData>();
- AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
- Module* M = F.getParent();
-
- // Walk through all instructions in the function, identifying those that
- // may allow their inputs to escape.
- for(inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE; ++II) {
- Instruction* I = &*II;
-
- // The most obvious case is stores. Any store that may write to global
- // memory or to a function argument potentially allows its input to escape.
- if (StoreInst* S = dyn_cast<StoreInst>(I)) {
- const Type* StoreType = S->getOperand(0)->getType();
- unsigned StoreSize = TD.getTypeStoreSize(StoreType);
- Value* Pointer = S->getPointerOperand();
-
- bool inserted = false;
- for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end();
- AI != AE; ++AI) {
- if (!isa<PointerType>(AI->getType())) continue;
- AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, AI, ~0U);
- if (R != AliasAnalysis::NoAlias) {
- EscapePoints.insert(S);
- inserted = true;
- break;
- }
- }
-
- if (inserted)
- continue;
-
- for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
- GI != GE; ++GI) {
- AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, GI, ~0U);
- if (R != AliasAnalysis::NoAlias) {
- EscapePoints.insert(S);
- break;
- }
- }
-
- // Calls and invokes potentially allow their parameters to escape.
- // FIXME: This can and should be refined. Intrinsics have known escape
- // behavior, and alias analysis may be able to tell us more about callees.
- } else if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
- EscapePoints.insert(I);
-
- // Returns allow the return value to escape. This is mostly important
- // for malloc to alloca promotion.
- } else if (isa<ReturnInst>(I)) {
- EscapePoints.insert(I);
-
- // Branching on the value of a pointer may allow the value to escape through
- // methods not discoverable via def-use chaining.
- } else if(isa<BranchInst>(I) || isa<SwitchInst>(I)) {
- EscapePoints.insert(I);
- }
-
- // FIXME: Are there any other possible escape points?
- }
-
- return false;
-}
-
-/// escapes - Determines whether the passed allocation can escape from the
-/// current function. It does this by using a simple worklist algorithm to
-/// search for a path in the def-use graph from the allocation to an
-/// escape point.
-/// FIXME: Once we've discovered a path, it would be a good idea to memoize it,
-/// and all of its subpaths, to amortize the cost of future queries.
-bool EscapeAnalysis::escapes(Value* A) {
- assert(isa<PointerType>(A->getType()) &&
- "Can't do escape analysis on non-pointer types!");
-
- std::vector<Value*> worklist;
- worklist.push_back(A);
-
- SmallPtrSet<Value*, 8> visited;
- visited.insert(A);
- while (!worklist.empty()) {
- Value* curr = worklist.back();
- worklist.pop_back();
-
- if (Instruction* I = dyn_cast<Instruction>(curr))
- if (EscapePoints.count(I)) {
- BranchInst* B = dyn_cast<BranchInst>(I);
- if (!B) return true;
- Value* condition = B->getCondition();
- ICmpInst* C = dyn_cast<ICmpInst>(condition);
- if (!C) return true;
- Value* O1 = C->getOperand(0);
- Value* O2 = C->getOperand(1);
- if (isa<MallocInst>(O1->stripPointerCasts())) {
- if (!isa<ConstantPointerNull>(O2)) return true;
- } else if(isa<MallocInst>(O2->stripPointerCasts())) {
- if (!isa<ConstantPointerNull>(O1)) return true;
- } else
- return true;
- }
-
- if (StoreInst* S = dyn_cast<StoreInst>(curr)) {
- // We know this must be an instruction, because constant gep's would
- // have been found to alias a global, so stores to them would have
- // been in EscapePoints.
- if (visited.insert(cast<Instruction>(S->getPointerOperand())))
- worklist.push_back(cast<Instruction>(S->getPointerOperand()));
- } else {
- for (Instruction::use_iterator UI = curr->use_begin(),
- UE = curr->use_end(); UI != UE; ++UI)
- if (Instruction* U = dyn_cast<Instruction>(UI))
- if (visited.insert(U))
- worklist.push_back(U);
- }
- }
-
- return false;
-}
diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp
index c8f1d920658e..ea7d7feb4cd8 100644
--- a/lib/Analysis/IPA/CallGraph.cpp
+++ b/lib/Analysis/IPA/CallGraph.cpp
@@ -126,7 +126,8 @@ private:
// Loop over all of the users of the function, looking for non-call uses.
for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; ++I)
- if ((!isa<CallInst>(*I) && !isa<InvokeInst>(*I)) || I.getOperandNo()) {
+ if ((!isa<CallInst>(I) && !isa<InvokeInst>(I))
+ || !CallSite(cast<Instruction>(I)).isCallee(I)) {
// Not a call, or being used as a parameter rather than as the callee.
ExternalCallingNode->addCalledFunction(CallSite(), Node);
break;
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index c84a51fb062f..6af365b76a90 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -751,11 +751,9 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
// cache remains sorted. Sort it now (if needed) so that recursive
// invocations of getNonLocalPointerDepFromBB that could reuse the cache
// value will only see properly sorted cache arrays.
- if (Cache && NumSortedEntries != Cache->size()) {
+ if (Cache && NumSortedEntries != Cache->size())
std::sort(Cache->begin(), Cache->end());
- NumSortedEntries = Cache->size();
- Cache = 0;
- }
+ Cache = 0;
// FIXME: it is entirely possible that PHI translating will end up with
// the same value. Consider PHI translating something like:
@@ -790,10 +788,16 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
// cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0);
PredTranslationFailure:
- // Refresh the CacheInfo/Cache pointer so that it isn't invalidated.
- CacheInfo = &NonLocalPointerDeps[CacheKey];
- Cache = &CacheInfo->second;
-
+ if (Cache == 0) {
+ // Refresh the CacheInfo/Cache pointer if it got invalidated.
+ CacheInfo = &NonLocalPointerDeps[CacheKey];
+ Cache = &CacheInfo->second;
+ NumSortedEntries = Cache->size();
+ } else if (NumSortedEntries != Cache->size()) {
+ std::sort(Cache->begin(), Cache->end());
+ NumSortedEntries = Cache->size();
+ }
+
// Since we did phi translation, the "Cache" set won't contain all of the
// results for the query. This is ok (we can still use it to accelerate
// specific block queries) but we can't do the fastpath "return all
@@ -822,7 +826,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
break;
}
}
-
+
// Okay, we're done now. If we added new values to the cache, re-sort it.
switch (Cache->size()-NumSortedEntries) {
case 0:
@@ -1046,6 +1050,10 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) {
if (Instruction *NewDirtyInst = NewDirtyVal.getInst())
ReversePtrDepsToAdd.push_back(std::make_pair(NewDirtyInst, P));
}
+
+ // Re-sort the NonLocalDepInfo. Changing the dirty entry to its
+ // subsequent value may invalidate the sortedness.
+ std::sort(NLPDI.begin(), NLPDI.end());
}
ReverseNonLocalPtrDeps.erase(ReversePtrDepIt);
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index ca16a755dcab..c05ba8d0ef27 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -585,17 +585,7 @@ static SCEVHandle BinomialCoefficient(SCEVHandle It, unsigned K,
}
// We need at least W + T bits for the multiplication step
- // FIXME: A temporary hack; we round up the bitwidths
- // to the nearest power of 2 to be nice to the code generator.
- unsigned CalculationBits = 1U << Log2_32_Ceil(W + T);
- // FIXME: Temporary hack to avoid generating integers that are too wide.
- // Although, it's not completely clear how to determine how much
- // widening is safe; for example, on X86, we can't really widen
- // beyond 64 because we need to be able to do multiplication
- // that's CalculationBits wide, but on X86-64, we can safely widen up to
- // 128 bits.
- if (CalculationBits > 64)
- return new SCEVCouldNotCompute();
+ unsigned CalculationBits = W + T;
// Calcuate 2^T, at width T+W.
APInt DivFactor = APInt(CalculationBits, 1).shl(T);
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 0f9a1de368a1..fb491d3278d8 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -560,6 +560,7 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(shl, Shl); INSTKEYWORD(lshr, LShr); INSTKEYWORD(ashr, AShr);
INSTKEYWORD(and, And); INSTKEYWORD(or, Or); INSTKEYWORD(xor, Xor);
INSTKEYWORD(icmp, ICmp); INSTKEYWORD(fcmp, FCmp);
+ INSTKEYWORD(vicmp, VICmp); INSTKEYWORD(vfcmp, VFCmp);
INSTKEYWORD(phi, PHI);
INSTKEYWORD(call, Call);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 401dc39ca539..943f1d002568 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -471,8 +471,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
GlobalVariable *GV = 0;
// See if the global was forward referenced, if so, use the global.
- if (!Name.empty() && (GV = M->getGlobalVariable(Name, true))) {
- if (!ForwardRefVals.erase(Name))
+ if (!Name.empty()) {
+ if ((GV = M->getGlobalVariable(Name, true)) &&
+ !ForwardRefVals.erase(Name))
return Error(NameLoc, "redefinition of global '@" + Name + "'");
} else {
std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 87700284c483..adffe8292027 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -915,8 +915,7 @@ bool BitcodeReader::ParseConstants() {
dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
if (OpTy == 0) return Error("Invalid CE_EXTRACTELT record");
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
- Constant *Op1 = ValueList.getConstantFwdRef(Record[2],
- OpTy->getElementType());
+ Constant *Op1 = ValueList.getConstantFwdRef(Record[2], Type::Int32Ty);
V = ConstantExpr::getExtractElement(Op0, Op1);
break;
}
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 0cb476e30519..e37c439f5ce0 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -811,11 +811,14 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
}
break;
case Instruction::Br:
- Code = bitc::FUNC_CODE_INST_BR;
- Vals.push_back(VE.getValueID(I.getOperand(0)));
- if (cast<BranchInst>(I).isConditional()) {
- Vals.push_back(VE.getValueID(I.getOperand(1)));
- Vals.push_back(VE.getValueID(I.getOperand(2)));
+ {
+ Code = bitc::FUNC_CODE_INST_BR;
+ BranchInst &II(cast<BranchInst>(I));
+ Vals.push_back(VE.getValueID(II.getSuccessor(0)));
+ if (II.isConditional()) {
+ Vals.push_back(VE.getValueID(II.getSuccessor(1)));
+ Vals.push_back(VE.getValueID(II.getCondition()));
+ }
}
break;
case Instruction::Switch:
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 5b665a0c2213..c6b0313c39f4 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -141,7 +141,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
bool AsmPrinter::doInitialization(Module &M) {
Mang = new Mangler(M, TAI->getGlobalPrefix(), TAI->getPrivateGlobalPrefix());
- GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
if (TAI->hasSingleParameterDotFile()) {
@@ -163,9 +163,9 @@ bool AsmPrinter::doInitialization(Module &M) {
SwitchToDataSection(""); // Reset back to no section.
- MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
if (MMI) MMI->AnalyzeModule(M);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
return false;
}
@@ -218,7 +218,7 @@ bool AsmPrinter::doFinalization(Module &M) {
}
}
- GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
@@ -681,7 +681,7 @@ static void printStringChar(raw_ostream &O, char C) {
O << "\\\"";
} else if (C == '\\') {
O << "\\\\";
- } else if (isprint(C)) {
+ } else if (isprint((unsigned char)C)) {
O << C;
} else {
switch(C) {
@@ -770,7 +770,7 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV,
/// EmitZeros - Emit a block of zeros.
///
-void AsmPrinter::EmitZeros(uint64_t NumZeros) const {
+void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const {
if (NumZeros) {
if (TAI->getZeroDirective()) {
O << TAI->getZeroDirective() << NumZeros;
@@ -779,7 +779,7 @@ void AsmPrinter::EmitZeros(uint64_t NumZeros) const {
O << '\n';
} else {
for (; NumZeros; --NumZeros)
- O << TAI->getData8bitsDirective() << "0\n";
+ O << TAI->getData8bitsDirective(AddrSpace) << "0\n";
}
}
}
@@ -956,7 +956,8 @@ void AsmPrinter::EmitGlobalConstantVector(const ConstantVector *CP) {
EmitGlobalConstant(CP->getOperand(I));
}
-void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS) {
+void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
+ unsigned AddrSpace) {
// Print the fields in successive locations. Pad to align if needed!
const TargetData *TD = TM.getTargetData();
unsigned Size = TD->getTypePaddedSize(CVS->getType());
@@ -972,46 +973,47 @@ void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS) {
sizeSoFar += fieldSize + padSize;
// Now print the actual field value.
- EmitGlobalConstant(field);
+ EmitGlobalConstant(field, AddrSpace);
// Insert padding - this may include padding to increase the size of the
// current field up to the ABI size (if the struct is not packed) as well
// as padding to ensure that the next field starts at the right offset.
- EmitZeros(padSize);
+ EmitZeros(padSize, AddrSpace);
}
assert(sizeSoFar == cvsLayout->getSizeInBytes() &&
"Layout of constant struct may be incorrect!");
}
-void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
+void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP,
+ unsigned AddrSpace) {
// FP Constants are printed as integer constants to avoid losing
// precision...
const TargetData *TD = TM.getTargetData();
if (CFP->getType() == Type::DoubleTy) {
double Val = CFP->getValueAPF().convertToDouble(); // for comment only
uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- if (TAI->getData64bitsDirective())
- O << TAI->getData64bitsDirective() << i << '\t'
+ if (TAI->getData64bitsDirective(AddrSpace))
+ O << TAI->getData64bitsDirective(AddrSpace) << i << '\t'
<< TAI->getCommentString() << " double value: " << Val << '\n';
else if (TD->isBigEndian()) {
- O << TAI->getData32bitsDirective() << unsigned(i >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32)
<< '\t' << TAI->getCommentString()
<< " double most significant word " << Val << '\n';
- O << TAI->getData32bitsDirective() << unsigned(i)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i)
<< '\t' << TAI->getCommentString()
<< " double least significant word " << Val << '\n';
} else {
- O << TAI->getData32bitsDirective() << unsigned(i)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i)
<< '\t' << TAI->getCommentString()
<< " double least significant word " << Val << '\n';
- O << TAI->getData32bitsDirective() << unsigned(i >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32)
<< '\t' << TAI->getCommentString()
<< " double most significant word " << Val << '\n';
}
return;
} else if (CFP->getType() == Type::FloatTy) {
float Val = CFP->getValueAPF().convertToFloat(); // for comment only
- O << TAI->getData32bitsDirective()
+ O << TAI->getData32bitsDirective(AddrSpace)
<< CFP->getValueAPF().bitcastToAPInt().getZExtValue()
<< '\t' << TAI->getCommentString() << " float " << Val << '\n';
return;
@@ -1026,42 +1028,42 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
&ignored);
if (TD->isBigEndian()) {
- O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48)
<< '\t' << TAI->getCommentString()
<< " long double most significant halfword of ~"
<< DoubleVal.convertToDouble() << '\n';
- O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32)
<< '\t' << TAI->getCommentString()
<< " long double next halfword\n";
- O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16)
<< '\t' << TAI->getCommentString()
<< " long double next halfword\n";
- O << TAI->getData16bitsDirective() << uint16_t(p[0])
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0])
<< '\t' << TAI->getCommentString()
<< " long double next halfword\n";
- O << TAI->getData16bitsDirective() << uint16_t(p[1])
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
<< '\t' << TAI->getCommentString()
<< " long double least significant halfword\n";
} else {
- O << TAI->getData16bitsDirective() << uint16_t(p[1])
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
<< '\t' << TAI->getCommentString()
<< " long double least significant halfword of ~"
<< DoubleVal.convertToDouble() << '\n';
- O << TAI->getData16bitsDirective() << uint16_t(p[0])
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0])
<< '\t' << TAI->getCommentString()
<< " long double next halfword\n";
- O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16)
<< '\t' << TAI->getCommentString()
<< " long double next halfword\n";
- O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32)
<< '\t' << TAI->getCommentString()
<< " long double next halfword\n";
- O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
+ O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48)
<< '\t' << TAI->getCommentString()
<< " long double most significant halfword\n";
}
EmitZeros(TD->getTypePaddedSize(Type::X86_FP80Ty) -
- TD->getTypeStoreSize(Type::X86_FP80Ty));
+ TD->getTypeStoreSize(Type::X86_FP80Ty), AddrSpace);
return;
} else if (CFP->getType() == Type::PPC_FP128Ty) {
// all long double variants are printed as hex
@@ -1069,29 +1071,29 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
APInt api = CFP->getValueAPF().bitcastToAPInt();
const uint64_t *p = api.getRawData();
if (TD->isBigEndian()) {
- O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32)
<< '\t' << TAI->getCommentString()
<< " long double most significant word\n";
- O << TAI->getData32bitsDirective() << uint32_t(p[0])
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0])
<< '\t' << TAI->getCommentString()
<< " long double next word\n";
- O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32)
<< '\t' << TAI->getCommentString()
<< " long double next word\n";
- O << TAI->getData32bitsDirective() << uint32_t(p[1])
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1])
<< '\t' << TAI->getCommentString()
<< " long double least significant word\n";
} else {
- O << TAI->getData32bitsDirective() << uint32_t(p[1])
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1])
<< '\t' << TAI->getCommentString()
<< " long double least significant word\n";
- O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32)
<< '\t' << TAI->getCommentString()
<< " long double next word\n";
- O << TAI->getData32bitsDirective() << uint32_t(p[0])
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0])
<< '\t' << TAI->getCommentString()
<< " long double next word\n";
- O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32)
<< '\t' << TAI->getCommentString()
<< " long double most significant word\n";
}
@@ -1099,7 +1101,8 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
} else assert(0 && "Floating point constant type not handled");
}
-void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI) {
+void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
+ unsigned AddrSpace) {
const TargetData *TD = TM.getTargetData();
unsigned BitWidth = CI->getBitWidth();
assert(isPowerOf2_32(BitWidth) &&
@@ -1116,20 +1119,20 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI) {
else
Val = RawData[i];
- if (TAI->getData64bitsDirective())
- O << TAI->getData64bitsDirective() << Val << '\n';
+ if (TAI->getData64bitsDirective(AddrSpace))
+ O << TAI->getData64bitsDirective(AddrSpace) << Val << '\n';
else if (TD->isBigEndian()) {
- O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32)
<< '\t' << TAI->getCommentString()
<< " Double-word most significant word " << Val << '\n';
- O << TAI->getData32bitsDirective() << unsigned(Val)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val)
<< '\t' << TAI->getCommentString()
<< " Double-word least significant word " << Val << '\n';
} else {
- O << TAI->getData32bitsDirective() << unsigned(Val)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val)
<< '\t' << TAI->getCommentString()
<< " Double-word least significant word " << Val << '\n';
- O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+ O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32)
<< '\t' << TAI->getCommentString()
<< " Double-word most significant word " << Val << '\n';
}
@@ -1137,27 +1140,27 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI) {
}
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
-void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
+void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
const TargetData *TD = TM.getTargetData();
const Type *type = CV->getType();
unsigned Size = TD->getTypePaddedSize(type);
if (CV->isNullValue() || isa<UndefValue>(CV)) {
- EmitZeros(Size);
+ EmitZeros(Size, AddrSpace);
return;
} else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
EmitGlobalConstantArray(CVA);
return;
} else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
- EmitGlobalConstantStruct(CVS);
+ EmitGlobalConstantStruct(CVS, AddrSpace);
return;
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- EmitGlobalConstantFP(CFP);
+ EmitGlobalConstantFP(CFP, AddrSpace);
return;
} else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
// Small integers are handled below; large integers are handled here.
if (Size > 4) {
- EmitGlobalConstantLargeInt(CI);
+ EmitGlobalConstantLargeInt(CI, AddrSpace);
return;
}
} else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
@@ -1165,7 +1168,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
return;
}
- printDataDirective(type);
+ printDataDirective(type, AddrSpace);
EmitConstantValueOnly(CV);
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
SmallString<40> S;
@@ -1491,21 +1494,21 @@ void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
/// printDataDirective - This method prints the asm directive for the
/// specified type.
-void AsmPrinter::printDataDirective(const Type *type) {
+void AsmPrinter::printDataDirective(const Type *type, unsigned AddrSpace) {
const TargetData *TD = TM.getTargetData();
switch (type->getTypeID()) {
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(type)->getBitWidth();
if (BitWidth <= 8)
- O << TAI->getData8bitsDirective();
+ O << TAI->getData8bitsDirective(AddrSpace);
else if (BitWidth <= 16)
- O << TAI->getData16bitsDirective();
+ O << TAI->getData16bitsDirective(AddrSpace);
else if (BitWidth <= 32)
- O << TAI->getData32bitsDirective();
+ O << TAI->getData32bitsDirective(AddrSpace);
else if (BitWidth <= 64) {
- assert(TAI->getData64bitsDirective() &&
+ assert(TAI->getData64bitsDirective(AddrSpace) &&
"Target cannot handle 64-bit constant exprs!");
- O << TAI->getData64bitsDirective();
+ O << TAI->getData64bitsDirective(AddrSpace);
} else {
assert(0 && "Target cannot handle given data directive width!");
}
@@ -1513,11 +1516,15 @@ void AsmPrinter::printDataDirective(const Type *type) {
}
case Type::PointerTyID:
if (TD->getPointerSize() == 8) {
- assert(TAI->getData64bitsDirective() &&
+ assert(TAI->getData64bitsDirective(AddrSpace) &&
"Target cannot handle 64-bit pointer exprs!");
- O << TAI->getData64bitsDirective();
+ O << TAI->getData64bitsDirective(AddrSpace);
+ } else if (TD->getPointerSize() == 2) {
+ O << TAI->getData16bitsDirective(AddrSpace);
+ } else if (TD->getPointerSize() == 1) {
+ O << TAI->getData8bitsDirective(AddrSpace);
} else {
- O << TAI->getData32bitsDirective();
+ O << TAI->getData32bitsDirective(AddrSpace);
}
break;
case Type::FloatTyID: case Type::DoubleTyID:
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index 6ac415fab76c..638def2b0620 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -1274,6 +1274,9 @@ private:
/// of each entry in this vector corresponds to the sources in MMI.
DenseMap<Value *, CompileUnit *> DW_CUs;
+ /// MainCU - Some platform prefers one compile unit per .o file. In such
+ /// cases, all dies are inserted in MainCU.
+ CompileUnit *MainCU;
/// AbbreviationsSet - Used to uniquely define abbreviations.
///
FoldingSet<DIEAbbrev> AbbreviationsSet;
@@ -1559,16 +1562,8 @@ private:
void AddSourceLine(DIE *Die, const DIVariable *V) {
unsigned FileID = 0;
unsigned Line = V->getLineNumber();
- if (V->getVersion() <= LLVMDebugVersion6) {
- // Version6 or earlier. Use compile unit info to get file id.
- CompileUnit *Unit = FindCompileUnit(V->getCompileUnit());
- FileID = Unit->getID();
- } else {
- // Version7 or newer, use filename and directory info from DIVariable
- // directly.
- unsigned DID = Directories.idFor(V->getDirectory());
- FileID = SrcFiles.idFor(SrcFileInfo(DID, V->getFilename()));
- }
+ CompileUnit *Unit = FindCompileUnit(V->getCompileUnit());
+ FileID = Unit->getID();
AddUInt(Die, DW_AT_decl_file, 0, FileID);
AddUInt(Die, DW_AT_decl_line, 0, Line);
}
@@ -1578,16 +1573,8 @@ private:
void AddSourceLine(DIE *Die, const DIGlobal *G) {
unsigned FileID = 0;
unsigned Line = G->getLineNumber();
- if (G->getVersion() <= LLVMDebugVersion6) {
- // Version6 or earlier. Use compile unit info to get file id.
- CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
- FileID = Unit->getID();
- } else {
- // Version7 or newer, use filename and directory info from DIGlobal
- // directly.
- unsigned DID = Directories.idFor(G->getDirectory());
- FileID = SrcFiles.idFor(SrcFileInfo(DID, G->getFilename()));
- }
+ CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
+ FileID = Unit->getID();
AddUInt(Die, DW_AT_decl_file, 0, FileID);
AddUInt(Die, DW_AT_decl_line, 0, Line);
}
@@ -1595,16 +1582,11 @@ private:
void AddSourceLine(DIE *Die, const DIType *Ty) {
unsigned FileID = 0;
unsigned Line = Ty->getLineNumber();
- if (Ty->getVersion() <= LLVMDebugVersion6) {
- // Version6 or earlier. Use compile unit info to get file id.
- CompileUnit *Unit = FindCompileUnit(Ty->getCompileUnit());
- FileID = Unit->getID();
- } else {
- // Version7 or newer, use filename and directory info from DIType
- // directly.
- unsigned DID = Directories.idFor(Ty->getDirectory());
- FileID = SrcFiles.idFor(SrcFileInfo(DID, Ty->getFilename()));
- }
+ DICompileUnit CU = Ty->getCompileUnit();
+ if (CU.isNull())
+ return;
+ CompileUnit *Unit = FindCompileUnit(CU);
+ FileID = Unit->getID();
AddUInt(Die, DW_AT_decl_file, 0, FileID);
AddUInt(Die, DW_AT_decl_line, 0, Line);
}
@@ -1636,30 +1618,6 @@ private:
AddBlock(Die, Attribute, 0, Block);
}
- /// AddBasicType - Add a new basic type attribute to the specified entity.
- ///
- void AddBasicType(DIE *Entity, CompileUnit *Unit,
- const std::string &Name,
- unsigned Encoding, unsigned Size) {
-
- DIE Buffer(DW_TAG_base_type);
- AddUInt(&Buffer, DW_AT_byte_size, 0, Size);
- AddUInt(&Buffer, DW_AT_encoding, DW_FORM_data1, Encoding);
- if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
- DIE *BasicTypeDie = Unit->AddDie(Buffer);
- AddDIEntry(Entity, DW_AT_type, DW_FORM_ref4, BasicTypeDie);
- }
-
- /// AddPointerType - Add a new pointer type attribute to the specified entity.
- ///
- void AddPointerType(DIE *Entity, CompileUnit *Unit, const std::string &Name) {
- DIE Buffer(DW_TAG_pointer_type);
- AddUInt(&Buffer, DW_AT_byte_size, 0, TD->getPointerSize());
- if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
- DIE *PointerTypeDie = Unit->AddDie(Buffer);
- AddDIEntry(Entity, DW_AT_type, DW_FORM_ref4, PointerTypeDie);
- }
-
/// AddType - Add a new type attribute to the specified entity.
void AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
if (Ty.isNull())
@@ -1687,9 +1645,23 @@ private:
ConstructTypeDIE(DW_Unit, Buffer, DICompositeType(Ty.getGV()));
}
- // Add debug information entry to entity and unit.
- DIE *Die = DW_Unit->AddDie(Buffer);
- SetDIEntry(Slot, Die);
+ // Add debug information entry to entity and appropriate context.
+ DIE *Die = NULL;
+ DIDescriptor Context = Ty.getContext();
+ if (!Context.isNull())
+ Die = DW_Unit->getDieMapSlotFor(Context.getGV());
+
+ if (Die) {
+ DIE *Child = new DIE(Buffer);
+ Die->AddChild(Child);
+ Buffer.Detach();
+ SetDIEntry(Slot, Child);
+ }
+ else {
+ Die = DW_Unit->AddDie(Buffer);
+ SetDIEntry(Slot, Die);
+ }
+
Entity->AddValue(DW_AT_type, DW_FORM_ref4, Slot);
}
@@ -1855,6 +1827,8 @@ private:
if (CTy->getTag() == DW_TAG_vector_type)
AddUInt(&Buffer, DW_AT_GNU_vector, DW_FORM_flag, 1);
+ // Emit derived type.
+ AddType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom());
DIArray Elements = CTy->getTypeArray();
// Construct an anonymous type for index type.
@@ -1940,18 +1914,23 @@ private:
// Add Return Type.
if (!IsConstructor)
AddType(DW_Unit, SPDie, DIType(Args.getElement(0).getGV()));
-
- // Add arguments.
- if (!Args.isNull())
- for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIE *Arg = new DIE(DW_TAG_formal_parameter);
- AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV()));
- AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ???
- SPDie->AddChild(Arg);
- }
-
+
+ if (!SP.isDefinition()) {
+ AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1);
+ // Add arguments.
+ // Do not add arguments for subprogram definition. They will be
+ // handled through RecordVariable.
+ if (!Args.isNull())
+ for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
+ DIE *Arg = new DIE(DW_TAG_formal_parameter);
+ AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV()));
+ AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ???
+ SPDie->AddChild(Arg);
+ }
+ }
+
if (!SP.isLocalToUnit())
- AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);
+ AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);
return SPDie;
}
@@ -2096,7 +2075,9 @@ private:
DISubprogram SPD(Desc.getGV());
// Get the compile unit context.
- CompileUnit *Unit = FindCompileUnit(SPD.getCompileUnit());
+ CompileUnit *Unit = MainCU;
+ if (!Unit)
+ Unit = FindCompileUnit(SPD.getCompileUnit());
// Get the subprogram die.
DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV());
@@ -2127,7 +2108,9 @@ private:
if (SPD.getName() == MF->getFunction()->getName()) {
// Get the compile unit context.
- CompileUnit *Unit = FindCompileUnit(SPD.getCompileUnit());
+ CompileUnit *Unit = MainCU;
+ if (!Unit)
+ Unit = FindCompileUnit(SPD.getCompileUnit());
// Get the subprogram die.
DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV());
@@ -2169,8 +2152,10 @@ private:
EmitLabel("section_abbrev", 0);
Asm->SwitchToDataSection(TAI->getDwarfARangesSection());
EmitLabel("section_aranges", 0);
- Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection());
- EmitLabel("section_macinfo", 0);
+ if (TAI->doesSupportMacInfoSection()) {
+ Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection());
+ EmitLabel("section_macinfo", 0);
+ }
Asm->SwitchToDataSection(TAI->getDwarfLineSection());
EmitLabel("section_line", 0);
Asm->SwitchToDataSection(TAI->getDwarfLocSection());
@@ -2297,6 +2282,15 @@ private:
///
void SizeAndOffsets() {
// Process base compile unit.
+ if (MainCU) {
+ // Compute size of compile unit header
+ unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
+ sizeof(int16_t) + // DWARF version number
+ sizeof(int32_t) + // Offset Into Abbrev. Section
+ sizeof(int8_t); // Pointer Size (in bytes)
+ SizeAndOffsetDie(MainCU->getDie(), Offset, true);
+ return;
+ }
for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
CE = DW_CUs.end(); CI != CE; ++CI) {
CompileUnit *Unit = CI->second;
@@ -2318,6 +2312,8 @@ private:
for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
CE = DW_CUs.end(); CI != CE; ++CI) {
CompileUnit *Unit = CI->second;
+ if (MainCU)
+ Unit = MainCU;
DIE *Die = Unit->getDie();
// Emit the compile units header.
EmitLabel("info_begin", Unit->getID());
@@ -2343,6 +2339,8 @@ private:
EmitLabel("info_end", Unit->getID());
Asm->EOL();
+ if (MainCU)
+ return;
}
}
@@ -2642,6 +2640,8 @@ private:
for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
CE = DW_CUs.end(); CI != CE; ++CI) {
CompileUnit *Unit = CI->second;
+ if (MainCU)
+ Unit = MainCU;
EmitDifference("pubnames_end", Unit->getID(),
"pubnames_begin", Unit->getID(), true);
@@ -2675,6 +2675,8 @@ private:
EmitLabel("pubnames_end", Unit->getID());
Asm->EOL();
+ if (MainCU)
+ return;
}
}
@@ -2757,10 +2759,12 @@ private:
/// EmitDebugMacInfo - Emit visible names into a debug macinfo section.
///
void EmitDebugMacInfo() {
- // Start the dwarf macinfo section.
- Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection());
+ if (TAI->doesSupportMacInfoSection()) {
+ // Start the dwarf macinfo section.
+ Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection());
- Asm->EOL();
+ Asm->EOL();
+ }
}
/// ConstructCompileUnits - Create a compile unit DIEs.
@@ -2783,8 +2787,17 @@ private:
AddString(Die, DW_AT_name, DW_FORM_string, DIUnit.getFilename());
if (!DIUnit.getDirectory().empty())
AddString(Die, DW_AT_comp_dir, DW_FORM_string, DIUnit.getDirectory());
+ if (DIUnit.isOptimized())
+ AddUInt(Die, DW_AT_APPLE_optimized, DW_FORM_flag, 1);
+ const std::string &Flags = DIUnit.getFlags();
+ if (!Flags.empty())
+ AddString(Die, DW_AT_APPLE_flags, DW_FORM_string, Flags);
CompileUnit *Unit = new CompileUnit(ID, Die);
+ if (DIUnit.isMain()) {
+ assert (!MainCU && "Multiple main compile units are found!");
+ MainCU = Unit;
+ }
DW_CUs[DIUnit.getGV()] = Unit;
}
}
@@ -2798,7 +2811,9 @@ private:
for (std::vector<GlobalVariable *>::iterator GVI = Result.begin(),
GVE = Result.end(); GVI != GVE; ++GVI) {
DIGlobalVariable DI_GV(*GVI);
- CompileUnit *DW_Unit = FindCompileUnit(DI_GV.getCompileUnit());
+ CompileUnit *DW_Unit = MainCU;
+ if (!DW_Unit)
+ DW_Unit = FindCompileUnit(DI_GV.getCompileUnit());
// Check for pre-existence.
DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
@@ -2835,12 +2850,19 @@ private:
RE = Result.end(); RI != RE; ++RI) {
DISubprogram SP(*RI);
- CompileUnit *Unit = FindCompileUnit(SP.getCompileUnit());
+ CompileUnit *Unit = MainCU;
+ if (!Unit)
+ Unit = FindCompileUnit(SP.getCompileUnit());
// Check for pre-existence.
DIE *&Slot = Unit->getDieMapSlotFor(SP.getGV());
if (Slot) continue;
+ if (!SP.isDefinition())
+ // This is a method declaration which will be handled while
+ // constructing class type.
+ continue;
+
DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
//Add to map.
@@ -2858,6 +2880,7 @@ public:
//
DwarfDebug(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
: Dwarf(OS, A, T, "dbg")
+ , MainCU(NULL)
, AbbreviationsSet(InitAbbreviationsSetSize)
, Abbreviations()
, ValuesSet(InitValuesSetSize)
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 85df7a9d36c1..fe8ce522f065 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -198,7 +198,7 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL;
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
bool MadeChangeThisIteration = true;
while (MadeChangeThisIteration) {
diff --git a/lib/CodeGen/GCMetadata.cpp b/lib/CodeGen/GCMetadata.cpp
index f2978f88882c..4742ad8bbbb9 100644
--- a/lib/CodeGen/GCMetadata.cpp
+++ b/lib/CodeGen/GCMetadata.cpp
@@ -205,7 +205,7 @@ bool Deleter::runOnFunction(Function &MF) {
}
bool Deleter::doFinalization(Module &M) {
- GCModuleInfo *GMI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>();
assert(GMI && "Deleter didn't require GCModuleInfo?!");
GMI->clear();
return false;
diff --git a/lib/CodeGen/GCStrategy.cpp b/lib/CodeGen/GCStrategy.cpp
index 517b3a7762e7..b851c074c218 100644
--- a/lib/CodeGen/GCStrategy.cpp
+++ b/lib/CodeGen/GCStrategy.cpp
@@ -144,7 +144,7 @@ bool LowerIntrinsics::doInitialization(Module &M) {
// work against the entire module. But this cannot be done at
// runFunction time (initializeCustomLowering likely needs to change
// the module).
- GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration() && I->hasGC())
@@ -329,7 +329,8 @@ void MachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
unsigned MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
unsigned Label = MMI->NextLabelID();
- BuildMI(MBB, MI, TII->get(TargetInstrInfo::GC_LABEL)).addImm(Label);
+ BuildMI(MBB, MI, MI->getDebugLoc(),
+ TII->get(TargetInstrInfo::GC_LABEL)).addImm(Label);
return Label;
}
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index 960d660cb946..e893a06699c3 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -533,6 +533,8 @@ static Instruction *LowerPartSet(CallInst *CI) {
Lo = new ZExtInst(Lo_pn, ValTy, "", entry);
} else if (ValBits < 32) {
Lo = new TruncInst(Lo_pn, ValTy, "", entry);
+ } else {
+ Lo = Lo_pn;
}
// Determine if the replacement bits are larger than the number of bits we
// are replacing and deal with it.
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index ff430d71c7d7..40f8cd4388d8 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -244,9 +244,19 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) {
return ranges.insert(it, LR);
}
+/// isInOneLiveRange - Return true if the range specified is entirely in the
+/// a single LiveRange of the live interval.
+bool LiveInterval::isInOneLiveRange(unsigned Start, unsigned End) {
+ Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start);
+ if (I == ranges.begin())
+ return false;
+ --I;
+ return I->contains(Start) && I->contains(End-1);
+}
+
/// removeRange - Remove the specified range from this interval. Note that
-/// the range must already be in this interval in its entirety.
+/// the range must be in a single LiveRange in its entirety.
void LiveInterval::removeRange(unsigned Start, unsigned End,
bool RemoveDeadValNo) {
// Find the LiveRange containing this span.
@@ -581,7 +591,7 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers,
/// are found to be equivalent. This eliminates V1, replacing all
/// LiveRanges with the V1 value number with the V2 value number. This can
/// cause merging of V1/V2 values numbers and compaction of the value space.
-void LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
+VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
assert(V1 != V2 && "Identical value#'s are always equivalent!");
// This code actually merges the (numerically) larger value number into the
@@ -642,6 +652,8 @@ void LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
} else {
V1->def = ~1U;
}
+
+ return V2;
}
void LiveInterval::Copy(const LiveInterval &RHS,
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 8cd82a694bfc..8e8e8ff6d0ca 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -2228,7 +2228,19 @@ void LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li,
unsigned Index = getInstructionIndex(MI);
if (pli.liveAt(Index)) {
vrm.addEmergencySpill(SpillReg, MI);
- pli.removeRange(getLoadIndex(Index), getStoreIndex(Index)+1);
+ unsigned StartIdx = getLoadIndex(Index);
+ unsigned EndIdx = getStoreIndex(Index)+1;
+ if (pli.isInOneLiveRange(StartIdx, EndIdx))
+ pli.removeRange(StartIdx, EndIdx);
+ else {
+ cerr << "Ran out of registers during register allocation!\n";
+ if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ cerr << "Please check your inline asm statement for invalid "
+ << "constraints:\n";
+ MI->print(cerr.stream(), tm_);
+ }
+ exit(1);
+ }
for (const unsigned* AS = tri_->getSubRegisters(SpillReg); *AS; ++AS) {
if (!hasInterval(*AS))
continue;
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index 8bae7bbb92cc..434034b888f0 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -192,9 +192,10 @@ void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) {
/// of `new MachineInstr'.
///
MachineInstr *
-MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID, bool NoImp) {
+MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID,
+ DebugLoc DL, bool NoImp) {
return new (InstructionRecycler.Allocate<MachineInstr>(Allocator))
- MachineInstr(TID, NoImp);
+ MachineInstr(TID, DL, NoImp);
}
/// CloneMachineInstr - Create a new MachineInstr which is a copy of the
@@ -378,6 +379,23 @@ MachineFunction& MachineFunction::get(const Function *F)
return *mc;
}
+/// getOrCreateDebugLocID - Look up the DebugLocTuple index with the given
+/// source file, line, and column. If none currently exists, create add a new
+/// new DebugLocTuple and insert it into the DebugIdMap.
+unsigned MachineFunction::getOrCreateDebugLocID(unsigned Src, unsigned Line,
+ unsigned Col) {
+ struct DebugLocTuple Tuple(Src, Line, Col);
+ DenseMap<DebugLocTuple, unsigned>::iterator II
+ = DebugLocInfo.DebugIdMap.find(Tuple);
+ if (II != DebugLocInfo.DebugIdMap.end())
+ return II->second;
+ // Add a new tuple.
+ unsigned Id = DebugLocInfo.DebugLocations.size();
+ DebugLocInfo.DebugLocations.push_back(Tuple);
+ DebugLocInfo.DebugIdMap[Tuple] = Id;
+ return Id;
+}
+
//===----------------------------------------------------------------------===//
// MachineFrameInfo implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index 3825ddbb0742..d4a60bc6ae88 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -283,7 +283,7 @@ void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
/// TID NULL and no operands.
MachineInstr::MachineInstr()
- : TID(0), NumImplicitOps(0), Parent(0) {
+ : TID(0), NumImplicitOps(0), Parent(0), debugLoc(DebugLoc::getUnknownLoc()) {
// Make sure that we get added to a machine basicblock
LeakDetector::addGarbageObject(this);
}
@@ -302,7 +302,8 @@ void MachineInstr::addImplicitDefUseOperands() {
/// TargetInstrDesc or the numOperands if it is not zero. (for
/// instructions with variable number of operands).
MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp)
- : TID(&tid), NumImplicitOps(0), Parent(0) {
+ : TID(&tid), NumImplicitOps(0), Parent(0),
+ debugLoc(DebugLoc::getUnknownLoc()) {
if (!NoImp && TID->getImplicitDefs())
for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
NumImplicitOps++;
@@ -316,12 +317,49 @@ MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp)
LeakDetector::addGarbageObject(this);
}
-/// MachineInstr ctor - Work exactly the same as the ctor above, except that the
-/// MachineInstr is created and added to the end of the specified basic block.
+/// MachineInstr ctor - As above, but with a DebugLoc.
+MachineInstr::MachineInstr(const TargetInstrDesc &tid, const DebugLoc dl,
+ bool NoImp)
+ : TID(&tid), NumImplicitOps(0), Parent(0), debugLoc(dl) {
+ if (!NoImp && TID->getImplicitDefs())
+ for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
+ NumImplicitOps++;
+ if (!NoImp && TID->getImplicitUses())
+ for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses)
+ NumImplicitOps++;
+ Operands.reserve(NumImplicitOps + TID->getNumOperands());
+ if (!NoImp)
+ addImplicitDefUseOperands();
+ // Make sure that we get added to a machine basicblock
+ LeakDetector::addGarbageObject(this);
+}
+
+/// MachineInstr ctor - Work exactly the same as the ctor two above, except
+/// that the MachineInstr is created and added to the end of the specified
+/// basic block.
+///
+MachineInstr::MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &tid)
+ : TID(&tid), NumImplicitOps(0), Parent(0),
+ debugLoc(DebugLoc::getUnknownLoc()) {
+ assert(MBB && "Cannot use inserting ctor with null basic block!");
+ if (TID->ImplicitDefs)
+ for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
+ NumImplicitOps++;
+ if (TID->ImplicitUses)
+ for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses)
+ NumImplicitOps++;
+ Operands.reserve(NumImplicitOps + TID->getNumOperands());
+ addImplicitDefUseOperands();
+ // Make sure that we get added to a machine basicblock
+ LeakDetector::addGarbageObject(this);
+ MBB->push_back(this); // Add instruction to end of basic block!
+}
+
+/// MachineInstr ctor - As above, but with a DebugLoc.
///
-MachineInstr::MachineInstr(MachineBasicBlock *MBB,
+MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
const TargetInstrDesc &tid)
- : TID(&tid), NumImplicitOps(0), Parent(0) {
+ : TID(&tid), NumImplicitOps(0), Parent(0), debugLoc(dl) {
assert(MBB && "Cannot use inserting ctor with null basic block!");
if (TID->ImplicitDefs)
for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
@@ -339,7 +377,8 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB,
/// MachineInstr ctor - Copies MachineInstr arg exactly
///
MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
- : TID(&MI.getDesc()), NumImplicitOps(0), Parent(0) {
+ : TID(&MI.getDesc()), NumImplicitOps(0), Parent(0),
+ debugLoc(MI.getDebugLoc()) {
Operands.reserve(MI.getNumOperands());
// Add operands
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index 724c113b79b9..1c29c7fed350 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -320,7 +320,7 @@ char DebugLabelFolder::ID = 0;
bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
// Get machine module info.
- MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
if (!MMI) return false;
// Track if change is made.
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index bd389db31f3a..b32db2e062fa 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -166,7 +166,7 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,
if (isSourceDefinedByImplicitDef(MPhi, MRI))
// If all sources of a PHI node are implicit_def, just emit an
// implicit_def instead of a copy.
- BuildMI(MBB, AfterPHIsIt,
+ BuildMI(MBB, AfterPHIsIt, MPhi->getDebugLoc(),
TII->get(TargetInstrInfo::IMPLICIT_DEF), DestReg);
else {
IncomingReg = MF.getRegInfo().createVirtualRegister(RC);
@@ -174,7 +174,7 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,
}
// Update live variable information if there is any.
- LiveVariables *LV = getAnalysisToUpdate<LiveVariables>();
+ LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>();
if (LV) {
MachineInstr *PHICopy = prior(AfterPHIsIt);
diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp
index ca4f7ec6f2d2..99fdb840cc74 100644
--- a/lib/CodeGen/PreAllocSplitting.cpp
+++ b/lib/CodeGen/PreAllocSplitting.cpp
@@ -37,17 +37,20 @@
using namespace llvm;
static cl::opt<int> PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden);
+static cl::opt<int> DeadSplitLimit("dead-split-limit", cl::init(-1), cl::Hidden);
STATISTIC(NumSplits, "Number of intervals split");
STATISTIC(NumRemats, "Number of intervals split by rematerialization");
STATISTIC(NumFolds, "Number of intervals split with spill folding");
STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers");
+STATISTIC(NumDeadSpills, "Number of dead spills removed");
namespace {
class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass {
MachineFunction *CurrMF;
const TargetMachine *TM;
const TargetInstrInfo *TII;
+ const TargetRegisterInfo* TRI;
MachineFrameInfo *MFI;
MachineRegisterInfo *MRI;
LiveIntervals *LIs;
@@ -138,24 +141,10 @@ namespace {
void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned);
- VNInfo* UpdateRegisterInterval(VNInfo*, unsigned, unsigned);
-
- bool ShrinkWrapToLastUse(MachineBasicBlock*, VNInfo*,
- SmallVector<MachineOperand*, 4>&,
- SmallPtrSet<MachineInstr*, 4>&);
-
- void ShrinkWrapLiveInterval(VNInfo*, MachineBasicBlock*, MachineBasicBlock*,
- MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*, 8>&,
- DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> >&,
- DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >&,
- SmallVector<MachineBasicBlock*, 4>&);
-
bool SplitRegLiveInterval(LiveInterval*);
- bool SplitRegLiveIntervals(const TargetRegisterClass **);
-
- void RepairLiveInterval(LiveInterval* CurrLI, VNInfo* ValNo,
- MachineInstr* DefMI, unsigned RestoreIdx);
+ bool SplitRegLiveIntervals(const TargetRegisterClass **,
+ SmallPtrSet<LiveInterval*, 8>&);
bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB,
MachineBasicBlock* BarrierMBB);
@@ -172,16 +161,27 @@ namespace {
SmallPtrSet<MachineInstr*, 4>& RefsInMBB);
void RenumberValno(VNInfo* VN);
void ReconstructLiveInterval(LiveInterval* LI);
- VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use,
- MachineBasicBlock* MBB,
- LiveInterval* LI,
+ bool removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split);
+ unsigned getNumberOfNonSpills(SmallPtrSet<MachineInstr*, 4>& MIs,
+ unsigned Reg, int FrameIndex, bool& TwoAddr);
+ VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator Use,
+ MachineBasicBlock* MBB, LiveInterval* LI,
SmallPtrSet<MachineInstr*, 4>& Visited,
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
DenseMap<MachineInstr*, VNInfo*>& NewVNs,
DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
- bool toplevel, bool intrablock);
+ bool IsTopLevel, bool IsIntraBlock);
+ VNInfo* PerformPHIConstructionFallBack(MachineBasicBlock::iterator Use,
+ MachineBasicBlock* MBB, LiveInterval* LI,
+ SmallPtrSet<MachineInstr*, 4>& Visited,
+ DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
+ DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
+ DenseMap<MachineInstr*, VNInfo*>& NewVNs,
+ DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
+ DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
+ bool IsTopLevel, bool IsIntraBlock);
};
} // end anonymous namespace
@@ -232,12 +232,21 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI,
Pt = MII;
SpillIndex = Gap;
break;
- }
+
+ // We can't insert the spill between the barrier (a call), and its
+ // corresponding call frame setup.
+ } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode() &&
+ MII == MachineBasicBlock::iterator(MI))
+ break;
} while (MII != EndPt);
} else {
MachineBasicBlock::iterator MII = MI;
MachineBasicBlock::iterator EndPt = DefMI
? MachineBasicBlock::iterator(DefMI) : MBB->begin();
+
+ // We can't insert the spill between the barrier (a call), and its
+ // corresponding call frame setup.
+ if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) --MII;
while (MII != EndPt && !RefsInMBB.count(MII)) {
unsigned Index = LIs->getInstructionIndex(MII);
if (LIs->hasGapBeforeInstr(Index)) {
@@ -278,15 +287,25 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI,
Pt = MII;
RestoreIndex = Gap;
break;
- }
+
+ // We can't insert a restore between the barrier (a call) and its
+ // corresponding call frame teardown.
+ } else if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode() &&
+ prior(MII) == MachineBasicBlock::iterator(MI))
+ break;
--MII;
} while (MII != EndPt);
} else {
MachineBasicBlock::iterator MII = MI;
MII = ++MII;
+ // We can't insert a restore between the barrier (a call) and its
+ // corresponding call frame teardown.
+ if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode())
+ ++MII;
+
// FIXME: Limit the number of instructions to examine to reduce
// compile time?
- while (MII != MBB->end()) {
+ while (MII != MBB->getFirstTerminator()) {
unsigned Index = LIs->getInstructionIndex(MII);
if (Index > LastIdx)
break;
@@ -418,266 +437,37 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex,
}
}
-/// UpdateRegisterInterval - Given the specified val# of the current live
-/// interval is being split, and the spill and restore indices, update the live
-/// interval accordingly.
-VNInfo*
-PreAllocSplitting::UpdateRegisterInterval(VNInfo *ValNo, unsigned SpillIndex,
- unsigned RestoreIndex) {
- assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB &&
- "Expect restore in the barrier mbb");
-
- SmallVector<std::pair<unsigned,unsigned>, 4> Before;
- SmallVector<std::pair<unsigned,unsigned>, 4> After;
- SmallVector<unsigned, 4> BeforeKills;
- SmallVector<unsigned, 4> AfterKills;
- SmallPtrSet<const LiveRange*, 4> Processed;
-
- // First, let's figure out which parts of the live interval is now defined
- // by the restore, which are defined by the original definition.
- const LiveRange *LR = CurrLI->getLiveRangeContaining(RestoreIndex);
- After.push_back(std::make_pair(RestoreIndex, LR->end));
- if (CurrLI->isKill(ValNo, LR->end))
- AfterKills.push_back(LR->end);
-
- assert(LR->contains(SpillIndex));
- if (SpillIndex > LR->start) {
- Before.push_back(std::make_pair(LR->start, SpillIndex));
- BeforeKills.push_back(SpillIndex);
- }
- Processed.insert(LR);
-
- // Start from the restore mbb, figure out what part of the live interval
- // are defined by the restore.
- SmallVector<MachineBasicBlock*, 4> WorkList;
- MachineBasicBlock *MBB = BarrierMBB;
- for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
- SE = MBB->succ_end(); SI != SE; ++SI)
- WorkList.push_back(*SI);
-
- SmallPtrSet<MachineBasicBlock*, 4> ProcessedBlocks;
- ProcessedBlocks.insert(MBB);
-
- while (!WorkList.empty()) {
- MBB = WorkList.back();
- WorkList.pop_back();
- unsigned Idx = LIs->getMBBStartIdx(MBB);
- LR = CurrLI->getLiveRangeContaining(Idx);
- if (LR && LR->valno == ValNo && !Processed.count(LR)) {
- After.push_back(std::make_pair(LR->start, LR->end));
- if (CurrLI->isKill(ValNo, LR->end))
- AfterKills.push_back(LR->end);
- Idx = LIs->getMBBEndIdx(MBB);
- if (LR->end > Idx) {
- // Live range extend beyond at least one mbb. Let's see what other
- // mbbs it reaches.
- LIs->findReachableMBBs(LR->start, LR->end, WorkList);
- }
- Processed.insert(LR);
- }
-
- ProcessedBlocks.insert(MBB);
- if (LR)
- for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
- SE = MBB->succ_end(); SI != SE; ++SI)
- if (!ProcessedBlocks.count(*SI))
- WorkList.push_back(*SI);
- }
-
- for (LiveInterval::iterator I = CurrLI->begin(), E = CurrLI->end();
- I != E; ++I) {
- LiveRange *LR = I;
- if (LR->valno == ValNo && !Processed.count(LR)) {
- Before.push_back(std::make_pair(LR->start, LR->end));
- if (CurrLI->isKill(ValNo, LR->end))
- BeforeKills.push_back(LR->end);
- }
- }
-
- // Now create new val#s to represent the live ranges defined by the old def
- // those defined by the restore.
- unsigned AfterDef = ValNo->def;
- MachineInstr *AfterCopy = ValNo->copy;
- bool HasPHIKill = ValNo->hasPHIKill;
- CurrLI->removeValNo(ValNo);
- VNInfo *BValNo = (Before.empty())
- ? NULL
- : CurrLI->getNextValue(AfterDef, AfterCopy, LIs->getVNInfoAllocator());
- if (BValNo)
- CurrLI->addKills(BValNo, BeforeKills);
-
- VNInfo *AValNo = (After.empty())
- ? NULL
- : CurrLI->getNextValue(RestoreIndex, 0, LIs->getVNInfoAllocator());
- if (AValNo) {
- AValNo->hasPHIKill = HasPHIKill;
- CurrLI->addKills(AValNo, AfterKills);
- }
-
- for (unsigned i = 0, e = Before.size(); i != e; ++i) {
- unsigned Start = Before[i].first;
- unsigned End = Before[i].second;
- CurrLI->addRange(LiveRange(Start, End, BValNo));
- }
- for (unsigned i = 0, e = After.size(); i != e; ++i) {
- unsigned Start = After[i].first;
- unsigned End = After[i].second;
- CurrLI->addRange(LiveRange(Start, End, AValNo));
- }
-
- return AValNo;
-}
-
-/// ShrinkWrapToLastUse - There are uses of the current live interval in the
-/// given block, shrink wrap the live interval to the last use (i.e. remove
-/// from last use to the end of the mbb). In case mbb is the where the barrier
-/// is, remove from the last use to the barrier.
-bool
-PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB, VNInfo *ValNo,
- SmallVector<MachineOperand*, 4> &Uses,
- SmallPtrSet<MachineInstr*, 4> &UseMIs) {
- MachineOperand *LastMO = 0;
- MachineInstr *LastMI = 0;
- if (MBB != BarrierMBB && Uses.size() == 1) {
- // Single use, no need to traverse the block. We can't assume this for the
- // barrier bb though since the use is probably below the barrier.
- LastMO = Uses[0];
- LastMI = LastMO->getParent();
- } else {
- MachineBasicBlock::iterator MEE = MBB->begin();
- MachineBasicBlock::iterator MII;
- if (MBB == BarrierMBB)
- MII = Barrier;
- else
- MII = MBB->end();
- while (MII != MEE) {
- --MII;
- MachineInstr *UseMI = &*MII;
- if (!UseMIs.count(UseMI))
- continue;
- for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) {
- MachineOperand &MO = UseMI->getOperand(i);
- if (MO.isReg() && MO.getReg() == CurrLI->reg) {
- LastMO = &MO;
- break;
- }
- }
- LastMI = UseMI;
- break;
- }
- }
-
- // Cut off live range from last use (or beginning of the mbb if there
- // are no uses in it) to the end of the mbb.
- unsigned RangeStart, RangeEnd = LIs->getMBBEndIdx(MBB)+1;
- if (LastMI) {
- RangeStart = LIs->getUseIndex(LIs->getInstructionIndex(LastMI))+1;
- assert(!LastMO->isKill() && "Last use already terminates the interval?");
- LastMO->setIsKill();
- } else {
- assert(MBB == BarrierMBB);
- RangeStart = LIs->getMBBStartIdx(MBB);
- }
- if (MBB == BarrierMBB)
- RangeEnd = LIs->getUseIndex(BarrierIdx)+1;
- CurrLI->removeRange(RangeStart, RangeEnd);
- if (LastMI)
- CurrLI->addKill(ValNo, RangeStart);
-
- // Return true if the last use becomes a new kill.
- return LastMI;
-}
-
/// PerformPHIConstruction - From properly set up use and def lists, use a PHI
/// construction algorithm to compute the ranges and valnos for an interval.
-VNInfo* PreAllocSplitting::PerformPHIConstruction(
- MachineBasicBlock::iterator use,
- MachineBasicBlock* MBB,
- LiveInterval* LI,
+VNInfo*
+PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI,
+ MachineBasicBlock* MBB, LiveInterval* LI,
SmallPtrSet<MachineInstr*, 4>& Visited,
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
DenseMap<MachineInstr*, VNInfo*>& NewVNs,
DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
- bool toplevel, bool intrablock) {
+ bool IsTopLevel, bool IsIntraBlock) {
// Return memoized result if it's available.
- if (toplevel && Visited.count(use) && NewVNs.count(use))
- return NewVNs[use];
- else if (!toplevel && intrablock && NewVNs.count(use))
- return NewVNs[use];
- else if (!intrablock && LiveOut.count(MBB))
+ if (IsTopLevel && Visited.count(UseI) && NewVNs.count(UseI))
+ return NewVNs[UseI];
+ else if (!IsTopLevel && IsIntraBlock && NewVNs.count(UseI))
+ return NewVNs[UseI];
+ else if (!IsIntraBlock && LiveOut.count(MBB))
return LiveOut[MBB];
- typedef DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> > RegMap;
-
// Check if our block contains any uses or defs.
bool ContainsDefs = Defs.count(MBB);
bool ContainsUses = Uses.count(MBB);
- VNInfo* ret = 0;
+ VNInfo* RetVNI = 0;
// Enumerate the cases of use/def contaning blocks.
if (!ContainsDefs && !ContainsUses) {
- Fallback:
- // NOTE: Because this is the fallback case from other cases, we do NOT
- // assume that we are not intrablock here.
- if (Phis.count(MBB)) return Phis[MBB];
-
- unsigned StartIndex = LIs->getMBBStartIdx(MBB);
-
- if (MBB->pred_size() == 1) {
- Phis[MBB] = ret = PerformPHIConstruction((*MBB->pred_begin())->end(),
- *(MBB->pred_begin()), LI, Visited,
- Defs, Uses, NewVNs, LiveOut, Phis,
- false, false);
- unsigned EndIndex = 0;
- if (intrablock) {
- EndIndex = LIs->getInstructionIndex(use);
- EndIndex = LiveIntervals::getUseIndex(EndIndex);
- } else
- EndIndex = LIs->getMBBEndIdx(MBB);
-
- LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
- if (intrablock)
- LI->addKill(ret, EndIndex);
- } else {
- Phis[MBB] = ret = LI->getNextValue(~0U, /*FIXME*/ 0,
- LIs->getVNInfoAllocator());
- if (!intrablock) LiveOut[MBB] = ret;
-
- // If there are no uses or defs between our starting point and the
- // beginning of the block, then recursive perform phi construction
- // on our predecessors.
- DenseMap<MachineBasicBlock*, VNInfo*> IncomingVNs;
- for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
- PE = MBB->pred_end(); PI != PE; ++PI) {
- VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI,
- Visited, Defs, Uses, NewVNs,
- LiveOut, Phis, false, false);
- if (Incoming != 0)
- IncomingVNs[*PI] = Incoming;
- }
-
- // Otherwise, merge the incoming VNInfos with a phi join. Create a new
- // VNInfo to represent the joined value.
- for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator I =
- IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) {
- I->second->hasPHIKill = true;
- unsigned KillIndex = LIs->getMBBEndIdx(I->first);
- LI->addKill(I->second, KillIndex);
- }
-
- unsigned EndIndex = 0;
- if (intrablock) {
- EndIndex = LIs->getInstructionIndex(use);
- EndIndex = LiveIntervals::getUseIndex(EndIndex);
- } else
- EndIndex = LIs->getMBBEndIdx(MBB);
- LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
- if (intrablock)
- LI->addKill(ret, EndIndex);
- }
+ return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, Uses,
+ NewVNs, LiveOut, Phis,
+ IsTopLevel, IsIntraBlock);
} else if (ContainsDefs && !ContainsUses) {
SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB];
@@ -685,71 +475,75 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction(
// instruction we care about, go to the fallback case. Note that that
// should never happen: this cannot be intrablock, so use should
// always be an end() iterator.
- assert(use == MBB->end() && "No use marked in intrablock");
+ assert(UseI == MBB->end() && "No use marked in intrablock");
- MachineBasicBlock::iterator walker = use;
- --walker;
- while (walker != MBB->begin())
- if (BlockDefs.count(walker)) {
+ MachineBasicBlock::iterator Walker = UseI;
+ --Walker;
+ while (Walker != MBB->begin()) {
+ if (BlockDefs.count(Walker))
break;
- } else
- --walker;
+ --Walker;
+ }
// Once we've found it, extend its VNInfo to our instruction.
- unsigned DefIndex = LIs->getInstructionIndex(walker);
+ unsigned DefIndex = LIs->getInstructionIndex(Walker);
DefIndex = LiveIntervals::getDefIndex(DefIndex);
unsigned EndIndex = LIs->getMBBEndIdx(MBB);
- ret = NewVNs[walker];
- LI->addRange(LiveRange(DefIndex, EndIndex+1, ret));
+ RetVNI = NewVNs[Walker];
+ LI->addRange(LiveRange(DefIndex, EndIndex+1, RetVNI));
} else if (!ContainsDefs && ContainsUses) {
SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB];
// Search for the use in this block that precedes the instruction we care
- // about, going to the fallback case if we don't find it.
+ // about, going to the fallback case if we don't find it.
+ if (UseI == MBB->begin())
+ return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs,
+ Uses, NewVNs, LiveOut, Phis,
+ IsTopLevel, IsIntraBlock);
- if (use == MBB->begin())
- goto Fallback;
-
- MachineBasicBlock::iterator walker = use;
- --walker;
+ MachineBasicBlock::iterator Walker = UseI;
+ --Walker;
bool found = false;
- while (walker != MBB->begin())
- if (BlockUses.count(walker)) {
+ while (Walker != MBB->begin()) {
+ if (BlockUses.count(Walker)) {
found = true;
break;
- } else
- --walker;
+ }
+ --Walker;
+ }
// Must check begin() too.
if (!found) {
- if (BlockUses.count(walker))
+ if (BlockUses.count(Walker))
found = true;
else
- goto Fallback;
+ return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs,
+ Uses, NewVNs, LiveOut, Phis,
+ IsTopLevel, IsIntraBlock);
}
- unsigned UseIndex = LIs->getInstructionIndex(walker);
+ unsigned UseIndex = LIs->getInstructionIndex(Walker);
UseIndex = LiveIntervals::getUseIndex(UseIndex);
unsigned EndIndex = 0;
- if (intrablock) {
- EndIndex = LIs->getInstructionIndex(use);
+ if (IsIntraBlock) {
+ EndIndex = LIs->getInstructionIndex(UseI);
EndIndex = LiveIntervals::getUseIndex(EndIndex);
} else
EndIndex = LIs->getMBBEndIdx(MBB);
// Now, recursively phi construct the VNInfo for the use we found,
// and then extend it to include the instruction we care about
- ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
- NewVNs, LiveOut, Phis, false, true);
+ RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses,
+ NewVNs, LiveOut, Phis, false, true);
- // FIXME: Need to set kills properly for inter-block stuff.
- if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex);
- if (intrablock)
- LI->addKill(ret, EndIndex);
+ LI->addRange(LiveRange(UseIndex, EndIndex+1, RetVNI));
- LI->addRange(LiveRange(UseIndex, EndIndex+1, ret));
- } else if (ContainsDefs && ContainsUses){
+ // FIXME: Need to set kills properly for inter-block stuff.
+ if (LI->isKill(RetVNI, UseIndex)) LI->removeKill(RetVNI, UseIndex);
+ if (IsIntraBlock)
+ LI->addKill(RetVNI, EndIndex);
+ } else if (ContainsDefs && ContainsUses) {
SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB];
SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB];
@@ -757,67 +551,159 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction(
// special note that checking for defs must take precedence over checking
// for uses, because of two-address instructions.
- if (use == MBB->begin())
- goto Fallback;
+ if (UseI == MBB->begin())
+ return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, Uses,
+ NewVNs, LiveOut, Phis,
+ IsTopLevel, IsIntraBlock);
- MachineBasicBlock::iterator walker = use;
- --walker;
+ MachineBasicBlock::iterator Walker = UseI;
+ --Walker;
bool foundDef = false;
bool foundUse = false;
- while (walker != MBB->begin())
- if (BlockDefs.count(walker)) {
+ while (Walker != MBB->begin()) {
+ if (BlockDefs.count(Walker)) {
foundDef = true;
break;
- } else if (BlockUses.count(walker)) {
+ } else if (BlockUses.count(Walker)) {
foundUse = true;
break;
- } else
- --walker;
+ }
+ --Walker;
+ }
// Must check begin() too.
if (!foundDef && !foundUse) {
- if (BlockDefs.count(walker))
+ if (BlockDefs.count(Walker))
foundDef = true;
- else if (BlockUses.count(walker))
+ else if (BlockUses.count(Walker))
foundUse = true;
else
- goto Fallback;
+ return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs,
+ Uses, NewVNs, LiveOut, Phis,
+ IsTopLevel, IsIntraBlock);
}
- unsigned StartIndex = LIs->getInstructionIndex(walker);
+ unsigned StartIndex = LIs->getInstructionIndex(Walker);
StartIndex = foundDef ? LiveIntervals::getDefIndex(StartIndex) :
LiveIntervals::getUseIndex(StartIndex);
unsigned EndIndex = 0;
- if (intrablock) {
- EndIndex = LIs->getInstructionIndex(use);
+ if (IsIntraBlock) {
+ EndIndex = LIs->getInstructionIndex(UseI);
EndIndex = LiveIntervals::getUseIndex(EndIndex);
} else
EndIndex = LIs->getMBBEndIdx(MBB);
if (foundDef)
- ret = NewVNs[walker];
+ RetVNI = NewVNs[Walker];
else
- ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
- NewVNs, LiveOut, Phis, false, true);
+ RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses,
+ NewVNs, LiveOut, Phis, false, true);
- if (foundUse && LI->isKill(ret, StartIndex))
- LI->removeKill(ret, StartIndex);
- if (intrablock) {
- LI->addKill(ret, EndIndex);
+ LI->addRange(LiveRange(StartIndex, EndIndex+1, RetVNI));
+
+ if (foundUse && LI->isKill(RetVNI, StartIndex))
+ LI->removeKill(RetVNI, StartIndex);
+ if (IsIntraBlock) {
+ LI->addKill(RetVNI, EndIndex);
}
-
- LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
}
// Memoize results so we don't have to recompute them.
- if (!intrablock) LiveOut[MBB] = ret;
+ if (!IsIntraBlock) LiveOut[MBB] = RetVNI;
else {
- if (!NewVNs.count(use))
- NewVNs[use] = ret;
- Visited.insert(use);
+ if (!NewVNs.count(UseI))
+ NewVNs[UseI] = RetVNI;
+ Visited.insert(UseI);
}
- return ret;
+ return RetVNI;
+}
+
+/// PerformPHIConstructionFallBack - PerformPHIConstruction fall back path.
+///
+VNInfo*
+PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator UseI,
+ MachineBasicBlock* MBB, LiveInterval* LI,
+ SmallPtrSet<MachineInstr*, 4>& Visited,
+ DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
+ DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
+ DenseMap<MachineInstr*, VNInfo*>& NewVNs,
+ DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
+ DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
+ bool IsTopLevel, bool IsIntraBlock) {
+ // NOTE: Because this is the fallback case from other cases, we do NOT
+ // assume that we are not intrablock here.
+ if (Phis.count(MBB)) return Phis[MBB];
+
+ unsigned StartIndex = LIs->getMBBStartIdx(MBB);
+ VNInfo *RetVNI = Phis[MBB] = LI->getNextValue(~0U, /*FIXME*/ 0,
+ LIs->getVNInfoAllocator());
+ if (!IsIntraBlock) LiveOut[MBB] = RetVNI;
+
+ // If there are no uses or defs between our starting point and the
+ // beginning of the block, then recursive perform phi construction
+ // on our predecessors.
+ DenseMap<MachineBasicBlock*, VNInfo*> IncomingVNs;
+ for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+ PE = MBB->pred_end(); PI != PE; ++PI) {
+ VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI,
+ Visited, Defs, Uses, NewVNs,
+ LiveOut, Phis, false, false);
+ if (Incoming != 0)
+ IncomingVNs[*PI] = Incoming;
+ }
+
+ if (MBB->pred_size() == 1 && !RetVNI->hasPHIKill) {
+ VNInfo* OldVN = RetVNI;
+ VNInfo* NewVN = IncomingVNs.begin()->second;
+ VNInfo* MergedVN = LI->MergeValueNumberInto(OldVN, NewVN);
+ if (MergedVN == OldVN) std::swap(OldVN, NewVN);
+
+ for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator LOI = LiveOut.begin(),
+ LOE = LiveOut.end(); LOI != LOE; ++LOI)
+ if (LOI->second == OldVN)
+ LOI->second = MergedVN;
+ for (DenseMap<MachineInstr*, VNInfo*>::iterator NVI = NewVNs.begin(),
+ NVE = NewVNs.end(); NVI != NVE; ++NVI)
+ if (NVI->second == OldVN)
+ NVI->second = MergedVN;
+ for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator PI = Phis.begin(),
+ PE = Phis.end(); PI != PE; ++PI)
+ if (PI->second == OldVN)
+ PI->second = MergedVN;
+ RetVNI = MergedVN;
+ } else {
+ // Otherwise, merge the incoming VNInfos with a phi join. Create a new
+ // VNInfo to represent the joined value.
+ for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator I =
+ IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) {
+ I->second->hasPHIKill = true;
+ unsigned KillIndex = LIs->getMBBEndIdx(I->first);
+ if (!LiveInterval::isKill(I->second, KillIndex))
+ LI->addKill(I->second, KillIndex);
+ }
+ }
+
+ unsigned EndIndex = 0;
+ if (IsIntraBlock) {
+ EndIndex = LIs->getInstructionIndex(UseI);
+ EndIndex = LiveIntervals::getUseIndex(EndIndex);
+ } else
+ EndIndex = LIs->getMBBEndIdx(MBB);
+ LI->addRange(LiveRange(StartIndex, EndIndex+1, RetVNI));
+ if (IsIntraBlock)
+ LI->addKill(RetVNI, EndIndex);
+
+ // Memoize results so we don't have to recompute them.
+ if (!IsIntraBlock)
+ LiveOut[MBB] = RetVNI;
+ else {
+ if (!NewVNs.count(UseI))
+ NewVNs[UseI] = RetVNI;
+ Visited.insert(UseI);
+ }
+
+ return RetVNI;
}
/// ReconstructLiveInterval - Recompute a live interval from scratch.
@@ -885,142 +771,6 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) {
}
}
-/// ShrinkWrapLiveInterval - Recursively traverse the predecessor
-/// chain to find the new 'kills' and shrink wrap the live interval to the
-/// new kill indices.
-void
-PreAllocSplitting::ShrinkWrapLiveInterval(VNInfo *ValNo, MachineBasicBlock *MBB,
- MachineBasicBlock *SuccMBB, MachineBasicBlock *DefMBB,
- SmallPtrSet<MachineBasicBlock*, 8> &Visited,
- DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> > &Uses,
- DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> > &UseMIs,
- SmallVector<MachineBasicBlock*, 4> &UseMBBs) {
- if (Visited.count(MBB))
- return;
-
- // If live interval is live in another successor path, then we can't process
- // this block. But we may able to do so after all the successors have been
- // processed.
- if (MBB != BarrierMBB) {
- for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
- SE = MBB->succ_end(); SI != SE; ++SI) {
- MachineBasicBlock *SMBB = *SI;
- if (SMBB == SuccMBB)
- continue;
- if (CurrLI->liveAt(LIs->getMBBStartIdx(SMBB)))
- return;
- }
- }
-
- Visited.insert(MBB);
-
- DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> >::iterator
- UMII = Uses.find(MBB);
- if (UMII != Uses.end()) {
- // At least one use in this mbb, lets look for the kill.
- DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >::iterator
- UMII2 = UseMIs.find(MBB);
- if (ShrinkWrapToLastUse(MBB, ValNo, UMII->second, UMII2->second))
- // Found a kill, shrink wrapping of this path ends here.
- return;
- } else if (MBB == DefMBB) {
- // There are no uses after the def.
- MachineInstr *DefMI = LIs->getInstructionFromIndex(ValNo->def);
- if (UseMBBs.empty()) {
- // The only use must be below barrier in the barrier block. It's safe to
- // remove the def.
- LIs->RemoveMachineInstrFromMaps(DefMI);
- DefMI->eraseFromParent();
- CurrLI->removeRange(ValNo->def, LIs->getMBBEndIdx(MBB)+1);
- }
- } else if (MBB == BarrierMBB) {
- // Remove entire live range from start of mbb to barrier.
- CurrLI->removeRange(LIs->getMBBStartIdx(MBB),
- LIs->getUseIndex(BarrierIdx)+1);
- } else {
- // Remove entire live range of the mbb out of the live interval.
- CurrLI->removeRange(LIs->getMBBStartIdx(MBB), LIs->getMBBEndIdx(MBB)+1);
- }
-
- if (MBB == DefMBB)
- // Reached the def mbb, stop traversing this path further.
- return;
-
- // Traverse the pathes up the predecessor chains further.
- for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
- PE = MBB->pred_end(); PI != PE; ++PI) {
- MachineBasicBlock *Pred = *PI;
- if (Pred == MBB)
- continue;
- if (Pred == DefMBB && ValNo->hasPHIKill)
- // Pred is the def bb and the def reaches other val#s, we must
- // allow the value to be live out of the bb.
- continue;
- if (!CurrLI->liveAt(LIs->getMBBEndIdx(Pred)-1))
- return;
- ShrinkWrapLiveInterval(ValNo, Pred, MBB, DefMBB, Visited,
- Uses, UseMIs, UseMBBs);
- }
-
- return;
-}
-
-
-void PreAllocSplitting::RepairLiveInterval(LiveInterval* CurrLI,
- VNInfo* ValNo,
- MachineInstr* DefMI,
- unsigned RestoreIdx) {
- // Shrink wrap the live interval by walking up the CFG and find the
- // new kills.
- // Now let's find all the uses of the val#.
- DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> > Uses;
- DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> > UseMIs;
- SmallPtrSet<MachineBasicBlock*, 4> Seen;
- SmallVector<MachineBasicBlock*, 4> UseMBBs;
- for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI->reg),
- UE = MRI->use_end(); UI != UE; ++UI) {
- MachineOperand &UseMO = UI.getOperand();
- MachineInstr *UseMI = UseMO.getParent();
- unsigned UseIdx = LIs->getInstructionIndex(UseMI);
- LiveInterval::iterator ULR = CurrLI->FindLiveRangeContaining(UseIdx);
- if (ULR->valno != ValNo)
- continue;
- MachineBasicBlock *UseMBB = UseMI->getParent();
- // Remember which other mbb's use this val#.
- if (Seen.insert(UseMBB) && UseMBB != BarrierMBB)
- UseMBBs.push_back(UseMBB);
- DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> >::iterator
- UMII = Uses.find(UseMBB);
- if (UMII != Uses.end()) {
- DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >::iterator
- UMII2 = UseMIs.find(UseMBB);
- UMII->second.push_back(&UseMO);
- UMII2->second.insert(UseMI);
- } else {
- SmallVector<MachineOperand*, 4> Ops;
- Ops.push_back(&UseMO);
- Uses.insert(std::make_pair(UseMBB, Ops));
- SmallPtrSet<MachineInstr*, 4> MIs;
- MIs.insert(UseMI);
- UseMIs.insert(std::make_pair(UseMBB, MIs));
- }
- }
-
- // Walk up the predecessor chains.
- SmallPtrSet<MachineBasicBlock*, 8> Visited;
- ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI->getParent(), Visited,
- Uses, UseMIs, UseMBBs);
-
- // Remove live range from barrier to the restore. FIXME: Find a better
- // point to re-start the live interval.
- VNInfo* AfterValNo = UpdateRegisterInterval(ValNo,
- LIs->getUseIndex(BarrierIdx)+1,
- LIs->getDefIndex(RestoreIdx));
-
- // Attempt to renumber the new valno into a new vreg.
- RenumberValno(AfterValNo);
-}
-
/// RenumberValno - Split the given valno out into a new vreg, allowing it to
/// be allocated to a different register. This function creates a new vreg,
/// copies the valno and its live ranges over to the new vreg's interval,
@@ -1050,12 +800,12 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
for (SmallVector<unsigned, 4>::iterator KI = OldVN->kills.begin(),
KE = OldVN->kills.end(); KI != KE; ++KI) {
MachineInstr* MI = LIs->getInstructionFromIndex(*KI);
- //if (!MI) continue;
unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg);
if (DefIdx == ~0U) continue;
if (MI->isRegReDefinedByTwoAddr(DefIdx)) {
VNInfo* NextVN =
CurrLI->findDefinedVNInfo(LiveIntervals::getDefIndex(*KI));
+ if (NextVN == OldVN) continue;
Stack.push_back(NextVN);
}
}
@@ -1103,6 +853,10 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
MO.setReg(NewVReg);
}
+ // The renumbered vreg shares a stack slot with the old register.
+ if (IntervalSSMap.count(CurrLI->reg))
+ IntervalSSMap[NewVReg] = IntervalSSMap[CurrLI->reg];
+
NumRenumbers++;
}
@@ -1126,18 +880,10 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
TII->reMaterialize(MBB, RestorePt, vreg, DefMI);
LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx);
- if (KillPt->getParent() == BarrierMBB) {
- VNInfo* After = UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1,
- LIs->getDefIndex(RestoreIdx));
-
- RenumberValno(After);
-
- ++NumSplits;
- ++NumRemats;
- return true;
- }
-
- RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIdx);
+ ReconstructLiveInterval(CurrLI);
+ unsigned RematIdx = LIs->getInstructionIndex(prior(RestorePt));
+ RematIdx = LiveIntervals::getDefIndex(RematIdx);
+ RenumberValno(CurrLI->findDefinedVNInfo(RematIdx));
++NumSplits;
++NumRemats;
@@ -1233,7 +979,7 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
}
// Find a point to restore the value after the barrier.
- unsigned RestoreIndex;
+ unsigned RestoreIndex = 0;
MachineBasicBlock::iterator RestorePt =
findRestorePoint(BarrierMBB, Barrier, LR->end, RefsInMBB, RestoreIndex);
if (RestorePt == BarrierMBB->end())
@@ -1310,28 +1056,14 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
MachineInstr *LoadMI = prior(RestorePt);
LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
- // If live interval is spilled in the same block as the barrier, just
- // create a hole in the interval.
- if (!DefMBB ||
- (SpillMI && SpillMI->getParent() == BarrierMBB)) {
- // Update spill stack slot live interval.
- UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
- LIs->getDefIndex(RestoreIndex));
-
- VNInfo* After = UpdateRegisterInterval(ValNo,
- LIs->getUseIndex(SpillIndex)+1,
- LIs->getDefIndex(RestoreIndex));
- RenumberValno(After);
-
- ++NumSplits;
- return true;
- }
-
// Update spill stack slot live interval.
UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
LIs->getDefIndex(RestoreIndex));
- RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIndex);
+ ReconstructLiveInterval(CurrLI);
+ unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt));
+ RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx);
+ RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx));
++NumSplits;
return true;
@@ -1340,7 +1072,8 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
/// SplitRegLiveIntervals - Split all register live intervals that cross the
/// barrier that's being processed.
bool
-PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs) {
+PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs,
+ SmallPtrSet<LiveInterval*, 8>& Split) {
// First find all the virtual registers whose live intervals are intercepted
// by the current barrier.
SmallVector<LiveInterval*, 8> Intervals;
@@ -1369,12 +1102,191 @@ PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs) {
Change |= Change;
LiveInterval *LI = Intervals.back();
Intervals.pop_back();
- Change |= SplitRegLiveInterval(LI);
+ bool result = SplitRegLiveInterval(LI);
+ if (result) Split.insert(LI);
+ Change |= result;
}
return Change;
}
+unsigned PreAllocSplitting::getNumberOfNonSpills(
+ SmallPtrSet<MachineInstr*, 4>& MIs,
+ unsigned Reg, int FrameIndex,
+ bool& FeedsTwoAddr) {
+ unsigned NonSpills = 0;
+ for (SmallPtrSet<MachineInstr*, 4>::iterator UI = MIs.begin(), UE = MIs.end();
+ UI != UE; ++UI) {
+ int StoreFrameIndex;
+ unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
+ if (StoreVReg != Reg || StoreFrameIndex != FrameIndex)
+ NonSpills++;
+
+ int DefIdx = (*UI)->findRegisterDefOperandIdx(Reg);
+ if (DefIdx != -1 && (*UI)->isRegReDefinedByTwoAddr(DefIdx))
+ FeedsTwoAddr = true;
+ }
+
+ return NonSpills;
+}
+
+/// removeDeadSpills - After doing splitting, filter through all intervals we've
+/// split, and see if any of the spills are unnecessary. If so, remove them.
+bool PreAllocSplitting::removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split) {
+ bool changed = false;
+
+ // Walk over all of the live intervals that were touched by the splitter,
+ // and see if we can do any DCE and/or folding.
+ for (SmallPtrSet<LiveInterval*, 8>::iterator LI = split.begin(),
+ LE = split.end(); LI != LE; ++LI) {
+ DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> > VNUseCount;
+
+ // First, collect all the uses of the vreg, and sort them by their
+ // reaching definition (VNInfo).
+ for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg),
+ UE = MRI->use_end(); UI != UE; ++UI) {
+ unsigned index = LIs->getInstructionIndex(&*UI);
+ index = LiveIntervals::getUseIndex(index);
+
+ const LiveRange* LR = (*LI)->getLiveRangeContaining(index);
+ VNUseCount[LR->valno].insert(&*UI);
+ }
+
+ // Now, take the definitions (VNInfo's) one at a time and try to DCE
+ // and/or fold them away.
+ for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(),
+ VE = (*LI)->vni_end(); VI != VE; ++VI) {
+
+ if (DeadSplitLimit != -1 && (int)NumDeadSpills == DeadSplitLimit)
+ return changed;
+
+ VNInfo* CurrVN = *VI;
+
+ // We don't currently try to handle definitions with PHI kills, because
+ // it would involve processing more than one VNInfo at once.
+ if (CurrVN->hasPHIKill) continue;
+
+ // We also don't try to handle the results of PHI joins, since there's
+ // no defining instruction to analyze.
+ unsigned DefIdx = CurrVN->def;
+ if (DefIdx == ~0U || DefIdx == ~1U) continue;
+
+ // We're only interested in eliminating cruft introduced by the splitter,
+ // is of the form load-use or load-use-store. First, check that the
+ // definition is a load, and remember what stack slot we loaded it from.
+ MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx);
+ int FrameIndex;
+ if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue;
+
+ // If the definition has no uses at all, just DCE it.
+ if (VNUseCount[CurrVN].size() == 0) {
+ LIs->RemoveMachineInstrFromMaps(DefMI);
+ (*LI)->removeValNo(CurrVN);
+ DefMI->eraseFromParent();
+ VNUseCount.erase(CurrVN);
+ NumDeadSpills++;
+ changed = true;
+ continue;
+ }
+
+ // Second, get the number of non-store uses of the definition, as well as
+ // a flag indicating whether it feeds into a later two-address definition.
+ bool FeedsTwoAddr = false;
+ unsigned NonSpillCount = getNumberOfNonSpills(VNUseCount[CurrVN],
+ (*LI)->reg, FrameIndex,
+ FeedsTwoAddr);
+
+ // If there's one non-store use and it doesn't feed a two-addr, then
+ // this is a load-use-store case that we can try to fold.
+ if (NonSpillCount == 1 && !FeedsTwoAddr) {
+ // Start by finding the non-store use MachineInstr.
+ SmallPtrSet<MachineInstr*, 4>::iterator UI = VNUseCount[CurrVN].begin();
+ int StoreFrameIndex;
+ unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
+ while (UI != VNUseCount[CurrVN].end() &&
+ (StoreVReg == (*LI)->reg && StoreFrameIndex == FrameIndex)) {
+ ++UI;
+ if (UI != VNUseCount[CurrVN].end())
+ StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
+ }
+ if (UI == VNUseCount[CurrVN].end()) continue;
+
+ MachineInstr* use = *UI;
+
+ // Attempt to fold it away!
+ int OpIdx = use->findRegisterUseOperandIdx((*LI)->reg, false);
+ if (OpIdx == -1) continue;
+ SmallVector<unsigned, 1> Ops;
+ Ops.push_back(OpIdx);
+ if (!TII->canFoldMemoryOperand(use, Ops)) continue;
+
+ MachineInstr* NewMI =
+ TII->foldMemoryOperand(*use->getParent()->getParent(),
+ use, Ops, FrameIndex);
+
+ if (!NewMI) continue;
+
+ // Update relevant analyses.
+ LIs->RemoveMachineInstrFromMaps(DefMI);
+ LIs->ReplaceMachineInstrInMaps(use, NewMI);
+ (*LI)->removeValNo(CurrVN);
+
+ DefMI->eraseFromParent();
+ MachineBasicBlock* MBB = use->getParent();
+ NewMI = MBB->insert(MBB->erase(use), NewMI);
+ VNUseCount[CurrVN].erase(use);
+
+ // Remove deleted instructions. Note that we need to remove them from
+ // the VNInfo->use map as well, just to be safe.
+ for (SmallPtrSet<MachineInstr*, 4>::iterator II =
+ VNUseCount[CurrVN].begin(), IE = VNUseCount[CurrVN].end();
+ II != IE; ++II) {
+ for (DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> >::iterator
+ VNI = VNUseCount.begin(), VNE = VNUseCount.end(); VNI != VNE;
+ ++VNI)
+ if (VNI->first != CurrVN)
+ VNI->second.erase(*II);
+ LIs->RemoveMachineInstrFromMaps(*II);
+ (*II)->eraseFromParent();
+ }
+
+ VNUseCount.erase(CurrVN);
+
+ for (DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> >::iterator
+ VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI)
+ if (VI->second.erase(use))
+ VI->second.insert(NewMI);
+
+ NumDeadSpills++;
+ changed = true;
+ continue;
+ }
+
+ // If there's more than one non-store instruction, we can't profitably
+ // fold it, so bail.
+ if (NonSpillCount) continue;
+
+ // Otherwise, this is a load-store case, so DCE them.
+ for (SmallPtrSet<MachineInstr*, 4>::iterator UI =
+ VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end();
+ UI != UI; ++UI) {
+ LIs->RemoveMachineInstrFromMaps(*UI);
+ (*UI)->eraseFromParent();
+ }
+
+ VNUseCount.erase(CurrVN);
+
+ LIs->RemoveMachineInstrFromMaps(DefMI);
+ (*LI)->removeValNo(CurrVN);
+ DefMI->eraseFromParent();
+ NumDeadSpills++;
+ changed = true;
+ }
+ }
+
+ return changed;
+}
+
bool PreAllocSplitting::createsNewJoin(LiveRange* LR,
MachineBasicBlock* DefMBB,
MachineBasicBlock* BarrierMBB) {
@@ -1443,6 +1355,7 @@ bool PreAllocSplitting::createsNewJoin(LiveRange* LR,
bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
CurrMF = &MF;
TM = &MF.getTarget();
+ TRI = TM->getRegisterInfo();
TII = TM->getInstrInfo();
MFI = MF.getFrameInfo();
MRI = &MF.getRegInfo();
@@ -1457,6 +1370,8 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
MachineBasicBlock *Entry = MF.begin();
SmallPtrSet<MachineBasicBlock*,16> Visited;
+ SmallPtrSet<LiveInterval*, 8> Split;
+
for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
DFI != E; ++DFI) {
@@ -1469,9 +1384,11 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
if (!BarrierRCs)
continue;
BarrierIdx = LIs->getInstructionIndex(Barrier);
- MadeChange |= SplitRegLiveIntervals(BarrierRCs);
+ MadeChange |= SplitRegLiveIntervals(BarrierRCs, Split);
}
}
+ MadeChange |= removeDeadSpills(Split);
+
return MadeChange;
}
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 4ebf742a4c31..39f96133bd19 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -56,7 +56,7 @@ namespace {
// Get MachineModuleInfo so that we can track the construction of the
// frame.
- if (MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>())
+ if (MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>())
Fn.getFrameInfo()->setMachineModuleInfo(MMI);
// Allow the target machine to make some adjustments to the function
diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp
index acd3ddeccf29..a8c69008c24a 100644
--- a/lib/CodeGen/RegAllocLocal.cpp
+++ b/lib/CodeGen/RegAllocLocal.cpp
@@ -27,6 +27,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
@@ -220,10 +221,10 @@ namespace {
/// getReg - Find a physical register to hold the specified virtual
/// register. If all compatible physical registers are used, this method
/// spills the last used virtual register to the stack, and uses that
- /// register.
- ///
+ /// register. If NoFree is true, that means the caller knows there isn't
+ /// a free register, do not call getFreeReg().
unsigned getReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned VirtReg);
+ unsigned VirtReg, bool NoFree = false);
/// reloadVirtReg - This method transforms the specified specified virtual
/// register use to refer to a physical register. This method may do this
@@ -237,7 +238,7 @@ namespace {
/// value. This method returns the modified instruction.
///
MachineInstr *reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned OpNum);
+ unsigned OpNum, SmallSet<unsigned, 4> &RRegs);
/// ComputeLocalLiveness - Computes liveness of registers within a basic
/// block, setting the killed/dead flags as appropriate.
@@ -398,11 +399,11 @@ unsigned RALocal::getFreeReg(const TargetRegisterClass *RC) {
/// the last used virtual register to the stack, and uses that register.
///
unsigned RALocal::getReg(MachineBasicBlock &MBB, MachineInstr *I,
- unsigned VirtReg) {
+ unsigned VirtReg, bool NoFree) {
const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
// First check to see if we have a free register of the requested type...
- unsigned PhysReg = getFreeReg(RC);
+ unsigned PhysReg = NoFree ? 0 : getFreeReg(RC);
// If we didn't find an unused register, scavenge one now!
if (PhysReg == 0) {
@@ -475,7 +476,8 @@ unsigned RALocal::getReg(MachineBasicBlock &MBB, MachineInstr *I,
/// modified instruction.
///
MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ SmallSet<unsigned, 4> &ReloadedRegs) {
unsigned VirtReg = MI->getOperand(OpNum).getReg();
// If the virtual register is already available, just update the instruction
@@ -498,7 +500,7 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
} else { // No registers available.
// Force some poor hapless value out of the register file to
// make room for the new register, and reload it.
- PhysReg = getReg(MBB, MI, VirtReg);
+ PhysReg = getReg(MBB, MI, VirtReg, true);
}
markVirtRegModified(VirtReg, false); // Note that this reg was just reloaded
@@ -513,6 +515,29 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
MF->getRegInfo().setPhysRegUsed(PhysReg);
MI->getOperand(OpNum).setReg(PhysReg); // Assign the input register
getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum);
+
+ if (!ReloadedRegs.insert(PhysReg)) {
+ cerr << "Ran out of registers during register allocation!\n";
+ if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ cerr << "Please check your inline asm statement for invalid "
+ << "constraints:\n";
+ MI->print(cerr.stream(), TM);
+ }
+ exit(1);
+ }
+ for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg);
+ *SubRegs; ++SubRegs) {
+ if (!ReloadedRegs.insert(*SubRegs)) {
+ cerr << "Ran out of registers during register allocation!\n";
+ if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ cerr << "Please check your inline asm statement for invalid "
+ << "constraints:\n";
+ MI->print(cerr.stream(), TM);
+ }
+ exit(1);
+ }
+ }
+
return MI;
}
@@ -581,17 +606,16 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
- const unsigned* subregs = TRI->getAliasSet(MO.getReg());
- if (subregs) {
- while (*subregs) {
+ const unsigned* Aliases = TRI->getAliasSet(MO.getReg());
+ if (Aliases) {
+ while (*Aliases) {
DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
- alias = LastUseDef.find(*subregs);
+ alias = LastUseDef.find(*Aliases);
- if (alias != LastUseDef.end() &&
- alias->second.first != I)
- LastUseDef[*subregs] = std::make_pair(I, i);
+ if (alias != LastUseDef.end() && alias->second.first != I)
+ LastUseDef[*Aliases] = std::make_pair(I, i);
- ++subregs;
+ ++Aliases;
}
}
}
@@ -686,24 +710,21 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
DEBUG(const BasicBlock *LBB = MBB.getBasicBlock();
if (LBB) DOUT << "\nStarting RegAlloc of BB: " << LBB->getName());
- // If this is the first basic block in the machine function, add live-in
- // registers as active.
- if (&MBB == &*MF->begin() || MBB.isLandingPad()) {
- for (MachineBasicBlock::livein_iterator I = MBB.livein_begin(),
+ // Add live-in registers as active.
+ for (MachineBasicBlock::livein_iterator I = MBB.livein_begin(),
E = MBB.livein_end(); I != E; ++I) {
- unsigned Reg = *I;
- MF->getRegInfo().setPhysRegUsed(Reg);
- PhysRegsUsed[Reg] = 0; // It is free and reserved now
- AddToPhysRegsUseOrder(Reg);
- for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
- *AliasSet; ++AliasSet) {
- if (PhysRegsUsed[*AliasSet] != -2) {
- AddToPhysRegsUseOrder(*AliasSet);
- PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
- MF->getRegInfo().setPhysRegUsed(*AliasSet);
- }
+ unsigned Reg = *I;
+ MF->getRegInfo().setPhysRegUsed(Reg);
+ PhysRegsUsed[Reg] = 0; // It is free and reserved now
+ AddToPhysRegsUseOrder(Reg);
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] != -2) {
+ AddToPhysRegsUseOrder(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
}
- }
+ }
}
ComputeLocalLiveness(MBB);
@@ -778,12 +799,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
PhysRegsUsed[Reg] = 0; // It is free and reserved now
AddToPhysRegsUseOrder(Reg);
- for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
- *AliasSet; ++AliasSet) {
- if (PhysRegsUsed[*AliasSet] != -2) {
- MF->getRegInfo().setPhysRegUsed(*AliasSet);
- PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
- AddToPhysRegsUseOrder(*AliasSet);
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] != -2) {
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ AddToPhysRegsUseOrder(*SubRegs);
}
}
}
@@ -797,12 +818,13 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// physical register is referenced by the instruction, that it is guaranteed
// to be live-in, or the input is badly hosed.
//
+ SmallSet<unsigned, 4> ReloadedRegs;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& MO = MI->getOperand(i);
// here we are looking for only used operands (never def&use)
if (MO.isReg() && !MO.isDef() && MO.getReg() && !MO.isImplicit() &&
TargetRegisterInfo::isVirtualRegister(MO.getReg()))
- MI = reloadVirtReg(MBB, MI, i);
+ MI = reloadVirtReg(MBB, MI, i, ReloadedRegs);
}
// If this instruction is the last user of this register, kill the
@@ -830,13 +852,13 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
DOUT << " Last use of " << TRI->getName(PhysReg)
<< "[%reg" << VirtReg <<"], removing it from live set\n";
removePhysReg(PhysReg);
- for (const unsigned *AliasSet = TRI->getSubRegisters(PhysReg);
- *AliasSet; ++AliasSet) {
- if (PhysRegsUsed[*AliasSet] != -2) {
+ for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] != -2) {
DOUT << " Last use of "
- << TRI->getName(*AliasSet)
+ << TRI->getName(*SubRegs)
<< "[%reg" << VirtReg <<"], removing it from live set\n";
- removePhysReg(*AliasSet);
+ removePhysReg(*SubRegs);
}
}
}
@@ -861,12 +883,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
PhysRegsUsed[Reg] = 0; // It is free and reserved now
AddToPhysRegsUseOrder(Reg);
- for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
- *AliasSet; ++AliasSet) {
- if (PhysRegsUsed[*AliasSet] != -2) {
- MF->getRegInfo().setPhysRegUsed(*AliasSet);
- PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
- AddToPhysRegsUseOrder(*AliasSet);
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] != -2) {
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ AddToPhysRegsUseOrder(*SubRegs);
}
}
}
@@ -883,12 +905,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
PhysRegsUsed[Reg] = 0; // It is free and reserved now
}
MF->getRegInfo().setPhysRegUsed(Reg);
- for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
- *AliasSet; ++AliasSet) {
- if (PhysRegsUsed[*AliasSet] != -2) {
- AddToPhysRegsUseOrder(*AliasSet);
- PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
- MF->getRegInfo().setPhysRegUsed(*AliasSet);
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] != -2) {
+ AddToPhysRegsUseOrder(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
}
}
}
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp
index 0ffdd05c2ee1..9541de642423 100644
--- a/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sched-instrs"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
@@ -95,6 +96,82 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
const MachineDominatorTree &mdt)
: ScheduleDAG(mf), MLI(mli), MDT(mdt) {}
+/// getOpcode - If this is an Instruction or a ConstantExpr, return the
+/// opcode value. Otherwise return UserOp1.
+static unsigned getOpcode(const Value *V) {
+ if (const Instruction *I = dyn_cast<Instruction>(V))
+ return I->getOpcode();
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode();
+ // Use UserOp1 to mean there's no opcode.
+ return Instruction::UserOp1;
+}
+
+/// getUnderlyingObjectFromInt - This is the function that does the work of
+/// looking through basic ptrtoint+arithmetic+inttoptr sequences.
+static const Value *getUnderlyingObjectFromInt(const Value *V) {
+ do {
+ if (const User *U = dyn_cast<User>(V)) {
+ // If we find a ptrtoint, we can transfer control back to the
+ // regular getUnderlyingObjectFromInt.
+ if (getOpcode(U) == Instruction::PtrToInt)
+ return U->getOperand(0);
+ // If we find an add of a constant or a multiplied value, it's
+ // likely that the other operand will lead us to the base
+ // object. We don't have to worry about the case where the
+ // object address is somehow being computed bt the multiply,
+ // because our callers only care when the result is an
+ // identifibale object.
+ if (getOpcode(U) != Instruction::Add ||
+ (!isa<ConstantInt>(U->getOperand(1)) &&
+ getOpcode(U->getOperand(1)) != Instruction::Mul))
+ return V;
+ V = U->getOperand(0);
+ } else {
+ return V;
+ }
+ assert(isa<IntegerType>(V->getType()) && "Unexpected operand type!");
+ } while (1);
+}
+
+/// getUnderlyingObject - This is a wrapper around Value::getUnderlyingObject
+/// and adds support for basic ptrtoint+arithmetic+inttoptr sequences.
+static const Value *getUnderlyingObject(const Value *V) {
+ // First just call Value::getUnderlyingObject to let it do what it does.
+ do {
+ V = V->getUnderlyingObject();
+ // If it found an inttoptr, use special code to continue climing.
+ if (getOpcode(V) != Instruction::IntToPtr)
+ 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()))
+ break;
+ V = O;
+ } while (1);
+ return V;
+}
+
+/// getUnderlyingObjectForInstr - If this machine instr has memory reference
+/// information and it can be tracked to a normal reference to a known
+/// object, return the Value for that object. Otherwise return null.
+static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI) {
+ if (!MI->hasOneMemOperand() ||
+ !MI->memoperands_begin()->getValue() ||
+ MI->memoperands_begin()->isVolatile())
+ return 0;
+
+ const Value *V = MI->memoperands_begin()->getValue();
+ if (!V)
+ return 0;
+
+ V = getUnderlyingObject(V);
+ if (!isa<PseudoSourceValue>(V) && !isIdentifiedObject(V))
+ return 0;
+
+ return V;
+}
+
void ScheduleDAGInstrs::BuildSchedGraph() {
SUnits.reserve(BB->size());
@@ -313,12 +390,8 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
// Unknown memory accesses. Assume the worst.
ChainMMO = 0;
} else if (TID.mayStore()) {
- if (MI->hasOneMemOperand() &&
- MI->memoperands_begin()->getValue() &&
- !MI->memoperands_begin()->isVolatile() &&
- isa<PseudoSourceValue>(MI->memoperands_begin()->getValue())) {
+ if (const Value *V = getUnderlyingObjectForInstr(MI)) {
// A store to a specific PseudoSourceValue. Add precise dependencies.
- const Value *V = MI->memoperands_begin()->getValue();
// Handle the def in MemDefs, if there is one.
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
if (I != MemDefs.end()) {
@@ -337,6 +410,10 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
/*isNormalMemory=*/true));
J->second.clear();
}
+ // Add dependencies from all the PendingLoads, since without
+ // memoperands we must assume they alias anything.
+ for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
+ PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency));
// Add a general dependence too, if needed.
if (Chain)
Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
@@ -346,12 +423,8 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
} else if (TID.mayLoad()) {
if (TII->isInvariantLoad(MI)) {
// Invariant load, no chain dependencies needed!
- } else if (MI->hasOneMemOperand() &&
- MI->memoperands_begin()->getValue() &&
- !MI->memoperands_begin()->isVolatile() &&
- isa<PseudoSourceValue>(MI->memoperands_begin()->getValue())) {
+ } else if (const Value *V = getUnderlyingObjectForInstr(MI)) {
// A load from a specific PseudoSourceValue. Add precise dependencies.
- const Value *V = MI->memoperands_begin()->getValue();
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
if (I != MemDefs.end())
I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0,
@@ -367,9 +440,15 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
// cases where memoperand information is unavailable.
goto new_chain;
} else {
- // A normal load. Just depend on the general chain.
+ // A normal load. Depend on the general chain, as well as on
+ // all stores. In the absense of MachineMemOperand information,
+ // we can't even assume that the load doesn't alias well-behaved
+ // memory locations.
if (Chain)
Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
+ for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
+ E = MemDefs.end(); I != E; ++I)
+ I->second->addPred(SDep(SU, SDep::Order, SU->Latency));
PendingLoads.push_back(SU);
}
}
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 8d0c82a0b808..ebe471083e82 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -102,6 +102,8 @@ namespace {
SDValue To[] = { Res0, Res1 };
return CombineTo(N, To, 2, AddTo);
}
+
+ void CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO);
private:
@@ -194,25 +196,25 @@ namespace {
SDValue visitVECTOR_SHUFFLE(SDNode *N);
SDValue XformToShuffleWithZero(SDNode *N);
- SDValue ReassociateOps(unsigned Opc, SDValue LHS, SDValue RHS);
+ SDValue ReassociateOps(unsigned Opc, DebugLoc DL, SDValue LHS, SDValue RHS);
SDValue visitShiftByConstant(SDNode *N, unsigned Amt);
bool SimplifySelectOps(SDNode *SELECT, SDValue LHS, SDValue RHS);
SDValue SimplifyBinOpWithSameOpcodeHands(SDNode *N);
- SDValue SimplifySelect(SDValue N0, SDValue N1, SDValue N2);
- SDValue SimplifySelectCC(SDValue N0, SDValue N1, SDValue N2,
- SDValue N3, ISD::CondCode CC,
- bool NotExtCompare = false);
+ SDValue SimplifySelect(DebugLoc DL, SDValue N0, SDValue N1, SDValue N2);
+ SDValue SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue N2,
+ SDValue N3, ISD::CondCode CC,
+ bool NotExtCompare = false);
SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
- bool foldBooleans = true);
+ DebugLoc DL, bool foldBooleans = true);
SDValue SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
unsigned HiOp);
SDValue CombineConsecutiveLoads(SDNode *N, MVT VT);
SDValue ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *, MVT);
SDValue BuildSDIV(SDNode *N);
SDValue BuildUDIV(SDNode *N);
- SDNode *MatchRotate(SDValue LHS, SDValue RHS);
+ SDNode *MatchRotate(SDValue LHS, SDValue RHS, DebugLoc DL);
SDValue ReduceLoadWidth(SDNode *N);
SDValue GetDemandedBits(SDValue V, const APInt &Mask);
@@ -227,18 +229,24 @@ namespace {
bool isAlias(SDValue Ptr1, int64_t Size1,
const Value *SrcValue1, int SrcValueOffset1,
SDValue Ptr2, int64_t Size2,
- const Value *SrcValue2, int SrcValueOffset2);
+ const Value *SrcValue2, int SrcValueOffset2) const;
/// FindAliasInfo - Extracts the relevant alias information from the memory
/// node. Returns true if the operand was a load.
bool FindAliasInfo(SDNode *N,
SDValue &Ptr, int64_t &Size,
- const Value *&SrcValue, int &SrcValueOffset);
+ const Value *&SrcValue, int &SrcValueOffset) const;
/// FindBetterChain - Walk up chain skipping non-aliasing memory nodes,
/// looking for a better chain (aliasing node.)
SDValue FindBetterChain(SDNode *N, SDValue Chain);
-
+
+ /// getShiftAmountTy - Returns a type large enough to hold any valid
+ /// shift amount - before type legalization these can be huge.
+ MVT getShiftAmountTy() {
+ return LegalTypes ? TLI.getShiftAmountTy() : TLI.getPointerTy();
+ }
+
public:
DAGCombiner(SelectionDAG &D, AliasAnalysis &A, bool fast)
: DAG(D),
@@ -298,6 +306,10 @@ CombineTo(SDNode *N, SDValue Res0, SDValue Res1) {
return ((DAGCombiner*)DC)->CombineTo(N, Res0, Res1);
}
+void TargetLowering::DAGCombinerInfo::
+CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO) {
+ return ((DAGCombiner*)DC)->CommitTargetLoweringOpt(TLO);
+}
//===----------------------------------------------------------------------===//
// Helper Functions
@@ -331,23 +343,23 @@ static char isNegatibleForFree(SDValue Op, bool LegalOperations,
// FIXME: determine better conditions for this xform.
if (!UnsafeFPMath) return 0;
- // -(A+B) -> -A - B
+ // fold (fsub (fadd A, B)) -> (fsub (fneg A), B)
if (char V = isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1))
return V;
- // -(A+B) -> -B - A
+ // fold (fneg (fadd A, B)) -> (fsub (fneg B), A)
return isNegatibleForFree(Op.getOperand(1), LegalOperations, Depth+1);
case ISD::FSUB:
// We can't turn -(A-B) into B-A when we honor signed zeros.
if (!UnsafeFPMath) return 0;
- // -(A-B) -> B-A
+ // fold (fneg (fsub A, B)) -> (fsub B, A)
return 1;
case ISD::FMUL:
case ISD::FDIV:
if (HonorSignDependentRoundingFPMath()) return 0;
- // -(X*Y) -> (-X * Y) or (X*-Y)
+ // fold (fneg (fmul X, Y)) -> (fmul (fneg X), Y) or (fmul X, (fneg Y))
if (char V = isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1))
return V;
@@ -382,14 +394,14 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG,
// FIXME: determine better conditions for this xform.
assert(UnsafeFPMath);
- // -(A+B) -> -A - B
+ // fold (fneg (fadd A, B)) -> (fsub (fneg A), B)
if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1))
- return DAG.getNode(ISD::FSUB, Op.getValueType(),
+ return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(),
GetNegatedExpression(Op.getOperand(0), DAG,
LegalOperations, Depth+1),
Op.getOperand(1));
- // -(A+B) -> -B - A
- return DAG.getNode(ISD::FSUB, Op.getValueType(),
+ // fold (fneg (fadd A, B)) -> (fsub (fneg B), A)
+ return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(),
GetNegatedExpression(Op.getOperand(1), DAG,
LegalOperations, Depth+1),
Op.getOperand(0));
@@ -397,39 +409,39 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG,
// We can't turn -(A-B) into B-A when we honor signed zeros.
assert(UnsafeFPMath);
- // -(0-B) -> B
+ // fold (fneg (fsub 0, B)) -> B
if (ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(Op.getOperand(0)))
if (N0CFP->getValueAPF().isZero())
return Op.getOperand(1);
- // -(A-B) -> B-A
- return DAG.getNode(ISD::FSUB, Op.getValueType(), Op.getOperand(1),
- Op.getOperand(0));
+ // fold (fneg (fsub A, B)) -> (fsub B, A)
+ return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(),
+ Op.getOperand(1), Op.getOperand(0));
case ISD::FMUL:
case ISD::FDIV:
assert(!HonorSignDependentRoundingFPMath());
- // -(X*Y) -> -X * Y
+ // fold (fneg (fmul X, Y)) -> (fmul (fneg X), Y)
if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1))
- return DAG.getNode(Op.getOpcode(), Op.getValueType(),
+ return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(),
GetNegatedExpression(Op.getOperand(0), DAG,
LegalOperations, Depth+1),
Op.getOperand(1));
- // -(X*Y) -> X * -Y
- return DAG.getNode(Op.getOpcode(), Op.getValueType(),
+ // fold (fneg (fmul X, Y)) -> (fmul X, (fneg Y))
+ return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(),
Op.getOperand(0),
GetNegatedExpression(Op.getOperand(1), DAG,
LegalOperations, Depth+1));
case ISD::FP_EXTEND:
case ISD::FSIN:
- return DAG.getNode(Op.getOpcode(), Op.getValueType(),
+ return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(),
GetNegatedExpression(Op.getOperand(0), DAG,
LegalOperations, Depth+1));
case ISD::FP_ROUND:
- return DAG.getNode(ISD::FP_ROUND, Op.getValueType(),
+ return DAG.getNode(ISD::FP_ROUND, Op.getDebugLoc(), Op.getValueType(),
GetNegatedExpression(Op.getOperand(0), DAG,
LegalOperations, Depth+1),
Op.getOperand(1));
@@ -473,34 +485,43 @@ static bool isOneUseSetCC(SDValue N) {
return false;
}
-SDValue DAGCombiner::ReassociateOps(unsigned Opc, SDValue N0, SDValue N1){
+SDValue DAGCombiner::ReassociateOps(unsigned Opc, DebugLoc DL,
+ SDValue N0, SDValue N1) {
MVT VT = N0.getValueType();
- // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
- // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
if (N0.getOpcode() == Opc && isa<ConstantSDNode>(N0.getOperand(1))) {
if (isa<ConstantSDNode>(N1)) {
- SDValue OpNode = DAG.getNode(Opc, VT, N0.getOperand(1), N1);
- AddToWorkList(OpNode.getNode());
- return DAG.getNode(Opc, VT, OpNode, N0.getOperand(0));
+ // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
+ SDValue OpNode =
+ DAG.FoldConstantArithmetic(Opc, VT,
+ cast<ConstantSDNode>(N0.getOperand(1)),
+ cast<ConstantSDNode>(N1));
+ return DAG.getNode(Opc, DL, VT, N0.getOperand(0), OpNode);
} else if (N0.hasOneUse()) {
- SDValue OpNode = DAG.getNode(Opc, VT, N0.getOperand(0), N1);
+ // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
+ SDValue OpNode = DAG.getNode(Opc, N0.getDebugLoc(), VT,
+ N0.getOperand(0), N1);
AddToWorkList(OpNode.getNode());
- return DAG.getNode(Opc, VT, OpNode, N0.getOperand(1));
+ return DAG.getNode(Opc, DL, VT, OpNode, N0.getOperand(1));
}
}
- // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
- // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2))
+
if (N1.getOpcode() == Opc && isa<ConstantSDNode>(N1.getOperand(1))) {
if (isa<ConstantSDNode>(N0)) {
- SDValue OpNode = DAG.getNode(Opc, VT, N1.getOperand(1), N0);
- AddToWorkList(OpNode.getNode());
- return DAG.getNode(Opc, VT, OpNode, N1.getOperand(0));
+ // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2))
+ SDValue OpNode =
+ DAG.FoldConstantArithmetic(Opc, VT,
+ cast<ConstantSDNode>(N1.getOperand(1)),
+ cast<ConstantSDNode>(N0));
+ return DAG.getNode(Opc, DL, VT, N1.getOperand(0), OpNode);
} else if (N1.hasOneUse()) {
- SDValue OpNode = DAG.getNode(Opc, VT, N1.getOperand(0), N0);
+ // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
+ SDValue OpNode = DAG.getNode(Opc, N0.getDebugLoc(), VT,
+ N1.getOperand(0), N0);
AddToWorkList(OpNode.getNode());
- return DAG.getNode(Opc, VT, OpNode, N1.getOperand(1));
+ return DAG.getNode(Opc, DL, VT, OpNode, N1.getOperand(1));
}
}
+
return SDValue();
}
@@ -539,29 +560,14 @@ SDValue DAGCombiner::CombineTo(SDNode *N, const SDValue *To, unsigned NumTo,
return SDValue(N, 0);
}
-/// SimplifyDemandedBits - Check the specified integer node value to see if
-/// it can be simplified or if things it uses can be simplified by bit
-/// propagation. If so, return true.
-bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
- TargetLowering::TargetLoweringOpt TLO(DAG);
- APInt KnownZero, KnownOne;
- if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO))
- return false;
-
- // Revisit the node.
- AddToWorkList(Op.getNode());
-
- // Replace the old value with the new one.
- ++NodesCombined;
- DOUT << "\nReplacing.2 "; DEBUG(TLO.Old.getNode()->dump(&DAG));
- DOUT << "\nWith: "; DEBUG(TLO.New.getNode()->dump(&DAG));
- DOUT << '\n';
-
+void
+DAGCombiner::CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &
+ TLO) {
// Replace all uses. If any nodes become isomorphic to other nodes and
// are deleted, make sure to remove them from our worklist.
WorkListRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, &DeadNodes);
-
+
// Push the new node and any (possibly new) users onto the worklist.
AddToWorkList(TLO.New.getNode());
AddUsersToWorkList(TLO.New.getNode());
@@ -580,6 +586,27 @@ bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
DAG.DeleteNode(TLO.Old.getNode());
}
+}
+
+/// SimplifyDemandedBits - Check the specified integer node value to see if
+/// it can be simplified or if things it uses can be simplified by bit
+/// propagation. If so, return true.
+bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
+ TargetLowering::TargetLoweringOpt TLO(DAG);
+ APInt KnownZero, KnownOne;
+ if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO))
+ return false;
+
+ // Revisit the node.
+ AddToWorkList(Op.getNode());
+
+ // Replace the old value with the new one.
+ ++NodesCombined;
+ DOUT << "\nReplacing.2 "; DEBUG(TLO.Old.getNode()->dump(&DAG));
+ DOUT << "\nWith: "; DEBUG(TLO.New.getNode()->dump(&DAG));
+ DOUT << '\n';
+
+ CommitTargetLoweringOpt(TLO);
return true;
}
@@ -751,7 +778,6 @@ SDValue DAGCombiner::visit(SDNode *N) {
}
SDValue DAGCombiner::combine(SDNode *N) {
-
SDValue RV = visit(N);
// If nothing happened, try a target-specific DAG combine.
@@ -777,6 +803,7 @@ SDValue DAGCombiner::combine(SDNode *N) {
N->getNumValues() == 1) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
+
// Constant operands are canonicalized to RHS.
if (isa<ConstantSDNode>(N0) || !isa<ConstantSDNode>(N1)) {
SDValue Ops[] = { N1, N0 };
@@ -802,7 +829,7 @@ static SDValue getInputChainForNode(SDNode *N) {
if (N->getOperand(i).getValueType() == MVT::Other)
return N->getOperand(i);
}
- return SDValue(0, 0);
+ return SDValue();
}
SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
@@ -871,9 +898,10 @@ SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
Result = DAG.getEntryNode();
} else {
// New and improved token factor.
- Result = DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0], Ops.size());
+ Result = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(),
+ MVT::Other, &Ops[0], Ops.size());
}
-
+
// Don't add users to work list.
return CombineTo(N, Result, false);
}
@@ -892,20 +920,25 @@ SDValue DAGCombiner::visitMERGE_VALUES(SDNode *N) {
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
-
static
-SDValue combineShlAddConstant(SDValue N0, SDValue N1, SelectionDAG &DAG) {
+SDValue combineShlAddConstant(DebugLoc DL, SDValue N0, SDValue N1,
+ SelectionDAG &DAG) {
MVT VT = N0.getValueType();
SDValue N00 = N0.getOperand(0);
SDValue N01 = N0.getOperand(1);
ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N01);
+
if (N01C && N00.getOpcode() == ISD::ADD && N00.getNode()->hasOneUse() &&
isa<ConstantSDNode>(N00.getOperand(1))) {
- N0 = DAG.getNode(ISD::ADD, VT,
- DAG.getNode(ISD::SHL, VT, N00.getOperand(0), N01),
- DAG.getNode(ISD::SHL, VT, N00.getOperand(1), N01));
- return DAG.getNode(ISD::ADD, VT, N0, N1);
+ // fold (add (shl (add x, c1), c2), ) -> (add (add (shl x, c2), c1<<c2), )
+ N0 = DAG.getNode(ISD::ADD, N0.getDebugLoc(), VT,
+ DAG.getNode(ISD::SHL, N00.getDebugLoc(), VT,
+ N00.getOperand(0), N01),
+ DAG.getNode(ISD::SHL, N01.getDebugLoc(), VT,
+ N00.getOperand(1), N01));
+ return DAG.getNode(ISD::ADD, DL, VT, N0, N1);
}
+
return SDValue();
}
@@ -954,15 +987,16 @@ SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp,
}
if (DoXform) {
- SDValue Result = DAG.getNode(Opc, VT, OtherOp, RHS);
+ SDValue Result = DAG.getNode(Opc, RHS.getDebugLoc(), VT, OtherOp, RHS);
if (isSlctCC)
- return DAG.getSelectCC(OtherOp, Result,
+ return DAG.getSelectCC(N->getDebugLoc(), OtherOp, Result,
Slct.getOperand(0), Slct.getOperand(1), CC);
SDValue CCOp = Slct.getOperand(0);
if (InvCC)
- CCOp = DAG.getSetCC(CCOp.getValueType(), CCOp.getOperand(0),
- CCOp.getOperand(1), CC);
- return DAG.getNode(ISD::SELECT, VT, CCOp, OtherOp, Result);
+ CCOp = DAG.getSetCC(Slct.getDebugLoc(), CCOp.getValueType(),
+ CCOp.getOperand(0), CCOp.getOperand(1), CC);
+ return DAG.getNode(ISD::SELECT, N->getDebugLoc(), VT,
+ CCOp, OtherOp, Result);
}
return SDValue();
}
@@ -990,7 +1024,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::ADD, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
- return DAG.getNode(ISD::ADD, VT, N1, N0);
+ return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0);
// fold (add x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
@@ -1004,22 +1038,22 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
// fold ((c1-A)+c2) -> (c1+c2)-A
if (N1C && N0.getOpcode() == ISD::SUB)
if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.getOperand(0)))
- return DAG.getNode(ISD::SUB, VT,
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
DAG.getConstant(N1C->getAPIntValue()+
N0C->getAPIntValue(), VT),
N0.getOperand(1));
// reassociate add
- SDValue RADD = ReassociateOps(ISD::ADD, N0, N1);
+ SDValue RADD = ReassociateOps(ISD::ADD, N->getDebugLoc(), N0, N1);
if (RADD.getNode() != 0)
return RADD;
// fold ((0-A) + B) -> B-A
if (N0.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N0.getOperand(0)) &&
cast<ConstantSDNode>(N0.getOperand(0))->isNullValue())
- return DAG.getNode(ISD::SUB, VT, N1, N0.getOperand(1));
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N1, N0.getOperand(1));
// fold (A + (0-B)) -> A-B
if (N1.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N1.getOperand(0)) &&
cast<ConstantSDNode>(N1.getOperand(0))->isNullValue())
- return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(1));
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0, N1.getOperand(1));
// fold (A+(B-A)) -> B
if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1))
return N1.getOperand(0);
@@ -1028,23 +1062,20 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
return N0.getOperand(0);
// fold (A+(B-(A+C))) to (B-C)
if (N1.getOpcode() == ISD::SUB && N1.getOperand(1).getOpcode() == ISD::ADD &&
- N0 == N1.getOperand(1).getOperand(0)) {
- return DAG.getNode(ISD::SUB, VT, N1.getOperand(0),
+ N0 == N1.getOperand(1).getOperand(0))
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N1.getOperand(0),
N1.getOperand(1).getOperand(1));
- }
// fold (A+(B-(C+A))) to (B-C)
if (N1.getOpcode() == ISD::SUB && N1.getOperand(1).getOpcode() == ISD::ADD &&
- N0 == N1.getOperand(1).getOperand(1)) {
- return DAG.getNode(ISD::SUB, VT, N1.getOperand(0),
+ N0 == N1.getOperand(1).getOperand(1))
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N1.getOperand(0),
N1.getOperand(1).getOperand(0));
- }
// fold (A+((B-A)+or-C)) to (B+or-C)
if ((N1.getOpcode() == ISD::SUB || N1.getOpcode() == ISD::ADD) &&
N1.getOperand(0).getOpcode() == ISD::SUB &&
- N0 == N1.getOperand(0).getOperand(1)) {
- return DAG.getNode(N1.getOpcode(), VT, N1.getOperand(0).getOperand(0),
- N1.getOperand(1));
- }
+ N0 == N1.getOperand(0).getOperand(1))
+ return DAG.getNode(N1.getOpcode(), N->getDebugLoc(), VT,
+ N1.getOperand(0).getOperand(0), N1.getOperand(1));
// fold (A-B)+(C-D) to (A+C)-(B+D) when A or C is constant
if (N0.getOpcode() == ISD::SUB && N1.getOpcode() == ISD::SUB) {
@@ -1052,11 +1083,11 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
SDValue N01 = N0.getOperand(1);
SDValue N10 = N1.getOperand(0);
SDValue N11 = N1.getOperand(1);
- if (isa<ConstantSDNode>(N00) || isa<ConstantSDNode>(N10)) {
- return DAG.getNode(ISD::SUB, VT,
- DAG.getNode(ISD::ADD, VT, N00, N10),
- DAG.getNode(ISD::ADD, VT, N01, N11));
- }
+
+ if (isa<ConstantSDNode>(N00) || isa<ConstantSDNode>(N10))
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
+ DAG.getNode(ISD::ADD, N0.getDebugLoc(), VT, N00, N10),
+ DAG.getNode(ISD::ADD, N1.getDebugLoc(), VT, N01, N11));
}
if (!VT.isVector() && SimplifyDemandedBits(SDValue(N, 0)))
@@ -1068,6 +1099,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
APInt RHSZero, RHSOne;
APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
DAG.ComputeMaskedBits(N0, Mask, LHSZero, LHSOne);
+
if (LHSZero.getBoolValue()) {
DAG.ComputeMaskedBits(N1, Mask, RHSZero, RHSOne);
@@ -1075,17 +1107,17 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
// If all possibly-set bits on the RHS are clear on the LHS, return an OR.
if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) ||
(LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask))
- return DAG.getNode(ISD::OR, VT, N0, N1);
+ return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N1);
}
}
// fold (add (shl (add x, c1), c2), ) -> (add (add (shl x, c2), c1<<c2), )
if (N0.getOpcode() == ISD::SHL && N0.getNode()->hasOneUse()) {
- SDValue Result = combineShlAddConstant(N0, N1, DAG);
+ SDValue Result = combineShlAddConstant(N->getDebugLoc(), N0, N1, DAG);
if (Result.getNode()) return Result;
}
if (N1.getOpcode() == ISD::SHL && N1.getNode()->hasOneUse()) {
- SDValue Result = combineShlAddConstant(N1, N0, DAG);
+ SDValue Result = combineShlAddConstant(N->getDebugLoc(), N1, N0, DAG);
if (Result.getNode()) return Result;
}
@@ -1111,22 +1143,25 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
// If the flag result is dead, turn this into an ADD.
if (N->hasNUsesOfValue(0, 1))
- return CombineTo(N, DAG.getNode(ISD::ADD, VT, N1, N0),
- DAG.getNode(ISD::CARRY_FALSE, MVT::Flag));
+ return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0),
+ DAG.getNode(ISD::CARRY_FALSE,
+ N->getDebugLoc(), MVT::Flag));
// canonicalize constant to RHS.
if (N0C && !N1C)
- return DAG.getNode(ISD::ADDC, N->getVTList(), N1, N0);
+ return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0);
// fold (addc x, 0) -> x + no carry out
if (N1C && N1C->isNullValue())
- return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE, MVT::Flag));
+ return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE,
+ N->getDebugLoc(), MVT::Flag));
// 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());
DAG.ComputeMaskedBits(N0, Mask, LHSZero, LHSOne);
+
if (LHSZero.getBoolValue()) {
DAG.ComputeMaskedBits(N1, Mask, RHSZero, RHSOne);
@@ -1134,8 +1169,9 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
// If all possibly-set bits on the RHS are clear on the LHS, return an OR.
if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) ||
(LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask))
- return CombineTo(N, DAG.getNode(ISD::OR, VT, N0, N1),
- DAG.getNode(ISD::CARRY_FALSE, MVT::Flag));
+ return CombineTo(N, DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N1),
+ DAG.getNode(ISD::CARRY_FALSE,
+ N->getDebugLoc(), MVT::Flag));
}
return SDValue();
@@ -1147,21 +1183,19 @@ SDValue DAGCombiner::visitADDE(SDNode *N) {
SDValue CarryIn = N->getOperand(2);
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
- //MVT VT = N0.getValueType();
// canonicalize constant to RHS
if (N0C && !N1C)
- return DAG.getNode(ISD::ADDE, N->getVTList(), N1, N0, CarryIn);
+ return DAG.getNode(ISD::ADDE, N->getDebugLoc(), N->getVTList(),
+ N1, N0, CarryIn);
// fold (adde x, y, false) -> (addc x, y)
if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
- return DAG.getNode(ISD::ADDC, N->getVTList(), N1, N0);
+ return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0);
return SDValue();
}
-
-
SDValue DAGCombiner::visitSUB(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -1183,7 +1217,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::SUB, VT, N0C, N1C);
// fold (sub x, c) -> (add x, -c)
if (N1C)
- return DAG.getNode(ISD::ADD, VT, N0,
+ return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0,
DAG.getConstant(-N1C->getAPIntValue(), VT));
// fold (A+B)-A -> B
if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1)
@@ -1196,25 +1230,26 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
(N0.getOperand(1).getOpcode() == ISD::SUB ||
N0.getOperand(1).getOpcode() == ISD::ADD) &&
N0.getOperand(1).getOperand(0) == N1)
- return DAG.getNode(N0.getOperand(1).getOpcode(), VT, N0.getOperand(0),
- N0.getOperand(1).getOperand(1));
+ return DAG.getNode(N0.getOperand(1).getOpcode(), N->getDebugLoc(), VT,
+ N0.getOperand(0), N0.getOperand(1).getOperand(1));
// fold ((A+(C+B))-B) -> A+C
if (N0.getOpcode() == ISD::ADD &&
N0.getOperand(1).getOpcode() == ISD::ADD &&
N0.getOperand(1).getOperand(1) == N1)
- return DAG.getNode(ISD::ADD, VT, N0.getOperand(0),
- N0.getOperand(1).getOperand(0));
+ return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT,
+ N0.getOperand(0), N0.getOperand(1).getOperand(0));
// fold ((A-(B-C))-C) -> A-B
if (N0.getOpcode() == ISD::SUB &&
N0.getOperand(1).getOpcode() == ISD::SUB &&
N0.getOperand(1).getOperand(1) == N1)
- return DAG.getNode(ISD::SUB, VT, N0.getOperand(0),
- N0.getOperand(1).getOperand(0));
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
+ N0.getOperand(0), N0.getOperand(1).getOperand(0));
// fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) {
SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, LegalOperations);
if (Result.getNode()) return Result;
}
+
// If either operand of a sub is undef, the result is undef
if (N0.getOpcode() == ISD::UNDEF)
return N0;
@@ -1260,34 +1295,36 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::MUL, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
- return DAG.getNode(ISD::MUL, VT, N1, N0);
+ return DAG.getNode(ISD::MUL, N->getDebugLoc(), VT, N1, N0);
// fold (mul x, 0) -> 0
if (N1C && N1C->isNullValue())
return N1;
// fold (mul x, -1) -> 0-x
if (N1C && N1C->isAllOnesValue())
- return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0);
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
+ DAG.getConstant(0, VT), N0);
// fold (mul x, (1 << c)) -> x << c
if (N1C && N1C->getAPIntValue().isPowerOf2())
- return DAG.getNode(ISD::SHL, VT, N0,
+ return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
DAG.getConstant(N1C->getAPIntValue().logBase2(),
- TLI.getShiftAmountTy()));
+ getShiftAmountTy()));
// fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c
- if (N1C && isPowerOf2_64(-N1C->getSExtValue())) {
+ if (N1C && isPowerOf2_64(-N1C->getSExtValue()))
// FIXME: If the input is something that is easily negated (e.g. a
// single-use add), we should put the negate there.
- return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT),
- DAG.getNode(ISD::SHL, VT, N0,
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
+ DAG.getConstant(0, VT),
+ DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
DAG.getConstant(Log2_64(-N1C->getSExtValue()),
- TLI.getShiftAmountTy())));
- }
-
+ getShiftAmountTy())));
// (mul (shl X, c1), c2) -> (mul X, c2 << c1)
- if (N1C && N0.getOpcode() == ISD::SHL &&
+ if (N1C && N0.getOpcode() == ISD::SHL &&
isa<ConstantSDNode>(N0.getOperand(1))) {
- SDValue C3 = DAG.getNode(ISD::SHL, VT, N1, N0.getOperand(1));
+ SDValue C3 = DAG.getNode(ISD::SHL, N->getDebugLoc(), VT,
+ N1, N0.getOperand(1));
AddToWorkList(C3.getNode());
- return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), C3);
+ return DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
+ N0.getOperand(0), C3);
}
// Change (mul (shl X, C), Y) -> (shl (mul X, Y), C) when the shift has one
@@ -1303,21 +1340,26 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
N1.getNode()->hasOneUse()) {
Sh = N1; Y = N0;
}
+
if (Sh.getNode()) {
- SDValue Mul = DAG.getNode(ISD::MUL, VT, Sh.getOperand(0), Y);
- return DAG.getNode(ISD::SHL, VT, Mul, Sh.getOperand(1));
+ SDValue Mul = DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
+ Sh.getOperand(0), Y);
+ return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT,
+ Mul, Sh.getOperand(1));
}
}
+
// fold (mul (add x, c1), c2) -> (add (mul x, c2), c1*c2)
if (N1C && N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse() &&
- isa<ConstantSDNode>(N0.getOperand(1))) {
- return DAG.getNode(ISD::ADD, VT,
- DAG.getNode(ISD::MUL, VT, N0.getOperand(0), N1),
- DAG.getNode(ISD::MUL, VT, N0.getOperand(1), N1));
- }
+ isa<ConstantSDNode>(N0.getOperand(1)))
+ return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT,
+ DAG.getNode(ISD::MUL, N0.getDebugLoc(), VT,
+ N0.getOperand(0), N1),
+ DAG.getNode(ISD::MUL, N1.getDebugLoc(), VT,
+ N0.getOperand(1), N1));
// reassociate mul
- SDValue RMUL = ReassociateOps(ISD::MUL, N0, N1);
+ SDValue RMUL = ReassociateOps(ISD::MUL, N->getDebugLoc(), N0, N1);
if (RMUL.getNode() != 0)
return RMUL;
@@ -1345,12 +1387,14 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
return N0;
// fold (sdiv X, -1) -> 0-X
if (N1C && N1C->isAllOnesValue())
- return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0);
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
+ DAG.getConstant(0, VT), N0);
// If we know the sign bits of both operands are zero, strength reduce to a
// udiv instead. Handles (X&15) /s 4 -> X&15 >> 2
if (!VT.isVector()) {
if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
- return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
+ return DAG.getNode(ISD::UDIV, N->getDebugLoc(), N1.getValueType(),
+ N0, N1);
}
// fold (sdiv X, pow2) -> simple ops after legalize
if (N1C && !N1C->isNullValue() && !TLI.isIntDivCheap() &&
@@ -1360,30 +1404,37 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
// fold.
if (TLI.isPow2DivCheap())
return SDValue();
+
int64_t pow2 = N1C->getSExtValue();
int64_t abs2 = pow2 > 0 ? pow2 : -pow2;
unsigned lg2 = Log2_64(abs2);
+
// Splat the sign bit into the register
- SDValue SGN = DAG.getNode(ISD::SRA, VT, N0,
- DAG.getConstant(VT.getSizeInBits()-1,
- TLI.getShiftAmountTy()));
+ SDValue SGN = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0,
+ DAG.getConstant(VT.getSizeInBits()-1,
+ getShiftAmountTy()));
AddToWorkList(SGN.getNode());
+
// Add (N0 < 0) ? abs2 - 1 : 0;
- SDValue SRL = DAG.getNode(ISD::SRL, VT, SGN,
- DAG.getConstant(VT.getSizeInBits()-lg2,
- TLI.getShiftAmountTy()));
- SDValue ADD = DAG.getNode(ISD::ADD, VT, N0, SRL);
+ SDValue SRL = DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, SGN,
+ DAG.getConstant(VT.getSizeInBits() - lg2,
+ getShiftAmountTy()));
+ SDValue ADD = DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0, SRL);
AddToWorkList(SRL.getNode());
AddToWorkList(ADD.getNode()); // Divide by pow2
- SDValue SRA = DAG.getNode(ISD::SRA, VT, ADD,
- DAG.getConstant(lg2, TLI.getShiftAmountTy()));
+ SDValue SRA = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, ADD,
+ DAG.getConstant(lg2, getShiftAmountTy()));
+
// If we're dividing by a positive value, we're done. Otherwise, we must
// negate the result.
if (pow2 > 0)
return SRA;
+
AddToWorkList(SRA.getNode());
- return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), SRA);
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
+ DAG.getConstant(0, VT), SRA);
}
+
// if integer divide is expensive and we satisfy the requirements, emit an
// alternate sequence.
if (N1C && (N1C->getSExtValue() < -1 || N1C->getSExtValue() > 1) &&
@@ -1420,20 +1471,21 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::UDIV, VT, N0C, N1C);
// fold (udiv x, (1 << c)) -> x >>u c
if (N1C && N1C->getAPIntValue().isPowerOf2())
- return DAG.getNode(ISD::SRL, VT, N0,
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0,
DAG.getConstant(N1C->getAPIntValue().logBase2(),
- TLI.getShiftAmountTy()));
+ getShiftAmountTy()));
// fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2
if (N1.getOpcode() == ISD::SHL) {
if (ConstantSDNode *SHC = dyn_cast<ConstantSDNode>(N1.getOperand(0))) {
if (SHC->getAPIntValue().isPowerOf2()) {
MVT ADDVT = N1.getOperand(1).getValueType();
- SDValue Add = DAG.getNode(ISD::ADD, ADDVT, N1.getOperand(1),
- DAG.getConstant(SHC->getAPIntValue()
- .logBase2(),
- ADDVT));
+ SDValue Add = DAG.getNode(ISD::ADD, N->getDebugLoc(), ADDVT,
+ N1.getOperand(1),
+ DAG.getConstant(SHC->getAPIntValue()
+ .logBase2(),
+ ADDVT));
AddToWorkList(Add.getNode());
- return DAG.getNode(ISD::SRL, VT, N0, Add);
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, Add);
}
}
}
@@ -1467,18 +1519,19 @@ SDValue DAGCombiner::visitSREM(SDNode *N) {
// urem instead. Handles (X & 0x0FFFFFFF) %s 16 -> X&15
if (!VT.isVector()) {
if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
- return DAG.getNode(ISD::UREM, VT, N0, N1);
+ return DAG.getNode(ISD::UREM, N->getDebugLoc(), VT, N0, N1);
}
// If X/C can be simplified by the division-by-constant logic, lower
// X%C to the equivalent of X-X/C*C.
if (N1C && !N1C->isNullValue()) {
- SDValue Div = DAG.getNode(ISD::SDIV, VT, N0, N1);
+ SDValue Div = DAG.getNode(ISD::SDIV, N->getDebugLoc(), VT, N0, N1);
AddToWorkList(Div.getNode());
SDValue OptimizedDiv = combine(Div.getNode());
if (OptimizedDiv.getNode() && OptimizedDiv.getNode() != Div.getNode()) {
- SDValue Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1);
- SDValue Sub = DAG.getNode(ISD::SUB, VT, N0, Mul);
+ SDValue Mul = DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
+ OptimizedDiv, N1);
+ SDValue Sub = DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0, Mul);
AddToWorkList(Mul.getNode());
return Sub;
}
@@ -1506,18 +1559,18 @@ SDValue DAGCombiner::visitUREM(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::UREM, VT, N0C, N1C);
// fold (urem x, pow2) -> (and x, pow2-1)
if (N1C && !N1C->isNullValue() && N1C->getAPIntValue().isPowerOf2())
- return DAG.getNode(ISD::AND, VT, N0,
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0,
DAG.getConstant(N1C->getAPIntValue()-1,VT));
// fold (urem x, (shl pow2, y)) -> (and x, (add (shl pow2, y), -1))
if (N1.getOpcode() == ISD::SHL) {
if (ConstantSDNode *SHC = dyn_cast<ConstantSDNode>(N1.getOperand(0))) {
if (SHC->getAPIntValue().isPowerOf2()) {
SDValue Add =
- DAG.getNode(ISD::ADD, VT, N1,
+ DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1,
DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()),
VT));
AddToWorkList(Add.getNode());
- return DAG.getNode(ISD::AND, VT, N0, Add);
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0, Add);
}
}
}
@@ -1525,12 +1578,13 @@ SDValue DAGCombiner::visitUREM(SDNode *N) {
// If X/C can be simplified by the division-by-constant logic, lower
// X%C to the equivalent of X-X/C*C.
if (N1C && !N1C->isNullValue()) {
- SDValue Div = DAG.getNode(ISD::UDIV, VT, N0, N1);
+ SDValue Div = DAG.getNode(ISD::UDIV, N->getDebugLoc(), VT, N0, N1);
AddToWorkList(Div.getNode());
SDValue OptimizedDiv = combine(Div.getNode());
if (OptimizedDiv.getNode() && OptimizedDiv.getNode() != Div.getNode()) {
- SDValue Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1);
- SDValue Sub = DAG.getNode(ISD::SUB, VT, N0, Mul);
+ SDValue Mul = DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
+ OptimizedDiv, N1);
+ SDValue Sub = DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0, Mul);
AddToWorkList(Mul.getNode());
return Sub;
}
@@ -1557,9 +1611,9 @@ SDValue DAGCombiner::visitMULHS(SDNode *N) {
return N1;
// fold (mulhs x, 1) -> (sra x, size(x)-1)
if (N1C && N1C->getAPIntValue() == 1)
- return DAG.getNode(ISD::SRA, N0.getValueType(), N0,
- DAG.getConstant(N0.getValueType().getSizeInBits()-1,
- TLI.getShiftAmountTy()));
+ return DAG.getNode(ISD::SRA, N->getDebugLoc(), N0.getValueType(), N0,
+ DAG.getConstant(N0.getValueType().getSizeInBits() - 1,
+ getShiftAmountTy()));
// fold (mulhs x, undef) -> 0
if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
return DAG.getConstant(0, VT);
@@ -1597,8 +1651,8 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
if (!HiExists &&
(!LegalOperations ||
TLI.isOperationLegal(LoOp, N->getValueType(0)))) {
- SDValue Res = DAG.getNode(LoOp, N->getValueType(0), N->op_begin(),
- N->getNumOperands());
+ SDValue Res = DAG.getNode(LoOp, N->getDebugLoc(), N->getValueType(0),
+ N->op_begin(), N->getNumOperands());
return CombineTo(N, Res, Res);
}
@@ -1607,8 +1661,8 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
if (!LoExists &&
(!LegalOperations ||
TLI.isOperationLegal(HiOp, N->getValueType(1)))) {
- SDValue Res = DAG.getNode(HiOp, N->getValueType(1), N->op_begin(),
- N->getNumOperands());
+ SDValue Res = DAG.getNode(HiOp, N->getDebugLoc(), N->getValueType(1),
+ N->op_begin(), N->getNumOperands());
return CombineTo(N, Res, Res);
}
@@ -1618,8 +1672,8 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
// If the two computed results can be simplified separately, separate them.
if (LoExists) {
- SDValue Lo = DAG.getNode(LoOp, N->getValueType(0),
- N->op_begin(), N->getNumOperands());
+ SDValue Lo = DAG.getNode(LoOp, N->getDebugLoc(), N->getValueType(0),
+ N->op_begin(), N->getNumOperands());
AddToWorkList(Lo.getNode());
SDValue LoOpt = combine(Lo.getNode());
if (LoOpt.getNode() && LoOpt.getNode() != Lo.getNode() &&
@@ -1629,7 +1683,7 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
}
if (HiExists) {
- SDValue Hi = DAG.getNode(HiOp, N->getValueType(1),
+ SDValue Hi = DAG.getNode(HiOp, N->getDebugLoc(), N->getValueType(1),
N->op_begin(), N->getNumOperands());
AddToWorkList(Hi.getNode());
SDValue HiOpt = combine(Hi.getNode());
@@ -1638,6 +1692,7 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
TLI.isOperationLegal(HiOpt.getOpcode(), HiOpt.getValueType())))
return CombineTo(N, HiOpt, HiOpt);
}
+
return SDValue();
}
@@ -1684,11 +1739,11 @@ SDValue DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) {
if ((N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND||
N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::TRUNCATE) &&
N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
- SDValue ORNode = DAG.getNode(N->getOpcode(),
- N0.getOperand(0).getValueType(),
- N0.getOperand(0), N1.getOperand(0));
+ SDValue ORNode = DAG.getNode(N->getOpcode(), N0.getDebugLoc(),
+ N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
AddToWorkList(ORNode.getNode());
- return DAG.getNode(N0.getOpcode(), VT, ORNode);
+ return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT, ORNode);
}
// For each of OP in SHL/SRL/SRA/AND...
@@ -1698,11 +1753,12 @@ SDValue DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) {
if ((N0.getOpcode() == ISD::SHL || N0.getOpcode() == ISD::SRL ||
N0.getOpcode() == ISD::SRA || N0.getOpcode() == ISD::AND) &&
N0.getOperand(1) == N1.getOperand(1)) {
- SDValue ORNode = DAG.getNode(N->getOpcode(),
- N0.getOperand(0).getValueType(),
- N0.getOperand(0), N1.getOperand(0));
+ SDValue ORNode = DAG.getNode(N->getOpcode(), N0.getDebugLoc(),
+ N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
AddToWorkList(ORNode.getNode());
- return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1));
+ return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT,
+ ORNode, N0.getOperand(1));
}
return SDValue();
@@ -1731,7 +1787,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::AND, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
- return DAG.getNode(ISD::AND, VT, N1, N0);
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N1, N0);
// fold (and x, -1) -> x
if (N1C && N1C->isAllOnesValue())
return N0;
@@ -1740,7 +1796,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
APInt::getAllOnesValue(BitWidth)))
return DAG.getConstant(0, VT);
// reassociate and
- SDValue RAND = ReassociateOps(ISD::AND, N0, N1);
+ SDValue RAND = ReassociateOps(ISD::AND, N->getDebugLoc(), N0, N1);
if (RAND.getNode() != 0)
return RAND;
// fold (and (or x, 0xFFFF), 0xFF) -> 0xFF
@@ -1754,8 +1810,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
APInt Mask = ~N1C->getAPIntValue();
Mask.trunc(N0Op0.getValueSizeInBits());
if (DAG.MaskedValueIsZero(N0Op0, Mask)) {
- SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(),
- N0Op0);
+ SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(),
+ N0.getValueType(), N0Op0);
// Replace uses of the AND with uses of the Zero extend node.
CombineTo(N, Zext);
@@ -1774,23 +1830,26 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
if (LR == RR && isa<ConstantSDNode>(LR) && Op0 == Op1 &&
LL.getValueType().isInteger()) {
- // fold (X == 0) & (Y == 0) -> (X|Y == 0)
+ // fold (and (seteq X, 0), (seteq Y, 0)) -> (seteq (or X, Y), 0)
if (cast<ConstantSDNode>(LR)->isNullValue() && Op1 == ISD::SETEQ) {
- SDValue ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+ SDValue ORNode = DAG.getNode(ISD::OR, N0.getDebugLoc(),
+ LR.getValueType(), LL, RL);
AddToWorkList(ORNode.getNode());
- return DAG.getSetCC(VT, ORNode, LR, Op1);
+ return DAG.getSetCC(N->getDebugLoc(), VT, ORNode, LR, Op1);
}
- // fold (X == -1) & (Y == -1) -> (X&Y == -1)
+ // fold (and (seteq X, -1), (seteq Y, -1)) -> (seteq (and X, Y), -1)
if (cast<ConstantSDNode>(LR)->isAllOnesValue() && Op1 == ISD::SETEQ) {
- SDValue ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL);
+ SDValue ANDNode = DAG.getNode(ISD::AND, N0.getDebugLoc(),
+ LR.getValueType(), LL, RL);
AddToWorkList(ANDNode.getNode());
- return DAG.getSetCC(VT, ANDNode, LR, Op1);
+ return DAG.getSetCC(N->getDebugLoc(), VT, ANDNode, LR, Op1);
}
- // fold (X > -1) & (Y > -1) -> (X|Y > -1)
+ // fold (and (setgt X, -1), (setgt Y, -1)) -> (setgt (or X, Y), -1)
if (cast<ConstantSDNode>(LR)->isAllOnesValue() && Op1 == ISD::SETGT) {
- SDValue ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+ SDValue ORNode = DAG.getNode(ISD::OR, N0.getDebugLoc(),
+ LR.getValueType(), LL, RL);
AddToWorkList(ORNode.getNode());
- return DAG.getSetCC(VT, ORNode, LR, Op1);
+ return DAG.getSetCC(N->getDebugLoc(), VT, ORNode, LR, Op1);
}
}
// canonicalize equivalent to ll == rl
@@ -1803,11 +1862,12 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger);
if (Result != ISD::SETCC_INVALID &&
(!LegalOperations || TLI.isCondCodeLegal(Result, LL.getValueType())))
- return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
+ return DAG.getSetCC(N->getDebugLoc(), N0.getValueType(),
+ LL, LR, Result);
}
}
- // Simplify: and (op x...), (op y...) -> (op (and x, y))
+ // Simplify: (and (op x...), (op y...)) -> (op (and x, y))
if (N0.getOpcode() == N1.getOpcode()) {
SDValue Tmp = SimplifyBinOpWithSameOpcodeHands(N);
if (Tmp.getNode()) return Tmp;
@@ -1829,8 +1889,9 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
BitWidth - EVT.getSizeInBits())) &&
((!LegalOperations && !LN0->isVolatile()) ||
TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) {
- SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
- LN0->getBasePtr(), LN0->getSrcValue(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N0.getDebugLoc(), VT,
+ LN0->getChain(), LN0->getBasePtr(),
+ LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
AddToWorkList(N);
@@ -1850,7 +1911,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
BitWidth - EVT.getSizeInBits())) &&
((!LegalOperations && !LN0->isVolatile()) ||
TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) {
- SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N0.getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
@@ -1874,11 +1936,13 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
EVT = MVT::getIntegerVT(ActiveBits);
MVT LoadedVT = LN0->getMemoryVT();
+
// Do not generate loads of non-round integer types since these can
// be expensive (and would be wrong if the type is not byte sized).
if (EVT != MVT::Other && LoadedVT.bitsGT(EVT) && EVT.isRound() &&
(!LegalOperations || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) {
MVT PtrType = N0.getOperand(1).getValueType();
+
// For big endian targets, we need to add an offset to the pointer to
// load the correct bytes. For little endian systems, we merely need to
// read fewer bytes from the same pointer.
@@ -1887,16 +1951,18 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
unsigned PtrOff = LVTStoreBytes - EVTStoreBytes;
unsigned Alignment = LN0->getAlignment();
SDValue NewPtr = LN0->getBasePtr();
+
if (TLI.isBigEndian()) {
- NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr,
- DAG.getConstant(PtrOff, PtrType));
+ NewPtr = DAG.getNode(ISD::ADD, LN0->getDebugLoc(), PtrType,
+ NewPtr, DAG.getConstant(PtrOff, PtrType));
Alignment = MinAlign(Alignment, PtrOff);
}
+
AddToWorkList(NewPtr.getNode());
SDValue Load =
- DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), NewPtr,
- LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), Alignment);
+ DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), VT, LN0->getChain(),
+ NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(),
+ EVT, LN0->isVolatile(), Alignment);
AddToWorkList(N);
CombineTo(N0.getNode(), Load, Load.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -1929,7 +1995,7 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::OR, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
- return DAG.getNode(ISD::OR, VT, N1, N0);
+ return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N1, N0);
// fold (or x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
@@ -1940,17 +2006,17 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
if (N1C && DAG.MaskedValueIsZero(N0, ~N1C->getAPIntValue()))
return N1;
// reassociate or
- SDValue ROR = ReassociateOps(ISD::OR, N0, N1);
+ SDValue ROR = ReassociateOps(ISD::OR, N->getDebugLoc(), N0, N1);
if (ROR.getNode() != 0)
return ROR;
// Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
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, VT, DAG.getNode(ISD::OR, VT, N0.getOperand(0),
- N1),
- DAG.getConstant(N1C->getAPIntValue() |
- C1->getAPIntValue(), VT));
+ 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)){
@@ -1959,21 +2025,23 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
if (LR == RR && isa<ConstantSDNode>(LR) && Op0 == Op1 &&
LL.getValueType().isInteger()) {
- // fold (X != 0) | (Y != 0) -> (X|Y != 0)
- // fold (X < 0) | (Y < 0) -> (X|Y < 0)
+ // fold (or (setne X, 0), (setne Y, 0)) -> (setne (or X, Y), 0)
+ // fold (or (setlt X, 0), (setlt Y, 0)) -> (setne (or X, Y), 0)
if (cast<ConstantSDNode>(LR)->isNullValue() &&
(Op1 == ISD::SETNE || Op1 == ISD::SETLT)) {
- SDValue ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+ SDValue ORNode = DAG.getNode(ISD::OR, LR.getDebugLoc(),
+ LR.getValueType(), LL, RL);
AddToWorkList(ORNode.getNode());
- return DAG.getSetCC(VT, ORNode, LR, Op1);
+ return DAG.getSetCC(N->getDebugLoc(), VT, ORNode, LR, Op1);
}
- // fold (X != -1) | (Y != -1) -> (X&Y != -1)
- // fold (X > -1) | (Y > -1) -> (X&Y > -1)
+ // fold (or (setne X, -1), (setne Y, -1)) -> (setne (and X, Y), -1)
+ // fold (or (setgt X, -1), (setgt Y -1)) -> (setgt (and X, Y), -1)
if (cast<ConstantSDNode>(LR)->isAllOnesValue() &&
(Op1 == ISD::SETNE || Op1 == ISD::SETGT)) {
- SDValue ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL);
+ SDValue ANDNode = DAG.getNode(ISD::AND, LR.getDebugLoc(),
+ LR.getValueType(), LL, RL);
AddToWorkList(ANDNode.getNode());
- return DAG.getSetCC(VT, ANDNode, LR, Op1);
+ return DAG.getSetCC(N->getDebugLoc(), VT, ANDNode, LR, Op1);
}
}
// canonicalize equivalent to ll == rl
@@ -1986,17 +2054,18 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger);
if (Result != ISD::SETCC_INVALID &&
(!LegalOperations || TLI.isCondCodeLegal(Result, LL.getValueType())))
- return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
+ return DAG.getSetCC(N->getDebugLoc(), N0.getValueType(),
+ LL, LR, Result);
}
}
- // Simplify: or (op x...), (op y...) -> (op (or x, y))
+ // Simplify: (or (op x...), (op y...)) -> (op (or x, y))
if (N0.getOpcode() == N1.getOpcode()) {
SDValue Tmp = SimplifyBinOpWithSameOpcodeHands(N);
if (Tmp.getNode()) return Tmp;
}
- // (X & C1) | (Y & C2) -> (X|Y) & C3 if possible.
+ // (or (and X, C1), (and Y, C2)) -> (and (or X, Y), C3) if possible.
if (N0.getOpcode() == ISD::AND &&
N1.getOpcode() == ISD::AND &&
N0.getOperand(1).getOpcode() == ISD::Constant &&
@@ -2012,20 +2081,20 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
if (DAG.MaskedValueIsZero(N0.getOperand(0), RHSMask&~LHSMask) &&
DAG.MaskedValueIsZero(N1.getOperand(0), LHSMask&~RHSMask)) {
- SDValue X =DAG.getNode(ISD::OR, VT, N0.getOperand(0), N1.getOperand(0));
- return DAG.getNode(ISD::AND, VT, X, DAG.getConstant(LHSMask|RHSMask, VT));
+ SDValue X = DAG.getNode(ISD::OR, N0.getDebugLoc(), VT,
+ N0.getOperand(0), N1.getOperand(0));
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, X,
+ DAG.getConstant(LHSMask | RHSMask, VT));
}
}
-
// See if this is some rotate idiom.
- if (SDNode *Rot = MatchRotate(N0, N1))
+ if (SDNode *Rot = MatchRotate(N0, N1, N->getDebugLoc()))
return SDValue(Rot, 0);
return SDValue();
}
-
/// MatchRotateHalf - Match "(X shl/srl V1) & V2" where V2 may not be present.
static bool MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask) {
if (Op.getOpcode() == ISD::AND) {
@@ -2041,21 +2110,21 @@ static bool MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask) {
Shift = Op;
return true;
}
+
return false;
}
-
// MatchRotate - Handle an 'or' of two operands. If this is one of the many
// idioms for rotate, and if the target supports rotation instructions, generate
// a rot[lr].
-SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
+SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, DebugLoc DL) {
// Must be a legal type. Expanded 'n promoted things won't work with rotates.
MVT VT = LHS.getValueType();
if (!TLI.isTypeLegal(VT)) return 0;
// The target must have at least one rotate flavor.
- bool HasROTL = TLI.isOperationLegal(ISD::ROTL, VT);
- bool HasROTR = TLI.isOperationLegal(ISD::ROTR, VT);
+ bool HasROTL = TLI.isOperationLegalOrCustom(ISD::ROTL, VT);
+ bool HasROTR = TLI.isOperationLegalOrCustom(ISD::ROTR, VT);
if (!HasROTL && !HasROTR) return 0;
// Match "(X shl/srl V1) & V2" where V2 may not be present.
@@ -2098,9 +2167,9 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
SDValue Rot;
if (HasROTL)
- Rot = DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt);
+ Rot = DAG.getNode(ISD::ROTL, DL, VT, LHSShiftArg, LHSShiftAmt);
else
- Rot = DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt);
+ Rot = DAG.getNode(ISD::ROTR, DL, VT, LHSShiftArg, RHSShiftAmt);
// If there is an AND of either shifted operand, apply it to the result.
if (LHSMask.getNode() || RHSMask.getNode()) {
@@ -2115,7 +2184,7 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
Mask &= cast<ConstantSDNode>(RHSMask)->getAPIntValue() | LHSBits;
}
- Rot = DAG.getNode(ISD::AND, VT, Rot, DAG.getConstant(Mask, VT));
+ Rot = DAG.getNode(ISD::AND, DL, VT, Rot, DAG.getConstant(Mask, VT));
}
return Rot.getNode();
@@ -2134,9 +2203,11 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
dyn_cast<ConstantSDNode>(RHSShiftAmt.getOperand(0))) {
if (SUBC->getAPIntValue() == OpSizeInBits) {
if (HasROTL)
- return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).getNode();
+ return DAG.getNode(ISD::ROTL, DL, VT,
+ LHSShiftArg, LHSShiftAmt).getNode();
else
- return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).getNode();
+ return DAG.getNode(ISD::ROTR, DL, VT,
+ LHSShiftArg, RHSShiftAmt).getNode();
}
}
}
@@ -2149,9 +2220,11 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
dyn_cast<ConstantSDNode>(LHSShiftAmt.getOperand(0))) {
if (SUBC->getAPIntValue() == OpSizeInBits) {
if (HasROTR)
- return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).getNode();
+ return DAG.getNode(ISD::ROTR, DL, VT,
+ LHSShiftArg, RHSShiftAmt).getNode();
else
- return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).getNode();
+ return DAG.getNode(ISD::ROTL, DL, VT,
+ LHSShiftArg, LHSShiftAmt).getNode();
}
}
}
@@ -2176,7 +2249,8 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
if (ConstantSDNode *SUBC =
dyn_cast<ConstantSDNode>(RExtOp0.getOperand(0))) {
if (SUBC->getAPIntValue() == OpSizeInBits) {
- return DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, VT, LHSShiftArg,
+ return DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, DL, VT,
+ LHSShiftArg,
HasROTL ? LHSShiftAmt : RHSShiftAmt).getNode();
}
}
@@ -2189,7 +2263,8 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
if (ConstantSDNode *SUBC =
dyn_cast<ConstantSDNode>(LExtOp0.getOperand(0))) {
if (SUBC->getAPIntValue() == OpSizeInBits) {
- return DAG.getNode(HasROTR ? ISD::ROTR : ISD::ROTL, VT, LHSShiftArg,
+ return DAG.getNode(HasROTR ? ISD::ROTR : ISD::ROTL, DL, VT,
+ LHSShiftArg,
HasROTR ? RHSShiftAmt : LHSShiftAmt).getNode();
}
}
@@ -2199,7 +2274,6 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) {
return 0;
}
-
SDValue DAGCombiner::visitXOR(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -2227,12 +2301,12 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
return DAG.FoldConstantArithmetic(ISD::XOR, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
- return DAG.getNode(ISD::XOR, VT, N1, N0);
+ return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N1, N0);
// fold (xor x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
// reassociate xor
- SDValue RXOR = ReassociateOps(ISD::XOR, N0, N1);
+ SDValue RXOR = ReassociateOps(ISD::XOR, N->getDebugLoc(), N0, N1);
if (RXOR.getNode() != 0)
return RXOR;
@@ -2248,9 +2322,9 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
assert(0 && "Unhandled SetCC Equivalent!");
abort();
case ISD::SETCC:
- return DAG.getSetCC(VT, LHS, RHS, NotCC);
+ return DAG.getSetCC(N->getDebugLoc(), VT, LHS, RHS, NotCC);
case ISD::SELECT_CC:
- return DAG.getSelectCC(LHS, RHS, N0.getOperand(2),
+ return DAG.getSelectCC(N->getDebugLoc(), LHS, RHS, N0.getOperand(2),
N0.getOperand(3), NotCC);
}
}
@@ -2261,47 +2335,47 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
N0.getNode()->hasOneUse() &&
isSetCCEquivalent(N0.getOperand(0), LHS, RHS, CC)){
SDValue V = N0.getOperand(0);
- V = DAG.getNode(ISD::XOR, V.getValueType(), V,
+ V = DAG.getNode(ISD::XOR, N0.getDebugLoc(), V.getValueType(), V,
DAG.getConstant(1, V.getValueType()));
AddToWorkList(V.getNode());
- return DAG.getNode(ISD::ZERO_EXTEND, VT, V);
+ return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, V);
}
- // fold !(x or y) -> (!x and !y) iff x or y are setcc
+ // fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are setcc
if (N1C && N1C->getAPIntValue() == 1 && VT == MVT::i1 &&
(N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) {
SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1);
if (isOneUseSetCC(RHS) || isOneUseSetCC(LHS)) {
unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND;
- LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS
- RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS
+ LHS = DAG.getNode(ISD::XOR, LHS.getDebugLoc(), VT, LHS, N1); // LHS = ~LHS
+ RHS = DAG.getNode(ISD::XOR, RHS.getDebugLoc(), VT, RHS, N1); // RHS = ~RHS
AddToWorkList(LHS.getNode()); AddToWorkList(RHS.getNode());
- return DAG.getNode(NewOpcode, VT, LHS, RHS);
+ return DAG.getNode(NewOpcode, N->getDebugLoc(), VT, LHS, RHS);
}
}
- // fold !(x or y) -> (!x and !y) iff x or y are constants
+ // fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are constants
if (N1C && N1C->isAllOnesValue() &&
(N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) {
SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1);
if (isa<ConstantSDNode>(RHS) || isa<ConstantSDNode>(LHS)) {
unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND;
- LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS
- RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS
+ LHS = DAG.getNode(ISD::XOR, LHS.getDebugLoc(), VT, LHS, N1); // LHS = ~LHS
+ RHS = DAG.getNode(ISD::XOR, RHS.getDebugLoc(), VT, RHS, N1); // RHS = ~RHS
AddToWorkList(LHS.getNode()); AddToWorkList(RHS.getNode());
- return DAG.getNode(NewOpcode, VT, LHS, RHS);
+ return DAG.getNode(NewOpcode, N->getDebugLoc(), VT, LHS, RHS);
}
}
- // fold (xor (xor x, c1), c2) -> (xor x, c1^c2)
+ // fold (xor (xor x, c1), c2) -> (xor x, (xor c1, c2))
if (N1C && N0.getOpcode() == ISD::XOR) {
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (N00C)
- return DAG.getNode(ISD::XOR, VT, N0.getOperand(1),
- DAG.getConstant(N1C->getAPIntValue()^
+ return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N0.getOperand(1),
+ DAG.getConstant(N1C->getAPIntValue() ^
N00C->getAPIntValue(), VT));
if (N01C)
- return DAG.getNode(ISD::XOR, VT, N0.getOperand(0),
- DAG.getConstant(N1C->getAPIntValue()^
+ return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N0.getOperand(0),
+ DAG.getConstant(N1C->getAPIntValue() ^
N01C->getAPIntValue(), VT));
}
// fold (xor x, x) -> 0
@@ -2312,7 +2386,8 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
// Produce a vector of zeros.
SDValue El = DAG.getConstant(0, VT.getVectorElementType());
std::vector<SDValue> Ops(VT.getVectorNumElements(), El);
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
+ return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT,
+ &Ops[0], Ops.size());
}
}
@@ -2361,13 +2436,12 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) {
// We require the RHS of the binop to be a constant as well.
ConstantSDNode *BinOpCst = dyn_cast<ConstantSDNode>(LHS->getOperand(1));
if (!BinOpCst) return SDValue();
-
-
- // FIXME: disable this for unless the input to the binop is a shift by a
- // constant. If it is not a shift, it pessimizes some common cases like:
+
+ // FIXME: disable this unless the input to the binop is a shift by a constant.
+ // If it is not a shift, it pessimizes some common cases like:
//
- //void foo(int *X, int i) { X[i & 1235] = 1; }
- //int bar(int *X, int i) { return X[i & 255]; }
+ // void foo(int *X, int i) { X[i & 1235] = 1; }
+ // int bar(int *X, int i) { return X[i & 255]; }
SDNode *BinOpLHSVal = LHS->getOperand(0).getNode();
if ((BinOpLHSVal->getOpcode() != ISD::SHL &&
BinOpLHSVal->getOpcode() != ISD::SRA &&
@@ -2377,11 +2451,10 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) {
MVT VT = N->getValueType(0);
- // If this is a signed shift right, and the high bit is modified
- // by the logical operation, do not perform the transformation.
- // The highBitSet boolean indicates the value of the high bit of
- // the constant which would cause it to be modified for this
- // operation.
+ // If this is a signed shift right, and the high bit is modified by the
+ // logical operation, do not perform the transformation. The highBitSet
+ // boolean indicates the value of the high bit of the constant which would
+ // cause it to be modified for this operation.
if (N->getOpcode() == ISD::SRA) {
bool BinOpRHSSignSet = BinOpCst->getAPIntValue().isNegative();
if (BinOpRHSSignSet != HighBitSet)
@@ -2389,18 +2462,18 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) {
}
// Fold the constants, shifting the binop RHS by the shift amount.
- SDValue NewRHS = DAG.getNode(N->getOpcode(), N->getValueType(0),
- LHS->getOperand(1), N->getOperand(1));
+ SDValue NewRHS = DAG.getNode(N->getOpcode(), LHS->getOperand(1).getDebugLoc(),
+ N->getValueType(0),
+ LHS->getOperand(1), N->getOperand(1));
// Create the new shift.
- SDValue NewShift = DAG.getNode(N->getOpcode(), VT, LHS->getOperand(0),
- N->getOperand(1));
+ SDValue NewShift = DAG.getNode(N->getOpcode(), LHS->getOperand(0).getDebugLoc(),
+ VT, LHS->getOperand(0), N->getOperand(1));
// Create the new binop.
- return DAG.getNode(LHS->getOpcode(), VT, NewShift, NewRHS);
+ return DAG.getNode(LHS->getOpcode(), N->getDebugLoc(), VT, NewShift, NewRHS);
}
-
SDValue DAGCombiner::visitSHL(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -2417,7 +2490,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
return N0;
// fold (shl x, c >= size(x)) -> undef
if (N1C && N1C->getZExtValue() >= OpSizeInBits)
- return DAG.getNode(ISD::UNDEF, VT);
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT);
// fold (shl x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
@@ -2425,8 +2498,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
if (DAG.MaskedValueIsZero(SDValue(N, 0),
APInt::getAllOnesValue(VT.getSizeInBits())))
return DAG.getConstant(0, VT);
- // fold (shl x, (trunc (and y, c))) -> (shl x, (and (trunc y), c))
- // iff (trunc c) == c
+ // fold (shl x, (trunc (and y, c))) -> (shl x, (and (trunc y), (trunc c))).
if (N1.getOpcode() == ISD::TRUNCATE &&
N1.getOperand(0).getOpcode() == ISD::AND &&
N1.hasOneUse() && N1.getOperand(0).hasOneUse()) {
@@ -2434,44 +2506,48 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
if (ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101)) {
MVT TruncVT = N1.getValueType();
SDValue N100 = N1.getOperand(0).getOperand(0);
- return DAG.getNode(ISD::SHL, VT, N0,
- DAG.getNode(ISD::AND, TruncVT,
- DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
- DAG.getConstant(N101C->getZExtValue(),
- TruncVT)));
+ APInt TruncC = N101C->getAPIntValue();
+ TruncC.trunc(TruncVT.getSizeInBits());
+ return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
+ DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT,
+ DAG.getNode(ISD::TRUNCATE,
+ N->getDebugLoc(),
+ TruncVT, N100),
+ DAG.getConstant(TruncC, TruncVT)));
}
}
if (N1C && SimplifyDemandedBits(SDValue(N, 0)))
return SDValue(N, 0);
- // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2)
+
+ // fold (shl (shl x, c1), c2) -> 0 or (shl x, (add c1, c2))
if (N1C && N0.getOpcode() == ISD::SHL &&
N0.getOperand(1).getOpcode() == ISD::Constant) {
uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
uint64_t c2 = N1C->getZExtValue();
if (c1 + c2 > OpSizeInBits)
return DAG.getConstant(0, VT);
- return DAG.getNode(ISD::SHL, VT, N0.getOperand(0),
+ return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0),
DAG.getConstant(c1 + c2, N1.getValueType()));
}
- // fold (shl (srl x, c1), c2) -> (shl (and x, -1 << c1), c2-c1) or
- // (srl (and x, -1 << c1), c1-c2)
+ // fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or
+ // (srl (and x, (shl -1, c1)), (sub c1, c2))
if (N1C && N0.getOpcode() == ISD::SRL &&
N0.getOperand(1).getOpcode() == ISD::Constant) {
uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
uint64_t c2 = N1C->getZExtValue();
- SDValue Mask = DAG.getNode(ISD::AND, VT, N0.getOperand(0),
- DAG.getConstant(~0ULL << c1, VT));
+ SDValue Mask = DAG.getNode(ISD::AND, N0.getDebugLoc(), VT, N0.getOperand(0),
+ DAG.getConstant(~0ULL << c1, VT));
if (c2 > c1)
- return DAG.getNode(ISD::SHL, VT, Mask,
+ return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, Mask,
DAG.getConstant(c2-c1, N1.getValueType()));
else
- return DAG.getNode(ISD::SRL, VT, Mask,
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, Mask,
DAG.getConstant(c1-c2, N1.getValueType()));
}
- // fold (shl (sra x, c1), c1) -> (and x, -1 << c1)
+ // fold (shl (sra x, c1), c1) -> (and x, (shl -1, c1))
if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1))
- return DAG.getNode(ISD::AND, VT, N0.getOperand(0),
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0.getOperand(0),
DAG.getConstant(~0ULL << N1C->getZExtValue(), VT));
return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue();
@@ -2484,7 +2560,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
MVT VT = N0.getValueType();
- // fold (sra c1, c2) -> c1>>c2
+ // fold (sra c1, c2) -> (sra c1, c2)
if (N0C && N1C)
return DAG.FoldConstantArithmetic(ISD::SRA, VT, N0C, N1C);
// fold (sra 0, x) -> 0
@@ -2493,9 +2569,9 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
// fold (sra -1, x) -> -1
if (N0C && N0C->isAllOnesValue())
return N0;
- // fold (sra x, c >= size(x)) -> undef
+ // fold (sra x, (setge c, size(x))) -> undef
if (N1C && N1C->getZExtValue() >= VT.getSizeInBits())
- return DAG.getNode(ISD::UNDEF, VT);
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT);
// fold (sra x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
@@ -2505,22 +2581,22 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
unsigned LowBits = VT.getSizeInBits() - (unsigned)N1C->getZExtValue();
MVT EVT = MVT::getIntegerVT(LowBits);
if ((!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, EVT)))
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0),
- DAG.getValueType(EVT));
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT,
+ N0.getOperand(0), DAG.getValueType(EVT));
}
- // fold (sra (sra x, c1), c2) -> (sra x, c1+c2)
+ // fold (sra (sra x, c1), c2) -> (sra x, (add c1, c2))
if (N1C && N0.getOpcode() == ISD::SRA) {
if (ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
unsigned Sum = N1C->getZExtValue() + C1->getZExtValue();
if (Sum >= VT.getSizeInBits()) Sum = VT.getSizeInBits()-1;
- return DAG.getNode(ISD::SRA, VT, N0.getOperand(0),
+ return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0.getOperand(0),
DAG.getConstant(Sum, N1C->getValueType(0)));
}
}
- // fold sra (shl X, m), result_size - n
- // -> (sign_extend (trunc (shl X, result_size - n - m))) for
+ // fold (sra (shl X, m), (sub result_size, n))
+ // -> (sign_extend (trunc (shl X, (sub (sub result_size, n), m)))) for
// result_size - n != m.
// If truncate is free for the target sext(shl) is likely to result in better
// code.
@@ -2540,20 +2616,22 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
// on that type, and the the truncate to that type is both legal and free,
// perform the transform.
if (ShiftAmt &&
- TLI.isOperationLegal(ISD::SIGN_EXTEND, TruncVT) &&
- TLI.isOperationLegal(ISD::TRUNCATE, VT) &&
+ TLI.isOperationLegalOrCustom(ISD::SIGN_EXTEND, TruncVT) &&
+ TLI.isOperationLegalOrCustom(ISD::TRUNCATE, VT) &&
TLI.isTruncateFree(VT, TruncVT)) {
- SDValue Amt = DAG.getConstant(ShiftAmt, TLI.getShiftAmountTy());
- SDValue Shift = DAG.getNode(ISD::SRL, VT, N0.getOperand(0), Amt);
- SDValue Trunc = DAG.getNode(ISD::TRUNCATE, TruncVT, Shift);
- return DAG.getNode(ISD::SIGN_EXTEND, N->getValueType(0), Trunc);
+ SDValue Amt = DAG.getConstant(ShiftAmt, getShiftAmountTy());
+ SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT,
+ N0.getOperand(0), Amt);
+ SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), TruncVT,
+ Shift);
+ return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(),
+ N->getValueType(0), Trunc);
}
}
}
- // fold (sra x, (trunc (and y, c))) -> (sra x, (and (trunc y), c))
- // iff (trunc c) == c
+ // fold (sra x, (trunc (and y, c))) -> (sra x, (and (trunc y), (trunc c))).
if (N1.getOpcode() == ISD::TRUNCATE &&
N1.getOperand(0).getOpcode() == ISD::AND &&
N1.hasOneUse() && N1.getOperand(0).hasOneUse()) {
@@ -2561,11 +2639,15 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
if (ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101)) {
MVT TruncVT = N1.getValueType();
SDValue N100 = N1.getOperand(0).getOperand(0);
- return DAG.getNode(ISD::SRA, VT, N0,
- DAG.getNode(ISD::AND, TruncVT,
- DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
- DAG.getConstant(N101C->getZExtValue(),
- TruncVT)));
+ APInt TruncC = N101C->getAPIntValue();
+ TruncC.trunc(TruncVT.getSizeInBits());
+ return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0,
+ DAG.getNode(ISD::AND, N->getDebugLoc(),
+ TruncVT,
+ DAG.getNode(ISD::TRUNCATE,
+ N->getDebugLoc(),
+ TruncVT, N100),
+ DAG.getConstant(TruncC, TruncVT)));
}
}
@@ -2576,7 +2658,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
// If the sign bit is known to be zero, switch this to a SRL.
if (DAG.SignBitIsZero(N0))
- return DAG.getNode(ISD::SRL, VT, N0, N1);
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, N1);
return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue();
}
@@ -2597,7 +2679,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
return N0;
// fold (srl x, c >= size(x)) -> undef
if (N1C && N1C->getZExtValue() >= OpSizeInBits)
- return DAG.getNode(ISD::UNDEF, VT);
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT);
// fold (srl x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
@@ -2606,14 +2688,14 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
APInt::getAllOnesValue(OpSizeInBits)))
return DAG.getConstant(0, VT);
- // fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2)
+ // fold (srl (srl x, c1), c2) -> 0 or (srl x, (add c1, c2))
if (N1C && N0.getOpcode() == ISD::SRL &&
N0.getOperand(1).getOpcode() == ISD::Constant) {
uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
uint64_t c2 = N1C->getZExtValue();
if (c1 + c2 > OpSizeInBits)
return DAG.getConstant(0, VT);
- return DAG.getNode(ISD::SRL, VT, N0.getOperand(0),
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0),
DAG.getConstant(c1 + c2, N1.getValueType()));
}
@@ -2622,18 +2704,19 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
// Shifting in all undef bits?
MVT SmallVT = N0.getOperand(0).getValueType();
if (N1C->getZExtValue() >= SmallVT.getSizeInBits())
- return DAG.getNode(ISD::UNDEF, VT);
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT);
- SDValue SmallShift = DAG.getNode(ISD::SRL, SmallVT, N0.getOperand(0), N1);
+ SDValue SmallShift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), SmallVT,
+ N0.getOperand(0), N1);
AddToWorkList(SmallShift.getNode());
- return DAG.getNode(ISD::ANY_EXTEND, VT, SmallShift);
+ return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, SmallShift);
}
// fold (srl (sra X, Y), 31) -> (srl X, 31). This srl only looks at the sign
// bit, which is unmodified by sra.
- if (N1C && N1C->getZExtValue()+1 == VT.getSizeInBits()) {
+ if (N1C && N1C->getZExtValue() + 1 == VT.getSizeInBits()) {
if (N0.getOpcode() == ISD::SRA)
- return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), N1);
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0), N1);
}
// fold (srl (ctlz x), "5") -> x iff x has one bit set (the low bit).
@@ -2653,24 +2736,26 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
if (UnknownBits == 0) return DAG.getConstant(1, VT);
// Otherwise, check to see if there is exactly one bit input to the ctlz.
- if ((UnknownBits & (UnknownBits-1)) == 0) {
+ if ((UnknownBits & (UnknownBits - 1)) == 0) {
// Okay, we know that only that the single bit specified by UnknownBits
- // could be set on input to the CTLZ node. If this bit is set, the SRL
- // will return 0, if it is clear, it returns 1. Change the CTLZ/SRL pair
- // to an SRL,XOR pair, which is likely to simplify more.
+ // could be set on input to the CTLZ node. If this bit is set, the SRL
+ // will return 0, if it is clear, it returns 1. Change the CTLZ/SRL pair
+ // to an SRL/XOR pair, which is likely to simplify more.
unsigned ShAmt = UnknownBits.countTrailingZeros();
SDValue Op = N0.getOperand(0);
+
if (ShAmt) {
- Op = DAG.getNode(ISD::SRL, VT, Op,
- DAG.getConstant(ShAmt, TLI.getShiftAmountTy()));
+ Op = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, Op,
+ DAG.getConstant(ShAmt, getShiftAmountTy()));
AddToWorkList(Op.getNode());
}
- return DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(1, VT));
+
+ return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT,
+ Op, DAG.getConstant(1, VT));
}
}
- // fold (srl x, (trunc (and y, c))) -> (srl x, (and (trunc y), c))
- // iff (trunc c) == c
+ // fold (srl x, (trunc (and y, c))) -> (srl x, (and (trunc y), (trunc c))).
if (N1.getOpcode() == ISD::TRUNCATE &&
N1.getOperand(0).getOpcode() == ISD::AND &&
N1.hasOneUse() && N1.getOperand(0).hasOneUse()) {
@@ -2678,11 +2763,15 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
if (ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101)) {
MVT TruncVT = N1.getValueType();
SDValue N100 = N1.getOperand(0).getOperand(0);
- return DAG.getNode(ISD::SRL, VT, N0,
- DAG.getNode(ISD::AND, TruncVT,
- DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
- DAG.getConstant(N101C->getZExtValue(),
- TruncVT)));
+ APInt TruncC = N101C->getAPIntValue();
+ TruncC.trunc(TruncVT.getSizeInBits());
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0,
+ DAG.getNode(ISD::AND, N->getDebugLoc(),
+ TruncVT,
+ DAG.getNode(ISD::TRUNCATE,
+ N->getDebugLoc(),
+ TruncVT, N100),
+ DAG.getConstant(TruncC, TruncVT)));
}
}
@@ -2700,7 +2789,7 @@ SDValue DAGCombiner::visitCTLZ(SDNode *N) {
// fold (ctlz c1) -> c2
if (isa<ConstantSDNode>(N0))
- return DAG.getNode(ISD::CTLZ, VT, N0);
+ return DAG.getNode(ISD::CTLZ, N->getDebugLoc(), VT, N0);
return SDValue();
}
@@ -2710,7 +2799,7 @@ SDValue DAGCombiner::visitCTTZ(SDNode *N) {
// fold (cttz c1) -> c2
if (isa<ConstantSDNode>(N0))
- return DAG.getNode(ISD::CTTZ, VT, N0);
+ return DAG.getNode(ISD::CTTZ, N->getDebugLoc(), VT, N0);
return SDValue();
}
@@ -2720,7 +2809,7 @@ SDValue DAGCombiner::visitCTPOP(SDNode *N) {
// fold (ctpop c1) -> c2
if (isa<ConstantSDNode>(N0))
- return DAG.getNode(ISD::CTPOP, VT, N0);
+ return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), VT, N0);
return SDValue();
}
@@ -2734,51 +2823,58 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
MVT VT = N->getValueType(0);
MVT VT0 = N0.getValueType();
- // fold select C, X, X -> X
+ // fold (select C, X, X) -> X
if (N1 == N2)
return N1;
- // fold select true, X, Y -> X
+ // fold (select true, X, Y) -> X
if (N0C && !N0C->isNullValue())
return N1;
- // fold select false, X, Y -> Y
+ // fold (select false, X, Y) -> Y
if (N0C && N0C->isNullValue())
return N2;
- // fold select C, 1, X -> C | X
+ // fold (select C, 1, X) -> (or C, X)
if (VT == MVT::i1 && N1C && N1C->getAPIntValue() == 1)
- return DAG.getNode(ISD::OR, VT, N0, N2);
- // fold select C, 0, 1 -> ~C
- if (VT.isInteger() && VT0.isInteger() &&
+ return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N2);
+ // fold (select C, 0, 1) -> (xor C, 1)
+ if (VT.isInteger() &&
+ (VT0 == MVT::i1 ||
+ (VT0.isInteger() &&
+ TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent)) &&
N1C && N2C && N1C->isNullValue() && N2C->getAPIntValue() == 1) {
- SDValue XORNode = DAG.getNode(ISD::XOR, VT0, N0, DAG.getConstant(1, VT0));
+ SDValue XORNode;
if (VT == VT0)
- return XORNode;
+ return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT0,
+ N0, DAG.getConstant(1, VT0));
+ XORNode = DAG.getNode(ISD::XOR, N0.getDebugLoc(), VT0,
+ N0, DAG.getConstant(1, VT0));
AddToWorkList(XORNode.getNode());
if (VT.bitsGT(VT0))
- return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode);
- return DAG.getNode(ISD::TRUNCATE, VT, XORNode);
+ return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, XORNode);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, XORNode);
}
- // fold select C, 0, X -> ~C & X
+ // fold (select C, 0, X) -> (and (not C), X)
if (VT == VT0 && VT == MVT::i1 && N1C && N1C->isNullValue()) {
- SDValue XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT));
- AddToWorkList(XORNode.getNode());
- return DAG.getNode(ISD::AND, VT, XORNode, N2);
+ SDValue NOTNode = DAG.getNOT(N0.getDebugLoc(), N0, VT);
+ AddToWorkList(NOTNode.getNode());
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, NOTNode, N2);
}
- // fold select C, X, 1 -> ~C | X
+ // fold (select C, X, 1) -> (or (not C), X)
if (VT == VT0 && VT == MVT::i1 && N2C && N2C->getAPIntValue() == 1) {
- SDValue XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT));
- AddToWorkList(XORNode.getNode());
- return DAG.getNode(ISD::OR, VT, XORNode, N1);
+ SDValue NOTNode = DAG.getNOT(N0.getDebugLoc(), N0, VT);
+ AddToWorkList(NOTNode.getNode());
+ return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, NOTNode, N1);
}
- // fold select C, X, 0 -> C & X
- // FIXME: this should check for C type == X type, not i1?
+ // fold (select C, X, 0) -> (and C, X)
if (VT == MVT::i1 && N2C && N2C->isNullValue())
- return DAG.getNode(ISD::AND, VT, N0, N1);
- // fold X ? X : Y --> X ? 1 : Y --> X | Y
- if (VT == MVT::i1 && N0 == N1)
- return DAG.getNode(ISD::OR, VT, N0, N2);
- // fold X ? Y : X --> X ? Y : 0 --> X & Y
- if (VT == MVT::i1 && N0 == N2)
- return DAG.getNode(ISD::AND, VT, N0, N1);
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0, N1);
+ // fold (select X, X, Y) -> (or X, Y)
+ // fold (select X, 1, Y) -> (or X, Y)
+ if (VT == MVT::i1 && (N0 == N1 || (N1C && N1C->getAPIntValue() == 1)))
+ return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N2);
+ // fold (select X, Y, X) -> (and X, Y)
+ // fold (select X, Y, 0) -> (and X, Y)
+ if (VT == MVT::i1 && (N0 == N2 || (N2C && N2C->getAPIntValue() == 0)))
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0, N1);
// If we can fold this based on the true/false value, do so.
if (SimplifySelectOps(N, N1, N2))
@@ -2790,12 +2886,14 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
// Check against MVT::Other for SELECT_CC, which is a workaround for targets
// having to say they don't support SELECT_CC on every type the DAG knows
// about, since there is no way to mark an opcode illegal at all value types
- if (TLI.isOperationLegal(ISD::SELECT_CC, MVT::Other))
- return DAG.getNode(ISD::SELECT_CC, VT, N0.getOperand(0), N0.getOperand(1),
+ if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other))
+ return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT,
+ N0.getOperand(0), N0.getOperand(1),
N1, N2, N0.getOperand(2));
else
- return SimplifySelect(N0, N1, N2);
+ return SimplifySelect(N->getDebugLoc(), N0, N1, N2);
}
+
return SDValue();
}
@@ -2813,7 +2911,7 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) {
// Determine if the condition we're dealing with is constant
SDValue SCC = SimplifySetCC(TLI.getSetCCResultType(N0.getValueType()),
- N0, N1, CC, false);
+ N0, N1, CC, N->getDebugLoc(), false);
if (SCC.getNode()) AddToWorkList(SCC.getNode());
if (ConstantSDNode *SCCC = dyn_cast_or_null<ConstantSDNode>(SCC.getNode())) {
@@ -2825,7 +2923,7 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) {
// Fold to a simpler select_cc
if (SCC.getNode() && SCC.getOpcode() == ISD::SETCC)
- return DAG.getNode(ISD::SELECT_CC, N2.getValueType(),
+ return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), N2.getValueType(),
SCC.getOperand(0), SCC.getOperand(1), N2, N3,
SCC.getOperand(2));
@@ -2834,12 +2932,13 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) {
return SDValue(N, 0); // Don't revisit N.
// fold select_cc into other things, such as min/max/abs
- return SimplifySelectCC(N0, N1, N2, N3, CC);
+ return SimplifySelectCC(N->getDebugLoc(), N0, N1, N2, N3, CC);
}
SDValue DAGCombiner::visitSETCC(SDNode *N) {
return SimplifySetCC(N->getValueType(0), N->getOperand(0), N->getOperand(1),
- cast<CondCodeSDNode>(N->getOperand(2))->get());
+ cast<CondCodeSDNode>(N->getOperand(2))->get(),
+ N->getDebugLoc());
}
// ExtendUsesToFormExtLoad - Trying to extend uses of a load to enable this:
@@ -2917,12 +3016,13 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
// fold (sext c1) -> c1
if (isa<ConstantSDNode>(N0))
- return DAG.getNode(ISD::SIGN_EXTEND, VT, N0);
+ return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, N0);
// fold (sext (sext x)) -> (sext x)
// fold (sext (aext x)) -> (sext x)
if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
- return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0));
+ return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT,
+ N0.getOperand(0));
if (N0.getOpcode() == ISD::TRUNCATE) {
// fold (sext (truncate (load x))) -> (sext (smaller load x))
@@ -2931,7 +3031,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
if (NarrowLoad.getNode()) {
if (NarrowLoad.getNode() != N0.getNode())
CombineTo(N0.getNode(), NarrowLoad);
- return DAG.getNode(ISD::SIGN_EXTEND, VT, NarrowLoad);
+ return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, NarrowLoad);
}
// See if the value being truncated is already sign extended. If so, just
@@ -2951,22 +3051,22 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
// Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
// bits, just sext from i32.
if (NumSignBits > OpBits-MidBits)
- return DAG.getNode(ISD::SIGN_EXTEND, VT, Op);
+ return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, Op);
} else {
// Op is i64, Mid is i8, and Dest is i32. If Op has more than 56 sign
// bits, just truncate to i32.
if (NumSignBits > OpBits-MidBits)
- return DAG.getNode(ISD::TRUNCATE, VT, Op);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Op);
}
// fold (sext (truncate x)) -> (sextinreg x).
if (!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG,
N0.getValueType())) {
if (Op.getValueType().bitsLT(VT))
- Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op);
+ Op = DAG.getNode(ISD::ANY_EXTEND, N0.getDebugLoc(), VT, Op);
else if (Op.getValueType().bitsGT(VT))
- Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, Op,
+ Op = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), VT, Op);
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, Op,
DAG.getValueType(N0.getValueType()));
}
}
@@ -2981,29 +3081,37 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
DoXform = ExtendUsesToFormExtLoad(N, N0, ISD::SIGN_EXTEND, SetCCs, TLI);
if (DoXform) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(),
+ VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
LN0->isVolatile(), LN0->getAlignment());
CombineTo(N, ExtLoad);
- SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad);
+ SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
+ N0.getValueType(), ExtLoad);
CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1));
+
// Extend SetCC uses if necessary.
for (unsigned i = 0, e = SetCCs.size(); i != e; ++i) {
SDNode *SetCC = SetCCs[i];
SmallVector<SDValue, 4> Ops;
+
for (unsigned j = 0; j != 2; ++j) {
SDValue SOp = SetCC->getOperand(j);
if (SOp == Trunc)
Ops.push_back(ExtLoad);
else
- Ops.push_back(DAG.getNode(ISD::SIGN_EXTEND, VT, SOp));
- }
+ Ops.push_back(DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(),
+ VT, SOp));
+ }
+
Ops.push_back(SetCC->getOperand(2));
- CombineTo(SetCC, DAG.getNode(ISD::SETCC, SetCC->getValueType(0),
+ CombineTo(SetCC, DAG.getNode(ISD::SETCC, N->getDebugLoc(),
+ SetCC->getValueType(0),
&Ops[0], Ops.size()));
}
+
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
}
@@ -3016,22 +3124,24 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
MVT EVT = LN0->getMemoryVT();
if ((!LegalOperations && !LN0->isVolatile()) ||
TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT)) {
- SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
- DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
+ DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
+ N0.getValueType(), ExtLoad),
ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
}
- // sext(setcc x,y,cc) -> select_cc x, y, -1, 0, cc
+ // sext(setcc x, y, cc) -> (select_cc x, y, -1, 0, cc)
if (N0.getOpcode() == ISD::SETCC) {
SDValue SCC =
- SimplifySelectCC(N0.getOperand(0), N0.getOperand(1),
+ SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1),
DAG.getConstant(~0ULL, VT), DAG.getConstant(0, VT),
cast<CondCodeSDNode>(N0.getOperand(2))->get(), true);
if (SCC.getNode()) return SCC;
@@ -3040,7 +3150,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
// fold (sext x) -> (zext x) if the sign bit is known zero.
if ((!LegalOperations || TLI.isOperationLegal(ISD::ZERO_EXTEND, VT)) &&
DAG.SignBitIsZero(N0))
- return DAG.getNode(ISD::ZERO_EXTEND, VT, N0);
+ return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, N0);
return SDValue();
}
@@ -3051,11 +3161,12 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
// fold (zext c1) -> c1
if (isa<ConstantSDNode>(N0))
- return DAG.getNode(ISD::ZERO_EXTEND, VT, N0);
+ return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, N0);
// fold (zext (zext x)) -> (zext x)
// fold (zext (aext x)) -> (zext x)
if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
- return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0));
+ return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT,
+ N0.getOperand(0));
// fold (zext (truncate (load x))) -> (zext (smaller load x))
// fold (zext (truncate (srl (load x), c))) -> (zext (small load (x+c/n)))
@@ -3064,7 +3175,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
if (NarrowLoad.getNode()) {
if (NarrowLoad.getNode() != N0.getNode())
CombineTo(N0.getNode(), NarrowLoad);
- return DAG.getNode(ISD::ZERO_EXTEND, VT, NarrowLoad);
+ return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, NarrowLoad);
}
}
@@ -3073,11 +3184,11 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
(!LegalOperations || TLI.isOperationLegal(ISD::AND, VT))) {
SDValue Op = N0.getOperand(0);
if (Op.getValueType().bitsLT(VT)) {
- Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op);
+ Op = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, Op);
} else if (Op.getValueType().bitsGT(VT)) {
- Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
+ Op = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Op);
}
- return DAG.getZeroExtendInReg(Op, N0.getValueType());
+ return DAG.getZeroExtendInReg(Op, N->getDebugLoc(), N0.getValueType());
}
// fold (zext (and (trunc x), cst)) -> (and x, cst).
@@ -3086,13 +3197,14 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
N0.getOperand(1).getOpcode() == ISD::Constant) {
SDValue X = N0.getOperand(0).getOperand(0);
if (X.getValueType().bitsLT(VT)) {
- X = DAG.getNode(ISD::ANY_EXTEND, VT, X);
+ X = DAG.getNode(ISD::ANY_EXTEND, X.getDebugLoc(), VT, X);
} else if (X.getValueType().bitsGT(VT)) {
- X = DAG.getNode(ISD::TRUNCATE, VT, X);
+ X = DAG.getNode(ISD::TRUNCATE, X.getDebugLoc(), VT, X);
}
APInt Mask = cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue();
Mask.zext(VT.getSizeInBits());
- return DAG.getNode(ISD::AND, VT, X, DAG.getConstant(Mask, VT));
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT,
+ X, DAG.getConstant(Mask, VT));
}
// fold (zext (load x)) -> (zext (truncate (zextload x)))
@@ -3105,29 +3217,37 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
DoXform = ExtendUsesToFormExtLoad(N, N0, ISD::ZERO_EXTEND, SetCCs, TLI);
if (DoXform) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N->getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
LN0->isVolatile(), LN0->getAlignment());
CombineTo(N, ExtLoad);
- SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad);
+ SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
+ N0.getValueType(), ExtLoad);
CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1));
+
// Extend SetCC uses if necessary.
for (unsigned i = 0, e = SetCCs.size(); i != e; ++i) {
SDNode *SetCC = SetCCs[i];
SmallVector<SDValue, 4> Ops;
+
for (unsigned j = 0; j != 2; ++j) {
SDValue SOp = SetCC->getOperand(j);
if (SOp == Trunc)
Ops.push_back(ExtLoad);
else
- Ops.push_back(DAG.getNode(ISD::ZERO_EXTEND, VT, SOp));
- }
+ Ops.push_back(DAG.getNode(ISD::ZERO_EXTEND,
+ N->getDebugLoc(), VT, SOp));
+ }
+
Ops.push_back(SetCC->getOperand(2));
- CombineTo(SetCC, DAG.getNode(ISD::SETCC, SetCC->getValueType(0),
+ CombineTo(SetCC, DAG.getNode(ISD::SETCC, N->getDebugLoc(),
+ SetCC->getValueType(0),
&Ops[0], Ops.size()));
}
+
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
}
@@ -3140,13 +3260,15 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
MVT EVT = LN0->getMemoryVT();
if ((!LegalOperations && !LN0->isVolatile()) ||
TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT)) {
- SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N->getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
- DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
+ DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(),
+ ExtLoad),
ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
@@ -3155,7 +3277,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
// zext(setcc x,y,cc) -> select_cc x, y, 1, 0, cc
if (N0.getOpcode() == ISD::SETCC) {
SDValue SCC =
- SimplifySelectCC(N0.getOperand(0), N0.getOperand(1),
+ SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1),
DAG.getConstant(1, VT), DAG.getConstant(0, VT),
cast<CondCodeSDNode>(N0.getOperand(2))->get(), true);
if (SCC.getNode()) return SCC;
@@ -3170,14 +3292,14 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
// fold (aext c1) -> c1
if (isa<ConstantSDNode>(N0))
- return DAG.getNode(ISD::ANY_EXTEND, VT, N0);
+ return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, N0);
// fold (aext (aext x)) -> (aext x)
// fold (aext (zext x)) -> (zext x)
// fold (aext (sext x)) -> (sext x)
if (N0.getOpcode() == ISD::ANY_EXTEND ||
N0.getOpcode() == ISD::ZERO_EXTEND ||
N0.getOpcode() == ISD::SIGN_EXTEND)
- return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0));
+ return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT, N0.getOperand(0));
// fold (aext (truncate (load x))) -> (aext (smaller load x))
// fold (aext (truncate (srl (load x), c))) -> (aext (small load (x+c/n)))
@@ -3186,7 +3308,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
if (NarrowLoad.getNode()) {
if (NarrowLoad.getNode() != N0.getNode())
CombineTo(N0.getNode(), NarrowLoad);
- return DAG.getNode(ISD::ANY_EXTEND, VT, NarrowLoad);
+ return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, NarrowLoad);
}
}
@@ -3196,8 +3318,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
if (TruncOp.getValueType() == VT)
return TruncOp; // x iff x size == zext size.
if (TruncOp.getValueType().bitsGT(VT))
- return DAG.getNode(ISD::TRUNCATE, VT, TruncOp);
- return DAG.getNode(ISD::ANY_EXTEND, VT, TruncOp);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, TruncOp);
+ return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, TruncOp);
}
// fold (aext (and (trunc x), cst)) -> (and x, cst).
@@ -3206,13 +3328,14 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
N0.getOperand(1).getOpcode() == ISD::Constant) {
SDValue X = N0.getOperand(0).getOperand(0);
if (X.getValueType().bitsLT(VT)) {
- X = DAG.getNode(ISD::ANY_EXTEND, VT, X);
+ X = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, X);
} else if (X.getValueType().bitsGT(VT)) {
- X = DAG.getNode(ISD::TRUNCATE, VT, X);
+ X = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, X);
}
APInt Mask = cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue();
Mask.zext(VT.getSizeInBits());
- return DAG.getNode(ISD::AND, VT, X, DAG.getConstant(Mask, VT));
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT,
+ X, DAG.getConstant(Mask, VT));
}
// fold (aext (load x)) -> (aext (truncate (extload x)))
@@ -3220,7 +3343,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
((!LegalOperations && !cast<LoadSDNode>(N0)->isVolatile()) ||
TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, N->getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
@@ -3231,7 +3355,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
SDValue(ExtLoad.getNode(), 1));
// If any node needs the original loaded value, recompute it.
if (!LN0->use_empty())
- CombineTo(LN0, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
+ CombineTo(LN0, DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
+ N0.getValueType(), ExtLoad),
ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
@@ -3244,14 +3369,15 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
N0.hasOneUse()) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
MVT EVT = LN0->getMemoryVT();
- SDValue ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), VT,
- LN0->getChain(), LN0->getBasePtr(),
+ SDValue ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), N->getDebugLoc(),
+ VT, LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
- DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
+ DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
+ N0.getValueType(), ExtLoad),
ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
@@ -3259,7 +3385,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
// aext(setcc x,y,cc) -> select_cc x, y, 1, 0, cc
if (N0.getOpcode() == ISD::SETCC) {
SDValue SCC =
- SimplifySelectCC(N0.getOperand(0), N0.getOperand(1),
+ SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1),
DAG.getConstant(1, VT), DAG.getConstant(0, VT),
cast<CondCodeSDNode>(N0.getOperand(2))->get(), true);
if (SCC.getNode())
@@ -3290,14 +3416,14 @@ SDValue DAGCombiner::GetDemandedBits(SDValue V, const APInt &Mask) {
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(V.getOperand(1))) {
// See if we can recursively simplify the LHS.
unsigned Amt = RHSC->getZExtValue();
+
// Watch out for shift count overflow though.
if (Amt >= Mask.getBitWidth()) break;
APInt NewMask = Mask << Amt;
SDValue SimplifyLHS = GetDemandedBits(V.getOperand(0), NewMask);
- if (SimplifyLHS.getNode()) {
- return DAG.getNode(ISD::SRL, V.getValueType(),
+ if (SimplifyLHS.getNode())
+ return DAG.getNode(ISD::SRL, V.getDebugLoc(), V.getValueType(),
SimplifyLHS, V.getOperand(1));
- }
}
}
return SDValue();
@@ -3350,6 +3476,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
!cast<LoadSDNode>(N0)->isVolatile()) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
MVT PtrType = N0.getOperand(1).getValueType();
+
// For big endian targets, we need to adjust the offset to the pointer to
// load the correct bytes.
if (TLI.isBigEndian()) {
@@ -3357,22 +3484,27 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
unsigned EVTStoreBits = EVT.getStoreSizeInBits();
ShAmt = LVTStoreBits - EVTStoreBits - ShAmt;
}
+
uint64_t PtrOff = ShAmt / 8;
unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff);
- SDValue NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(),
+ SDValue NewPtr = DAG.getNode(ISD::ADD, LN0->getDebugLoc(),
+ PtrType, LN0->getBasePtr(),
DAG.getConstant(PtrOff, PtrType));
AddToWorkList(NewPtr.getNode());
+
SDValue Load = (ExtType == ISD::NON_EXTLOAD)
- ? DAG.getLoad(VT, LN0->getChain(), NewPtr,
+ ? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
LN0->isVolatile(), NewAlign)
- : DAG.getExtLoad(ExtType, VT, LN0->getChain(), NewPtr,
+ : DAG.getExtLoad(ExtType, N0.getDebugLoc(), VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
EVT, LN0->isVolatile(), NewAlign);
+
// Replace the old load's chain with the new load's chain.
WorkListRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1),
&DeadNodes);
+
// Return the new loaded value.
return Load;
}
@@ -3380,7 +3512,6 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
return SDValue();
}
-
SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -3391,7 +3522,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
// fold (sext_in_reg c1) -> c1
if (isa<ConstantSDNode>(N0) || N0.getOpcode() == ISD::UNDEF)
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0, N1);
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, N0, N1);
// If the input is already sign extended, just drop the extension.
if (DAG.ComputeNumSignBits(N0) >= VT.getSizeInBits()-EVTBits+1)
@@ -3400,7 +3531,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
// fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2
if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
EVT.bitsLT(cast<VTSDNode>(N0.getOperand(1))->getVT())) {
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1);
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT,
+ N0.getOperand(0), N1);
}
// fold (sext_in_reg (sext x)) -> (sext x)
@@ -3409,12 +3541,12 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) {
SDValue N00 = N0.getOperand(0);
if (N00.getValueType().getSizeInBits() < EVTBits)
- return DAG.getNode(ISD::SIGN_EXTEND, VT, N00, N1);
+ return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, N00, N1);
}
// fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is known zero.
if (DAG.MaskedValueIsZero(N0, APInt::getBitsSet(VTBits, EVTBits-1, EVTBits)))
- return DAG.getZeroExtendInReg(N0, EVT);
+ return DAG.getZeroExtendInReg(N0, N->getDebugLoc(), EVT);
// fold operands of sext_in_reg based on knowledge that the top bits are not
// demanded.
@@ -3427,8 +3559,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
if (NarrowLoad.getNode())
return NarrowLoad;
- // fold (sext_in_reg (srl X, 24), i8) -> sra X, 24
- // fold (sext_in_reg (srl X, 23), i8) -> sra X, 23 iff possible.
+ // fold (sext_in_reg (srl X, 24), i8) -> (sra X, 24)
+ // fold (sext_in_reg (srl X, 23), i8) -> (sra X, 23) iff possible.
// We already fold "(sext_in_reg (srl X, 25), i8) -> srl X, 25" above.
if (N0.getOpcode() == ISD::SRL) {
if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
@@ -3437,7 +3569,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
// extended enough.
unsigned InSignBits = DAG.ComputeNumSignBits(N0.getOperand(0));
if (VT.getSizeInBits()-(ShAmt->getZExtValue()+EVTBits) < InSignBits)
- return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), N0.getOperand(1));
+ return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT,
+ N0.getOperand(0), N0.getOperand(1));
}
}
@@ -3448,7 +3581,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
((!LegalOperations && !cast<LoadSDNode>(N0)->isVolatile()) ||
TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
@@ -3463,7 +3597,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
((!LegalOperations && !cast<LoadSDNode>(N0)->isVolatile()) ||
TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
@@ -3483,19 +3618,20 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
return N0;
// fold (truncate c1) -> c1
if (isa<ConstantSDNode>(N0))
- return DAG.getNode(ISD::TRUNCATE, VT, N0);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, N0);
// fold (truncate (truncate x)) -> (truncate x)
if (N0.getOpcode() == ISD::TRUNCATE)
- return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0));
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, N0.getOperand(0));
// fold (truncate (ext x)) -> (ext x) or (truncate x) or x
if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND||
N0.getOpcode() == ISD::ANY_EXTEND) {
if (N0.getOperand(0).getValueType().bitsLT(VT))
// if the source is smaller than the dest, we still need an extend
- return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0));
+ return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT,
+ N0.getOperand(0));
else if (N0.getOperand(0).getValueType().bitsGT(VT))
// if the source is larger than the dest, than we just need the truncate
- return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0));
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, N0.getOperand(0));
else
// if the source and dest are the same type, we can drop both the extend
// and the truncate
@@ -3509,7 +3645,7 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
GetDemandedBits(N0, APInt::getLowBitsSet(N0.getValueSizeInBits(),
VT.getSizeInBits()));
if (Shorter.getNode())
- return DAG.getNode(ISD::TRUNCATE, VT, Shorter);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Shorter);
// fold (truncate (load x)) -> (smaller load x)
// fold (truncate (srl (load x), c)) -> (smaller load (x+c/evtbits))
@@ -3534,6 +3670,7 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, MVT VT) {
MVT LD1VT = LD1->getValueType(0);
SDNode *LD2 = getBuildPairElt(N, 1);
const MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+
if (ISD::isNON_EXTLoad(LD2) &&
LD2->hasOneUse() &&
// If both are volatile this would reduce the number of volatile loads.
@@ -3545,12 +3682,14 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, MVT VT) {
unsigned Align = LD->getAlignment();
unsigned NewAlign = TLI.getTargetData()->
getABITypeAlignment(VT.getTypeForMVT());
+
if (NewAlign <= Align &&
(!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT)))
- return DAG.getLoad(VT, LD->getChain(), LD->getBasePtr(),
+ return DAG.getLoad(VT, N->getDebugLoc(), LD->getChain(), LD->getBasePtr(),
LD->getSrcValue(), LD->getSrcValueOffset(),
false, Align);
}
+
return SDValue();
}
@@ -3577,19 +3716,20 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) {
MVT DestEltVT = N->getValueType(0).getVectorElementType();
assert(!DestEltVT.isVector() &&
"Element type of vector ValueType must not be vector!");
- if (isSimple) {
+ if (isSimple)
return ConstantFoldBIT_CONVERTofBUILD_VECTOR(N0.getNode(), DestEltVT);
- }
}
// If the input is a constant, let getNode fold it.
if (isa<ConstantSDNode>(N0) || isa<ConstantFPSDNode>(N0)) {
- SDValue Res = DAG.getNode(ISD::BIT_CONVERT, VT, N0);
+ SDValue Res = DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), VT, N0);
if (Res.getNode() != N) return Res;
}
- if (N0.getOpcode() == ISD::BIT_CONVERT) // conv(conv(x,t1),t2) -> conv(x,t2)
- return DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0));
+ // (conv (conv x, t1), t2) -> (conv x, t2)
+ if (N0.getOpcode() == ISD::BIT_CONVERT)
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), VT,
+ N0.getOperand(0));
// fold (conv (load x)) -> (load (conv*)x)
// If the resultant load doesn't need a higher alignment than the original!
@@ -3601,69 +3741,81 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) {
unsigned Align = TLI.getTargetData()->
getABITypeAlignment(VT.getTypeForMVT());
unsigned OrigAlign = LN0->getAlignment();
+
if (Align <= OrigAlign) {
- SDValue Load = DAG.getLoad(VT, LN0->getChain(), LN0->getBasePtr(),
+ SDValue Load = DAG.getLoad(VT, N->getDebugLoc(), LN0->getChain(),
+ LN0->getBasePtr(),
LN0->getSrcValue(), LN0->getSrcValueOffset(),
LN0->isVolatile(), OrigAlign);
AddToWorkList(N);
CombineTo(N0.getNode(),
- DAG.getNode(ISD::BIT_CONVERT, N0.getValueType(), Load),
+ DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(),
+ N0.getValueType(), Load),
Load.getValue(1));
return Load;
}
}
- // Fold bitconvert(fneg(x)) -> xor(bitconvert(x), signbit)
- // Fold bitconvert(fabs(x)) -> and(bitconvert(x), ~signbit)
+ // fold (bitconvert (fneg x)) -> (xor (bitconvert x), signbit)
+ // fold (bitconvert (fabs x)) -> (and (bitconvert x), (not signbit))
// This often reduces constant pool loads.
if ((N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FABS) &&
N0.getNode()->hasOneUse() && VT.isInteger() && !VT.isVector()) {
- SDValue NewConv = DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0));
+ SDValue NewConv = DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(), VT,
+ N0.getOperand(0));
AddToWorkList(NewConv.getNode());
APInt SignBit = APInt::getSignBit(VT.getSizeInBits());
if (N0.getOpcode() == ISD::FNEG)
- return DAG.getNode(ISD::XOR, VT, NewConv, DAG.getConstant(SignBit, VT));
+ return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT,
+ NewConv, DAG.getConstant(SignBit, VT));
assert(N0.getOpcode() == ISD::FABS);
- return DAG.getNode(ISD::AND, VT, NewConv, DAG.getConstant(~SignBit, VT));
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT,
+ NewConv, DAG.getConstant(~SignBit, VT));
}
- // Fold bitconvert(fcopysign(cst, x)) -> bitconvert(x)&sign | cst&~sign'
- // Note that we don't handle copysign(x,cst) because this can always be folded
- // to an fneg or fabs.
+ // fold (bitconvert (fcopysign cst, x)) ->
+ // (or (and (bitconvert x), sign), (and cst, (not sign)))
+ // Note that we don't handle (copysign x, cst) because this can always be
+ // folded to an fneg or fabs.
if (N0.getOpcode() == ISD::FCOPYSIGN && N0.getNode()->hasOneUse() &&
isa<ConstantFPSDNode>(N0.getOperand(0)) &&
VT.isInteger() && !VT.isVector()) {
unsigned OrigXWidth = N0.getOperand(1).getValueType().getSizeInBits();
MVT IntXVT = MVT::getIntegerVT(OrigXWidth);
if (TLI.isTypeLegal(IntXVT) || !LegalTypes) {
- SDValue X = DAG.getNode(ISD::BIT_CONVERT, IntXVT, N0.getOperand(1));
+ SDValue X = DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(),
+ IntXVT, N0.getOperand(1));
AddToWorkList(X.getNode());
// If X has a different width than the result/lhs, sext it or truncate it.
unsigned VTWidth = VT.getSizeInBits();
if (OrigXWidth < VTWidth) {
- X = DAG.getNode(ISD::SIGN_EXTEND, VT, X);
+ X = DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, X);
AddToWorkList(X.getNode());
} else if (OrigXWidth > VTWidth) {
// To get the sign bit in the right place, we have to shift it right
// before truncating.
- X = DAG.getNode(ISD::SRL, X.getValueType(), X,
+ X = DAG.getNode(ISD::SRL, X.getDebugLoc(),
+ X.getValueType(), X,
DAG.getConstant(OrigXWidth-VTWidth, X.getValueType()));
AddToWorkList(X.getNode());
- X = DAG.getNode(ISD::TRUNCATE, VT, X);
+ X = DAG.getNode(ISD::TRUNCATE, X.getDebugLoc(), VT, X);
AddToWorkList(X.getNode());
}
APInt SignBit = APInt::getSignBit(VT.getSizeInBits());
- X = DAG.getNode(ISD::AND, VT, X, DAG.getConstant(SignBit, VT));
+ X = DAG.getNode(ISD::AND, X.getDebugLoc(), VT,
+ X, DAG.getConstant(SignBit, VT));
AddToWorkList(X.getNode());
- SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0));
- Cst = DAG.getNode(ISD::AND, VT, Cst, DAG.getConstant(~SignBit, VT));
+ SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(),
+ VT, N0.getOperand(0));
+ Cst = DAG.getNode(ISD::AND, Cst.getDebugLoc(), VT,
+ Cst, DAG.getConstant(~SignBit, VT));
AddToWorkList(Cst.getNode());
- return DAG.getNode(ISD::OR, VT, X, Cst);
+ return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, X, Cst);
}
}
@@ -3700,12 +3852,14 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) {
if (SrcBitSize == DstBitSize) {
SmallVector<SDValue, 8> Ops;
for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
- Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, DstEltVT, BV->getOperand(i)));
+ Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, BV->getDebugLoc(),
+ DstEltVT, BV->getOperand(i)));
AddToWorkList(Ops.back().getNode());
}
MVT VT = MVT::getVectorVT(DstEltVT,
BV->getValueType(0).getVectorNumElements());
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
+ return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT,
+ &Ops[0], Ops.size());
}
// Otherwise, we're growing or shrinking the elements. To avoid having to
@@ -3755,13 +3909,14 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) {
}
if (EltIsUndef)
- Ops.push_back(DAG.getNode(ISD::UNDEF, DstEltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, BV->getDebugLoc(), DstEltVT));
else
Ops.push_back(DAG.getConstant(NewBits, DstEltVT));
}
MVT VT = MVT::getVectorVT(DstEltVT, Ops.size());
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
+ return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT,
+ &Ops[0], Ops.size());
}
// Finally, this must be the case where we are shrinking elements: each input
@@ -3770,19 +3925,23 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) {
unsigned NumOutputsPerInput = SrcBitSize/DstBitSize;
MVT VT = MVT::getVectorVT(DstEltVT, NumOutputsPerInput*BV->getNumOperands());
SmallVector<SDValue, 8> Ops;
+
for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
if (BV->getOperand(i).getOpcode() == ISD::UNDEF) {
for (unsigned j = 0; j != NumOutputsPerInput; ++j)
- Ops.push_back(DAG.getNode(ISD::UNDEF, DstEltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, BV->getDebugLoc(), DstEltVT));
continue;
}
+
APInt OpVal = cast<ConstantSDNode>(BV->getOperand(i))->getAPIntValue();
+
for (unsigned j = 0; j != NumOutputsPerInput; ++j) {
APInt ThisVal = APInt(OpVal).trunc(DstBitSize);
Ops.push_back(DAG.getConstant(ThisVal, DstEltVT));
if (isS2V && i == 0 && j == 0 && APInt(ThisVal).zext(SrcBitSize) == OpVal)
// Simply turn this into a SCALAR_TO_VECTOR of the new type.
- return DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Ops[0]);
+ return DAG.getNode(ISD::SCALAR_TO_VECTOR, BV->getDebugLoc(), VT,
+ Ops[0]);
OpVal = OpVal.lshr(DstBitSize);
}
@@ -3790,10 +3949,10 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) {
if (TLI.isBigEndian())
std::reverse(Ops.end()-NumOutputsPerInput, Ops.end());
}
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
-}
-
+ return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT,
+ &Ops[0], Ops.size());
+}
SDValue DAGCombiner::visitFADD(SDNode *N) {
SDValue N0 = N->getOperand(0);
@@ -3808,29 +3967,30 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
if (FoldedVOp.getNode()) return FoldedVOp;
}
- // fold (fadd c1, c2) -> c1+c2
+ // fold (fadd c1, c2) -> (fadd c1, c2)
if (N0CFP && N1CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FADD, VT, N0, N1);
+ return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, N1);
// canonicalize constant to RHS
if (N0CFP && !N1CFP)
- return DAG.getNode(ISD::FADD, VT, N1, N0);
- // fold (A + 0) -> A
+ return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N1, N0);
+ // fold (fadd A, 0) -> A
if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero())
return N0;
- // fold (A + (-B)) -> A-B
+ // fold (fadd A, (fneg B)) -> (fsub A, B)
if (isNegatibleForFree(N1, LegalOperations) == 2)
- return DAG.getNode(ISD::FSUB, VT, N0,
+ return DAG.getNode(ISD::FSUB, N->getDebugLoc(), VT, N0,
GetNegatedExpression(N1, DAG, LegalOperations));
- // fold ((-A) + B) -> B-A
+ // fold (fadd (fneg A), B) -> (fsub B, A)
if (isNegatibleForFree(N0, LegalOperations) == 2)
- return DAG.getNode(ISD::FSUB, VT, N1,
+ return DAG.getNode(ISD::FSUB, N->getDebugLoc(), VT, N1,
GetNegatedExpression(N0, DAG, LegalOperations));
// If allowed, fold (fadd (fadd x, c1), c2) -> (fadd x, (fadd c1, c2))
if (UnsafeFPMath && N1CFP && N0.getOpcode() == ISD::FADD &&
N0.getNode()->hasOneUse() && isa<ConstantFPSDNode>(N0.getOperand(1)))
- return DAG.getNode(ISD::FADD, VT, N0.getOperand(0),
- DAG.getNode(ISD::FADD, VT, N0.getOperand(1), N1));
+ return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0.getOperand(0),
+ DAG.getNode(ISD::FADD, N->getDebugLoc(), VT,
+ N0.getOperand(1), N1));
return SDValue();
}
@@ -3850,20 +4010,20 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
// fold (fsub c1, c2) -> c1-c2
if (N0CFP && N1CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FSUB, VT, N0, N1);
- // fold (A-0) -> A
+ return DAG.getNode(ISD::FSUB, N->getDebugLoc(), VT, N0, N1);
+ // fold (fsub A, 0) -> A
if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero())
return N0;
- // fold (0-B) -> -B
+ // fold (fsub 0, B) -> -B
if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) {
if (isNegatibleForFree(N1, LegalOperations))
return GetNegatedExpression(N1, DAG, LegalOperations);
if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
- return DAG.getNode(ISD::FNEG, VT, N1);
+ return DAG.getNode(ISD::FNEG, N->getDebugLoc(), VT, N1);
}
- // fold (A-(-B)) -> A+B
+ // fold (fsub A, (fneg B)) -> (fadd A, B)
if (isNegatibleForFree(N1, LegalOperations))
- return DAG.getNode(ISD::FADD, VT, N0,
+ return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0,
GetNegatedExpression(N1, DAG, LegalOperations));
return SDValue();
@@ -3884,28 +4044,28 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
// fold (fmul c1, c2) -> c1*c2
if (N0CFP && N1CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FMUL, VT, N0, N1);
+ return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, N0, N1);
// canonicalize constant to RHS
if (N0CFP && !N1CFP)
- return DAG.getNode(ISD::FMUL, VT, N1, N0);
- // fold (A * 0) -> 0
+ return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, N1, N0);
+ // fold (fmul A, 0) -> 0
if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero())
return N1;
// fold (fmul X, 2.0) -> (fadd X, X)
if (N1CFP && N1CFP->isExactlyValue(+2.0))
- return DAG.getNode(ISD::FADD, VT, N0, N0);
- // fold (fmul X, -1.0) -> (fneg X)
+ return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, N0);
+ // fold (fmul X, (fneg 1.0)) -> (fneg X)
if (N1CFP && N1CFP->isExactlyValue(-1.0))
if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
- return DAG.getNode(ISD::FNEG, VT, N0);
+ return DAG.getNode(ISD::FNEG, N->getDebugLoc(), VT, N0);
- // -X * -Y -> X*Y
+ // fold (fmul (fneg X), (fneg Y)) -> (fmul X, Y)
if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) {
if (char RHSNeg = isNegatibleForFree(N1, LegalOperations)) {
// Both can be negated for free, check to see if at least one is cheaper
// negated.
if (LHSNeg == 2 || RHSNeg == 2)
- return DAG.getNode(ISD::FMUL, VT,
+ return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT,
GetNegatedExpression(N0, DAG, LegalOperations),
GetNegatedExpression(N1, DAG, LegalOperations));
}
@@ -3914,7 +4074,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
// If allowed, fold (fmul (fmul x, c1), c2) -> (fmul x, (fmul c1, c2))
if (UnsafeFPMath && N1CFP && N0.getOpcode() == ISD::FMUL &&
N0.getNode()->hasOneUse() && isa<ConstantFPSDNode>(N0.getOperand(1)))
- return DAG.getNode(ISD::FMUL, VT, N0.getOperand(0),
+ return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, N0.getOperand(0),
DAG.getNode(ISD::FMUL, VT, N0.getOperand(1), N1));
return SDValue();
@@ -3935,16 +4095,16 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
// fold (fdiv c1, c2) -> c1/c2
if (N0CFP && N1CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FDIV, VT, N0, N1);
+ return DAG.getNode(ISD::FDIV, N->getDebugLoc(), VT, N0, N1);
- // -X / -Y -> X*Y
+ // (fdiv (fneg X), (fneg Y)) -> (fdiv X, Y)
if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) {
if (char RHSNeg = isNegatibleForFree(N1, LegalOperations)) {
// Both can be negated for free, check to see if at least one is cheaper
// negated.
if (LHSNeg == 2 || RHSNeg == 2)
- return DAG.getNode(ISD::FDIV, VT,
+ return DAG.getNode(ISD::FDIV, N->getDebugLoc(), VT,
GetNegatedExpression(N0, DAG, LegalOperations),
GetNegatedExpression(N1, DAG, LegalOperations));
}
@@ -3962,7 +4122,7 @@ SDValue DAGCombiner::visitFREM(SDNode *N) {
// fold (frem c1, c2) -> fmod(c1,c2)
if (N0CFP && N1CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FREM, VT, N0, N1);
+ return DAG.getNode(ISD::FREM, N->getDebugLoc(), VT, N0, N1);
return SDValue();
}
@@ -3975,7 +4135,7 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
MVT VT = N->getValueType(0);
if (N0CFP && N1CFP && VT != MVT::ppcf128) // Constant fold
- return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1);
+ return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT, N0, N1);
if (N1CFP) {
const APFloat& V = N1CFP->getValueAPF();
@@ -3983,10 +4143,11 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
// copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1)
if (!V.isNegative()) {
if (!LegalOperations || TLI.isOperationLegal(ISD::FABS, VT))
- return DAG.getNode(ISD::FABS, VT, N0);
+ return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0);
} else {
if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
- return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0));
+ return DAG.getNode(ISD::FNEG, N->getDebugLoc(), VT,
+ DAG.getNode(ISD::FABS, N0.getDebugLoc(), VT, N0));
}
}
@@ -3995,26 +4156,27 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
// copysign(copysign(x,z), y) -> copysign(x, y)
if (N0.getOpcode() == ISD::FABS || N0.getOpcode() == ISD::FNEG ||
N0.getOpcode() == ISD::FCOPYSIGN)
- return DAG.getNode(ISD::FCOPYSIGN, VT, N0.getOperand(0), N1);
+ return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT,
+ N0.getOperand(0), N1);
// copysign(x, abs(y)) -> abs(x)
if (N1.getOpcode() == ISD::FABS)
- return DAG.getNode(ISD::FABS, VT, N0);
+ return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0);
// copysign(x, copysign(y,z)) -> copysign(x, z)
if (N1.getOpcode() == ISD::FCOPYSIGN)
- return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(1));
+ return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT,
+ N0, N1.getOperand(1));
// copysign(x, fp_extend(y)) -> copysign(x, y)
// copysign(x, fp_round(y)) -> copysign(x, y)
if (N1.getOpcode() == ISD::FP_EXTEND || N1.getOpcode() == ISD::FP_ROUND)
- return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(0));
+ return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT,
+ N0, N1.getOperand(0));
return SDValue();
}
-
-
SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
SDValue N0 = N->getOperand(0);
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
@@ -4023,18 +4185,17 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
// fold (sint_to_fp c1) -> c1fp
if (N0C && OpVT != MVT::ppcf128)
- return DAG.getNode(ISD::SINT_TO_FP, VT, N0);
+ return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0);
// If the input is a legal type, and SINT_TO_FP is not legal on this target,
// but UINT_TO_FP is legal on this target, try to convert.
- if (!TLI.isOperationLegal(ISD::SINT_TO_FP, OpVT) &&
- TLI.isOperationLegal(ISD::UINT_TO_FP, OpVT)) {
+ if (!TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, OpVT) &&
+ TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, OpVT)) {
// If the sign bit is known to be zero, we can change this to UINT_TO_FP.
if (DAG.SignBitIsZero(N0))
- return DAG.getNode(ISD::UINT_TO_FP, VT, N0);
+ return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0);
}
-
-
+
return SDValue();
}
@@ -4046,15 +4207,15 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) {
// fold (uint_to_fp c1) -> c1fp
if (N0C && OpVT != MVT::ppcf128)
- return DAG.getNode(ISD::UINT_TO_FP, VT, N0);
+ return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0);
// If the input is a legal type, and UINT_TO_FP is not legal on this target,
// but SINT_TO_FP is legal on this target, try to convert.
- if (!TLI.isOperationLegal(ISD::UINT_TO_FP, OpVT) &&
- TLI.isOperationLegal(ISD::SINT_TO_FP, OpVT)) {
+ if (!TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, OpVT) &&
+ TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, OpVT)) {
// If the sign bit is known to be zero, we can change this to SINT_TO_FP.
if (DAG.SignBitIsZero(N0))
- return DAG.getNode(ISD::SINT_TO_FP, VT, N0);
+ return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0);
}
return SDValue();
@@ -4067,7 +4228,8 @@ SDValue DAGCombiner::visitFP_TO_SINT(SDNode *N) {
// fold (fp_to_sint c1fp) -> c1
if (N0CFP)
- return DAG.getNode(ISD::FP_TO_SINT, VT, N0);
+ return DAG.getNode(ISD::FP_TO_SINT, N->getDebugLoc(), VT, N0);
+
return SDValue();
}
@@ -4078,7 +4240,8 @@ SDValue DAGCombiner::visitFP_TO_UINT(SDNode *N) {
// fold (fp_to_uint c1fp) -> c1
if (N0CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FP_TO_UINT, VT, N0);
+ return DAG.getNode(ISD::FP_TO_UINT, N->getDebugLoc(), VT, N0);
+
return SDValue();
}
@@ -4090,7 +4253,7 @@ SDValue DAGCombiner::visitFP_ROUND(SDNode *N) {
// fold (fp_round c1fp) -> c1fp
if (N0CFP && N0.getValueType() != MVT::ppcf128)
- return DAG.getNode(ISD::FP_ROUND, VT, N0, N1);
+ return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), VT, N0, N1);
// fold (fp_round (fp_extend x)) -> x
if (N0.getOpcode() == ISD::FP_EXTEND && VT == N0.getOperand(0).getValueType())
@@ -4101,15 +4264,17 @@ SDValue DAGCombiner::visitFP_ROUND(SDNode *N) {
// This is a value preserving truncation if both round's are.
bool IsTrunc = N->getConstantOperandVal(1) == 1 &&
N0.getNode()->getConstantOperandVal(1) == 1;
- return DAG.getNode(ISD::FP_ROUND, VT, N0.getOperand(0),
+ return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), VT, N0.getOperand(0),
DAG.getIntPtrConstant(IsTrunc));
}
// fold (fp_round (copysign X, Y)) -> (copysign (fp_round X), Y)
if (N0.getOpcode() == ISD::FCOPYSIGN && N0.getNode()->hasOneUse()) {
- SDValue Tmp = DAG.getNode(ISD::FP_ROUND, VT, N0.getOperand(0), N1);
+ SDValue Tmp = DAG.getNode(ISD::FP_ROUND, N0.getDebugLoc(), VT,
+ N0.getOperand(0), N1);
AddToWorkList(Tmp.getNode());
- return DAG.getNode(ISD::FCOPYSIGN, VT, Tmp, N0.getOperand(1));
+ return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT,
+ Tmp, N0.getOperand(1));
}
return SDValue();
@@ -4124,8 +4289,9 @@ SDValue DAGCombiner::visitFP_ROUND_INREG(SDNode *N) {
// fold (fp_round_inreg c1fp) -> c1fp
if (N0CFP && (TLI.isTypeLegal(EVT) || !LegalTypes)) {
SDValue Round = DAG.getConstantFP(*N0CFP->getConstantFPValue(), EVT);
- return DAG.getNode(ISD::FP_EXTEND, VT, Round);
+ return DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), VT, Round);
}
+
return SDValue();
}
@@ -4136,12 +4302,12 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {
// If this is fp_round(fpextend), don't fold it, allow ourselves to be folded.
if (N->hasOneUse() &&
- N->use_begin().getUse().getSDValue().getOpcode() == ISD::FP_ROUND)
+ N->use_begin()->getOpcode() == ISD::FP_ROUND)
return SDValue();
// fold (fp_extend c1fp) -> c1fp
if (N0CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FP_EXTEND, VT, N0);
+ return DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), VT, N0);
// Turn fp_extend(fp_round(X, 1)) -> x since the fp_round doesn't affect the
// value of X.
@@ -4150,8 +4316,9 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {
SDValue In = N0.getOperand(0);
if (In.getValueType() == VT) return In;
if (VT.bitsLT(In.getValueType()))
- return DAG.getNode(ISD::FP_ROUND, VT, In, N0.getOperand(1));
- return DAG.getNode(ISD::FP_EXTEND, VT, In);
+ return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), VT,
+ In, N0.getOperand(1));
+ return DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), VT, In);
}
// fold (fpext (load x)) -> (fpext (fptrunc (extload x)))
@@ -4159,14 +4326,16 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {
((!LegalOperations && !cast<LoadSDNode>(N0)->isVolatile()) ||
TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
+ SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, N->getDebugLoc(), VT,
+ LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
LN0->isVolatile(), LN0->getAlignment());
CombineTo(N, ExtLoad);
- CombineTo(N0.getNode(), DAG.getNode(ISD::FP_ROUND, N0.getValueType(),
- ExtLoad, DAG.getIntPtrConstant(1)),
+ CombineTo(N0.getNode(),
+ DAG.getNode(ISD::FP_ROUND, N0.getDebugLoc(),
+ N0.getValueType(), ExtLoad, DAG.getIntPtrConstant(1)),
ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
@@ -4188,10 +4357,11 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) {
SDValue Int = N0.getOperand(0);
MVT IntVT = Int.getValueType();
if (IntVT.isInteger() && !IntVT.isVector()) {
- Int = DAG.getNode(ISD::XOR, IntVT, Int,
- DAG.getConstant(IntVT.getIntegerVTSignBit(), IntVT));
+ Int = DAG.getNode(ISD::XOR, N0.getDebugLoc(), IntVT, Int,
+ DAG.getConstant(APInt::getSignBit(IntVT.getSizeInBits()), IntVT));
AddToWorkList(Int.getNode());
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Int);
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(),
+ N->getValueType(0), Int);
}
}
@@ -4205,14 +4375,14 @@ SDValue DAGCombiner::visitFABS(SDNode *N) {
// fold (fabs c1) -> fabs(c1)
if (N0CFP && VT != MVT::ppcf128)
- return DAG.getNode(ISD::FABS, VT, N0);
+ return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0);
// fold (fabs (fabs x)) -> (fabs x)
if (N0.getOpcode() == ISD::FABS)
return N->getOperand(0);
// fold (fabs (fneg x)) -> (fabs x)
// fold (fabs (fcopysign x, y)) -> (fabs x)
if (N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FCOPYSIGN)
- return DAG.getNode(ISD::FABS, VT, N0.getOperand(0));
+ return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0.getOperand(0));
// Transform fabs(bitconvert(x)) -> bitconvert(x&~sign) to avoid loading
// constant pool values.
@@ -4222,10 +4392,11 @@ SDValue DAGCombiner::visitFABS(SDNode *N) {
SDValue Int = N0.getOperand(0);
MVT IntVT = Int.getValueType();
if (IntVT.isInteger() && !IntVT.isVector()) {
- Int = DAG.getNode(ISD::AND, IntVT, Int,
- DAG.getConstant(~IntVT.getIntegerVTSignBit(), IntVT));
+ Int = DAG.getNode(ISD::AND, N0.getDebugLoc(), IntVT, Int,
+ DAG.getConstant(~APInt::getSignBit(IntVT.getSizeInBits()), IntVT));
AddToWorkList(Int.getNode());
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Int);
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(),
+ N->getValueType(0), Int);
}
}
@@ -4243,14 +4414,16 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
return Chain;
// unconditional branch
if (N1C && N1C->getAPIntValue() == 1)
- return DAG.getNode(ISD::BR, MVT::Other, Chain, N2);
+ return DAG.getNode(ISD::BR, N->getDebugLoc(), MVT::Other, Chain, N2);
// fold a brcond with a setcc condition into a BR_CC node if BR_CC is legal
// on the target.
if (N1.getOpcode() == ISD::SETCC &&
- TLI.isOperationLegal(ISD::BR_CC, MVT::Other)) {
- return DAG.getNode(ISD::BR_CC, MVT::Other, Chain, N1.getOperand(2),
+ TLI.isOperationLegalOrCustom(ISD::BR_CC, MVT::Other)) {
+ return DAG.getNode(ISD::BR_CC, N->getDebugLoc(), MVT::Other,
+ Chain, N1.getOperand(2),
N1.getOperand(0), N1.getOperand(1), N2);
}
+
return SDValue();
}
@@ -4262,28 +4435,30 @@ SDValue DAGCombiner::visitBR_CC(SDNode *N) {
// Use SimplifySetCC to simplify SETCC's.
SDValue Simp = SimplifySetCC(TLI.getSetCCResultType(CondLHS.getValueType()),
- CondLHS, CondRHS, CC->get(), false);
+ CondLHS, CondRHS, CC->get(), N->getDebugLoc(),
+ false);
if (Simp.getNode()) AddToWorkList(Simp.getNode());
ConstantSDNode *SCCC = dyn_cast_or_null<ConstantSDNode>(Simp.getNode());
// fold br_cc true, dest -> br dest (unconditional branch)
if (SCCC && !SCCC->isNullValue())
- return DAG.getNode(ISD::BR, MVT::Other, N->getOperand(0),
- N->getOperand(4));
+ return DAG.getNode(ISD::BR, N->getDebugLoc(), MVT::Other,
+ N->getOperand(0), N->getOperand(4));
// fold br_cc false, dest -> unconditional fall through
if (SCCC && SCCC->isNullValue())
return N->getOperand(0);
// fold to a simpler setcc
if (Simp.getNode() && Simp.getOpcode() == ISD::SETCC)
- return DAG.getNode(ISD::BR_CC, MVT::Other, N->getOperand(0),
- Simp.getOperand(2), Simp.getOperand(0),
- Simp.getOperand(1), N->getOperand(4));
+ return DAG.getNode(ISD::BR_CC, N->getDebugLoc(), MVT::Other,
+ N->getOperand(0), Simp.getOperand(2),
+ Simp.getOperand(0), Simp.getOperand(1),
+ N->getOperand(4));
+
return SDValue();
}
-
/// CombineToPreIndexedLoadStore - Try turning a load / store into a
/// pre-indexed load / store when the base pointer is an add or subtract
/// and it has other uses besides the load / store. After the
@@ -4314,8 +4489,9 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
return false;
Ptr = ST->getBasePtr();
isLoad = false;
- } else
+ } else {
return false;
+ }
// If the pointer is not an add/sub, or if it doesn't have multiple uses, bail
// out. There is no reason to make this a preinc/predec.
@@ -4370,14 +4546,17 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
cast<StoreSDNode>(Use)->getBasePtr() == Ptr)))
RealUse = true;
}
+
if (!RealUse)
return false;
SDValue Result;
if (isLoad)
- Result = DAG.getIndexedLoad(SDValue(N,0), BasePtr, Offset, AM);
+ Result = DAG.getIndexedLoad(SDValue(N,0), N->getDebugLoc(),
+ BasePtr, Offset, AM);
else
- Result = DAG.getIndexedStore(SDValue(N,0), BasePtr, Offset, AM);
+ Result = DAG.getIndexedStore(SDValue(N,0), N->getDebugLoc(),
+ BasePtr, Offset, AM);
++PreIndexedNodes;
++NodesCombined;
DOUT << "\nReplacing.4 "; DEBUG(N->dump(&DAG));
@@ -4435,8 +4614,9 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
return false;
Ptr = ST->getBasePtr();
isLoad = false;
- } else
+ } else {
return false;
+ }
if (Ptr.getNode()->hasOneUse())
return false;
@@ -4495,14 +4675,17 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
}
}
}
+
if (TryNext)
continue;
// Check for #2
if (!Op->isPredecessorOf(N) && !N->isPredecessorOf(Op)) {
SDValue Result = isLoad
- ? DAG.getIndexedLoad(SDValue(N,0), BasePtr, Offset, AM)
- : DAG.getIndexedStore(SDValue(N,0), BasePtr, Offset, AM);
+ ? DAG.getIndexedLoad(SDValue(N,0), N->getDebugLoc(),
+ BasePtr, Offset, AM)
+ : DAG.getIndexedStore(SDValue(N,0), N->getDebugLoc(),
+ BasePtr, Offset, AM);
++PostIndexedNodes;
++NodesCombined;
DOUT << "\nReplacing.5 "; DEBUG(N->dump(&DAG));
@@ -4532,6 +4715,7 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
}
}
}
+
return false;
}
@@ -4587,13 +4771,13 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
if (!Fast && LD->isUnindexed()) {
if (unsigned Align = InferAlignment(Ptr, DAG)) {
if (Align > LD->getAlignment())
- return DAG.getExtLoad(LD->getExtensionType(), LD->getValueType(0),
+ return DAG.getExtLoad(LD->getExtensionType(), N->getDebugLoc(),
+ LD->getValueType(0),
Chain, Ptr, LD->getSrcValue(),
LD->getSrcValueOffset(), LD->getMemoryVT(),
LD->isVolatile(), Align);
}
}
-
// If load is not volatile and there are no uses of the loaded value (and
// the updated indexed value in case of indexed loads), change uses of the
@@ -4613,24 +4797,28 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
DOUT << "\n";
WorkListRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), Chain, &DeadNodes);
+
if (N->use_empty()) {
removeFromWorkList(N);
DAG.DeleteNode(N);
}
+
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
} else {
// Indexed loads.
assert(N->getValueType(2) == MVT::Other && "Malformed indexed loads?");
if (N->hasNUsesOfValue(0, 0) && N->hasNUsesOfValue(0, 1)) {
- SDValue Undef = DAG.getNode(ISD::UNDEF, N->getValueType(0));
+ SDValue Undef = DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
+ N->getValueType(0));
DOUT << "\nReplacing.6 "; DEBUG(N->dump(&DAG));
DOUT << "\nWith: "; DEBUG(Undef.getNode()->dump(&DAG));
DOUT << " and 2 other values\n";
WorkListRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Undef, &DeadNodes);
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1),
- DAG.getNode(ISD::UNDEF, N->getValueType(1)),
+ DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
+ N->getValueType(1)),
&DeadNodes);
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 2), Chain, &DeadNodes);
removeFromWorkList(N);
@@ -4664,11 +4852,12 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
// Replace the chain to void dependency.
if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
- ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr,
+ ReplLoad = DAG.getLoad(N->getValueType(0), LD->getDebugLoc(),
+ BetterChain, Ptr,
LD->getSrcValue(), LD->getSrcValueOffset(),
LD->isVolatile(), LD->getAlignment());
} else {
- ReplLoad = DAG.getExtLoad(LD->getExtensionType(),
+ ReplLoad = DAG.getExtLoad(LD->getExtensionType(), LD->getDebugLoc(),
LD->getValueType(0),
BetterChain, Ptr, LD->getSrcValue(),
LD->getSrcValueOffset(),
@@ -4678,8 +4867,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
}
// Create token factor to keep old chain connected.
- SDValue Token = DAG.getNode(ISD::TokenFactor, MVT::Other,
- Chain, ReplLoad.getValue(1));
+ SDValue Token = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(),
+ MVT::Other, Chain, ReplLoad.getValue(1));
// Replace uses with load result and token factor. Don't add users
// to work list.
@@ -4694,7 +4883,6 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
return SDValue();
}
-
SDValue DAGCombiner::visitSTORE(SDNode *N) {
StoreSDNode *ST = cast<StoreSDNode>(N);
SDValue Chain = ST->getChain();
@@ -4705,7 +4893,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
if (!Fast && ST->isUnindexed()) {
if (unsigned Align = InferAlignment(Ptr, DAG)) {
if (Align > ST->getAlignment())
- return DAG.getTruncStore(Chain, Value, Ptr, ST->getSrcValue(),
+ return DAG.getTruncStore(Chain, N->getDebugLoc(), Value,
+ Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
ST->isVolatile(), Align);
}
@@ -4721,8 +4910,9 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
getABITypeAlignment(SVT.getTypeForMVT());
if (Align <= OrigAlign &&
((!LegalOperations && !ST->isVolatile()) ||
- TLI.isOperationLegal(ISD::STORE, SVT)))
- return DAG.getStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(),
+ TLI.isOperationLegalOrCustom(ISD::STORE, SVT)))
+ return DAG.getStore(Chain, N->getDebugLoc(), Value.getOperand(0),
+ Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(), OrigAlign);
}
@@ -4742,24 +4932,28 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
break;
case MVT::f32:
if (((TLI.isTypeLegal(MVT::i32) || !LegalTypes) && !LegalOperations &&
- !ST->isVolatile()) || TLI.isOperationLegal(ISD::STORE, MVT::i32)) {
+ !ST->isVolatile()) ||
+ TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) {
Tmp = DAG.getConstant((uint32_t)CFP->getValueAPF().
bitcastToAPInt().getZExtValue(), MVT::i32);
- return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(),
+ return DAG.getStore(Chain, N->getDebugLoc(), Tmp,
+ Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
ST->getAlignment());
}
break;
case MVT::f64:
if (((TLI.isTypeLegal(MVT::i64) || !LegalTypes) && !LegalOperations &&
- !ST->isVolatile()) || TLI.isOperationLegal(ISD::STORE, MVT::i64)) {
+ !ST->isVolatile()) ||
+ TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i64)) {
Tmp = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt().
- getZExtValue(), MVT::i64);
- return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(),
+ getZExtValue(), MVT::i64);
+ return DAG.getStore(Chain, N->getDebugLoc(), Tmp,
+ Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
ST->getAlignment());
} else if (!ST->isVolatile() &&
- TLI.isOperationLegal(ISD::STORE, MVT::i32)) {
+ TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) {
// Many FP stores are not made apparent until after legalize, e.g. for
// argument passing. Since this is so common, custom legalize the
// 64-bit integer store into two 32-bit stores.
@@ -4772,17 +4966,21 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
unsigned Alignment = ST->getAlignment();
bool isVolatile = ST->isVolatile();
- SDValue St0 = DAG.getStore(Chain, Lo, Ptr, ST->getSrcValue(),
- ST->getSrcValueOffset(),
- isVolatile, ST->getAlignment());
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ SDValue St0 = DAG.getStore(Chain, ST->getDebugLoc(), Lo,
+ Ptr, ST->getSrcValue(),
+ ST->getSrcValueOffset(),
+ isVolatile, 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, Hi, Ptr, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
- return DAG.getNode(ISD::TokenFactor, MVT::Other, St0, St1);
+ SDValue St1 = DAG.getStore(Chain, ST->getDebugLoc(), Hi,
+ Ptr, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ return DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), MVT::Other,
+ St0, St1);
}
+
break;
}
}
@@ -4797,20 +4995,20 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
// Replace the chain to avoid dependency.
SDValue ReplStore;
if (ST->isTruncatingStore()) {
- ReplStore = DAG.getTruncStore(BetterChain, Value, Ptr,
+ ReplStore = DAG.getTruncStore(BetterChain, N->getDebugLoc(), Value, Ptr,
ST->getSrcValue(),ST->getSrcValueOffset(),
ST->getMemoryVT(),
ST->isVolatile(), ST->getAlignment());
} else {
- ReplStore = DAG.getStore(BetterChain, Value, Ptr,
+ ReplStore = DAG.getStore(BetterChain, N->getDebugLoc(), Value, Ptr,
ST->getSrcValue(), ST->getSrcValueOffset(),
ST->isVolatile(), ST->getAlignment());
}
// Create token to keep both nodes around.
- SDValue Token =
- DAG.getNode(ISD::TokenFactor, MVT::Other, Chain, ReplStore);
-
+ SDValue Token = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(),
+ MVT::Other, Chain, ReplStore);
+
// Don't add users to work list.
return CombineTo(N, Token, false);
}
@@ -4828,11 +5026,12 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
// "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8"
SDValue Shorter =
GetDemandedBits(Value,
- APInt::getLowBitsSet(Value.getValueSizeInBits(),
- ST->getMemoryVT().getSizeInBits()));
+ APInt::getLowBitsSet(Value.getValueSizeInBits(),
+ ST->getMemoryVT().getSizeInBits()));
AddToWorkList(Value.getNode());
if (Shorter.getNode())
- return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(),
+ return DAG.getTruncStore(Chain, N->getDebugLoc(), Shorter,
+ Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
ST->isVolatile(), ST->getAlignment());
@@ -4864,7 +5063,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
&& Value.getNode()->hasOneUse() && ST->isUnindexed() &&
TLI.isTruncStoreLegal(Value.getOperand(0).getValueType(),
ST->getMemoryVT())) {
- return DAG.getTruncStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(),
+ return DAG.getTruncStore(Chain, N->getDebugLoc(), Value.getOperand(0),
+ Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
ST->isVolatile(), ST->getAlignment());
}
@@ -4885,8 +5085,8 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) {
InVec.getNode()->op_end());
if (Elt < Ops.size())
Ops[Elt] = InVal;
- return DAG.getNode(ISD::BUILD_VECTOR, InVec.getValueType(),
- &Ops[0], Ops.size());
+ return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
+ InVec.getValueType(), &Ops[0], Ops.size());
}
return SDValue();
@@ -4915,6 +5115,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
MVT VT = InVec.getValueType();
MVT EVT = VT.getVectorElementType();
MVT LVT = EVT;
+
if (InVec.getOpcode() == ISD::BIT_CONVERT) {
MVT BCVT = InVec.getOperand(0).getValueType();
if (!BCVT.isVector() || EVT.bitsGT(BCVT.getVectorElementType()))
@@ -4927,11 +5128,11 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
}
LoadSDNode *LN0 = NULL;
- if (ISD::isNormalLoad(InVec.getNode()))
+ if (ISD::isNormalLoad(InVec.getNode())) {
LN0 = cast<LoadSDNode>(InVec);
- else if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR &&
- InVec.getOperand(0).getValueType() == EVT &&
- ISD::isNormalLoad(InVec.getOperand(0).getNode())) {
+ } else if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR &&
+ InVec.getOperand(0).getValueType() == EVT &&
+ ISD::isNormalLoad(InVec.getOperand(0).getNode())) {
LN0 = cast<LoadSDNode>(InVec.getOperand(0));
} else if (InVec.getOpcode() == ISD::VECTOR_SHUFFLE) {
// (vextract (vector_shuffle (load $addr), v2, <1, u, u, u>), 1)
@@ -4953,6 +5154,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
Elt = (Idx < NumElems) ? Idx : Idx - NumElems;
}
}
+
if (!LN0 || !LN0->hasOneUse() || LN0->isVolatile())
return SDValue();
@@ -4960,10 +5162,12 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
if (NewLoad) {
// Check the resultant load doesn't need a higher alignment than the
// original load.
- unsigned NewAlign = TLI.getTargetData()->
- getABITypeAlignment(LVT.getTypeForMVT());
- if (NewAlign > Align || !TLI.isOperationLegal(ISD::LOAD, LVT))
+ unsigned NewAlign =
+ TLI.getTargetData()->getABITypeAlignment(LVT.getTypeForMVT());
+
+ if (NewAlign > Align || !TLI.isOperationLegalOrCustom(ISD::LOAD, LVT))
return SDValue();
+
Align = NewAlign;
}
@@ -4973,16 +5177,17 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
MVT PtrType = NewPtr.getValueType();
if (TLI.isBigEndian())
PtrOff = VT.getSizeInBits() / 8 - PtrOff;
- NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr,
+ NewPtr = DAG.getNode(ISD::ADD, N->getDebugLoc(), PtrType, NewPtr,
DAG.getConstant(PtrOff, PtrType));
}
- return DAG.getLoad(LVT, LN0->getChain(), NewPtr,
+
+ return DAG.getLoad(LVT, N->getDebugLoc(), LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(),
LN0->isVolatile(), Align);
}
+
return SDValue();
}
-
SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
unsigned NumInScalars = N->getNumOperands();
@@ -5034,7 +5239,9 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
SmallVector<SDValue, 8> BuildVecIndices;
for (unsigned i = 0; i != NumInScalars; ++i) {
if (N->getOperand(i).getOpcode() == ISD::UNDEF) {
- BuildVecIndices.push_back(DAG.getNode(ISD::UNDEF, TLI.getPointerTy()));
+ BuildVecIndices.push_back(DAG.getNode(ISD::UNDEF,
+ N->getDebugLoc(),
+ TLI.getPointerTy()));
continue;
}
@@ -5065,15 +5272,16 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
} else {
// Use an undef build_vector as input for the second operand.
std::vector<SDValue> UnOps(NumInScalars,
- DAG.getNode(ISD::UNDEF,
- EltType));
- Ops[1] = DAG.getNode(ISD::BUILD_VECTOR, VT,
+ DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
+ EltType));
+ Ops[1] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT,
&UnOps[0], UnOps.size());
AddToWorkList(Ops[1].getNode());
}
- Ops[2] = DAG.getNode(ISD::BUILD_VECTOR, BuildVecVT,
+
+ Ops[2] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), BuildVecVT,
&BuildVecIndices[0], BuildVecIndices.size());
- return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Ops, 3);
+ return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), VT, Ops, 3);
}
return SDValue();
@@ -5086,9 +5294,8 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) {
// node.
// If we only have one input vector, we don't need to do any concatenation.
- if (N->getNumOperands() == 1) {
+ if (N->getNumOperands() == 1)
return N->getOperand(0);
- }
return SDValue();
}
@@ -5201,6 +5408,7 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
// Check the SHUFFLE mask, mapping any inputs from the 2nd operand into the
// first operand.
SmallVector<SDValue, 8> MappedOps;
+
for (unsigned i = 0; i != NumElts; ++i) {
if (ShufMask.getOperand(i).getOpcode() == ISD::UNDEF ||
cast<ConstantSDNode>(ShufMask.getOperand(i))->getZExtValue() <
@@ -5214,12 +5422,15 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
ShufMask.getOperand(i).getValueType()));
}
}
- ShufMask = DAG.getNode(ISD::BUILD_VECTOR, ShufMask.getValueType(),
+
+ ShufMask = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
+ ShufMask.getValueType(),
&MappedOps[0], MappedOps.size());
AddToWorkList(ShufMask.getNode());
- return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getValueType(0),
- N0,
- DAG.getNode(ISD::UNDEF, N->getValueType(0)),
+ return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(),
+ N->getValueType(0), N0,
+ DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
+ N->getValueType(0)),
ShufMask);
}
@@ -5261,21 +5472,25 @@ SDValue DAGCombiner::XformToShuffleWithZero(SDNode *N) {
MVT VT = MVT::getVectorVT(EVT, NumElts);
MVT MaskVT = MVT::getVectorVT(TLI.getPointerTy(), NumElts);
std::vector<SDValue> Ops;
- LHS = DAG.getNode(ISD::BIT_CONVERT, VT, LHS);
+ LHS = DAG.getNode(ISD::BIT_CONVERT, LHS.getDebugLoc(), VT, LHS);
Ops.push_back(LHS);
AddToWorkList(LHS.getNode());
std::vector<SDValue> ZeroOps(NumElts, DAG.getConstant(0, EVT));
- Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, VT,
- &ZeroOps[0], ZeroOps.size()));
- Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
- &IdxOps[0], IdxOps.size()));
- SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, VT,
- &Ops[0], Ops.size());
+ Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
+ VT, &ZeroOps[0], ZeroOps.size()));
+ Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
+ MaskVT, &IdxOps[0], IdxOps.size()));
+ SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(),
+ VT, &Ops[0], Ops.size());
+
if (VT != N->getValueType(0))
- Result = DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Result);
+ Result = DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(),
+ N->getValueType(0), Result);
+
return Result;
}
}
+
return SDValue();
}
@@ -5311,6 +5526,7 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
RHSOp.getOpcode() != ISD::Constant &&
RHSOp.getOpcode() != ISD::ConstantFP))
break;
+
// Can't fold divide by zero.
if (N->getOpcode() == ISD::SDIV || N->getOpcode() == ISD::UDIV ||
N->getOpcode() == ISD::FDIV) {
@@ -5320,7 +5536,9 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
cast<ConstantFPSDNode>(RHSOp.getNode())->getValueAPF().isZero()))
break;
}
- Ops.push_back(DAG.getNode(N->getOpcode(), EltType, LHSOp, RHSOp));
+
+ Ops.push_back(DAG.getNode(N->getOpcode(), LHS.getDebugLoc(),
+ EltType, LHSOp, RHSOp));
AddToWorkList(Ops.back().getNode());
assert((Ops.back().getOpcode() == ISD::UNDEF ||
Ops.back().getOpcode() == ISD::Constant ||
@@ -5330,18 +5548,21 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
if (Ops.size() == LHS.getNumOperands()) {
MVT VT = LHS.getValueType();
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
+ return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT,
+ &Ops[0], Ops.size());
}
}
return SDValue();
}
-SDValue DAGCombiner::SimplifySelect(SDValue N0, SDValue N1, SDValue N2){
+SDValue DAGCombiner::SimplifySelect(DebugLoc DL, SDValue N0,
+ SDValue N1, SDValue N2){
assert(N0.getOpcode() ==ISD::SETCC && "First argument must be a SetCC node!");
- SDValue SCC = SimplifySelectCC(N0.getOperand(0), N0.getOperand(1), N1, N2,
+ SDValue SCC = SimplifySelectCC(DL, N0.getOperand(0), N0.getOperand(1), N1, N2,
cast<CondCodeSDNode>(N0.getOperand(2))->get());
+
// If we got a simplified select_cc node back from SimplifySelectCC, then
// break it down into a new SETCC node, and a new SELECT node, and then return
// the SELECT node, since we were called with a SELECT node.
@@ -5349,13 +5570,15 @@ SDValue DAGCombiner::SimplifySelect(SDValue N0, SDValue N1, SDValue N2){
// Check to see if we got a select_cc back (to turn into setcc/select).
// Otherwise, just return whatever node we got back, like fabs.
if (SCC.getOpcode() == ISD::SELECT_CC) {
- SDValue SETCC = DAG.getNode(ISD::SETCC, N0.getValueType(),
- SCC.getOperand(0), SCC.getOperand(1),
- SCC.getOperand(4));
+ SDValue SETCC = DAG.getNode(ISD::SETCC, N0.getDebugLoc(),
+ N0.getValueType(),
+ SCC.getOperand(0), SCC.getOperand(1),
+ SCC.getOperand(4));
AddToWorkList(SETCC.getNode());
- return DAG.getNode(ISD::SELECT, SCC.getValueType(), SCC.getOperand(2),
- SCC.getOperand(3), SETCC);
+ return DAG.getNode(ISD::SELECT, SCC.getDebugLoc(), SCC.getValueType(),
+ SCC.getOperand(2), SCC.getOperand(3), SETCC);
}
+
return SCC;
}
return SDValue();
@@ -5367,7 +5590,6 @@ SDValue DAGCombiner::SimplifySelect(SDValue N0, SDValue N1, SDValue N2){
/// returns true. As such, they should return the appropriate thing (e.g. the
/// node) back to the top-level of the DAG combiner loop to avoid it being
/// looked at.
-///
bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
SDValue RHS) {
@@ -5398,7 +5620,8 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
// this will induce a cycle into the DAG.
if (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) &&
!RLD->isPredecessorOf(TheSelect->getOperand(0).getNode())) {
- Addr = DAG.getNode(ISD::SELECT, LLD->getBasePtr().getValueType(),
+ Addr = DAG.getNode(ISD::SELECT, TheSelect->getDebugLoc(),
+ LLD->getBasePtr().getValueType(),
TheSelect->getOperand(0), LLD->getBasePtr(),
RLD->getBasePtr());
}
@@ -5409,24 +5632,28 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
!RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) &&
!LLD->isPredecessorOf(TheSelect->getOperand(1).getNode()) &&
!RLD->isPredecessorOf(TheSelect->getOperand(1).getNode())) {
- Addr = DAG.getNode(ISD::SELECT_CC, LLD->getBasePtr().getValueType(),
- TheSelect->getOperand(0),
- TheSelect->getOperand(1),
- LLD->getBasePtr(), RLD->getBasePtr(),
- TheSelect->getOperand(4));
+ Addr = DAG.getNode(ISD::SELECT_CC, TheSelect->getDebugLoc(),
+ LLD->getBasePtr().getValueType(),
+ TheSelect->getOperand(0),
+ TheSelect->getOperand(1),
+ LLD->getBasePtr(), RLD->getBasePtr(),
+ TheSelect->getOperand(4));
}
}
if (Addr.getNode()) {
SDValue Load;
- if (LLD->getExtensionType() == ISD::NON_EXTLOAD)
- Load = DAG.getLoad(TheSelect->getValueType(0), LLD->getChain(),
+ if (LLD->getExtensionType() == ISD::NON_EXTLOAD) {
+ Load = DAG.getLoad(TheSelect->getValueType(0),
+ TheSelect->getDebugLoc(),
+ LLD->getChain(),
Addr,LLD->getSrcValue(),
LLD->getSrcValueOffset(),
LLD->isVolatile(),
LLD->getAlignment());
- else {
+ } else {
Load = DAG.getExtLoad(LLD->getExtensionType(),
+ TheSelect->getDebugLoc(),
TheSelect->getValueType(0),
LLD->getChain(), Addr, LLD->getSrcValue(),
LLD->getSrcValueOffset(),
@@ -5434,6 +5661,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
LLD->isVolatile(),
LLD->getAlignment());
}
+
// Users of the select now use the result of the load.
CombineTo(TheSelect, Load);
@@ -5450,10 +5678,9 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
return false;
}
-SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
+SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
SDValue N2, SDValue N3,
ISD::CondCode CC, bool NotExtCompare) {
-
MVT VT = N2.getValueType();
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode());
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.getNode());
@@ -5461,7 +5688,7 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
// Determine if the condition we're dealing with is constant
SDValue SCC = SimplifySetCC(TLI.getSetCCResultType(N0.getValueType()),
- N0, N1, CC, false);
+ N0, N1, CC, DL, false);
if (SCC.getNode()) AddToWorkList(SCC.getNode());
ConstantSDNode *SCCC = dyn_cast_or_null<ConstantSDNode>(SCC.getNode());
@@ -5480,18 +5707,18 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
if ((CC == ISD::SETGE || CC == ISD::SETGT) &&
N0 == N2 && N3.getOpcode() == ISD::FNEG &&
N2 == N3.getOperand(0))
- return DAG.getNode(ISD::FABS, VT, N0);
+ return DAG.getNode(ISD::FABS, DL, VT, N0);
// select (setl[te] X, +/-0.0), fneg(X), X -> fabs
if ((CC == ISD::SETLT || CC == ISD::SETLE) &&
N0 == N3 && N2.getOpcode() == ISD::FNEG &&
N2.getOperand(0) == N3)
- return DAG.getNode(ISD::FABS, VT, N3);
+ return DAG.getNode(ISD::FABS, DL, VT, N3);
}
}
// Check to see if we can perform the "gzip trick", transforming
- // select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A
+ // (select_cc setlt X, 0, A, 0) -> (and (sra X, (sub size(X), 1), A)
if (N1C && N3C && N3C->isNullValue() && CC == ISD::SETLT &&
N0.getValueType().isInteger() &&
N2.getValueType().isInteger() &&
@@ -5505,24 +5732,31 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
if (N2C && ((N2C->getAPIntValue() & (N2C->getAPIntValue()-1)) == 0)) {
unsigned ShCtV = N2C->getAPIntValue().logBase2();
ShCtV = XType.getSizeInBits()-ShCtV-1;
- SDValue ShCt = DAG.getConstant(ShCtV, TLI.getShiftAmountTy());
- SDValue Shift = DAG.getNode(ISD::SRL, XType, N0, ShCt);
+ SDValue ShCt = DAG.getConstant(ShCtV, getShiftAmountTy());
+ SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(),
+ XType, N0, ShCt);
AddToWorkList(Shift.getNode());
+
if (XType.bitsGT(AType)) {
- Shift = DAG.getNode(ISD::TRUNCATE, AType, Shift);
+ Shift = DAG.getNode(ISD::TRUNCATE, DL, AType, Shift);
AddToWorkList(Shift.getNode());
}
- return DAG.getNode(ISD::AND, AType, Shift, N2);
+
+ return DAG.getNode(ISD::AND, DL, AType, Shift, N2);
}
- SDValue Shift = DAG.getNode(ISD::SRA, XType, N0,
- DAG.getConstant(XType.getSizeInBits()-1,
- TLI.getShiftAmountTy()));
+
+ SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(),
+ XType, N0,
+ DAG.getConstant(XType.getSizeInBits()-1,
+ getShiftAmountTy()));
AddToWorkList(Shift.getNode());
+
if (XType.bitsGT(AType)) {
- Shift = DAG.getNode(ISD::TRUNCATE, AType, Shift);
+ Shift = DAG.getNode(ISD::TRUNCATE, DL, AType, Shift);
AddToWorkList(Shift.getNode());
}
- return DAG.getNode(ISD::AND, AType, Shift, N2);
+
+ return DAG.getNode(ISD::AND, DL, AType, Shift, N2);
}
}
@@ -5541,25 +5775,29 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
SDValue Temp, SCC;
// cast from setcc result type to select result type
if (LegalTypes) {
- SCC = DAG.getSetCC(TLI.getSetCCResultType(N0.getValueType()),
+ SCC = DAG.getSetCC(DL, TLI.getSetCCResultType(N0.getValueType()),
N0, N1, CC);
if (N2.getValueType().bitsLT(SCC.getValueType()))
- Temp = DAG.getZeroExtendInReg(SCC, N2.getValueType());
+ Temp = DAG.getZeroExtendInReg(SCC, N2.getDebugLoc(), N2.getValueType());
else
- Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getValueType(), SCC);
+ Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getDebugLoc(),
+ N2.getValueType(), SCC);
} else {
- SCC = DAG.getSetCC(MVT::i1, N0, N1, CC);
- Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getValueType(), SCC);
+ SCC = DAG.getSetCC(N0.getDebugLoc(), MVT::i1, N0, N1, CC);
+ Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getDebugLoc(),
+ N2.getValueType(), SCC);
}
+
AddToWorkList(SCC.getNode());
AddToWorkList(Temp.getNode());
if (N2C->getAPIntValue() == 1)
return Temp;
+
// shl setcc result by log2 n2c
- return DAG.getNode(ISD::SHL, N2.getValueType(), Temp,
+ return DAG.getNode(ISD::SHL, DL, N2.getValueType(), Temp,
DAG.getConstant(N2C->getAPIntValue().logBase2(),
- TLI.getShiftAmountTy()));
+ getShiftAmountTy()));
}
// Check to see if this is the equivalent of setcc
@@ -5569,38 +5807,37 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
MVT XType = N0.getValueType();
if (!LegalOperations ||
TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultType(XType))) {
- SDValue Res = DAG.getSetCC(TLI.getSetCCResultType(XType), N0, N1, CC);
+ SDValue Res = DAG.getSetCC(DL, TLI.getSetCCResultType(XType), N0, N1, CC);
if (Res.getValueType() != VT)
- Res = DAG.getNode(ISD::ZERO_EXTEND, VT, Res);
+ Res = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Res);
return Res;
}
- // seteq X, 0 -> srl (ctlz X, log2(size(X)))
+ // fold (seteq X, 0) -> (srl (ctlz X, log2(size(X))))
if (N1C && N1C->isNullValue() && CC == ISD::SETEQ &&
(!LegalOperations ||
TLI.isOperationLegal(ISD::CTLZ, XType))) {
- SDValue Ctlz = DAG.getNode(ISD::CTLZ, XType, N0);
- return DAG.getNode(ISD::SRL, XType, Ctlz,
+ SDValue Ctlz = DAG.getNode(ISD::CTLZ, N0.getDebugLoc(), XType, N0);
+ return DAG.getNode(ISD::SRL, DL, XType, Ctlz,
DAG.getConstant(Log2_32(XType.getSizeInBits()),
- TLI.getShiftAmountTy()));
+ getShiftAmountTy()));
}
- // setgt X, 0 -> srl (and (-X, ~X), size(X)-1)
+ // fold (setgt X, 0) -> (srl (and (-X, ~X), size(X)-1))
if (N1C && N1C->isNullValue() && CC == ISD::SETGT) {
- SDValue NegN0 = DAG.getNode(ISD::SUB, XType, DAG.getConstant(0, XType),
- N0);
- SDValue NotN0 = DAG.getNode(ISD::XOR, XType, N0,
- DAG.getConstant(~0ULL, XType));
- return DAG.getNode(ISD::SRL, XType,
- DAG.getNode(ISD::AND, XType, NegN0, NotN0),
+ SDValue NegN0 = DAG.getNode(ISD::SUB, N0.getDebugLoc(),
+ XType, DAG.getConstant(0, XType), N0);
+ SDValue NotN0 = DAG.getNOT(N0.getDebugLoc(), N0, XType);
+ return DAG.getNode(ISD::SRL, DL, XType,
+ DAG.getNode(ISD::AND, DL, XType, NegN0, NotN0),
DAG.getConstant(XType.getSizeInBits()-1,
- TLI.getShiftAmountTy()));
+ getShiftAmountTy()));
}
- // setgt X, -1 -> xor (srl (X, size(X)-1), 1)
+ // fold (setgt X, -1) -> (xor (srl (X, size(X)-1), 1))
if (N1C && N1C->isAllOnesValue() && CC == ISD::SETGT) {
- SDValue Sign = DAG.getNode(ISD::SRL, XType, N0,
- DAG.getConstant(XType.getSizeInBits()-1,
- TLI.getShiftAmountTy()));
- return DAG.getNode(ISD::XOR, XType, Sign, DAG.getConstant(1, XType));
+ SDValue Sign = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0,
+ DAG.getConstant(XType.getSizeInBits()-1,
+ getShiftAmountTy()));
+ return DAG.getNode(ISD::XOR, DL, XType, Sign, DAG.getConstant(1, XType));
}
}
@@ -5610,13 +5847,14 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
N0 == N3 && N2.getOpcode() == ISD::SUB && N0 == N2.getOperand(1) &&
N2.getOperand(0) == N1 && N0.getValueType().isInteger()) {
MVT XType = N0.getValueType();
- SDValue Shift = DAG.getNode(ISD::SRA, XType, N0,
- DAG.getConstant(XType.getSizeInBits()-1,
- TLI.getShiftAmountTy()));
- SDValue Add = DAG.getNode(ISD::ADD, XType, N0, Shift);
+ SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0,
+ DAG.getConstant(XType.getSizeInBits()-1,
+ getShiftAmountTy()));
+ SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(), XType,
+ N0, Shift);
AddToWorkList(Shift.getNode());
AddToWorkList(Add.getNode());
- return DAG.getNode(ISD::XOR, XType, Add, Shift);
+ return DAG.getNode(ISD::XOR, DL, XType, Add, Shift);
}
// Check to see if this is an integer abs. select_cc setgt X, -1, X, -X ->
// Y = sra (X, size(X)-1); xor (add (X, Y), Y)
@@ -5625,13 +5863,15 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
if (ConstantSDNode *SubC = dyn_cast<ConstantSDNode>(N3.getOperand(0))) {
MVT XType = N0.getValueType();
if (SubC->isNullValue() && XType.isInteger()) {
- SDValue Shift = DAG.getNode(ISD::SRA, XType, N0,
- DAG.getConstant(XType.getSizeInBits()-1,
- TLI.getShiftAmountTy()));
- SDValue Add = DAG.getNode(ISD::ADD, XType, N0, Shift);
+ SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType,
+ N0,
+ DAG.getConstant(XType.getSizeInBits()-1,
+ getShiftAmountTy()));
+ SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(),
+ XType, N0, Shift);
AddToWorkList(Shift.getNode());
AddToWorkList(Add.getNode());
- return DAG.getNode(ISD::XOR, XType, Add, Shift);
+ return DAG.getNode(ISD::XOR, DL, XType, Add, Shift);
}
}
}
@@ -5642,10 +5882,10 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1,
/// SimplifySetCC - This is a stub for TargetLowering::SimplifySetCC.
SDValue DAGCombiner::SimplifySetCC(MVT VT, SDValue N0,
SDValue N1, ISD::CondCode Cond,
- bool foldBooleans) {
+ DebugLoc DL, bool foldBooleans) {
TargetLowering::DAGCombinerInfo
DagCombineInfo(DAG, Level == Unrestricted, false, this);
- return TLI.SimplifySetCC(VT, N0, N1, Cond, foldBooleans, DagCombineInfo);
+ return TLI.SimplifySetCC(VT, N0, N1, Cond, foldBooleans, DagCombineInfo, DL);
}
/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant,
@@ -5701,8 +5941,7 @@ static bool FindBaseOffset(SDValue Ptr, SDValue &Base, int64_t &Offset) {
bool DAGCombiner::isAlias(SDValue Ptr1, int64_t Size1,
const Value *SrcValue1, int SrcValueOffset1,
SDValue Ptr2, int64_t Size2,
- const Value *SrcValue2, int SrcValueOffset2)
-{
+ const Value *SrcValue2, int SrcValueOffset2) const {
// If they are the same then they must be aliases.
if (Ptr1 == Ptr2) return true;
@@ -5713,10 +5952,9 @@ bool DAGCombiner::isAlias(SDValue Ptr1, int64_t Size1,
bool KnownBase2 = FindBaseOffset(Ptr2, Base2, Offset2);
// If they have a same base address then...
- if (Base1 == Base2) {
+ if (Base1 == Base2)
// Check to see if the addresses overlap.
- return!((Offset1 + Size1) <= Offset2 || (Offset2 + Size2) <= Offset1);
- }
+ return !((Offset1 + Size1) <= Offset2 || (Offset2 + Size2) <= Offset1);
// If we know both bases then they can't alias.
if (KnownBase1 && KnownBase2) return false;
@@ -5740,7 +5978,7 @@ bool DAGCombiner::isAlias(SDValue Ptr1, int64_t Size1,
/// node. Returns true if the operand was a load.
bool DAGCombiner::FindAliasInfo(SDNode *N,
SDValue &Ptr, int64_t &Size,
- const Value *&SrcValue, int &SrcValueOffset) {
+ const Value *&SrcValue, int &SrcValueOffset) const {
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
Ptr = LD->getBasePtr();
Size = LD->getMemoryVT().getSizeInBits() >> 3;
@@ -5852,8 +6090,8 @@ SDValue DAGCombiner::FindBetterChain(SDNode *N, SDValue OldChain) {
}
// Construct a custom tailored token factor.
- SDValue NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other,
- &Aliases[0], Aliases.size());
+ SDValue NewChain = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), MVT::Other,
+ &Aliases[0], Aliases.size());
// Make sure the old chain gets cleaned up.
if (NewChain != OldChain) AddToWorkList(OldChain.getNode());
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index dff75510ac13..04e97212ddf3 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -114,7 +114,7 @@ unsigned FastISel::getRegForValue(Value *V) {
Reg = LocalValueMap[CE];
} else if (isa<UndefValue>(V)) {
Reg = createResultReg(TLI.getRegClassFor(VT));
- BuildMI(MBB, TII.get(TargetInstrInfo::IMPLICIT_DEF), Reg);
+ BuildMI(MBB, DL, TII.get(TargetInstrInfo::IMPLICIT_DEF), Reg);
}
// If target-independent code couldn't handle the value, give target-specific
@@ -324,8 +324,10 @@ bool FastISel::SelectCall(User *I) {
unsigned Line = SPI->getLine();
unsigned Col = SPI->getColumn();
unsigned ID = DW->RecordSourceLine(Line, Col, SrcFile);
+ unsigned Idx = MF.getOrCreateDebugLocID(SrcFile, Line, Col);
+ setCurDebugLoc(DebugLoc::get(Idx));
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- BuildMI(MBB, II).addImm(ID);
+ BuildMI(MBB, DL, II).addImm(ID);
}
return true;
}
@@ -335,7 +337,7 @@ bool FastISel::SelectCall(User *I) {
unsigned ID =
DW->RecordRegionStart(cast<GlobalVariable>(RSI->getContext()));
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- BuildMI(MBB, II).addImm(ID);
+ BuildMI(MBB, DL, II).addImm(ID);
}
return true;
}
@@ -345,7 +347,7 @@ bool FastISel::SelectCall(User *I) {
unsigned ID =
DW->RecordRegionEnd(cast<GlobalVariable>(REI->getContext()));
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- BuildMI(MBB, II).addImm(ID);
+ BuildMI(MBB, DL, II).addImm(ID);
}
return true;
}
@@ -353,23 +355,28 @@ bool FastISel::SelectCall(User *I) {
if (!DW) return true;
DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
Value *SP = FSI->getSubprogram();
+
if (DW->ValidDebugInfo(SP)) {
- // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
- // what (most?) gdb expects.
+ // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
+ // (most?) gdb expects.
DISubprogram Subprogram(cast<GlobalVariable>(SP));
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
unsigned SrcFile = DW->RecordSource(CompileUnit.getDirectory(),
CompileUnit.getFilename());
+
// Record the source line but does not create a label for the normal
// function start. It will be emitted at asm emission time. However,
// create a label if this is a beginning of inlined function.
- unsigned LabelID =
- DW->RecordSourceLine(Subprogram.getLineNumber(), 0, SrcFile);
+ unsigned Line = Subprogram.getLineNumber();
+ unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
+ setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+
if (DW->getRecordSourceLineCount() != 1) {
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- BuildMI(MBB, II).addImm(LabelID);
+ BuildMI(MBB, DL, II).addImm(LabelID);
}
}
+
return true;
}
case Intrinsic::dbg_declare: {
@@ -393,7 +400,7 @@ bool FastISel::SelectCall(User *I) {
// Build the DECLARE instruction.
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE);
- BuildMI(MBB, II).addFrameIndex(FI).addGlobalAddress(GV);
+ BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV);
}
return true;
}
@@ -830,7 +837,7 @@ unsigned FastISel::FastEmitInst_(unsigned MachineInstOpcode,
unsigned ResultReg = createResultReg(RC);
const TargetInstrDesc &II = TII.get(MachineInstOpcode);
- BuildMI(MBB, II, ResultReg);
+ BuildMI(MBB, DL, II, ResultReg);
return ResultReg;
}
@@ -841,9 +848,9 @@ unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode,
const TargetInstrDesc &II = TII.get(MachineInstOpcode);
if (II.getNumDefs() >= 1)
- BuildMI(MBB, II, ResultReg).addReg(Op0);
+ BuildMI(MBB, DL, II, ResultReg).addReg(Op0);
else {
- BuildMI(MBB, II).addReg(Op0);
+ BuildMI(MBB, DL, II).addReg(Op0);
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
II.ImplicitDefs[0], RC, RC);
if (!InsertedCopy)
@@ -860,9 +867,9 @@ unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
const TargetInstrDesc &II = TII.get(MachineInstOpcode);
if (II.getNumDefs() >= 1)
- BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1);
+ BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addReg(Op1);
else {
- BuildMI(MBB, II).addReg(Op0).addReg(Op1);
+ BuildMI(MBB, DL, II).addReg(Op0).addReg(Op1);
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
II.ImplicitDefs[0], RC, RC);
if (!InsertedCopy)
@@ -878,9 +885,9 @@ unsigned FastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
const TargetInstrDesc &II = TII.get(MachineInstOpcode);
if (II.getNumDefs() >= 1)
- BuildMI(MBB, II, ResultReg).addReg(Op0).addImm(Imm);
+ BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Imm);
else {
- BuildMI(MBB, II).addReg(Op0).addImm(Imm);
+ BuildMI(MBB, DL, II).addReg(Op0).addImm(Imm);
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
II.ImplicitDefs[0], RC, RC);
if (!InsertedCopy)
@@ -896,9 +903,9 @@ unsigned FastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
const TargetInstrDesc &II = TII.get(MachineInstOpcode);
if (II.getNumDefs() >= 1)
- BuildMI(MBB, II, ResultReg).addReg(Op0).addFPImm(FPImm);
+ BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addFPImm(FPImm);
else {
- BuildMI(MBB, II).addReg(Op0).addFPImm(FPImm);
+ BuildMI(MBB, DL, II).addReg(Op0).addFPImm(FPImm);
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
II.ImplicitDefs[0], RC, RC);
if (!InsertedCopy)
@@ -914,9 +921,9 @@ unsigned FastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
const TargetInstrDesc &II = TII.get(MachineInstOpcode);
if (II.getNumDefs() >= 1)
- BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1).addImm(Imm);
+ BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addReg(Op1).addImm(Imm);
else {
- BuildMI(MBB, II).addReg(Op0).addReg(Op1).addImm(Imm);
+ BuildMI(MBB, DL, II).addReg(Op0).addReg(Op1).addImm(Imm);
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
II.ImplicitDefs[0], RC, RC);
if (!InsertedCopy)
@@ -932,9 +939,9 @@ unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode,
const TargetInstrDesc &II = TII.get(MachineInstOpcode);
if (II.getNumDefs() >= 1)
- BuildMI(MBB, II, ResultReg).addImm(Imm);
+ BuildMI(MBB, DL, II, ResultReg).addImm(Imm);
else {
- BuildMI(MBB, II).addImm(Imm);
+ BuildMI(MBB, DL, II).addImm(Imm);
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
II.ImplicitDefs[0], RC, RC);
if (!InsertedCopy)
@@ -943,17 +950,17 @@ unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode,
return ResultReg;
}
-unsigned FastISel::FastEmitInst_extractsubreg(unsigned Op0, uint32_t Idx) {
+unsigned FastISel::FastEmitInst_extractsubreg(MVT::SimpleValueType RetVT,
+ unsigned Op0, uint32_t Idx) {
const TargetRegisterClass* RC = MRI.getRegClass(Op0);
- const TargetRegisterClass* SRC = *(RC->subregclasses_begin()+Idx-1);
- unsigned ResultReg = createResultReg(SRC);
+ unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
const TargetInstrDesc &II = TII.get(TargetInstrInfo::EXTRACT_SUBREG);
if (II.getNumDefs() >= 1)
- BuildMI(MBB, II, ResultReg).addReg(Op0).addImm(Idx);
+ BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Idx);
else {
- BuildMI(MBB, II).addReg(Op0).addImm(Idx);
+ BuildMI(MBB, DL, II).addReg(Op0).addImm(Idx);
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
II.ImplicitDefs[0], RC, RC);
if (!InsertedCopy)
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 608dde214441..b7ace2ed43da 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -169,7 +169,7 @@ private:
/// is necessary to spill the vector being inserted into to memory, perform
/// the insert there, and then read the result back.
SDValue PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val,
- SDValue Idx);
+ SDValue Idx, DebugLoc dl);
/// PromoteOp - Given an operation that produces a value in an invalid type,
/// promote it to compute the value into a larger type. The produced value
@@ -231,7 +231,7 @@ private:
SDValue BasePtr, const Value *SV,
int SVOffset, unsigned Alignment,
bool isVolatile, unsigned LdWidth,
- MVT ResType);
+ MVT ResType, DebugLoc dl);
/// StoreWidenVectorOp - Stores a widen vector into non widen memory
/// location. It takes
@@ -257,7 +257,7 @@ private:
SDValue BasePtr, const Value *SV,
int SVOffset, unsigned Alignment,
bool isVolatile, SDValue ValOp,
- unsigned StWidth);
+ unsigned StWidth, DebugLoc dl);
/// isShuffleLegal - Return non-null if a vector shuffle is legal with the
/// specified mask and type. Targets can specify exactly which masks they
@@ -273,37 +273,41 @@ private:
bool LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest,
SmallPtrSet<SDNode*, 32> &NodesLeadingTo);
- void LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, SDValue &CC);
- void LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC);
- void LegalizeSetCC(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC) {
- LegalizeSetCCOperands(LHS, RHS, CC);
- LegalizeSetCCCondCode(VT, LHS, RHS, CC);
+ void LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, SDValue &CC,
+ DebugLoc dl);
+ void LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC,
+ DebugLoc dl);
+ void LegalizeSetCC(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC,
+ DebugLoc dl) {
+ LegalizeSetCCOperands(LHS, RHS, CC, dl);
+ LegalizeSetCCCondCode(VT, LHS, RHS, CC, dl);
}
SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned,
SDValue &Hi);
- SDValue ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source);
+ SDValue ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl);
- SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT);
+ SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT, DebugLoc dl);
SDValue ExpandBUILD_VECTOR(SDNode *Node);
SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node);
- SDValue LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op);
- SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, MVT DestVT);
- SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, MVT DestVT, bool isSigned);
- SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, MVT DestVT, bool isSigned);
-
- SDValue ExpandBSWAP(SDValue Op);
- SDValue ExpandBitCount(unsigned Opc, SDValue Op);
+ SDValue LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy,
+ SDValue Op, DebugLoc dl);
+ SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, MVT DestVT,
+ DebugLoc dl);
+ SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, MVT DestVT, bool isSigned,
+ DebugLoc dl);
+ SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, MVT DestVT, bool isSigned,
+ DebugLoc dl);
+
+ SDValue ExpandBSWAP(SDValue Op, DebugLoc dl);
+ SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl);
bool ExpandShift(unsigned Opc, SDValue Op, SDValue Amt,
- SDValue &Lo, SDValue &Hi);
+ SDValue &Lo, SDValue &Hi, DebugLoc dl);
void ExpandShiftParts(unsigned NodeOp, SDValue Op, SDValue Amt,
- SDValue &Lo, SDValue &Hi);
+ SDValue &Lo, SDValue &Hi, DebugLoc dl);
SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op);
SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op);
-
- // Returns the legalized (truncated or extended) shift amount.
- SDValue LegalizeShiftAmount(SDValue ShiftAmt);
};
}
@@ -336,14 +340,16 @@ SDNode *SelectionDAGLegalize::isShuffleLegal(MVT VT, SDValue Mask) const {
SDValue InOp = Mask.getOperand(i);
for (unsigned j = 0; j != NumEltsGrowth; ++j) {
if (InOp.getOpcode() == ISD::UNDEF)
- Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF,
+ InOp.getNode()->getDebugLoc(), EltVT));
else {
unsigned InEltNo = cast<ConstantSDNode>(InOp)->getZExtValue();
Ops.push_back(DAG.getConstant(InEltNo*NumEltsGrowth+j, EltVT));
}
}
}
- Mask = DAG.getNode(ISD::BUILD_VECTOR, NVT, &Ops[0], Ops.size());
+ Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getNode()->getDebugLoc(),
+ NVT, &Ops[0], Ops.size());
}
VT = NVT;
break;
@@ -593,6 +599,7 @@ static
SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT,
SelectionDAG &DAG,
const TargetLowering &TLI) {
+ DebugLoc dl = Node->getDebugLoc();
MVT VT = Node->getValueType(0);
MVT SrcVT = Node->getOperand(1).getValueType();
assert((SrcVT == MVT::f32 || SrcVT == MVT::f64) &&
@@ -603,18 +610,19 @@ SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT,
SDValue Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
- Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
- SDValue SignBit= DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Node->getOperand(1));
- SignBit = DAG.getNode(ISD::AND, SrcNVT, SignBit, Mask1);
+ Mask1 = DAG.getNode(ISD::BIT_CONVERT, dl, SrcNVT, Mask1);
+ SDValue SignBit= DAG.getNode(ISD::BIT_CONVERT, dl, SrcNVT,
+ Node->getOperand(1));
+ SignBit = DAG.getNode(ISD::AND, dl, SrcNVT, SignBit, Mask1);
// Shift right or sign-extend it if the two operands have different types.
int SizeDiff = SrcNVT.getSizeInBits() - NVT.getSizeInBits();
if (SizeDiff > 0) {
- SignBit = DAG.getNode(ISD::SRL, SrcNVT, SignBit,
+ SignBit = DAG.getNode(ISD::SRL, dl, SrcNVT, SignBit,
DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
- SignBit = DAG.getNode(ISD::TRUNCATE, NVT, SignBit);
+ SignBit = DAG.getNode(ISD::TRUNCATE, dl, NVT, SignBit);
} else if (SizeDiff < 0) {
- SignBit = DAG.getNode(ISD::ZERO_EXTEND, NVT, SignBit);
- SignBit = DAG.getNode(ISD::SHL, NVT, SignBit,
+ SignBit = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, SignBit);
+ SignBit = DAG.getNode(ISD::SHL, dl, NVT, SignBit,
DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
}
@@ -622,12 +630,12 @@ SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT,
SDValue Mask2 = (VT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), VT)
: DAG.getConstantFP(BitsToFloat(~(1U << 31)), VT);
- Mask2 = DAG.getNode(ISD::BIT_CONVERT, NVT, Mask2);
- SDValue Result = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0));
- Result = DAG.getNode(ISD::AND, NVT, Result, Mask2);
+ Mask2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Mask2);
+ SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0));
+ Result = DAG.getNode(ISD::AND, dl, NVT, Result, Mask2);
// Or the value with the sign bit.
- Result = DAG.getNode(ISD::OR, NVT, Result, SignBit);
+ Result = DAG.getNode(ISD::OR, dl, NVT, Result, SignBit);
return Result;
}
@@ -641,6 +649,7 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
MVT VT = Val.getValueType();
int Alignment = ST->getAlignment();
int SVOffset = ST->getSrcValueOffset();
+ DebugLoc dl = ST->getDebugLoc();
if (ST->getMemoryVT().isFloatingPoint() ||
ST->getMemoryVT().isVector()) {
MVT intVT = MVT::getIntegerVT(VT.getSizeInBits());
@@ -648,8 +657,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Expand to a bitconvert of the value to the integer type of the
// same size, then a (misaligned) int store.
// FIXME: Does not handle truncating floating point stores!
- SDValue Result = DAG.getNode(ISD::BIT_CONVERT, intVT, Val);
- return DAG.getStore(Chain, Result, Ptr, ST->getSrcValue(),
+ SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, intVT, Val);
+ return DAG.getStore(Chain, dl, Result, Ptr, ST->getSrcValue(),
SVOffset, ST->isVolatile(), Alignment);
} else {
// Do a (aligned) store to a stack slot, then copy from the stack slot
@@ -665,7 +674,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT);
// Perform the original store, only redirected to the stack slot.
- SDValue Store = DAG.getTruncStore(Chain, Val, StackPtr, NULL, 0,StoredVT);
+ SDValue Store = DAG.getTruncStore(Chain, dl,
+ Val, StackPtr, NULL, 0,StoredVT);
SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy());
SmallVector<SDValue, 8> Stores;
unsigned Offset = 0;
@@ -673,17 +683,17 @@ 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, Store, StackPtr, NULL, 0);
+ SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0);
// Store it to the final location. Remember the store.
- Stores.push_back(DAG.getStore(Load.getValue(1), Load, Ptr,
+ Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr,
ST->getSrcValue(), SVOffset + Offset,
ST->isVolatile(),
MinAlign(ST->getAlignment(), Offset)));
// Increment the pointers.
Offset += RegBytes;
- StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr,
+ StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
Increment);
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, Increment);
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment);
}
// The last store may be partial. Do a truncating store. On big-endian
@@ -692,15 +702,15 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
MVT MemVT = MVT::getIntegerVT(8 * (StoredBytes - Offset));
// Load from the stack slot.
- SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, RegVT, Store, StackPtr,
+ SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr,
NULL, 0, MemVT);
- Stores.push_back(DAG.getTruncStore(Load.getValue(1), Load, Ptr,
+ Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr,
ST->getSrcValue(), SVOffset + Offset,
MemVT, ST->isVolatile(),
MinAlign(ST->getAlignment(), Offset)));
// The order of the stores doesn't matter - say it with a TokenFactor.
- return DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
Stores.size());
}
}
@@ -716,21 +726,21 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Divide the stored value in two parts.
SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy());
SDValue Lo = Val;
- SDValue Hi = DAG.getNode(ISD::SRL, VT, Val, ShiftAmount);
+ SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount);
// Store the two parts
SDValue Store1, Store2;
- Store1 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Lo:Hi, Ptr,
+ Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr,
ST->getSrcValue(), SVOffset, NewStoredVT,
ST->isVolatile(), Alignment);
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Alignment = MinAlign(Alignment, IncrementSize);
- Store2 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Hi:Lo, Ptr,
+ Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr,
ST->getSrcValue(), SVOffset + IncrementSize,
NewStoredVT, ST->isVolatile(), Alignment);
- return DAG.getNode(ISD::TokenFactor, MVT::Other, Store1, Store2);
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
}
/// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads.
@@ -742,20 +752,21 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
SDValue Ptr = LD->getBasePtr();
MVT VT = LD->getValueType(0);
MVT LoadedVT = LD->getMemoryVT();
+ DebugLoc dl = LD->getDebugLoc();
if (VT.isFloatingPoint() || VT.isVector()) {
MVT intVT = MVT::getIntegerVT(LoadedVT.getSizeInBits());
if (TLI.isTypeLegal(intVT)) {
// Expand to a (misaligned) integer load of the same size,
// then bitconvert to floating point or vector.
- SDValue newLoad = DAG.getLoad(intVT, Chain, Ptr, LD->getSrcValue(),
+ SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset, LD->isVolatile(),
LD->getAlignment());
- SDValue Result = DAG.getNode(ISD::BIT_CONVERT, LoadedVT, newLoad);
+ SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, LoadedVT, newLoad);
if (VT.isFloatingPoint() && LoadedVT != VT)
- Result = DAG.getNode(ISD::FP_EXTEND, VT, Result);
+ Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result);
SDValue Ops[] = { Result, Chain };
- return DAG.getMergeValues(Ops, 2);
+ return DAG.getMergeValues(Ops, 2, dl);
} else {
// Copy the value to a (aligned) stack slot using (unaligned) integer
// loads and stores, then do a (aligned) load from the stack slot.
@@ -775,42 +786,42 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, 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 original location.
- SDValue Load = DAG.getLoad(RegVT, Chain, Ptr, LD->getSrcValue(),
+ SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset + Offset, LD->isVolatile(),
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), Load, StackPtr,
+ Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr,
NULL, 0));
// Increment the pointers.
Offset += RegBytes;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, Increment);
- StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment);
+ StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
Increment);
}
// The last copy may be partial. Do an extending load.
MVT MemVT = MVT::getIntegerVT(8 * (LoadedBytes - Offset));
- SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, RegVT, Chain, Ptr,
+ SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr,
LD->getSrcValue(), SVOffset + Offset,
MemVT, LD->isVolatile(),
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), Load, StackPtr,
+ Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr,
NULL, 0, MemVT));
// The order of the stores doesn't matter - say it with a TokenFactor.
- SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],
+ SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
Stores.size());
// Finally, perform the original load only redirected to the stack slot.
- Load = DAG.getExtLoad(LD->getExtensionType(), VT, TF, StackBase,
+ Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase,
NULL, 0, LoadedVT);
// Callers expect a MERGE_VALUES node.
SDValue Ops[] = { Load, TF };
- return DAG.getMergeValues(Ops, 2);
+ return DAG.getMergeValues(Ops, 2, dl);
}
}
assert(LoadedVT.isInteger() && !LoadedVT.isVector() &&
@@ -834,33 +845,33 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
// Load the value in two parts
SDValue Lo, Hi;
if (TLI.isLittleEndian()) {
- Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(),
+ Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset, NewLoadedVT, LD->isVolatile(), Alignment);
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
- Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(),
+ Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
MinAlign(Alignment, IncrementSize));
} else {
- Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset,
- NewLoadedVT,LD->isVolatile(), Alignment);
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(),
+ SVOffset, NewLoadedVT,LD->isVolatile(), Alignment);
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
- Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(),
+ Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
MinAlign(Alignment, IncrementSize));
}
// aggregate the two parts
SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy());
- SDValue Result = DAG.getNode(ISD::SHL, VT, Hi, ShiftAmount);
- Result = DAG.getNode(ISD::OR, VT, Result, Lo);
+ SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount);
+ Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo);
- SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
SDValue Ops[] = { Result, TF };
- return DAG.getMergeValues(Ops, 2);
+ return DAG.getMergeValues(Ops, 2, dl);
}
/// UnrollVectorOp - We know that the given vector has a legal type, however
@@ -875,6 +886,7 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) {
"Can't unroll a vector with multiple results!");
unsigned NE = VT.getVectorNumElements();
MVT EltVT = VT.getVectorElementType();
+ DebugLoc dl = Op.getNode()->getDebugLoc();
SmallVector<SDValue, 8> Scalars;
SmallVector<SDValue, 4> Operands(Op.getNumOperands());
@@ -885,7 +897,7 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) {
if (OperandVT.isVector()) {
// A vector operand; extract a single element.
MVT OperandEltVT = OperandVT.getVectorElementType();
- Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+ Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
OperandEltVT,
Operand,
DAG.getConstant(i, MVT::i32));
@@ -897,19 +909,21 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) {
switch (Op.getOpcode()) {
default:
- Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT,
+ Scalars.push_back(DAG.getNode(Op.getOpcode(), dl, EltVT,
&Operands[0], Operands.size()));
break;
case ISD::SHL:
case ISD::SRA:
case ISD::SRL:
- Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, Operands[0],
- LegalizeShiftAmount(Operands[1])));
+ case ISD::ROTL:
+ case ISD::ROTR:
+ Scalars.push_back(DAG.getNode(Op.getOpcode(), dl, EltVT, Operands[0],
+ DAG.getShiftAmountOperand(Operands[1])));
break;
}
}
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size());
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Scalars[0], Scalars.size());
}
/// GetFPLibCall - Return the right libcall for the given floating point type.
@@ -931,7 +945,8 @@ static RTLIB::Libcall GetFPLibCall(MVT VT,
/// is necessary to spill the vector being inserted into to memory, perform
/// the insert there, and then read the result back.
SDValue SelectionDAGLegalize::
-PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx) {
+PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx,
+ DebugLoc dl) {
SDValue Tmp1 = Vec;
SDValue Tmp2 = Val;
SDValue Tmp3 = Idx;
@@ -951,34 +966,24 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx) {
int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
// Store the vector.
- SDValue Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr,
+ SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr,
PseudoSourceValue::getFixedStack(SPFI), 0);
// Truncate or zero extend offset to target pointer type.
unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
- Tmp3 = DAG.getNode(CastOpc, PtrVT, Tmp3);
+ Tmp3 = DAG.getNode(CastOpc, dl, PtrVT, Tmp3);
// Add the offset to the index.
unsigned EltSize = EltVT.getSizeInBits()/8;
- Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT));
- SDValue StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr);
+ Tmp3 = DAG.getNode(ISD::MUL, dl, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT));
+ SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr);
// Store the scalar value.
- Ch = DAG.getTruncStore(Ch, Tmp2, StackPtr2,
+ Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2,
PseudoSourceValue::getFixedStack(SPFI), 0, EltVT);
// Load the updated vector.
- return DAG.getLoad(VT, Ch, StackPtr,
+ return DAG.getLoad(VT, dl, Ch, StackPtr,
PseudoSourceValue::getFixedStack(SPFI), 0);
}
-SDValue SelectionDAGLegalize::LegalizeShiftAmount(SDValue ShiftAmt) {
- if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType()))
- return DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt);
-
- if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType()))
- return DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), ShiftAmt);
-
- return ShiftAmt;
-}
-
/// LegalizeOp - We know that the specified value has a legal type, and
/// that its operands are legal. Now ensure that the operation itself
@@ -991,6 +996,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
assert(isTypeLegal(Op.getValueType()) &&
"Caller should expand or promote operands that are not legal!");
SDNode *Node = Op.getNode();
+ DebugLoc dl = Node->getDebugLoc();
// If this operation defines any values that cannot be represented in a
// register on this target, make sure to expand or promote them.
@@ -1111,7 +1117,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Fall Thru
case TargetLowering::Legal: {
SDValue Ops[] = { DAG.getConstant(0, VT), Tmp1 };
- Result = DAG.getMergeValues(Ops, 2);
+ Result = DAG.getMergeValues(Ops, 2, dl);
break;
}
}
@@ -1145,7 +1151,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Fall Thru
case TargetLowering::Legal: {
SDValue Ops[] = { DAG.getConstant(0, VT), Tmp2 };
- Result = DAG.getMergeValues(Ops, 2);
+ Result = DAG.getMergeValues(Ops, 2, dl);
break;
}
}
@@ -1263,8 +1269,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
default: assert(0 && "This action is not supported yet!");
case TargetLowering::Expand: {
DwarfWriter *DW = DAG.getDwarfWriter();
- bool useDEBUG_LOC = TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other);
- bool useLABEL = TLI.isOperationLegal(ISD::DBG_LABEL, MVT::Other);
+ bool useDEBUG_LOC = TLI.isOperationLegalOrCustom(ISD::DEBUG_LOC,
+ MVT::Other);
+ bool useLABEL = TLI.isOperationLegalOrCustom(ISD::DBG_LABEL, MVT::Other);
const DbgStopPointSDNode *DSP = cast<DbgStopPointSDNode>(Node);
GlobalVariable *CU_GV = cast<GlobalVariable>(DSP->getCompileUnit());
@@ -1276,14 +1283,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
unsigned Line = DSP->getLine();
unsigned Col = DSP->getColumn();
+ // A bit self-referential to have DebugLoc on Debug_Loc nodes, but
+ // it won't hurt anything.
if (useDEBUG_LOC) {
SDValue Ops[] = { Tmp1, DAG.getConstant(Line, MVT::i32),
DAG.getConstant(Col, MVT::i32),
DAG.getConstant(SrcFile, MVT::i32) };
- Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops, 4);
+ Result = DAG.getNode(ISD::DEBUG_LOC, dl, MVT::Other, Ops, 4);
} else {
unsigned ID = DW->RecordSourceLine(Line, Col, SrcFile);
- Result = DAG.getLabel(ISD::DBG_LABEL, Tmp1, ID);
+ Result = DAG.getLabel(ISD::DBG_LABEL, dl, Tmp1, ID);
}
} else {
Result = Tmp1; // chain
@@ -1635,7 +1644,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// match the element type of the vector being created.
if (Tmp2.getValueType() ==
Op.getValueType().getVectorElementType()) {
- SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR,
+ SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,
Tmp1.getValueType(), Tmp2);
unsigned NumElts = Tmp1.getValueType().getVectorNumElements();
@@ -1653,16 +1662,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
else
ShufOps.push_back(DAG.getConstant(NumElts, ShufMaskEltVT));
}
- SDValue ShufMask = DAG.getNode(ISD::BUILD_VECTOR, ShufMaskVT,
+ SDValue ShufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, ShufMaskVT,
&ShufOps[0], ShufOps.size());
- Result = DAG.getNode(ISD::VECTOR_SHUFFLE, Tmp1.getValueType(),
+ Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, Tmp1.getValueType(),
Tmp1, ScVec, ShufMask);
Result = LegalizeOp(Result);
break;
}
}
- Result = PerformInsertVectorEltInMemory(Tmp1, Tmp2, Tmp3);
+ Result = PerformInsertVectorEltInMemory(Tmp1, Tmp2, Tmp3, dl);
break;
}
}
@@ -1721,19 +1730,19 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
for (unsigned i = 0; i != NumElems; ++i) {
SDValue Arg = Mask.getOperand(i);
if (Arg.getOpcode() == ISD::UNDEF) {
- Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT));
} else {
assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
unsigned Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
if (Idx < NumElems)
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp1,
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp1,
DAG.getConstant(Idx, PtrVT)));
else
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp2,
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp2,
DAG.getConstant(Idx - NumElems, PtrVT)));
}
}
- Result = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
+ Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
break;
}
case TargetLowering::Promote: {
@@ -1742,14 +1751,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
// Cast the two input vectors.
- Tmp1 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp1);
- Tmp2 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp2);
+ Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1);
+ Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2);
// Convert the shuffle mask to the right # elements.
Tmp3 = SDValue(isShuffleLegal(OVT, Node->getOperand(2)), 0);
assert(Tmp3.getNode() && "Shuffle not legal?");
- Result = DAG.getNode(ISD::VECTOR_SHUFFLE, NVT, Tmp1, Tmp2, Tmp3);
- Result = DAG.getNode(ISD::BIT_CONVERT, OVT, Result);
+ Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, NVT, Tmp1, Tmp2, Tmp3);
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result);
break;
}
}
@@ -1781,11 +1790,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT EltVT = VVT.getVectorElementType();
unsigned NumSubElem = VVT.getVectorNumElements();
for (unsigned j=0; j < NumSubElem; ++j) {
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, SubOp,
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, SubOp,
DAG.getConstant(j, PtrVT)));
}
}
- return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, Node->getValueType(0),
+ return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0),
&Ops[0], Ops.size()));
}
@@ -1808,7 +1817,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Merge in the last call, to ensure that this call start after the last
// call ended.
if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) {
- Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1);
}
@@ -1907,12 +1917,12 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
unsigned StackAlign =
TLI.getTargetMachine().getFrameInfo()->getStackAlignment();
if (Align > StackAlign)
- SP = DAG.getNode(ISD::AND, VT, SP,
+ SP = DAG.getNode(ISD::AND, dl, VT, SP,
DAG.getConstant(-(uint64_t)Align, VT));
- Tmp1 = DAG.getNode(ISD::SUB, VT, SP, Size); // Value
+ Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value
Chain = DAG.getCopyToReg(Chain, SPReg, Tmp1); // Output chain
- Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true),
+ Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true),
DAG.getIntPtrConstant(0, true), SDValue());
Tmp1 = LegalizeOp(Tmp1);
@@ -1974,7 +1984,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::BR:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
// Ensure that libcalls are emitted before a branch.
- Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1);
LastCALLSEQ_END = DAG.getEntryNode();
@@ -1983,7 +1993,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::BRIND:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
// Ensure that libcalls are emitted before a branch.
- Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1);
LastCALLSEQ_END = DAG.getEntryNode();
@@ -1998,7 +2008,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::BR_JT:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
// Ensure that libcalls are emitted before a branch.
- Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1);
LastCALLSEQ_END = DAG.getEntryNode();
@@ -2020,28 +2030,29 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT PTy = TLI.getPointerTy();
MachineFunction &MF = DAG.getMachineFunction();
unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize();
- Index= DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(EntrySize, PTy));
- SDValue Addr = DAG.getNode(ISD::ADD, PTy, Index, Table);
+ Index= DAG.getNode(ISD::MUL, dl, PTy,
+ Index, DAG.getConstant(EntrySize, PTy));
+ SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
MVT MemVT = MVT::getIntegerVT(EntrySize * 8);
- SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, PTy, Chain, Addr,
+ SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr,
PseudoSourceValue::getJumpTable(), 0, MemVT);
Addr = LD;
if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) {
// For PIC, the sequence is:
// BRIND(load(Jumptable + index) + RelocBase)
// RelocBase can be JumpTable, GOT or some sort of global base.
- Addr = DAG.getNode(ISD::ADD, PTy, Addr,
+ Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr,
TLI.getPICJumpTableRelocBase(Table, DAG));
}
- Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr);
+ Result = DAG.getNode(ISD::BRIND, dl, MVT::Other, LD.getValue(1), Addr);
}
}
break;
case ISD::BRCOND:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
// Ensure that libcalls are emitted before a return.
- Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1);
LastCALLSEQ_END = DAG.getEntryNode();
@@ -2058,7 +2069,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
unsigned BitWidth = Tmp2.getValueSizeInBits();
if (!DAG.MaskedValueIsZero(Tmp2,
APInt::getHighBitsSet(BitWidth, BitWidth-1)))
- Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1);
+ Tmp2 = DAG.getZeroExtendInReg(Tmp2, dl, MVT::i1);
break;
}
}
@@ -2077,11 +2088,12 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Expand brcond's setcc into its constituent parts and create a BR_CC
// Node.
if (Tmp2.getOpcode() == ISD::SETCC) {
- Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, Tmp2.getOperand(2),
+ Result = DAG.getNode(ISD::BR_CC, dl, MVT::Other,
+ Tmp1, Tmp2.getOperand(2),
Tmp2.getOperand(0), Tmp2.getOperand(1),
Node->getOperand(2));
} else {
- Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1,
+ Result = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1,
DAG.getCondCode(ISD::SETNE), Tmp2,
DAG.getConstant(0, Tmp2.getValueType()),
Node->getOperand(2));
@@ -2092,13 +2104,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::BR_CC:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
// Ensure that libcalls are emitted before a branch.
- Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1);
Tmp2 = Node->getOperand(2); // LHS
Tmp3 = Node->getOperand(3); // RHS
Tmp4 = Node->getOperand(1); // CC
- LegalizeSetCC(TLI.getSetCCResultType(Tmp2.getValueType()), Tmp2, Tmp3,Tmp4);
+ LegalizeSetCC(TLI.getSetCCResultType(Tmp2.getValueType()),
+ Tmp2, Tmp3, Tmp4, dl);
LastCALLSEQ_END = DAG.getEntryNode();
// If we didn't get both a LHS and RHS back from LegalizeSetCC,
@@ -2164,7 +2177,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Change base type to a different vector type.
MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
- Tmp1 = DAG.getLoad(NVT, Tmp1, Tmp2, LD->getSrcValue(),
+ Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(),
LD->isVolatile(), LD->getAlignment());
Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp1));
@@ -2206,7 +2219,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
ISD::LoadExtType NewExtType =
ExtType == ISD::ZEXTLOAD ? ISD::ZEXTLOAD : ISD::EXTLOAD;
- Result = DAG.getExtLoad(NewExtType, Node->getValueType(0),
+ Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0),
Tmp1, Tmp2, LD->getSrcValue(), SVOffset,
NVT, isVolatile, Alignment);
@@ -2214,11 +2227,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (ExtType == ISD::SEXTLOAD)
// Having the top bits zero doesn't help when sign extending.
- Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
+ Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl,
+ Result.getValueType(),
Result, DAG.getValueType(SrcVT));
else if (ExtType == ISD::ZEXTLOAD || NVT == Result.getValueType())
// All the top bits are guaranteed to be zero - inform the optimizers.
- Result = DAG.getNode(ISD::AssertZext, Result.getValueType(), Result,
+ Result = DAG.getNode(ISD::AssertZext, dl,
+ Result.getValueType(), Result,
DAG.getValueType(SrcVT));
Tmp1 = LegalizeOp(Result);
@@ -2241,58 +2256,60 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (TLI.isLittleEndian()) {
// EXTLOAD:i24 -> ZEXTLOAD:i16 | (shl EXTLOAD@+2:i8, 16)
// Load the bottom RoundWidth bits.
- Lo = DAG.getExtLoad(ISD::ZEXTLOAD, Node->getValueType(0), Tmp1, Tmp2,
+ Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl,
+ Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
Alignment);
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
- Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(IncrementSize));
- Hi = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
+ Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset + IncrementSize,
ExtraVT, isVolatile,
MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
- Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
// Move the top bits to the right place.
- Hi = DAG.getNode(ISD::SHL, Hi.getValueType(), Hi,
+ Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi,
DAG.getConstant(RoundWidth, TLI.getShiftAmountTy()));
// Join the hi and lo parts.
- Result = DAG.getNode(ISD::OR, Node->getValueType(0), Lo, Hi);
+ Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi);
} else {
// Big endian - avoid unaligned loads.
// EXTLOAD:i24 -> (shl EXTLOAD:i16, 8) | ZEXTLOAD@+2:i8
// Load the top RoundWidth bits.
- Hi = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
+ Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
Alignment);
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
- Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(IncrementSize));
- Lo = DAG.getExtLoad(ISD::ZEXTLOAD, Node->getValueType(0), Tmp1, Tmp2,
+ Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl,
+ Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset + IncrementSize,
ExtraVT, isVolatile,
MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
- Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
// Move the top bits to the right place.
- Hi = DAG.getNode(ISD::SHL, Hi.getValueType(), Hi,
+ Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi,
DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy()));
// Join the hi and lo parts.
- Result = DAG.getNode(ISD::OR, Node->getValueType(0), Lo, Hi);
+ Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi);
}
Tmp1 = LegalizeOp(Result);
@@ -2334,10 +2351,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case TargetLowering::Expand:
// f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) {
- SDValue Load = DAG.getLoad(SrcVT, Tmp1, Tmp2, LD->getSrcValue(),
+ SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(),
LD->isVolatile(), LD->getAlignment());
- Result = DAG.getNode(ISD::FP_EXTEND, Node->getValueType(0), Load);
+ Result = DAG.getNode(ISD::FP_EXTEND, dl,
+ Node->getValueType(0), Load);
Tmp1 = LegalizeOp(Result); // Relegalize new nodes.
Tmp2 = LegalizeOp(Load.getValue(1));
break;
@@ -2345,16 +2363,17 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
assert(ExtType != ISD::EXTLOAD &&"EXTLOAD should always be supported!");
// Turn the unsupported load into an EXTLOAD followed by an explicit
// zero/sign extend inreg.
- Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0),
+ Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0),
Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(), SrcVT,
LD->isVolatile(), LD->getAlignment());
SDValue ValRes;
if (ExtType == ISD::SEXTLOAD)
- ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
+ ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl,
+ Result.getValueType(),
Result, DAG.getValueType(SrcVT));
else
- ValRes = DAG.getZeroExtendInReg(Result, SrcVT);
+ ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT);
Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes.
Tmp2 = LegalizeOp(Result.getValue(1)); // Relegalize new nodes.
break;
@@ -2375,13 +2394,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case Legal:
if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
// 1 -> Hi
- Result = DAG.getNode(ISD::SRL, OpTy, Node->getOperand(0),
+ Result = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0),
DAG.getConstant(OpTy.getSizeInBits()/2,
TLI.getShiftAmountTy()));
- Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), Result);
+ Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Result);
} else {
// 0 -> Lo
- Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0),
+ Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0),
Node->getOperand(0));
}
break;
@@ -2428,7 +2447,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
// Ensure that libcalls are emitted before a return.
- Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
Tmp1 = LegalizeOp(Tmp1);
LastCALLSEQ_END = DAG.getEntryNode();
@@ -2450,9 +2469,10 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
std::swap(Lo, Hi);
if (Hi.getNode())
- Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi,Tmp3);
+ Result = DAG.getNode(ISD::RET, dl, MVT::Other,
+ Tmp1, Lo, Tmp3, Hi,Tmp3);
else
- Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3);
+ Result = DAG.getNode(ISD::RET, dl, MVT::Other, Tmp1, Lo, Tmp3);
Result = LegalizeOp(Result);
} else {
SDNode *InVal = Tmp2.getNode();
@@ -2484,7 +2504,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// type should be returned by reference!
SDValue Lo, Hi;
SplitVectorOp(Tmp2, Lo, Hi);
- Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi,Tmp3);
+ Result = DAG.getNode(ISD::RET, dl, MVT::Other,
+ Tmp1, Lo, Tmp3, Hi,Tmp3);
Result = LegalizeOp(Result);
}
}
@@ -2528,7 +2549,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (NewValues.size() == Node->getNumOperands())
Result = DAG.UpdateNodeOperands(Result, &NewValues[0],NewValues.size());
else
- Result = DAG.getNode(ISD::RET, MVT::Other,
+ Result = DAG.getNode(ISD::RET, dl, MVT::Other,
&NewValues[0], NewValues.size());
break;
}
@@ -2567,7 +2588,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp3 = DAG.getConstant(CFP->getValueAPF().
bitcastToAPInt().zextOrTrunc(32),
MVT::i32);
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
break;
} else if (CFP->getValueType(0) == MVT::f64) {
@@ -2575,7 +2596,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (getTypeAction(MVT::i64) == Legal) {
Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt().
zextOrTrunc(64), MVT::i64);
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
break;
} else if (getTypeAction(MVT::i32) == Legal && !ST->isVolatile()) {
@@ -2587,14 +2608,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
SDValue Hi = DAG.getConstant(IntVal.lshr(32).trunc(32), MVT::i32);
if (TLI.isBigEndian()) std::swap(Lo, Hi);
- Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(),
+ Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
- Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(4));
- Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
+ Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
isVolatile, MinAlign(Alignment, 4U));
- Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
break;
}
}
@@ -2626,9 +2647,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
case TargetLowering::Promote:
assert(VT.isVector() && "Unknown legal promote case!");
- Tmp3 = DAG.getNode(ISD::BIT_CONVERT,
+ Tmp3 = DAG.getNode(ISD::BIT_CONVERT, dl,
TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3);
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2,
+ Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2,
ST->getSrcValue(), SVOffset, isVolatile,
Alignment);
break;
@@ -2639,7 +2660,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (!ST->getMemoryVT().isVector()) {
// Truncate the value and store the result.
Tmp3 = PromoteOp(ST->getValue());
- Result = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, ST->getMemoryVT(),
isVolatile, Alignment);
break;
@@ -2665,14 +2686,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (TLI.isTypeLegal(TVT)) {
// Turn this into a normal store of the vector type.
Tmp3 = LegalizeOp(ST->getValue());
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
Result = LegalizeOp(Result);
break;
} else if (NumElems == 1) {
// Turn this into a normal store of the scalar type.
Tmp3 = ScalarizeVectorOp(ST->getValue());
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
// The scalarized value type may not be legal, e.g. it might require
// promotion or expansion. Relegalize the scalar store.
@@ -2700,7 +2721,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
std::swap(Lo, Hi);
}
- Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(),
+ Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
if (Hi.getNode() == NULL) {
@@ -2709,15 +2730,15 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
}
- Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(IncrementSize));
assert(isTypeLegal(Tmp2.getValueType()) &&
"Pointers must be legal!");
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
- Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(),
+ Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
- Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
break;
} // case Expand
}
@@ -2737,7 +2758,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Just store the low part. This may become a non-trunc store, so make
// sure to use getTruncStore, not UpdateNodeOperands below.
ExpandOp(ST->getValue(), Tmp3, Tmp4);
- return DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ return DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, MVT::i8, isVolatile, Alignment);
}
@@ -2749,8 +2770,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// storing an integral number of bytes. For example, promote
// TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
MVT NVT = MVT::getIntegerVT(StVT.getStoreSizeInBits());
- Tmp3 = DAG.getZeroExtendInReg(Tmp3, StVT);
- Result = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT);
+ Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, NVT, isVolatile, Alignment);
} else if (StWidth & (StWidth - 1)) {
// If not storing a power-of-2 number of bits, expand as two stores.
@@ -2770,39 +2791,39 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (TLI.isLittleEndian()) {
// TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE@+2:i8 (srl X, 16)
// Store the bottom RoundWidth bits.
- Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, RoundVT,
isVolatile, Alignment);
// Store the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
- Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(IncrementSize));
- Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3,
+ Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3,
DAG.getConstant(RoundWidth, TLI.getShiftAmountTy()));
- Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(),
+ Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(),
SVOffset + IncrementSize, ExtraVT, isVolatile,
MinAlign(Alignment, IncrementSize));
} else {
// Big endian - avoid unaligned stores.
// TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X
// Store the top RoundWidth bits.
- Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3,
+ Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3,
DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy()));
- Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset,
- RoundVT, isVolatile, Alignment);
+ Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(),
+ SVOffset, RoundVT, isVolatile, Alignment);
// Store the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
- Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(IncrementSize));
- Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset + IncrementSize, ExtraVT, isVolatile,
MinAlign(Alignment, IncrementSize));
}
// The order of the stores doesn't matter.
- Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
} else {
if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() ||
Tmp2 != ST->getBasePtr())
@@ -2828,9 +2849,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case Expand:
// TRUNCSTORE:i16 i32 -> STORE i16
assert(isTypeLegal(StVT) && "Do not know how to expand this store!");
- Tmp3 = DAG.getNode(ISD::TRUNCATE, StVT, Tmp3);
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3);
+ Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
break;
}
}
@@ -2865,7 +2886,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Node->getValueType(0));
Tmp2 = Tmp1.getValue(1);
} else {
- Tmp1 = DAG.getNode(ISD::UNDEF, Node->getValueType(0));
+ Tmp1 = DAG.getNode(ISD::UNDEF, dl, Node->getValueType(0));
Tmp2 = Node->getOperand(0);
}
break;
@@ -2937,7 +2958,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
unsigned BitWidth = Tmp1.getValueSizeInBits();
if (!DAG.MaskedValueIsZero(Tmp1,
APInt::getHighBitsSet(BitWidth, BitWidth-1)))
- Tmp1 = DAG.getZeroExtendInReg(Tmp1, MVT::i1);
+ Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, MVT::i1);
break;
}
}
@@ -2956,11 +2977,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
}
case TargetLowering::Expand:
if (Tmp1.getOpcode() == ISD::SETCC) {
- Result = DAG.getSelectCC(Tmp1.getOperand(0), Tmp1.getOperand(1),
+ Result = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1),
Tmp2, Tmp3,
cast<CondCodeSDNode>(Tmp1.getOperand(2))->get());
} else {
- Result = DAG.getSelectCC(Tmp1,
+ Result = DAG.getSelectCC(dl, Tmp1,
DAG.getConstant(0, Tmp1.getValueType()),
Tmp2, Tmp3, ISD::SETNE);
}
@@ -2980,14 +3001,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
TruncOp = ISD::FP_ROUND;
}
// Promote each of the values to the new type.
- Tmp2 = DAG.getNode(ExtOp, NVT, Tmp2);
- Tmp3 = DAG.getNode(ExtOp, NVT, Tmp3);
+ Tmp2 = DAG.getNode(ExtOp, dl, NVT, Tmp2);
+ Tmp3 = DAG.getNode(ExtOp, dl, NVT, Tmp3);
// Perform the larger operation, then round down.
- Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2,Tmp3);
+ Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp1, Tmp2,Tmp3);
if (TruncOp != ISD::FP_ROUND)
- Result = DAG.getNode(TruncOp, Node->getValueType(0), Result);
+ Result = DAG.getNode(TruncOp, dl, Node->getValueType(0), Result);
else
- Result = DAG.getNode(TruncOp, Node->getValueType(0), Result,
+ Result = DAG.getNode(TruncOp, dl, Node->getValueType(0), Result,
DAG.getIntPtrConstant(0));
break;
}
@@ -3000,7 +3021,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp4 = LegalizeOp(Node->getOperand(3)); // False
SDValue CC = Node->getOperand(4);
- LegalizeSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC);
+ LegalizeSetCC(TLI.getSetCCResultType(Tmp1.getValueType()),
+ Tmp1, Tmp2, CC, dl);
// If we didn't get both a LHS and RHS back from LegalizeSetCC,
// the LHS is a legal SETCC itself. In this case, we need to compare
@@ -3026,7 +3048,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp1 = Node->getOperand(0);
Tmp2 = Node->getOperand(1);
Tmp3 = Node->getOperand(2);
- LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, Tmp3);
+ LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, Tmp3, dl);
// If we had to Expand the SetCC operands into a SELECT node, then it may
// not always be possible to return a true LHS & RHS. In this case, just
@@ -3065,14 +3087,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
"Fell off of the edge of the floating point world");
// If the target supports SETCC of this type, use it.
- if (TLI.isOperationLegal(ISD::SETCC, NewInTy))
+ if (TLI.isOperationLegalOrCustom(ISD::SETCC, NewInTy))
break;
}
if (NewInTy.isInteger())
assert(0 && "Cannot promote Legal Integer SETCC yet");
else {
- Tmp1 = DAG.getNode(ISD::FP_EXTEND, NewInTy, Tmp1);
- Tmp2 = DAG.getNode(ISD::FP_EXTEND, NewInTy, Tmp2);
+ Tmp1 = DAG.getNode(ISD::FP_EXTEND, dl, NewInTy, Tmp1);
+ Tmp2 = DAG.getNode(ISD::FP_EXTEND, dl, NewInTy, Tmp2);
}
Tmp1 = LegalizeOp(Tmp1);
Tmp2 = LegalizeOp(Tmp2);
@@ -3084,7 +3106,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Expand a setcc node into a select_cc of the same condition, lhs, and
// rhs that selects between const 1 (true) and const 0 (false).
MVT VT = Node->getValueType(0);
- Result = DAG.getNode(ISD::SELECT_CC, VT, Tmp1, Tmp2,
+ Result = DAG.getNode(ISD::SELECT_CC, dl, VT, Tmp1, Tmp2,
DAG.getConstant(1, VT), DAG.getConstant(0, VT),
Tmp3);
break;
@@ -3113,17 +3135,18 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT TmpEltVT = Tmp1.getValueType().getVectorElementType();
SmallVector<SDValue, 8> Ops(NumElems);
for (unsigned i = 0; i < NumElems; ++i) {
- SDValue In1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, TmpEltVT,
+ SDValue In1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT,
Tmp1, DAG.getIntPtrConstant(i));
- Ops[i] = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(TmpEltVT), In1,
- DAG.getNode(ISD::EXTRACT_VECTOR_ELT, TmpEltVT,
- Tmp2, DAG.getIntPtrConstant(i)),
+ Ops[i] = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(TmpEltVT),
+ In1, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
+ TmpEltVT, Tmp2,
+ DAG.getIntPtrConstant(i)),
CC);
- Ops[i] = DAG.getNode(ISD::SELECT, EltVT, Ops[i],
- DAG.getConstant(EltVT.getIntegerVTBitMask(),EltVT),
- DAG.getConstant(0, EltVT));
+ Ops[i] = DAG.getNode(ISD::SELECT, dl, EltVT, Ops[i], DAG.getConstant(
+ APInt::getAllOnesValue(EltVT.getSizeInBits()),
+ EltVT), DAG.getConstant(0, EltVT));
}
- Result = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElems);
+ Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElems);
break;
}
}
@@ -3135,10 +3158,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::SRL_PARTS: {
SmallVector<SDValue, 8> Ops;
bool Changed = false;
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
+ unsigned N = Node->getNumOperands();
+ for (unsigned i = 0; i + 1 < N; ++i) {
Ops.push_back(LegalizeOp(Node->getOperand(i)));
Changed |= Ops.back() != Node->getOperand(i);
}
+ Ops.push_back(LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(N-1))));
+ Changed |= Ops.back() != Node->getOperand(N-1);
if (Changed)
Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
@@ -3189,23 +3215,24 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::FDIV:
case ISD::FPOW:
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
- switch (getTypeAction(Node->getOperand(1).getValueType())) {
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS
+
+ if ((Node->getOpcode() == ISD::SHL ||
+ Node->getOpcode() == ISD::SRL ||
+ Node->getOpcode() == ISD::SRA) &&
+ !Node->getValueType(0).isVector())
+ Tmp2 = DAG.getShiftAmountOperand(Tmp2);
+
+ switch (getTypeAction(Tmp2.getValueType())) {
case Expand: assert(0 && "Not possible");
case Legal:
- Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS.
+ Tmp2 = LegalizeOp(Tmp2); // Legalize the RHS.
break;
case Promote:
- Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the RHS.
+ Tmp2 = PromoteOp(Tmp2); // Promote the RHS.
break;
}
- if ((Node->getOpcode() == ISD::SHL ||
- Node->getOpcode() == ISD::SRL ||
- Node->getOpcode() == ISD::SRA) &&
- !Node->getValueType(0).isVector()) {
- Tmp2 = LegalizeShiftAmount(Tmp2);
- }
-
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
@@ -3228,10 +3255,10 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// and unsigned forms. If the target supports both SMUL_LOHI and
// UMUL_LOHI, form a preference by checking which forms of plain
// MULH it supports.
- bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, VT);
- bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, VT);
- bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, VT);
- bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, VT);
+ bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT);
+ bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT);
+ bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT);
+ bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT);
unsigned OpToUse = 0;
if (HasSMUL_LOHI && !HasMULHS) {
OpToUse = ISD::SMUL_LOHI;
@@ -3243,31 +3270,36 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
OpToUse = ISD::UMUL_LOHI;
}
if (OpToUse) {
- Result = SDValue(DAG.getNode(OpToUse, VTs, Tmp1, Tmp2).getNode(), 0);
+ Result = SDValue(DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2).getNode(),
+ 0);
break;
}
}
if (Node->getOpcode() == ISD::MULHS &&
- TLI.isOperationLegal(ISD::SMUL_LOHI, VT)) {
- Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, VTs, Tmp1, Tmp2).getNode(),
+ TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) {
+ Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl,
+ VTs, Tmp1, Tmp2).getNode(),
1);
break;
}
if (Node->getOpcode() == ISD::MULHU &&
- TLI.isOperationLegal(ISD::UMUL_LOHI, VT)) {
- Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, VTs, Tmp1, Tmp2).getNode(),
+ TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) {
+ Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl,
+ VTs, Tmp1, Tmp2).getNode(),
1);
break;
}
if (Node->getOpcode() == ISD::SDIV &&
- TLI.isOperationLegal(ISD::SDIVREM, VT)) {
- Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(),
+ TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) {
+ Result = SDValue(DAG.getNode(ISD::SDIVREM, dl,
+ VTs, Tmp1, Tmp2).getNode(),
0);
break;
}
if (Node->getOpcode() == ISD::UDIV &&
- TLI.isOperationLegal(ISD::UDIVREM, VT)) {
- Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(),
+ TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) {
+ Result = SDValue(DAG.getNode(ISD::UDIVREM, dl,
+ VTs, Tmp1, Tmp2).getNode(),
0);
break;
}
@@ -3287,7 +3319,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::MUL:
if (VT == MVT::i32)
LC = RTLIB::MUL_I32;
- else if (VT == MVT::i64)
+ else if (VT == MVT::i64)
LC = RTLIB::MUL_I64;
break;
case ISD::FPOW:
@@ -3322,11 +3354,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
assert(OVT.isVector() && "Cannot promote this BinOp!");
// Bit convert each of the values to the new type.
- Tmp1 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp1);
- Tmp2 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp2);
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+ Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1);
+ Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
// Bit convert the result back the original type.
- Result = DAG.getNode(ISD::BIT_CONVERT, OVT, Result);
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result);
break;
}
}
@@ -3380,14 +3412,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Get the sign bit of the RHS.
MVT IVT =
Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64;
- SDValue SignBit = DAG.getNode(ISD::BIT_CONVERT, IVT, Tmp2);
- SignBit = DAG.getSetCC(TLI.getSetCCResultType(IVT),
+ SDValue SignBit = DAG.getNode(ISD::BIT_CONVERT, dl, IVT, Tmp2);
+ SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(IVT),
SignBit, DAG.getConstant(0, IVT), ISD::SETLT);
// Get the absolute value of the result.
- SDValue AbsVal = DAG.getNode(ISD::FABS, Tmp1.getValueType(), Tmp1);
+ SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1);
// Select between the nabs and abs value based on the sign bit of
// the input.
- Result = DAG.getNode(ISD::SELECT, AbsVal.getValueType(), SignBit,
+ Result = DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit,
DAG.getNode(ISD::FNEG, AbsVal.getValueType(),
AbsVal),
AbsVal);
@@ -3399,7 +3431,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT NVT =
Node->getValueType(0) == MVT::f32 ? MVT::i32 : MVT::i64;
Result = ExpandFCOPYSIGNToBitwiseOps(Node, NVT, DAG, TLI);
- Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0), Result);
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0), Result);
Result = LegalizeOp(Result);
break;
}
@@ -3470,15 +3502,15 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
assert(0 && "Cannot promote/custom this yet!");
case TargetLowering::Legal:
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
- Result = DAG.getNode(ISD::BUILD_PAIR, PairTy, Tmp1, Tmp2);
+ Result = DAG.getNode(ISD::BUILD_PAIR, dl, PairTy, Tmp1, Tmp2);
break;
case TargetLowering::Expand:
- Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, PairTy, Tmp1);
- Tmp2 = DAG.getNode(ISD::ANY_EXTEND, PairTy, Tmp2);
- Tmp2 = DAG.getNode(ISD::SHL, PairTy, Tmp2,
+ Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, PairTy, Tmp1);
+ Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Tmp2);
+ Tmp2 = DAG.getNode(ISD::SHL, dl, PairTy, Tmp2,
DAG.getConstant(PairTy.getSizeInBits()/2,
TLI.getShiftAmountTy()));
- Result = DAG.getNode(ISD::OR, PairTy, Tmp1, Tmp2);
+ Result = DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2);
break;
}
break;
@@ -3510,13 +3542,15 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// See if remainder can be lowered using two-result operations.
SDVTList VTs = DAG.getVTList(VT, VT);
if (Node->getOpcode() == ISD::SREM &&
- TLI.isOperationLegal(ISD::SDIVREM, VT)) {
- Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(), 1);
+ TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) {
+ Result = SDValue(DAG.getNode(ISD::SDIVREM, dl,
+ VTs, Tmp1, Tmp2).getNode(), 1);
break;
}
if (Node->getOpcode() == ISD::UREM &&
- TLI.isOperationLegal(ISD::UDIVREM, VT)) {
- Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(), 1);
+ TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) {
+ Result = SDValue(DAG.getNode(ISD::UDIVREM, dl,
+ VTs, Tmp1, Tmp2).getNode(), 1);
break;
}
@@ -3524,9 +3558,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (TLI.getOperationAction(DivOpc, VT) ==
TargetLowering::Legal) {
// X % Y -> X-X/Y*Y
- Result = DAG.getNode(DivOpc, VT, Tmp1, Tmp2);
- Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2);
- Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result);
+ Result = DAG.getNode(DivOpc, dl, VT, Tmp1, Tmp2);
+ Result = DAG.getNode(ISD::MUL, dl, VT, Result, Tmp2);
+ Result = DAG.getNode(ISD::SUB, dl, VT, Tmp1, Result);
} else if (VT.isVector()) {
Result = LegalizeOp(UnrollVectorOp(Op));
} else {
@@ -3579,16 +3613,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
case TargetLowering::Expand: {
const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
- SDValue VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0);
+ SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0);
// Increment the pointer, VAList, to the next vaarg
- Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList,
+ Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList,
DAG.getConstant(TLI.getTargetData()->
getTypePaddedSize(VT.getTypeForMVT()),
TLI.getPointerTy()));
// Store the incremented VAList to the legalized pointer
- Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, V, 0);
+ Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0);
// Load the actual argument out of the pointer VAList
- Result = DAG.getLoad(VT, Tmp3, VAList, NULL, 0);
+ Result = DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0);
Tmp1 = LegalizeOp(Result.getValue(1));
Result = LegalizeOp(Result);
break;
@@ -3624,8 +3658,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// output, returning the chain.
const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue();
const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue();
- Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, VS, 0);
- Result = DAG.getStore(Tmp4.getValue(1), Tmp4, Tmp2, VD, 0);
+ Tmp4 = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp3, VS, 0);
+ Result = DAG.getStore(Tmp4.getValue(1), dl, Tmp4, Tmp2, VD, 0);
break;
}
break;
@@ -3671,7 +3705,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::ROTL:
case ISD::ROTR:
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
- Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS
+ Tmp2 = LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(1))); // RHS
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
default:
@@ -3705,14 +3739,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
- Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
- Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1);
- Result = DAG.getNode(ISD::SRL, NVT, Tmp1,
+ Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1);
+ Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1);
+ Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1,
DAG.getConstant(DiffBits, TLI.getShiftAmountTy()));
break;
}
case TargetLowering::Expand:
- Result = ExpandBSWAP(Tmp1);
+ Result = ExpandBSWAP(Tmp1, dl);
break;
}
break;
@@ -3738,24 +3772,24 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
// Zero extend the argument.
- Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
+ Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1);
// Perform the larger operation, then subtract if needed.
- Tmp1 = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
+ Tmp1 = DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Tmp1);
switch (Node->getOpcode()) {
case ISD::CTPOP:
Result = Tmp1;
break;
case ISD::CTTZ:
//if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1,
- DAG.getConstant(NVT.getSizeInBits(), NVT),
+ Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()),
+ Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT),
ISD::SETEQ);
- Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
+ Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2,
DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1);
break;
case ISD::CTLZ:
// Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
- Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
+ Result = DAG.getNode(ISD::SUB, dl, NVT, Tmp1,
DAG.getConstant(NVT.getSizeInBits() -
OVT.getSizeInBits(), NVT));
break;
@@ -3763,7 +3797,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
}
case TargetLowering::Expand:
- Result = ExpandBitCount(Node->getOpcode(), Tmp1);
+ Result = ExpandBitCount(Node->getOpcode(), Tmp1, dl);
break;
}
break;
@@ -3803,16 +3837,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::FNEG:
// Expand Y = FNEG(X) -> Y = SUB -0.0, X
Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0));
- Result = DAG.getNode(ISD::FSUB, Node->getValueType(0), Tmp2, Tmp1);
+ Result = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp2, Tmp1);
break;
case ISD::FABS: {
// Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X).
MVT VT = Node->getValueType(0);
Tmp2 = DAG.getConstantFP(0.0, VT);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()),
+ Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()),
Tmp1, Tmp2, ISD::SETUGT);
- Tmp3 = DAG.getNode(ISD::FNEG, VT, Tmp1);
- Result = DAG.getNode(ISD::SELECT, VT, Tmp2, Tmp1, Tmp3);
+ Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1);
+ Result = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3);
break;
}
case ISD::FSQRT:
@@ -3920,7 +3954,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::BIT_CONVERT:
if (!isTypeLegal(Node->getOperand(0).getValueType())) {
Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
- Node->getValueType(0));
+ Node->getValueType(0), dl);
} else if (Op.getOperand(0).getValueType().isVector()) {
// The input has to be a vector type, we have to either scalarize it, pack
// it, or convert it based on whether the input vector type is legal.
@@ -3934,12 +3968,12 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
MVT TVT = MVT::getVectorVT(EVT, NumElems);
if (TLI.isTypeLegal(TVT)) {
// Turn this into a bit convert of the vector input.
- Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0),
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0),
LegalizeOp(Node->getOperand(0)));
break;
} else if (NumElems == 1) {
// Turn this into a bit convert of the scalar input.
- Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0),
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0),
ScalarizeVectorOp(Node->getOperand(0)));
break;
} else {
@@ -3952,7 +3986,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
default: assert(0 && "Unknown operation action!");
case TargetLowering::Expand:
Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
- Node->getValueType(0));
+ Node->getValueType(0), dl);
break;
case TargetLowering::Legal:
Tmp1 = LegalizeOp(Node->getOperand(0));
@@ -4009,7 +4043,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::UINT_TO_FP: {
bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
Result = LegalizeINT_TO_FP(Result, isSigned,
- Node->getValueType(0), Node->getOperand(0));
+ Node->getValueType(0), Node->getOperand(0), dl);
break;
}
case ISD::TRUNCATE:
@@ -4039,11 +4073,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Since the result is legal, we should just be able to truncate the low
// part of the source.
- Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), Tmp1);
+ Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1);
break;
case Promote:
Result = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::TRUNCATE, Op.getValueType(), Result);
+ Result = DAG.getNode(ISD::TRUNCATE, dl, Op.getValueType(), Result);
break;
}
break;
@@ -4068,7 +4102,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
case TargetLowering::Promote:
Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0),
- Node->getOpcode() == ISD::FP_TO_SINT);
+ Node->getOpcode() == ISD::FP_TO_SINT,
+ dl);
break;
case TargetLowering::Expand:
if (Node->getOpcode() == ISD::FP_TO_UINT) {
@@ -4080,15 +4115,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
APInt x = APInt::getSignBit(NVT.getSizeInBits());
(void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
Tmp2 = DAG.getConstantFP(apf, VT);
- Tmp3 = DAG.getSetCC(TLI.getSetCCResultType(VT), Node->getOperand(0),
+ Tmp3 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT),
+ Node->getOperand(0),
Tmp2, ISD::SETLT);
- True = DAG.getNode(ISD::FP_TO_SINT, NVT, Node->getOperand(0));
- False = DAG.getNode(ISD::FP_TO_SINT, NVT,
- DAG.getNode(ISD::FSUB, VT, Node->getOperand(0),
- Tmp2));
- False = DAG.getNode(ISD::XOR, NVT, False,
+ True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0));
+ False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT,
+ DAG.getNode(ISD::FSUB, dl, VT,
+ Node->getOperand(0), Tmp2));
+ False = DAG.getNode(ISD::XOR, dl, NVT, False,
DAG.getConstant(x, NVT));
- Result = DAG.getNode(ISD::SELECT, NVT, Tmp3, True, False);
+ Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp3, True, False);
break;
} else {
assert(0 && "Do not know how to expand FP_TO_SINT yet!");
@@ -4102,24 +4138,25 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Convert ppcf128 to i32
if (OVT == MVT::ppcf128 && VT == MVT::i32) {
if (Node->getOpcode() == ISD::FP_TO_SINT) {
- Result = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128,
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128,
Node->getOperand(0), DAG.getValueType(MVT::f64));
- Result = DAG.getNode(ISD::FP_ROUND, MVT::f64, Result,
+ Result = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Result,
DAG.getIntPtrConstant(1));
- Result = DAG.getNode(ISD::FP_TO_SINT, VT, Result);
+ Result = DAG.getNode(ISD::FP_TO_SINT, dl, VT, Result);
} else {
const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
APFloat apf = APFloat(APInt(128, 2, TwoE31));
Tmp2 = DAG.getConstantFP(apf, OVT);
// X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
// FIXME: generated code sucks.
- Result = DAG.getNode(ISD::SELECT_CC, VT, Node->getOperand(0), Tmp2,
- DAG.getNode(ISD::ADD, MVT::i32,
- DAG.getNode(ISD::FP_TO_SINT, VT,
- DAG.getNode(ISD::FSUB, OVT,
+ Result = DAG.getNode(ISD::SELECT_CC, dl, VT, Node->getOperand(0),
+ Tmp2,
+ DAG.getNode(ISD::ADD, dl, MVT::i32,
+ DAG.getNode(ISD::FP_TO_SINT, dl, VT,
+ DAG.getNode(ISD::FSUB, dl, OVT,
Node->getOperand(0), Tmp2)),
DAG.getConstant(0x80000000, MVT::i32)),
- DAG.getNode(ISD::FP_TO_SINT, VT,
+ DAG.getNode(ISD::FP_TO_SINT, dl, VT,
Node->getOperand(0)),
DAG.getCondCode(ISD::SETGE));
}
@@ -4147,7 +4184,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
// The only other way we can lower this is to turn it into a STORE,
// LOAD pair, targetting a temporary location (a stack slot).
- Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT);
+ Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT, dl);
break;
}
switch (getTypeAction(Node->getOperand(0).getValueType())) {
@@ -4158,7 +4195,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
case Promote:
Tmp1 = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::FP_EXTEND, Op.getValueType(), Tmp1);
+ Result = DAG.getNode(ISD::FP_EXTEND, dl, Op.getValueType(), Tmp1);
break;
}
break;
@@ -4172,12 +4209,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
ExpandOp(Node->getOperand(0), Lo, Result);
// Round it the rest of the way (e.g. to f32) if needed.
if (DstVT!=MVT::f64)
- Result = DAG.getNode(ISD::FP_ROUND, DstVT, Result, Op.getOperand(1));
+ Result = DAG.getNode(ISD::FP_ROUND, dl,
+ DstVT, Result, Op.getOperand(1));
break;
}
// The only other way we can lower this is to turn it into a STORE,
// LOAD pair, targetting a temporary location (a stack slot).
- Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT);
+ Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT, dl);
break;
}
switch (getTypeAction(Node->getOperand(0).getValueType())) {
@@ -4188,7 +4226,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
case Promote:
Tmp1 = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::FP_ROUND, Op.getValueType(), Tmp1,
+ Result = DAG.getNode(ISD::FP_ROUND, dl, Op.getValueType(), Tmp1,
Node->getOperand(1));
break;
}
@@ -4212,18 +4250,18 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
switch (Node->getOpcode()) {
case ISD::ANY_EXTEND:
Tmp1 = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Tmp1);
+ Result = DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(), Tmp1);
break;
case ISD::ZERO_EXTEND:
Result = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result);
- Result = DAG.getZeroExtendInReg(Result,
+ Result = DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(), Result);
+ Result = DAG.getZeroExtendInReg(Result, dl,
Node->getOperand(0).getValueType());
break;
case ISD::SIGN_EXTEND:
Result = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result);
- Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
+ Result = DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(), Result);
+ Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Result.getValueType(),
Result,
DAG.getValueType(Node->getOperand(0).getValueType()));
break;
@@ -4250,9 +4288,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
unsigned BitsDiff = Node->getValueType(0).getSizeInBits() -
ExtraVT.getSizeInBits();
SDValue ShiftCst = DAG.getConstant(BitsDiff, TLI.getShiftAmountTy());
- Result = DAG.getNode(ISD::SHL, Node->getValueType(0),
+ Result = DAG.getNode(ISD::SHL, dl, Node->getValueType(0),
Node->getOperand(0), ShiftCst);
- Result = DAG.getNode(ISD::SRA, Node->getValueType(0),
+ Result = DAG.getNode(ISD::SRA, dl, Node->getValueType(0),
Result, ShiftCst);
} else if (Node->getOpcode() == ISD::FP_ROUND_INREG) {
// The only way we can lower this is to turn it into a TRUNCSTORE,
@@ -4262,7 +4300,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// slots and always reusing the same one. We currently always create
// new ones, as reuse may inhibit scheduling.
Result = EmitStackConvert(Node->getOperand(0), ExtraVT,
- Node->getValueType(0));
+ Node->getValueType(0), dl);
} else {
assert(0 && "Unknown op");
}
@@ -4322,7 +4360,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
TLI.LowerCallTo(Tmp1, Type::VoidTy,
false, false, false, false, CallingConv::C, false,
DAG.getExternalSymbol("abort", TLI.getPointerTy()),
- Args, DAG);
+ Args, DAG, dl);
Result = CallResult.second;
break;
}
@@ -4343,7 +4381,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
SDValue RHS = LegalizeOp(Node->getOperand(1));
SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
- ISD::ADD : ISD::SUB, LHS.getValueType(),
+ ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
LHS, RHS);
MVT OType = Node->getValueType(1);
@@ -4358,21 +4396,22 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Sub:
// Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
//
- SDValue LHSSign = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE);
- SDValue RHSSign = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE);
- SDValue SignsMatch = DAG.getSetCC(OType, LHSSign, RHSSign,
+ SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE);
+ SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE);
+ SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
Node->getOpcode() == ISD::SADDO ?
ISD::SETEQ : ISD::SETNE);
- SDValue SumSign = DAG.getSetCC(OType, Sum, Zero, ISD::SETGE);
- SDValue SumSignNE = DAG.getSetCC(OType, LHSSign, SumSign, ISD::SETNE);
+ SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE);
+ SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
- SDValue Cmp = DAG.getNode(ISD::AND, OType, SignsMatch, SumSignNE);
+ SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE);
MVT ValueVTs[] = { LHS.getValueType(), OType };
SDValue Ops[] = { Sum, Cmp };
- Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2),
+ Result = DAG.getNode(ISD::MERGE_VALUES, dl,
+ DAG.getVTList(&ValueVTs[0], 2),
&Ops[0], 2);
SDNode *RNode = Result.getNode();
DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0));
@@ -4397,17 +4436,18 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
SDValue RHS = LegalizeOp(Node->getOperand(1));
SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ?
- ISD::ADD : ISD::SUB, LHS.getValueType(),
+ ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
LHS, RHS);
MVT OType = Node->getValueType(1);
- SDValue Cmp = DAG.getSetCC(OType, Sum, LHS,
+ SDValue Cmp = DAG.getSetCC(dl, OType, Sum, LHS,
Node->getOpcode () == ISD::UADDO ?
ISD::SETULT : ISD::SETUGT);
MVT ValueVTs[] = { LHS.getValueType(), OType };
SDValue Ops[] = { Sum, Cmp };
- Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2),
+ Result = DAG.getNode(ISD::MERGE_VALUES, dl,
+ DAG.getVTList(&ValueVTs[0], 2),
&Ops[0], 2);
SDNode *RNode = Result.getNode();
DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0));
@@ -4467,6 +4507,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
SDValue Tmp1, Tmp2, Tmp3;
SDValue Result;
SDNode *Node = Op.getNode();
+ DebugLoc dl = Node->getDebugLoc();
DenseMap<SDValue, SDValue>::iterator I = PromotedNodes.find(Op);
if (I != PromotedNodes.end()) return I->second;
@@ -4481,17 +4522,17 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
assert(0 && "Do not know how to promote this operator!");
abort();
case ISD::UNDEF:
- Result = DAG.getNode(ISD::UNDEF, NVT);
+ Result = DAG.getNode(ISD::UNDEF, dl, NVT);
break;
case ISD::Constant:
if (VT != MVT::i1)
- Result = DAG.getNode(ISD::SIGN_EXTEND, NVT, Op);
+ Result = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Op);
else
- Result = DAG.getNode(ISD::ZERO_EXTEND, NVT, Op);
+ Result = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Op);
assert(isa<ConstantSDNode>(Result) && "Didn't constant fold zext?");
break;
case ISD::ConstantFP:
- Result = DAG.getNode(ISD::FP_EXTEND, NVT, Op);
+ Result = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Op);
assert(isa<ConstantFPSDNode>(Result) && "Didn't constant fold fp_extend?");
break;
@@ -4499,7 +4540,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
MVT VT0 = Node->getOperand(0).getValueType();
assert(isTypeLegal(TLI.getSetCCResultType(VT0))
&& "SetCC type is not legal??");
- Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(VT0),
+ Result = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(VT0),
Node->getOperand(0), Node->getOperand(1),
Node->getOperand(2));
break;
@@ -4511,7 +4552,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
assert(Result.getValueType().bitsGE(NVT) &&
"This truncation doesn't make sense!");
if (Result.getValueType().bitsGT(NVT)) // Truncate to NVT instead of VT
- Result = DAG.getNode(ISD::TRUNCATE, NVT, Result);
+ Result = DAG.getNode(ISD::TRUNCATE, dl, NVT, Result);
break;
case Promote:
// The truncation is not required, because we don't guarantee anything
@@ -4521,7 +4562,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case Expand:
ExpandOp(Node->getOperand(0), Tmp1, Tmp2);
// Truncate the low part of the expanded value to the result type
- Result = DAG.getNode(ISD::TRUNCATE, NVT, Tmp1);
+ Result = DAG.getNode(ISD::TRUNCATE, dl, NVT, Tmp1);
}
break;
case ISD::SIGN_EXTEND:
@@ -4531,17 +4572,17 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case Expand: assert(0 && "BUG: Smaller reg should have been promoted!");
case Legal:
// Input is legal? Just do extend all the way to the larger type.
- Result = DAG.getNode(Node->getOpcode(), NVT, Node->getOperand(0));
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Node->getOperand(0));
break;
case Promote:
// Promote the reg if it's smaller.
Result = PromoteOp(Node->getOperand(0));
// The high bits are not guaranteed to be anything. Insert an extend.
if (Node->getOpcode() == ISD::SIGN_EXTEND)
- Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Result,
DAG.getValueType(Node->getOperand(0).getValueType()));
else if (Node->getOpcode() == ISD::ZERO_EXTEND)
- Result = DAG.getZeroExtendInReg(Result,
+ Result = DAG.getZeroExtendInReg(Result, dl,
Node->getOperand(0).getValueType());
break;
}
@@ -4561,7 +4602,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
}
case ISD::BIT_CONVERT:
Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
- Node->getValueType(0));
+ Node->getValueType(0), dl);
Result = PromoteOp(Result);
break;
@@ -4574,11 +4615,11 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case Legal:
if (Node->getConstantOperandVal(1) == 0) {
// Input is legal? Do an FP_ROUND_INREG.
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Node->getOperand(0),
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Node->getOperand(0),
DAG.getValueType(VT));
} else {
// Just remove the truncate, it isn't affecting the value.
- Result = DAG.getNode(ISD::FP_ROUND, NVT, Node->getOperand(0),
+ Result = DAG.getNode(ISD::FP_ROUND, dl, NVT, Node->getOperand(0),
Node->getOperand(1));
}
break;
@@ -4589,27 +4630,27 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case Legal:
// No extra round required here.
- Result = DAG.getNode(Node->getOpcode(), NVT, Node->getOperand(0));
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Node->getOperand(0));
break;
case Promote:
Result = PromoteOp(Node->getOperand(0));
if (Node->getOpcode() == ISD::SINT_TO_FP)
- Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
+ Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Result.getValueType(),
Result,
DAG.getValueType(Node->getOperand(0).getValueType()));
else
- Result = DAG.getZeroExtendInReg(Result,
+ Result = DAG.getZeroExtendInReg(Result, dl,
Node->getOperand(0).getValueType());
// No extra round required here.
- Result = DAG.getNode(Node->getOpcode(), NVT, Result);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Result);
break;
case Expand:
Result = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, NVT,
- Node->getOperand(0));
+ Node->getOperand(0), dl);
// Round if we cannot tolerate excess precision.
if (NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result,
DAG.getValueType(VT));
break;
}
@@ -4617,7 +4658,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case ISD::SIGN_EXTEND_INREG:
Result = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Result,
Node->getOperand(1));
break;
case ISD::FP_TO_SINT:
@@ -4639,12 +4680,12 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
// FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
// legal, such as PowerPC.
if (Node->getOpcode() == ISD::FP_TO_UINT &&
- !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
- (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) ||
+ !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) &&
+ (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT) ||
TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)){
- Result = DAG.getNode(ISD::FP_TO_SINT, NVT, Tmp1);
+ Result = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Tmp1);
} else {
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1);
}
break;
@@ -4652,7 +4693,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case ISD::FNEG:
Tmp1 = PromoteOp(Node->getOperand(0));
assert(Tmp1.getValueType() == NVT);
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1);
// NOTE: we do not have to do any extra rounding here for
// NoExcessFPPrecision, because we know the input will have the appropriate
// precision, and these operations don't modify precision at all.
@@ -4673,9 +4714,9 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case ISD::FNEARBYINT:
Tmp1 = PromoteOp(Node->getOperand(0));
assert(Tmp1.getValueType() == NVT);
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1);
if (NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result,
DAG.getValueType(VT));
break;
@@ -4688,9 +4729,9 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
if (Node->getOpcode() == ISD::FPOW)
Tmp2 = PromoteOp(Tmp2);
assert(Tmp1.getValueType() == NVT);
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
if (NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result,
DAG.getValueType(VT));
break;
}
@@ -4699,7 +4740,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node);
Tmp2 = PromoteOp(Node->getOperand(2));
Tmp3 = PromoteOp(Node->getOperand(3));
- Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getMemoryVT(),
+ Result = DAG.getAtomic(Node->getOpcode(), dl, AtomNode->getMemoryVT(),
AtomNode->getChain(),
AtomNode->getBasePtr(), Tmp2, Tmp3,
AtomNode->getSrcValue(),
@@ -4721,7 +4762,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case ISD::ATOMIC_SWAP: {
AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node);
Tmp2 = PromoteOp(Node->getOperand(2));
- Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getMemoryVT(),
+ Result = DAG.getAtomic(Node->getOpcode(), dl, AtomNode->getMemoryVT(),
AtomNode->getChain(),
AtomNode->getBasePtr(), Tmp2,
AtomNode->getSrcValue(),
@@ -4743,7 +4784,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
Tmp1 = PromoteOp(Node->getOperand(0));
Tmp2 = PromoteOp(Node->getOperand(1));
assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
break;
case ISD::FADD:
case ISD::FSUB:
@@ -4751,7 +4792,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
Tmp1 = PromoteOp(Node->getOperand(0));
Tmp2 = PromoteOp(Node->getOperand(1));
assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
// Floating point operations will give excess precision that we may not be
// able to tolerate. If we DO allow excess precision, just leave it,
@@ -4759,7 +4800,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
// FIXME: Why would we need to round FP ops more than integer ones?
// Is Round(Add(Add(A,B),C)) != Round(Add(Round(Add(A,B)), C))
if (NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result,
DAG.getValueType(VT));
break;
@@ -4769,16 +4810,16 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
Tmp1 = PromoteOp(Node->getOperand(0));
Tmp2 = PromoteOp(Node->getOperand(1));
if (NVT.isInteger()) {
- Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
+ Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1,
DAG.getValueType(VT));
- Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2,
+ Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp2,
DAG.getValueType(VT));
}
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
// Perform FP_ROUND: this is probably overly pessimistic.
if (NVT.isFloatingPoint() && NoExcessFPPrecision)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result,
DAG.getValueType(VT));
break;
case ISD::FDIV:
@@ -4795,11 +4836,11 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case Legal: Tmp2 = LegalizeOp(Node->getOperand(1)); break;
case Promote: Tmp2 = PromoteOp(Node->getOperand(1)); break;
}
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
// Perform FP_ROUND: this is probably overly pessimistic.
if (NoExcessFPPrecision && Node->getOpcode() != ISD::FCOPYSIGN)
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result,
DAG.getValueType(VT));
break;
@@ -4809,27 +4850,27 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
Tmp1 = PromoteOp(Node->getOperand(0));
Tmp2 = PromoteOp(Node->getOperand(1));
assert(NVT.isInteger() && "Operators don't apply to FP!");
- Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT);
- Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT);
- Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+ Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT);
+ Tmp2 = DAG.getZeroExtendInReg(Tmp2, dl, VT);
+ Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
break;
case ISD::SHL:
Tmp1 = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(ISD::SHL, NVT, Tmp1, Node->getOperand(1));
+ Result = DAG.getNode(ISD::SHL, dl, NVT, Tmp1, Node->getOperand(1));
break;
case ISD::SRA:
// The input value must be properly sign extended.
Tmp1 = PromoteOp(Node->getOperand(0));
- Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
+ Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1,
DAG.getValueType(VT));
- Result = DAG.getNode(ISD::SRA, NVT, Tmp1, Node->getOperand(1));
+ Result = DAG.getNode(ISD::SRA, dl, NVT, Tmp1, Node->getOperand(1));
break;
case ISD::SRL:
// The input value must be properly zero extended.
Tmp1 = PromoteOp(Node->getOperand(0));
- Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT);
- Result = DAG.getNode(ISD::SRL, NVT, Tmp1, Node->getOperand(1));
+ Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT);
+ Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, Node->getOperand(1));
break;
case ISD::VAARG:
@@ -4842,13 +4883,13 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
SDValue VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0);
// Increment the pointer, VAList, to the next vaarg
- Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList,
+ Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList,
DAG.getConstant(VT.getSizeInBits()/8,
TLI.getPointerTy()));
// Store the incremented VAList to the legalized pointer
- Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, V, 0);
+ Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0);
// Load the actual argument out of the pointer VAList
- Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp3, VAList, NULL, 0, VT);
+ Result = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Tmp3, VAList, NULL, 0, VT);
}
// Remember that we legalized the chain.
AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
@@ -4858,7 +4899,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
LoadSDNode *LD = cast<LoadSDNode>(Node);
ISD::LoadExtType ExtType = ISD::isNON_EXTLoad(Node)
? ISD::EXTLOAD : LD->getExtensionType();
- Result = DAG.getExtLoad(ExtType, NVT,
+ Result = DAG.getExtLoad(ExtType, dl, NVT,
LD->getChain(), LD->getBasePtr(),
LD->getSrcValue(), LD->getSrcValueOffset(),
LD->getMemoryVT(),
@@ -4878,20 +4919,20 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
// Ensure that the resulting node is at least the same size as the operands'
// value types, because we cannot assume that TLI.getSetCCValueType() is
// constant.
- Result = DAG.getNode(ISD::SELECT, VT2, Node->getOperand(0), Tmp2, Tmp3);
+ Result = DAG.getNode(ISD::SELECT, dl, VT2, Node->getOperand(0), Tmp2, Tmp3);
break;
}
case ISD::SELECT_CC:
Tmp2 = PromoteOp(Node->getOperand(2)); // True
Tmp3 = PromoteOp(Node->getOperand(3)); // False
- Result = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
+ Result = DAG.getNode(ISD::SELECT_CC, dl, NVT, Node->getOperand(0),
Node->getOperand(1), Tmp2, Tmp3, Node->getOperand(4));
break;
case ISD::BSWAP:
Tmp1 = Node->getOperand(0);
- Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
- Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1);
- Result = DAG.getNode(ISD::SRL, NVT, Tmp1,
+ Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1);
+ Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1);
+ Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1,
DAG.getConstant(NVT.getSizeInBits() -
VT.getSizeInBits(),
TLI.getShiftAmountTy()));
@@ -4900,24 +4941,24 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
case ISD::CTTZ:
case ISD::CTLZ:
// Zero extend the argument
- Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Node->getOperand(0));
+ Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0));
// Perform the larger operation, then subtract if needed.
- Tmp1 = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+ Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1);
switch(Node->getOpcode()) {
case ISD::CTPOP:
Result = Tmp1;
break;
case ISD::CTTZ:
// if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1,
+ Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1,
DAG.getConstant(NVT.getSizeInBits(), NVT),
ISD::SETEQ);
- Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
+ Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2,
DAG.getConstant(VT.getSizeInBits(), NVT), Tmp1);
break;
case ISD::CTLZ:
//Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
- Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
+ Result = DAG.getNode(ISD::SUB, dl, NVT, Tmp1,
DAG.getConstant(NVT.getSizeInBits() -
VT.getSizeInBits(), NVT));
break;
@@ -4951,6 +4992,7 @@ SDValue SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDValue Op) {
// lower to a store then an indexed load.
SDValue Vec = Op.getOperand(0);
SDValue Idx = Op.getOperand(1);
+ DebugLoc dl = Op.getNode()->getDebugLoc();
MVT TVT = Vec.getValueType();
unsigned NumElems = TVT.getVectorNumElements();
@@ -5002,21 +5044,21 @@ SDValue SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDValue Op) {
// Store the value to a temporary stack slot, then LOAD the scalar
// element back out.
SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType());
- SDValue Ch = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
+ SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0);
// Add the offset to the index.
unsigned EltSize = Op.getValueType().getSizeInBits()/8;
- Idx = DAG.getNode(ISD::MUL, Idx.getValueType(), Idx,
+ Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx,
DAG.getConstant(EltSize, Idx.getValueType()));
if (Idx.getValueType().bitsGT(TLI.getPointerTy()))
- Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx);
+ Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx);
else
- Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
+ Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx);
- StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr);
+ StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr);
- Op = DAG.getLoad(Op.getValueType(), Ch, StackPtr, NULL, 0);
+ Op = DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0);
}
return Op;
}
@@ -5060,7 +5102,8 @@ SDValue SelectionDAGLegalize::ExpandEXTRACT_SUBVECTOR(SDValue Op) {
/// LHS, and the SDValue returned in RHS has a nil SDNode value.
void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
SDValue &RHS,
- SDValue &CC) {
+ SDValue &CC,
+ DebugLoc dl) {
SDValue Tmp1, Tmp2, Tmp3, Result;
switch (getTypeAction(LHS.getValueType())) {
@@ -5092,16 +5135,16 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
// ALL of these operations will work if we either sign or zero extend
// the operands (including the unsigned comparisons!). Zero extend is
// usually a simpler/cheaper operation, so prefer it.
- Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT);
- Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT);
+ Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT);
+ Tmp2 = DAG.getZeroExtendInReg(Tmp2, dl, VT);
break;
case ISD::SETGE:
case ISD::SETGT:
case ISD::SETLT:
case ISD::SETLE:
- Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
+ Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1,
DAG.getValueType(VT));
- Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2,
+ Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp2,
DAG.getValueType(VT));
Tmp1 = LegalizeOp(Tmp1); // Relegalize new nodes.
Tmp2 = LegalizeOp(Tmp2); // Relegalize new nodes.
@@ -5173,20 +5216,20 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
SDValue Dummy;
SDValue Ops[2] = { LHS, RHS };
- Tmp1 = ExpandLibCall(LC1, DAG.getMergeValues(Ops, 2).getNode(),
+ Tmp1 = ExpandLibCall(LC1, DAG.getMergeValues(Ops, 2, dl).getNode(),
false /*sign irrelevant*/, Dummy);
Tmp2 = DAG.getConstant(0, MVT::i32);
CC = DAG.getCondCode(TLI.getCmpLibcallCC(LC1));
if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
- Tmp1 = DAG.getNode(ISD::SETCC,
+ Tmp1 = DAG.getNode(ISD::SETCC, dl,
TLI.getSetCCResultType(Tmp1.getValueType()),
Tmp1, Tmp2, CC);
- LHS = ExpandLibCall(LC2, DAG.getMergeValues(Ops, 2).getNode(),
+ LHS = ExpandLibCall(LC2, DAG.getMergeValues(Ops, 2, dl).getNode(),
false /*sign irrelevant*/, Dummy);
- Tmp2 = DAG.getNode(ISD::SETCC,
+ Tmp2 = DAG.getNode(ISD::SETCC, dl,
TLI.getSetCCResultType(LHS.getValueType()), LHS,
Tmp2, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
- Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp2);
Tmp2 = SDValue();
}
LHS = LegalizeOp(Tmp1);
@@ -5205,17 +5248,17 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
// BNE crN, L:
// FCMPU crN, lo1, lo2
// The following can be improved, but not that much.
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, ISD::SETOEQ);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+ Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
LHSLo, RHSLo, CCCode);
- Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, ISD::SETUNE);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, CCCode);
- Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
- Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
+ Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3);
Tmp2 = SDValue();
break;
}
@@ -5227,14 +5270,14 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo))
if (RHSCST->isAllOnesValue()) {
// Comparison to -1.
- Tmp1 = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
+ Tmp1 = DAG.getNode(ISD::AND, dl,LHSLo.getValueType(), LHSLo, LHSHi);
Tmp2 = RHSLo;
break;
}
- Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
- Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
- Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
+ Tmp2 = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
+ Tmp1 = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp2);
Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
break;
default:
@@ -5272,14 +5315,14 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
// this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
- LHSLo, RHSLo, LowCC, false, DagCombineInfo);
+ LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl);
if (!Tmp1.getNode())
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+ Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
LHSLo, RHSLo, LowCC);
Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
- LHSHi, RHSHi, CCCode, false, DagCombineInfo);
+ LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl);
if (!Tmp2.getNode())
- Tmp2 = DAG.getNode(ISD::SETCC,
+ Tmp2 = DAG.getNode(ISD::SETCC, dl,
TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi,CC);
@@ -5300,11 +5343,11 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
} else {
Result = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, ISD::SETEQ, false,
- DagCombineInfo);
+ DagCombineInfo, dl);
if (!Result.getNode())
- Result=DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ Result=DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, ISD::SETEQ);
- Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
+ Result = LegalizeOp(DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(),
Result, Tmp1, Tmp2));
Tmp1 = Result;
Tmp2 = SDValue();
@@ -5322,7 +5365,8 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
/// illegal condition code into AND / OR of multiple SETCC values.
void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT,
SDValue &LHS, SDValue &RHS,
- SDValue &CC) {
+ SDValue &CC,
+ DebugLoc dl) {
MVT OpVT = LHS.getValueType();
ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
switch (TLI.getCondCodeAction(CCCode, OpVT)) {
@@ -5350,9 +5394,9 @@ void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT,
// FIXME: Implement more expansions.
}
- SDValue SetCC1 = DAG.getSetCC(VT, LHS, RHS, CC1);
- SDValue SetCC2 = DAG.getSetCC(VT, LHS, RHS, CC2);
- LHS = DAG.getNode(Opc, VT, SetCC1, SetCC2);
+ SDValue SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1);
+ SDValue SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2);
+ LHS = DAG.getNode(Opc, dl, VT, SetCC1, SetCC2);
RHS = SDValue();
CC = SDValue();
break;
@@ -5366,7 +5410,8 @@ void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT,
/// The resultant code need not be legal.
SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
MVT SlotVT,
- MVT DestVT) {
+ MVT DestVT,
+ DebugLoc dl) {
// Create the stack frame object.
unsigned SrcAlign = TLI.getTargetData()->getPrefTypeAlignment(
SrcOp.getValueType().getTypeForMVT());
@@ -5374,7 +5419,8 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr);
int SPFI = StackPtrFI->getIndex();
-
+ const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
+
unsigned SrcSize = SrcOp.getValueType().getSizeInBits();
unsigned SlotSize = SlotVT.getSizeInBits();
unsigned DestSize = DestVT.getSizeInBits();
@@ -5386,26 +5432,25 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
SDValue Store;
if (SrcSize > SlotSize)
- Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0,
- SlotVT, false, SrcAlign);
+ Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr,
+ SV, 0, SlotVT, false, SrcAlign);
else {
assert(SrcSize == SlotSize && "Invalid store");
- Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0,
- false, SrcAlign);
+ Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr,
+ SV, 0, false, SrcAlign);
}
// Result is a load from the stack slot.
if (SlotSize == DestSize)
- return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0, false, DestAlign);
+ return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, DestAlign);
assert(SlotSize < DestSize && "Unknown extension!");
- return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, NULL, 0, SlotVT,
+ return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, SV, 0, SlotVT,
false, DestAlign);
}
SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
+ DebugLoc dl = Node->getDebugLoc();
// Create a vector sized/aligned stack slot, store the value to element #0,
// then load the whole vector back out.
SDValue StackPtr = DAG.CreateStackTemporary(Node->getValueType(0));
@@ -5413,9 +5458,10 @@ SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr);
int SPFI = StackPtrFI->getIndex();
- SDValue Ch = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0), StackPtr,
+ SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Node->getOperand(0),
+ StackPtr,
PseudoSourceValue::getFixedStack(SPFI), 0);
- return DAG.getLoad(Node->getValueType(0), Ch, StackPtr,
+ return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr,
PseudoSourceValue::getFixedStack(SPFI), 0);
}
@@ -5429,6 +5475,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
unsigned NumElems = Node->getNumOperands();
bool isOnlyLowElement = true;
SDValue SplatValue = Node->getOperand(0);
+ DebugLoc dl = Node->getDebugLoc();
// FIXME: it would be far nicer to change this into map<SDValue,uint64_t>
// and use a bitmask instead of a list of elements.
@@ -5457,9 +5504,9 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
if (isOnlyLowElement) {
// If the low element is an undef too, then this whole things is an undef.
if (Node->getOperand(0).getOpcode() == ISD::UNDEF)
- return DAG.getNode(ISD::UNDEF, Node->getValueType(0));
+ return DAG.getNode(ISD::UNDEF, dl, Node->getValueType(0));
// Otherwise, turn this into a scalar_to_vector node.
- return DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0),
+ return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, Node->getValueType(0),
Node->getOperand(0));
}
@@ -5484,7 +5531,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
Constant *CP = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
- return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+ return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
false, Alignment);
}
@@ -5494,17 +5541,19 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
SDValue Zero = DAG.getConstant(0, MaskVT.getVectorElementType());
std::vector<SDValue> ZeroVec(NumElems, Zero);
- SDValue SplatMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
+ SDValue SplatMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT,
&ZeroVec[0], ZeroVec.size());
// If the target supports VECTOR_SHUFFLE and this shuffle mask, use it.
if (isShuffleLegal(Node->getValueType(0), SplatMask)) {
// Get the splatted value into the low element of a vector register.
SDValue LowValVec =
- DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), SplatValue);
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,
+ Node->getValueType(0), SplatValue);
// Return shuffle(LowValVec, undef, <0,0,0,0>)
- return DAG.getNode(ISD::VECTOR_SHUFFLE, Node->getValueType(0), LowValVec,
+ return DAG.getNode(ISD::VECTOR_SHUFFLE, dl,
+ Node->getValueType(0), LowValVec,
DAG.getNode(ISD::UNDEF, Node->getValueType(0)),
SplatMask);
}
@@ -5543,20 +5592,21 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
if (Val2.getOpcode() != ISD::UNDEF)
MaskVec[Val2Elts[i]] = DAG.getConstant(NumElems, MaskEltVT);
else
- MaskVec[Val2Elts[i]] = DAG.getNode(ISD::UNDEF, MaskEltVT);
+ MaskVec[Val2Elts[i]] = DAG.getNode(ISD::UNDEF, dl, MaskEltVT);
- SDValue ShuffleMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
+ SDValue ShuffleMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT,
&MaskVec[0], MaskVec.size());
// If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it.
- if (TLI.isOperationLegal(ISD::SCALAR_TO_VECTOR, Node->getValueType(0)) &&
+ if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR,
+ Node->getValueType(0)) &&
isShuffleLegal(Node->getValueType(0), ShuffleMask)) {
- Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val1);
- Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val2);
+ Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,Node->getValueType(0), Val1);
+ Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,Node->getValueType(0), Val2);
SDValue Ops[] = { Val1, Val2, ShuffleMask };
// Return shuffle(LoValVec, HiValVec, <0,1,0,1>)
- return DAG.getNode(ISD::VECTOR_SHUFFLE, Node->getValueType(0), Ops, 3);
+ return DAG.getNode(ISD::VECTOR_SHUFFLE, dl,Node->getValueType(0), Ops, 3);
}
}
@@ -5566,7 +5616,9 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
MVT VT = Node->getValueType(0);
// Create the stack frame object.
SDValue FIPtr = DAG.CreateStackTemporary(VT);
-
+ int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
+ const Value *SV = PseudoSourceValue::getFixedStack(FI);
+
// Emit a store of each element to the stack slot.
SmallVector<SDValue, 8> Stores;
unsigned TypeByteSize = Node->getOperand(0).getValueType().getSizeInBits()/8;
@@ -5578,33 +5630,34 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
unsigned Offset = TypeByteSize*i;
SDValue Idx = DAG.getConstant(Offset, FIPtr.getValueType());
- Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
+ Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx);
- Stores.push_back(DAG.getStore(DAG.getEntryNode(), Node->getOperand(i), Idx,
- NULL, 0));
+ Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, Node->getOperand(i),
+ Idx, SV, Offset));
}
SDValue StoreChain;
if (!Stores.empty()) // Not all undef elements?
- StoreChain = DAG.getNode(ISD::TokenFactor, MVT::Other,
+ StoreChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&Stores[0], Stores.size());
else
StoreChain = DAG.getEntryNode();
// Result is a load from the stack slot.
- return DAG.getLoad(VT, StoreChain, FIPtr, NULL, 0);
+ return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0);
}
void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
SDValue Op, SDValue Amt,
- SDValue &Lo, SDValue &Hi) {
+ SDValue &Lo, SDValue &Hi,
+ DebugLoc dl) {
// Expand the subcomponents.
SDValue LHSL, LHSH;
ExpandOp(Op, LHSL, LHSH);
SDValue Ops[] = { LHSL, LHSH, Amt };
MVT VT = LHSL.getValueType();
- Lo = DAG.getNode(NodeOp, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
+ Lo = DAG.getNode(NodeOp, dl, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
Hi = Lo.getValue(1);
}
@@ -5614,7 +5667,8 @@ void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
/// libcall on this target, return false. Otherwise, return true with the
/// low-parts expanded into Lo and Hi.
bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt,
- SDValue &Lo, SDValue &Hi) {
+ SDValue &Lo, SDValue &Hi,
+ DebugLoc dl) {
assert((Opc == ISD::SHL || Opc == ISD::SRA || Opc == ISD::SRL) &&
"This is not a shift!");
@@ -5638,15 +5692,17 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt,
Hi = DAG.getConstant(0, NVT);
} else if (Cst > NVTBits) {
Lo = DAG.getConstant(0, NVT);
- Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst-NVTBits,ShTy));
+ Hi = DAG.getNode(ISD::SHL, dl,
+ NVT, InL, DAG.getConstant(Cst-NVTBits,ShTy));
} else if (Cst == NVTBits) {
Lo = DAG.getConstant(0, NVT);
Hi = InL;
} else {
- Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst, ShTy));
- Hi = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(Cst, ShTy)),
- DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(NVTBits-Cst, ShTy)));
+ Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Cst, ShTy));
+ Hi = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SHL, dl, NVT, InH, DAG.getConstant(Cst, ShTy)),
+ DAG.getNode(ISD::SRL, dl, NVT, InL,
+ DAG.getConstant(NVTBits-Cst, ShTy)));
}
return true;
case ISD::SRL:
@@ -5654,36 +5710,39 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt,
Lo = DAG.getConstant(0, NVT);
Hi = DAG.getConstant(0, NVT);
} else if (Cst > NVTBits) {
- Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst-NVTBits,ShTy));
+ Lo = DAG.getNode(ISD::SRL, dl, NVT,
+ InH, DAG.getConstant(Cst-NVTBits,ShTy));
Hi = DAG.getConstant(0, NVT);
} else if (Cst == NVTBits) {
Lo = InH;
Hi = DAG.getConstant(0, NVT);
} else {
- Lo = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)),
- DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy)));
- Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst, ShTy));
+ Lo = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SRL, dl, NVT, InL, DAG.getConstant(Cst, ShTy)),
+ DAG.getNode(ISD::SHL, dl, NVT, InH,
+ DAG.getConstant(NVTBits-Cst, ShTy)));
+ Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, DAG.getConstant(Cst, ShTy));
}
return true;
case ISD::SRA:
if (Cst > VTBits) {
- Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH,
+ Hi = Lo = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(NVTBits-1, ShTy));
} else if (Cst > NVTBits) {
- Lo = DAG.getNode(ISD::SRA, NVT, InH,
+ Lo = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(Cst-NVTBits, ShTy));
- Hi = DAG.getNode(ISD::SRA, NVT, InH,
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(NVTBits-1, ShTy));
} else if (Cst == NVTBits) {
Lo = InH;
- Hi = DAG.getNode(ISD::SRA, NVT, InH,
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(NVTBits-1, ShTy));
} else {
- Lo = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)),
- DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy)));
- Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Cst, ShTy));
+ Lo = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SRL, dl, NVT, InL, DAG.getConstant(Cst, ShTy)),
+ DAG.getNode(ISD::SHL, dl,
+ NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy)));
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Cst, ShTy));
}
return true;
}
@@ -5699,7 +5758,7 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt,
// we can do this as a couple of simple shifts.
if (KnownOne.intersects(Mask)) {
// Mask out the high bit, which we know is set.
- Amt = DAG.getNode(ISD::AND, Amt.getValueType(), Amt,
+ Amt = DAG.getNode(ISD::AND, dl, Amt.getValueType(), Amt,
DAG.getConstant(~Mask, Amt.getValueType()));
// Expand the incoming operand to be shifted, so that we have its parts
@@ -5708,16 +5767,16 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt,
switch(Opc) {
case ISD::SHL:
Lo = DAG.getConstant(0, NVT); // Low part is zero.
- Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part.
+ Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
return true;
case ISD::SRL:
Hi = DAG.getConstant(0, NVT); // Hi part is zero.
- Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part.
+ Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
return true;
case ISD::SRA:
- Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part.
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part.
DAG.getConstant(NVTBits-1, Amt.getValueType()));
- Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part.
+ Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
return true;
}
}
@@ -5726,7 +5785,7 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt,
// do this as a couple of simple shifts.
if ((KnownZero & Mask) == Mask) {
// Compute 32-amt.
- SDValue Amt2 = DAG.getNode(ISD::SUB, Amt.getValueType(),
+ SDValue Amt2 = DAG.getNode(ISD::SUB, dl, Amt.getValueType(),
DAG.getConstant(NVTBits, Amt.getValueType()),
Amt);
@@ -5735,22 +5794,22 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt,
ExpandOp(Op, InL, InH);
switch(Opc) {
case ISD::SHL:
- Lo = DAG.getNode(ISD::SHL, NVT, InL, Amt);
- Hi = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SHL, NVT, InH, Amt),
- DAG.getNode(ISD::SRL, NVT, InL, Amt2));
+ Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
+ Hi = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
+ DAG.getNode(ISD::SRL, dl, NVT, InL, Amt2));
return true;
case ISD::SRL:
- Hi = DAG.getNode(ISD::SRL, NVT, InH, Amt);
- Lo = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SRL, NVT, InL, Amt),
- DAG.getNode(ISD::SHL, NVT, InH, Amt2));
+ Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
+ Lo = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
+ DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2));
return true;
case ISD::SRA:
- Hi = DAG.getNode(ISD::SRA, NVT, InH, Amt);
- Lo = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SRL, NVT, InL, Amt),
- DAG.getNode(ISD::SHL, NVT, InH, Amt2));
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
+ Lo = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
+ DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2));
return true;
}
}
@@ -5788,7 +5847,8 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
const Type *RetTy = Node->getValueType(0).getTypeForMVT();
std::pair<SDValue,SDValue> CallInfo =
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
- CallingConv::C, false, Callee, Args, DAG);
+ CallingConv::C, false, 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
@@ -5810,7 +5870,8 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
/// LegalizeINT_TO_FP - Legalize a [US]INT_TO_FP operation.
///
SDValue SelectionDAGLegalize::
-LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) {
+LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op,
+ DebugLoc dl) {
bool isCustom = false;
SDValue Tmp1;
switch (getTypeAction(Op.getValueType())) {
@@ -5826,7 +5887,7 @@ LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) {
if (Result.getNode())
Result = DAG.UpdateNodeOperands(Result, Tmp1);
else
- Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP,
+ Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, dl,
DestTy, Tmp1);
if (isCustom) {
Tmp1 = TLI.LowerOperation(Result, DAG);
@@ -5834,29 +5895,29 @@ LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) {
}
break;
case TargetLowering::Expand:
- Result = ExpandLegalINT_TO_FP(isSigned, LegalizeOp(Op), DestTy);
+ Result = ExpandLegalINT_TO_FP(isSigned, LegalizeOp(Op), DestTy, dl);
break;
case TargetLowering::Promote:
- Result = PromoteLegalINT_TO_FP(LegalizeOp(Op), DestTy, isSigned);
+ Result = PromoteLegalINT_TO_FP(LegalizeOp(Op), DestTy, isSigned, dl);
break;
}
break;
case Expand:
- Result = ExpandIntToFP(isSigned, DestTy, Op);
+ Result = ExpandIntToFP(isSigned, DestTy, Op, dl) ;
break;
case Promote:
Tmp1 = PromoteOp(Op);
if (isSigned) {
- Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, Tmp1.getValueType(),
+ Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Tmp1.getValueType(),
Tmp1, DAG.getValueType(Op.getValueType()));
} else {
- Tmp1 = DAG.getZeroExtendInReg(Tmp1,
+ Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl,
Op.getValueType());
}
if (Result.getNode())
Result = DAG.UpdateNodeOperands(Result, Tmp1);
else
- Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP,
+ Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, dl,
DestTy, Tmp1);
Result = LegalizeOp(Result); // The 'op' is not necessarily legal!
break;
@@ -5867,7 +5928,7 @@ LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) {
/// ExpandIntToFP - Expand a [US]INT_TO_FP operation.
///
SDValue SelectionDAGLegalize::
-ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
+ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl) {
MVT SourceVT = Source.getValueType();
bool ExpandSource = getTypeAction(SourceVT) == Expand;
@@ -5879,16 +5940,18 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
if (DestTy.getVectorNumElements() == 1) {
SDValue Scalar = ScalarizeVectorOp(Source);
SDValue Result = LegalizeINT_TO_FP(SDValue(), isSigned,
- DestEltTy, Scalar);
- return DAG.getNode(ISD::BUILD_VECTOR, DestTy, Result);
+ DestEltTy, Scalar, dl);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, DestTy, Result);
}
SDValue Lo, Hi;
SplitVectorOp(Source, Lo, Hi);
MVT SplitDestTy = MVT::getVectorVT(DestEltTy,
DestTy.getVectorNumElements() / 2);
- SDValue LoResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy, Lo);
- SDValue HiResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy, Hi);
- return LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, DestTy, LoResult,
+ SDValue LoResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy,
+ Lo, dl);
+ SDValue HiResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy,
+ Hi, dl);
+ return LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, dl, DestTy, LoResult,
HiResult));
}
@@ -5901,7 +5964,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
if (ExpandSource) {
SDValue Lo;
ExpandOp(Source, Lo, Hi);
- Source = DAG.getNode(ISD::BUILD_PAIR, SourceVT, Lo, Hi);
+ Source = DAG.getNode(ISD::BUILD_PAIR, dl, SourceVT, Lo, Hi);
} else {
// The comparison for the sign bit will use the entire operand.
Hi = Source;
@@ -5925,13 +5988,14 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
// If this is unsigned, and not supported, first perform the conversion to
// signed, then adjust the result if the sign bit is set.
- SDValue SignedConv = ExpandIntToFP(true, DestTy, Source);
+ SDValue SignedConv = ExpandIntToFP(true, DestTy, Source, dl);
- SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi.getValueType()),
+ SDValue SignSet = DAG.getSetCC(dl,
+ TLI.getSetCCResultType(Hi.getValueType()),
Hi, DAG.getConstant(0, Hi.getValueType()),
ISD::SETLT);
SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
- SDValue CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
+ SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(),
SignSet, Four, Zero);
uint64_t FF = 0x5f800000ULL;
if (TLI.isLittleEndian()) FF <<= 32;
@@ -5939,16 +6003,16 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
- CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
+ CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset);
Alignment = std::min(Alignment, 4u);
SDValue FudgeInReg;
if (DestTy == MVT::f32)
- FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
+ FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
false, Alignment);
else if (DestTy.bitsGT(MVT::f32))
// FIXME: Avoid the extend by construction the right constantpool?
- FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(),
+ FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, dl, DestTy, DAG.getEntryNode(),
CPIdx,
PseudoSourceValue::getConstantPool(), 0,
MVT::f32, false, Alignment);
@@ -5961,12 +6025,12 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
// constructing will be expanded into a libcall.
if (SCVT.getSizeInBits() != DestTy.getSizeInBits()) {
assert(SCVT.getSizeInBits() * 2 == DestTy.getSizeInBits());
- SignedConv = DAG.getNode(ISD::BUILD_PAIR, DestTy,
+ SignedConv = DAG.getNode(ISD::BUILD_PAIR, dl, DestTy,
SignedConv, SignedConv.getValue(1));
}
- SignedConv = DAG.getNode(ISD::BIT_CONVERT, DestTy, SignedConv);
+ SignedConv = DAG.getNode(ISD::BIT_CONVERT, dl, DestTy, SignedConv);
}
- return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
+ return DAG.getNode(ISD::FADD, dl, DestTy, SignedConv, FudgeInReg);
}
// Check to see if the target has a custom way to lower this. If so, use it.
@@ -5976,7 +6040,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
case TargetLowering::Expand:
break; // This case is handled below.
case TargetLowering::Custom: {
- SDValue NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy,
+ SDValue NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, dl, DestTy,
Source), DAG);
if (NV.getNode())
return LegalizeOp(NV);
@@ -5989,7 +6053,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
if (ExpandSource) {
SDValue SrcLo, SrcHi;
ExpandOp(Source, SrcLo, SrcHi);
- Source = DAG.getNode(ISD::BUILD_PAIR, SourceVT, SrcLo, SrcHi);
+ Source = DAG.getNode(ISD::BUILD_PAIR, dl, SourceVT, SrcLo, SrcHi);
}
RTLIB::Libcall LC = isSigned ?
@@ -5997,11 +6061,11 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
RTLIB::getUINTTOFP(SourceVT, DestTy);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unknown int value type");
- Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source);
+ Source = DAG.getNode(ISD::SINT_TO_FP, dl, DestTy, Source);
SDValue HiPart;
SDValue Result = ExpandLibCall(LC, Source.getNode(), isSigned, HiPart);
if (Result.getValueType() != DestTy && HiPart.getNode())
- Result = DAG.getNode(ISD::BUILD_PAIR, DestTy, Result, HiPart);
+ Result = DAG.getNode(ISD::BUILD_PAIR, dl, DestTy, Result, HiPart);
return Result;
}
@@ -6011,7 +6075,8 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
/// legal for the target.
SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
SDValue Op0,
- MVT DestVT) {
+ MVT DestVT,
+ DebugLoc dl) {
if (Op0.getValueType() == MVT::i32) {
// simple 32-bit [signed|unsigned] integer to float/double expansion
@@ -6022,7 +6087,8 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
SDValue WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy());
// set up Hi and Lo (into buffer) address based on endian
SDValue Hi = StackSlot;
- SDValue Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot,WordOff);
+ SDValue Lo = DAG.getNode(ISD::ADD, dl,
+ TLI.getPointerTy(), StackSlot,WordOff);
if (TLI.isLittleEndian())
std::swap(Hi, Lo);
@@ -6031,26 +6097,26 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
if (isSigned) {
// constant used to invert sign bit (signed to unsigned mapping)
SDValue SignBit = DAG.getConstant(0x80000000u, MVT::i32);
- Op0Mapped = DAG.getNode(ISD::XOR, MVT::i32, Op0, SignBit);
+ Op0Mapped = DAG.getNode(ISD::XOR, dl, MVT::i32, Op0, SignBit);
} else {
Op0Mapped = Op0;
}
// store the lo of the constructed double - based on integer input
- SDValue Store1 = DAG.getStore(DAG.getEntryNode(),
+ SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl,
Op0Mapped, Lo, NULL, 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, InitialHi, Hi, NULL, 0);
+ SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0);
// load the constructed double
- SDValue Load = DAG.getLoad(MVT::f64, Store2, StackSlot, NULL, 0);
+ SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0);
// FP constant to bias correct the final result
SDValue Bias = DAG.getConstantFP(isSigned ?
BitsToDouble(0x4330000080000000ULL)
: BitsToDouble(0x4330000000000000ULL),
MVT::f64);
// subtract the bias
- SDValue Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias);
+ SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::f64, Load, Bias);
// final result
SDValue Result;
// handle final rounding
@@ -6058,21 +6124,21 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
// do nothing
Result = Sub;
} else if (DestVT.bitsLT(MVT::f64)) {
- Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub,
+ Result = DAG.getNode(ISD::FP_ROUND, dl, DestVT, Sub,
DAG.getIntPtrConstant(0));
} else if (DestVT.bitsGT(MVT::f64)) {
- Result = DAG.getNode(ISD::FP_EXTEND, DestVT, Sub);
+ Result = DAG.getNode(ISD::FP_EXTEND, dl, DestVT, Sub);
}
return Result;
}
assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
- SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
+ SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, dl, DestVT, Op0);
- SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Op0.getValueType()),
+ SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Op0.getValueType()),
Op0, DAG.getConstant(0, Op0.getValueType()),
ISD::SETLT);
SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
- SDValue CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
+ SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(),
SignSet, Four, Zero);
// If the sign bit of the integer is set, the large number will be treated
@@ -6091,22 +6157,22 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
- CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
+ CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset);
Alignment = std::min(Alignment, 4u);
SDValue FudgeInReg;
if (DestVT == MVT::f32)
- FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
+ FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
false, Alignment);
else {
FudgeInReg =
- LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, DestVT,
+ LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT,
DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
MVT::f32, false, Alignment));
}
- return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg);
+ return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg);
}
/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a
@@ -6116,7 +6182,8 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
/// operation that takes a larger input.
SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp,
MVT DestVT,
- bool isSigned) {
+ bool isSigned,
+ DebugLoc dl) {
// First step, figure out the appropriate *INT_TO_FP operation to use.
MVT NewInTy = LegalOp.getValueType();
@@ -6159,9 +6226,9 @@ SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp,
// Okay, we found the operation and type to use. Zero extend our input to the
// desired type then run the operation on it.
- return DAG.getNode(OpToUse, DestVT,
+ return DAG.getNode(OpToUse, dl, DestVT,
DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
- NewInTy, LegalOp));
+ dl, NewInTy, LegalOp));
}
/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a
@@ -6171,7 +6238,8 @@ SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp,
/// operation that returns a larger result.
SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp,
MVT DestVT,
- bool isSigned) {
+ bool isSigned,
+ DebugLoc dl) {
// First step, figure out the appropriate FP_TO*INT operation to use.
MVT NewOutTy = DestVT;
@@ -6213,7 +6281,7 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp,
// Okay, we found the operation and type to use.
- SDValue Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp);
+ SDValue Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp);
// If the operation produces an invalid type, it must be custom lowered. Use
// the target lowering hooks to expand it. Just keep the low part of the
@@ -6227,59 +6295,60 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp,
// Truncate the result of the extended FP_TO_*INT operation to the desired
// size.
- return DAG.getNode(ISD::TRUNCATE, DestVT, Operation);
+ return DAG.getNode(ISD::TRUNCATE, dl, DestVT, Operation);
}
/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation.
///
-SDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op) {
+SDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) {
MVT VT = Op.getValueType();
MVT SHVT = TLI.getShiftAmountTy();
SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8;
switch (VT.getSimpleVT()) {
default: assert(0 && "Unhandled Expand type in BSWAP!"); abort();
case MVT::i16:
- Tmp2 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
- return DAG.getNode(ISD::OR, VT, Tmp1, Tmp2);
+ Tmp2 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT));
+ return DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
case MVT::i32:
- Tmp4 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp3 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(0xFF0000, VT));
- Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(0xFF00, VT));
- Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
- Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
- return DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
+ Tmp4 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp3 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(0xFF0000, VT));
+ Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, VT));
+ Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3);
+ Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1);
+ return DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2);
case MVT::i64:
- Tmp8 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(56, SHVT));
- Tmp7 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(40, SHVT));
- Tmp6 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp5 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp4 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp3 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(40, SHVT));
- Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(56, SHVT));
- Tmp7 = DAG.getNode(ISD::AND, VT, Tmp7, DAG.getConstant(255ULL<<48, VT));
- Tmp6 = DAG.getNode(ISD::AND, VT, Tmp6, DAG.getConstant(255ULL<<40, VT));
- Tmp5 = DAG.getNode(ISD::AND, VT, Tmp5, DAG.getConstant(255ULL<<32, VT));
- Tmp4 = DAG.getNode(ISD::AND, VT, Tmp4, DAG.getConstant(255ULL<<24, VT));
- Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(255ULL<<16, VT));
- Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT));
- Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp7);
- Tmp6 = DAG.getNode(ISD::OR, VT, Tmp6, Tmp5);
- Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
- Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
- Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp6);
- Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
- return DAG.getNode(ISD::OR, VT, Tmp8, Tmp4);
+ Tmp8 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(56, SHVT));
+ Tmp7 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(40, SHVT));
+ Tmp6 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp5 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp4 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp3 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(40, SHVT));
+ Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(56, SHVT));
+ Tmp7 = DAG.getNode(ISD::AND, dl, VT, Tmp7, DAG.getConstant(255ULL<<48, VT));
+ Tmp6 = DAG.getNode(ISD::AND, dl, VT, Tmp6, DAG.getConstant(255ULL<<40, VT));
+ Tmp5 = DAG.getNode(ISD::AND, dl, VT, Tmp5, DAG.getConstant(255ULL<<32, VT));
+ Tmp4 = DAG.getNode(ISD::AND, dl, VT, Tmp4, DAG.getConstant(255ULL<<24, VT));
+ Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(255ULL<<16, VT));
+ Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT));
+ Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp7);
+ Tmp6 = DAG.getNode(ISD::OR, dl, VT, Tmp6, Tmp5);
+ Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3);
+ Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1);
+ Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp6);
+ Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2);
+ return DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp4);
}
}
/// ExpandBitCount - Expand the specified bitcount instruction into operations.
///
-SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) {
+SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op,
+ DebugLoc dl) {
switch (Opc) {
default: assert(0 && "Cannot expand this yet!");
case ISD::CTPOP: {
@@ -6293,11 +6362,14 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) {
unsigned len = VT.getSizeInBits();
for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
//x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
- SDValue Tmp2 = DAG.getConstant(mask[i], VT);
+ unsigned EltSize = VT.isVector() ?
+ VT.getVectorElementType().getSizeInBits() : len;
+ SDValue Tmp2 = DAG.getConstant(APInt(EltSize, mask[i]), VT);
SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT);
- Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2),
- DAG.getNode(ISD::AND, VT,
- DAG.getNode(ISD::SRL, VT, Op, Tmp3),Tmp2));
+ Op = DAG.getNode(ISD::ADD, dl, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2),
+ DAG.getNode(ISD::AND, dl, VT,
+ DAG.getNode(ISD::SRL, dl, VT, Op, Tmp3),
+ Tmp2));
}
return Op;
}
@@ -6316,10 +6388,11 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) {
unsigned len = VT.getSizeInBits();
for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT);
- Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3));
+ Op = DAG.getNode(ISD::OR, dl, VT, Op,
+ DAG.getNode(ISD::SRL, VT, Op, Tmp3));
}
- Op = DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(~0ULL, VT));
- return DAG.getNode(ISD::CTPOP, VT, Op);
+ Op = DAG.getNOT(dl, Op, VT);
+ return DAG.getNode(ISD::CTPOP, dl, VT, Op);
}
case ISD::CTTZ: {
// for now, we use: { return popcount(~x & (x - 1)); }
@@ -6327,17 +6400,17 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) {
// { return 32 - nlz(~x & (x-1)); }
// see also http://www.hackersdelight.org/HDcode/ntz.cc
MVT VT = Op.getValueType();
- SDValue Tmp2 = DAG.getConstant(~0ULL, VT);
- SDValue Tmp3 = DAG.getNode(ISD::AND, VT,
- DAG.getNode(ISD::XOR, VT, Op, Tmp2),
- DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT)));
+ SDValue Tmp3 = DAG.getNode(ISD::AND, dl, VT,
+ DAG.getNOT(dl, Op, VT),
+ DAG.getNode(ISD::SUB, dl, VT, Op,
+ DAG.getConstant(1, VT)));
// If ISD::CTLZ is legal and CTPOP isn't, then do that instead.
- if (!TLI.isOperationLegal(ISD::CTPOP, VT) &&
- TLI.isOperationLegal(ISD::CTLZ, VT))
- return DAG.getNode(ISD::SUB, VT,
+ if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) &&
+ TLI.isOperationLegalOrCustom(ISD::CTLZ, VT))
+ return DAG.getNode(ISD::SUB, dl, VT,
DAG.getConstant(VT.getSizeInBits(), VT),
- DAG.getNode(ISD::CTLZ, VT, Tmp3));
- return DAG.getNode(ISD::CTPOP, VT, Tmp3);
+ DAG.getNode(ISD::CTLZ, dl, VT, Tmp3));
+ return DAG.getNode(ISD::CTPOP, dl, VT, Tmp3);
}
}
}
@@ -6351,6 +6424,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
MVT VT = Op.getValueType();
MVT NVT = TLI.getTypeToTransformTo(VT);
SDNode *Node = Op.getNode();
+ DebugLoc dl = Node->getDebugLoc();
assert(getTypeAction(VT) == Expand && "Not an expanded type!");
assert(((NVT.isInteger() && NVT.bitsLT(VT)) || VT.isFloatingPoint() ||
VT.isVector()) && "Cannot expand to FP value or to larger int value!");
@@ -6373,9 +6447,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
TargetLowering::Custom) {
SDValue SrcLo, SrcHi, Src;
ExpandOp(Op.getOperand(0), SrcLo, SrcHi);
- Src = DAG.getNode(ISD::BUILD_PAIR, VT, SrcLo, SrcHi);
+ Src = DAG.getNode(ISD::BUILD_PAIR, dl, VT, SrcLo, SrcHi);
SDValue Result = TLI.LowerOperation(
- DAG.getNode(ISD::FP_ROUND_INREG, VT, Src, Op.getOperand(1)), DAG);
+ DAG.getNode(ISD::FP_ROUND_INREG, dl, VT, Src, Op.getOperand(1)), DAG);
assert(Result.getNode()->getOpcode() == ISD::BUILD_PAIR);
Lo = Result.getNode()->getOperand(0);
Hi = Result.getNode()->getOperand(1);
@@ -6398,8 +6472,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
Lo = ExpandEXTRACT_VECTOR_ELT(Op);
return ExpandOp(Lo, Lo, Hi);
case ISD::UNDEF:
- Lo = DAG.getNode(ISD::UNDEF, NVT);
- Hi = DAG.getNode(ISD::UNDEF, NVT);
+ Lo = DAG.getNode(ISD::UNDEF, dl, NVT);
+ Hi = DAG.getNode(ISD::UNDEF, dl, NVT);
break;
case ISD::Constant: {
unsigned NVTBits = NVT.getSizeInBits();
@@ -6446,28 +6520,28 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
case ISD::SIGN_EXTEND_INREG:
ExpandOp(Node->getOperand(0), Lo, Hi);
// sext_inreg the low part if needed.
- Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Lo, Node->getOperand(1));
+ Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Lo, Node->getOperand(1));
// The high part gets the sign extension from the lo-part. This handles
// things like sextinreg V:i64 from i8.
- Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
DAG.getConstant(NVT.getSizeInBits()-1,
TLI.getShiftAmountTy()));
break;
case ISD::BSWAP: {
ExpandOp(Node->getOperand(0), Lo, Hi);
- SDValue TempLo = DAG.getNode(ISD::BSWAP, NVT, Hi);
- Hi = DAG.getNode(ISD::BSWAP, NVT, Lo);
+ SDValue TempLo = DAG.getNode(ISD::BSWAP, dl, NVT, Hi);
+ Hi = DAG.getNode(ISD::BSWAP, dl, NVT, Lo);
Lo = TempLo;
break;
}
case ISD::CTPOP:
ExpandOp(Node->getOperand(0), Lo, Hi);
- Lo = DAG.getNode(ISD::ADD, NVT, // ctpop(HL) -> ctpop(H)+ctpop(L)
- DAG.getNode(ISD::CTPOP, NVT, Lo),
- DAG.getNode(ISD::CTPOP, NVT, Hi));
+ Lo = DAG.getNode(ISD::ADD, dl, NVT, // ctpop(HL) -> ctpop(H)+ctpop(L)
+ DAG.getNode(ISD::CTPOP, dl, NVT, Lo),
+ DAG.getNode(ISD::CTPOP, dl, NVT, Hi));
Hi = DAG.getConstant(0, NVT);
break;
@@ -6475,13 +6549,13 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// ctlz (HL) -> ctlz(H) != 32 ? ctlz(H) : (ctlz(L)+32)
ExpandOp(Node->getOperand(0), Lo, Hi);
SDValue BitsC = DAG.getConstant(NVT.getSizeInBits(), NVT);
- SDValue HLZ = DAG.getNode(ISD::CTLZ, NVT, Hi);
- SDValue TopNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), HLZ, BitsC,
- ISD::SETNE);
- SDValue LowPart = DAG.getNode(ISD::CTLZ, NVT, Lo);
- LowPart = DAG.getNode(ISD::ADD, NVT, LowPart, BitsC);
+ SDValue HLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi);
+ SDValue TopNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), HLZ,
+ BitsC, ISD::SETNE);
+ SDValue LowPart = DAG.getNode(ISD::CTLZ, dl, NVT, Lo);
+ LowPart = DAG.getNode(ISD::ADD, dl, NVT, LowPart, BitsC);
- Lo = DAG.getNode(ISD::SELECT, NVT, TopNotZero, HLZ, LowPart);
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, TopNotZero, HLZ, LowPart);
Hi = DAG.getConstant(0, NVT);
break;
}
@@ -6490,13 +6564,13 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// cttz (HL) -> cttz(L) != 32 ? cttz(L) : (cttz(H)+32)
ExpandOp(Node->getOperand(0), Lo, Hi);
SDValue BitsC = DAG.getConstant(NVT.getSizeInBits(), NVT);
- SDValue LTZ = DAG.getNode(ISD::CTTZ, NVT, Lo);
- SDValue BotNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), LTZ, BitsC,
- ISD::SETNE);
- SDValue HiPart = DAG.getNode(ISD::CTTZ, NVT, Hi);
- HiPart = DAG.getNode(ISD::ADD, NVT, HiPart, BitsC);
+ SDValue LTZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo);
+ SDValue BotNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), LTZ,
+ BitsC, ISD::SETNE);
+ SDValue HiPart = DAG.getNode(ISD::CTTZ, dl, NVT, Hi);
+ HiPart = DAG.getNode(ISD::ADD, dl, NVT, HiPart, BitsC);
- Lo = DAG.getNode(ISD::SELECT, NVT, BotNotZero, LTZ, HiPart);
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, BotNotZero, LTZ, HiPart);
Hi = DAG.getConstant(0, NVT);
break;
}
@@ -6526,7 +6600,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
bool isVolatile = LD->isVolatile();
if (ExtType == ISD::NON_EXTLOAD) {
- Lo = DAG.getLoad(NVT, Ch, Ptr, SV, SVOffset,
+ Lo = DAG.getLoad(NVT, dl, Ch, Ptr, SV, SVOffset,
isVolatile, Alignment);
if (VT == MVT::f32 || VT == MVT::f64) {
// f32->i32 or f64->i64 one to one expansion.
@@ -6540,16 +6614,16 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// Increment the pointer to the other half.
unsigned IncrementSize = Lo.getValueType().getSizeInBits()/8;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
- Hi = DAG.getLoad(NVT, Ch, Ptr, SV, SVOffset,
+ Hi = DAG.getLoad(NVT, dl, Ch, Ptr, SV, SVOffset,
isVolatile, Alignment);
// Build a factor node to remember that this load is independent of the
// other one.
- SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
// Remember that we legalized the chain.
@@ -6562,19 +6636,19 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
if ((VT == MVT::f64 && EVT == MVT::f32) ||
(VT == MVT::ppcf128 && (EVT==MVT::f64 || EVT==MVT::f32))) {
// f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
- SDValue Load = DAG.getLoad(EVT, Ch, Ptr, SV,
+ SDValue Load = DAG.getLoad(EVT, dl, Ch, Ptr, SV,
SVOffset, isVolatile, Alignment);
// Remember that we legalized the chain.
AddLegalizedOperand(SDValue(Node, 1), LegalizeOp(Load.getValue(1)));
- ExpandOp(DAG.getNode(ISD::FP_EXTEND, VT, Load), Lo, Hi);
+ ExpandOp(DAG.getNode(ISD::FP_EXTEND, dl, VT, Load), Lo, Hi);
break;
}
if (EVT == NVT)
- Lo = DAG.getLoad(NVT, Ch, Ptr, SV,
+ Lo = DAG.getLoad(NVT, dl, Ch, Ptr, SV,
SVOffset, isVolatile, Alignment);
else
- Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, SV,
+ Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, SV,
SVOffset, EVT, isVolatile,
Alignment);
@@ -6585,14 +6659,14 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// The high part is obtained by SRA'ing all but one of the bits of the
// lo part.
unsigned LoSize = Lo.getValueType().getSizeInBits();
- Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
} else if (ExtType == ISD::ZEXTLOAD) {
// The high part is just a zero.
Hi = DAG.getConstant(0, NVT);
} else /* if (ExtType == ISD::EXTLOAD) */ {
// The high part is undefined.
- Hi = DAG.getNode(ISD::UNDEF, NVT);
+ Hi = DAG.getNode(ISD::UNDEF, dl, NVT);
}
}
break;
@@ -6603,8 +6677,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
SDValue LL, LH, RL, RH;
ExpandOp(Node->getOperand(0), LL, LH);
ExpandOp(Node->getOperand(1), RL, RH);
- Lo = DAG.getNode(Node->getOpcode(), NVT, LL, RL);
- Hi = DAG.getNode(Node->getOpcode(), NVT, LH, RH);
+ Lo = DAG.getNode(Node->getOpcode(), dl, NVT, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), dl, NVT, LH, RH);
break;
}
case ISD::SELECT: {
@@ -6613,9 +6687,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
ExpandOp(Node->getOperand(2), RL, RH);
if (getTypeAction(NVT) == Expand)
NVT = TLI.getTypeToExpandTo(NVT);
- Lo = DAG.getNode(ISD::SELECT, NVT, Node->getOperand(0), LL, RL);
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, Node->getOperand(0), LL, RL);
if (VT != MVT::f32)
- Hi = DAG.getNode(ISD::SELECT, NVT, Node->getOperand(0), LH, RH);
+ Hi = DAG.getNode(ISD::SELECT, dl, NVT, Node->getOperand(0), LH, RH);
break;
}
case ISD::SELECT_CC: {
@@ -6624,35 +6698,35 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
ExpandOp(Node->getOperand(3), FL, FH);
if (getTypeAction(NVT) == Expand)
NVT = TLI.getTypeToExpandTo(NVT);
- Lo = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
+ Lo = DAG.getNode(ISD::SELECT_CC, dl, NVT, Node->getOperand(0),
Node->getOperand(1), TL, FL, Node->getOperand(4));
if (VT != MVT::f32)
- Hi = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
+ Hi = DAG.getNode(ISD::SELECT_CC, dl, NVT, Node->getOperand(0),
Node->getOperand(1), TH, FH, Node->getOperand(4));
break;
}
case ISD::ANY_EXTEND:
// The low part is any extension of the input (which degenerates to a copy).
- Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Node->getOperand(0));
+ Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Node->getOperand(0));
// The high part is undefined.
- Hi = DAG.getNode(ISD::UNDEF, NVT);
+ Hi = DAG.getNode(ISD::UNDEF, dl, NVT);
break;
case ISD::SIGN_EXTEND: {
// The low part is just a sign extension of the input (which degenerates to
// a copy).
- Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, Node->getOperand(0));
+ Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Node->getOperand(0));
// The high part is obtained by SRA'ing all but one of the bits of the lo
// part.
unsigned LoSize = Lo.getValueType().getSizeInBits();
- Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
break;
}
case ISD::ZERO_EXTEND:
// The low part is just a zero extension of the input (which degenerates to
// a copy).
- Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Node->getOperand(0));
+ Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0));
// The high part is just a zero.
Hi = DAG.getConstant(0, NVT);
@@ -6666,7 +6740,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// The low part is now either the right size, or it is closer. If not the
// right size, make an illegal truncate so we recursively expand it.
if (NewLo.getValueType() != Node->getValueType(0))
- NewLo = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), NewLo);
+ NewLo = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), NewLo);
ExpandOp(NewLo, Lo, Hi);
break;
}
@@ -6680,12 +6754,12 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
case Legal: Tmp = LegalizeOp(Node->getOperand(0)); break;
case Promote: Tmp = PromoteOp (Node->getOperand(0)); break;
}
- Tmp = TLI.LowerOperation(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp), DAG);
+ Tmp = TLI.LowerOperation(DAG.getNode(ISD::BIT_CONVERT, dl, VT, Tmp), DAG);
}
// f32 / f64 must be expanded to i32 / i64.
if (VT == MVT::f32 || VT == MVT::f64) {
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0));
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0));
if (getTypeAction(NVT) == Expand)
ExpandOp(Lo, Lo, Hi);
break;
@@ -6701,7 +6775,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// Turn this into a load/store pair by default.
if (Tmp.getNode() == 0)
- Tmp = EmitStackConvert(Node->getOperand(0), VT, VT);
+ Tmp = EmitStackConvert(Node->getOperand(0), VT, VT, dl);
ExpandOp(Tmp, Lo, Hi);
break;
@@ -6740,10 +6814,10 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// so substitute a target-dependent pseudo and expand that later.
SDValue In2Lo, In2Hi, In2;
ExpandOp(Op.getOperand(2), In2Lo, In2Hi);
- In2 = DAG.getNode(ISD::BUILD_PAIR, VT, In2Lo, In2Hi);
+ In2 = DAG.getNode(ISD::BUILD_PAIR, dl, VT, In2Lo, In2Hi);
AtomicSDNode* Anode = cast<AtomicSDNode>(Node);
SDValue Replace =
- DAG.getAtomic(Op.getOpcode(), Anode->getMemoryVT(),
+ DAG.getAtomic(Op.getOpcode(), dl, Anode->getMemoryVT(),
Op.getOperand(0), Op.getOperand(1), In2,
Anode->getSrcValue(), Anode->getAlignment());
SDValue Result = TLI.LowerOperation(Replace, DAG);
@@ -6764,7 +6838,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
case Promote: Op = PromoteOp (Node->getOperand(0)); break;
}
- Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_SINT, VT, Op), DAG);
+ Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_SINT, dl, VT, Op), DAG);
// Now that the custom expander is done, expand the result, which is still
// VT.
@@ -6790,7 +6864,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
case Promote: Op = PromoteOp (Node->getOperand(0)); break;
}
- Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_UINT, VT, Op), DAG);
+ Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_UINT, dl, VT, Op), DAG);
// Now that the custom expander is done, expand the result.
if (Op.getNode()) {
@@ -6810,7 +6884,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// If the target wants custom lowering, do so.
SDValue ShiftAmt = LegalizeOp(Node->getOperand(1));
if (TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Custom) {
- SDValue Op = DAG.getNode(ISD::SHL, VT, Node->getOperand(0), ShiftAmt);
+ SDValue Op = DAG.getNode(ISD::SHL, dl, VT, Node->getOperand(0), ShiftAmt);
Op = TLI.LowerOperation(Op, DAG);
if (Op.getNode()) {
// Now that the custom expander is done, expand the result, which is
@@ -6823,23 +6897,24 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// If ADDC/ADDE are supported and if the shift amount is a constant 1, emit
// this X << 1 as X+X.
if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(ShiftAmt)) {
- if (ShAmt->getAPIntValue() == 1 && TLI.isOperationLegal(ISD::ADDC, NVT) &&
- TLI.isOperationLegal(ISD::ADDE, NVT)) {
+ if (ShAmt->getAPIntValue() == 1 &&
+ TLI.isOperationLegalOrCustom(ISD::ADDC, NVT) &&
+ TLI.isOperationLegalOrCustom(ISD::ADDE, NVT)) {
SDValue LoOps[2], HiOps[3];
ExpandOp(Node->getOperand(0), LoOps[0], HiOps[0]);
SDVTList VTList = DAG.getVTList(LoOps[0].getValueType(), MVT::Flag);
LoOps[1] = LoOps[0];
- Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
HiOps[1] = HiOps[0];
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
break;
}
}
// If we can emit an efficient shift operation, do so now.
- if (ExpandShift(ISD::SHL, Node->getOperand(0), ShiftAmt, Lo, Hi))
+ if (ExpandShift(ISD::SHL, Node->getOperand(0), ShiftAmt, Lo, Hi, dl))
break;
// If this target supports SHL_PARTS, use it.
@@ -6847,7 +6922,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
TLI.getOperationAction(ISD::SHL_PARTS, NVT);
if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
Action == TargetLowering::Custom) {
- ExpandShiftParts(ISD::SHL_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi);
+ ExpandShiftParts(ISD::SHL_PARTS, Node->getOperand(0),
+ ShiftAmt, Lo, Hi, dl);
break;
}
@@ -6871,7 +6947,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
}
// If we can emit an efficient shift operation, do so now.
- if (ExpandShift(ISD::SRA, Node->getOperand(0), ShiftAmt, Lo, Hi))
+ if (ExpandShift(ISD::SRA, Node->getOperand(0), ShiftAmt, Lo, Hi, dl))
break;
// If this target supports SRA_PARTS, use it.
@@ -6879,7 +6955,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
TLI.getOperationAction(ISD::SRA_PARTS, NVT);
if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
Action == TargetLowering::Custom) {
- ExpandShiftParts(ISD::SRA_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi);
+ ExpandShiftParts(ISD::SRA_PARTS, Node->getOperand(0),
+ ShiftAmt, Lo, Hi, dl);
break;
}
@@ -6892,7 +6969,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// If the target wants custom lowering, do so.
SDValue ShiftAmt = LegalizeOp(Node->getOperand(1));
if (TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Custom) {
- SDValue Op = DAG.getNode(ISD::SRL, VT, Node->getOperand(0), ShiftAmt);
+ SDValue Op = DAG.getNode(ISD::SRL, dl, VT, Node->getOperand(0), ShiftAmt);
Op = TLI.LowerOperation(Op, DAG);
if (Op.getNode()) {
// Now that the custom expander is done, expand the result, which is
@@ -6903,7 +6980,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
}
// If we can emit an efficient shift operation, do so now.
- if (ExpandShift(ISD::SRL, Node->getOperand(0), ShiftAmt, Lo, Hi))
+ if (ExpandShift(ISD::SRL, Node->getOperand(0), ShiftAmt, Lo, Hi, dl))
break;
// If this target supports SRL_PARTS, use it.
@@ -6911,7 +6988,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
TLI.getOperationAction(ISD::SRL_PARTS, NVT);
if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
Action == TargetLowering::Custom) {
- ExpandShiftParts(ISD::SRL_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi);
+ ExpandShiftParts(ISD::SRL_PARTS,
+ Node->getOperand(0), ShiftAmt, Lo, Hi, dl);
break;
}
@@ -6946,7 +7024,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
bool hasCarry = false;
for (unsigned BitSize = NVT.getSizeInBits(); BitSize != 0; BitSize /= 2) {
MVT AVT = MVT::getIntegerVT(BitSize);
- if (TLI.isOperationLegal(OpV, AVT)) {
+ if (TLI.isOperationLegalOrCustom(OpV, AVT)) {
hasCarry = true;
break;
}
@@ -6955,38 +7033,38 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
if(hasCarry) {
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
if (Node->getOpcode() == ISD::ADD) {
- Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
} else {
- Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
}
break;
} else {
if (Node->getOpcode() == ISD::ADD) {
- Lo = DAG.getNode(ISD::ADD, NVT, LoOps, 2);
- Hi = DAG.getNode(ISD::ADD, NVT, HiOps, 2);
- SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(NVT),
+ Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2);
+ SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT),
Lo, LoOps[0], ISD::SETULT);
- SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1,
+ SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1,
DAG.getConstant(1, NVT),
DAG.getConstant(0, NVT));
- SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(NVT),
+ SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT),
Lo, LoOps[1], ISD::SETULT);
- SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2,
+ SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2,
DAG.getConstant(1, NVT),
Carry1);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, Carry2);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2);
} else {
- Lo = DAG.getNode(ISD::SUB, NVT, LoOps, 2);
- Hi = DAG.getNode(ISD::SUB, NVT, HiOps, 2);
- SDValue Cmp = DAG.getSetCC(NVT, LoOps[0], LoOps[1], ISD::SETULT);
- SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp,
+ Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2);
+ Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2);
+ SDValue Cmp = DAG.getSetCC(dl, NVT, LoOps[0], LoOps[1], ISD::SETULT);
+ SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp,
DAG.getConstant(1, NVT),
DAG.getConstant(0, NVT));
- Hi = DAG.getNode(ISD::SUB, NVT, Hi, Borrow);
+ Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
}
break;
}
@@ -7003,13 +7081,13 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
SDValue HiOps[3] = { LHSH, RHSH };
if (Node->getOpcode() == ISD::ADDC) {
- Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
} else {
- Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
}
// Remember that we legalized the flag.
AddLegalizedOperand(Op.getValue(1), LegalizeOp(Hi.getValue(1)));
@@ -7025,9 +7103,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
SDValue LoOps[3] = { LHSL, RHSL, Node->getOperand(2) };
SDValue HiOps[3] = { LHSH, RHSH };
- Lo = DAG.getNode(Node->getOpcode(), VTList, LoOps, 3);
+ Lo = DAG.getNode(Node->getOpcode(), dl, VTList, LoOps, 3);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(Node->getOpcode(), VTList, HiOps, 3);
+ Hi = DAG.getNode(Node->getOpcode(), dl, VTList, HiOps, 3);
// Remember that we legalized the flag.
AddLegalizedOperand(Op.getValue(1), LegalizeOp(Hi.getValue(1)));
@@ -7043,10 +7121,10 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
}
}
- bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
- bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
- bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
- bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
+ bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT);
+ bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT);
+ bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT);
+ bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT);
if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
SDValue LL, LH, RL, RH;
ExpandOp(Node->getOperand(0), LL, LH);
@@ -7061,14 +7139,14 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// The inputs are both zero-extended.
if (HasUMUL_LOHI) {
// We can emit a umul_lohi.
- Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
Hi = SDValue(Lo.getNode(), 1);
break;
}
if (HasMULHU) {
// We can emit a mulhu+mul.
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
- Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+ Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
break;
}
}
@@ -7076,36 +7154,36 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
// The input values are both sign-extended.
if (HasSMUL_LOHI) {
// We can emit a smul_lohi.
- Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
Hi = SDValue(Lo.getNode(), 1);
break;
}
if (HasMULHS) {
// We can emit a mulhs+mul.
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
- Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL);
+ Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL);
break;
}
}
if (HasUMUL_LOHI) {
// Lo,Hi = umul LHS, RHS.
- SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI,
+ SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl,
DAG.getVTList(NVT, NVT), LL, RL);
Lo = UMulLOHI;
Hi = UMulLOHI.getValue(1);
- RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
- LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+ RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
+ LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
break;
}
if (HasMULHU) {
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
- Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
- RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
- LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+ Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
+ RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
+ LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
break;
}
}
@@ -7161,7 +7239,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
Node->getOperand(0).getValueType()==MVT::f64);
const uint64_t zero = 0;
if (Node->getOperand(0).getValueType()==MVT::f32)
- Hi = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Node->getOperand(0));
+ Hi = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Node->getOperand(0));
else
Hi = Node->getOperand(0);
Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64);
@@ -7265,19 +7343,19 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
if (VT == MVT::ppcf128) {
SDValue Tmp;
ExpandOp(Node->getOperand(0), Lo, Tmp);
- Hi = DAG.getNode(ISD::FABS, NVT, Tmp);
+ Hi = DAG.getNode(ISD::FABS, dl, NVT, Tmp);
// lo = hi==fabs(hi) ? lo : -lo;
- Lo = DAG.getNode(ISD::SELECT_CC, NVT, Hi, Tmp,
- Lo, DAG.getNode(ISD::FNEG, NVT, Lo),
+ Lo = DAG.getNode(ISD::SELECT_CC, dl, NVT, Hi, Tmp,
+ Lo, DAG.getNode(ISD::FNEG, dl, NVT, Lo),
DAG.getCondCode(ISD::SETEQ));
break;
}
SDValue Mask = (VT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), VT)
: DAG.getConstantFP(BitsToFloat(~(1U << 31)), VT);
- Mask = DAG.getNode(ISD::BIT_CONVERT, NVT, Mask);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0));
- Lo = DAG.getNode(ISD::AND, NVT, Lo, Mask);
+ Mask = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Mask);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0));
+ Lo = DAG.getNode(ISD::AND, dl, NVT, Lo, Mask);
if (getTypeAction(NVT) == Expand)
ExpandOp(Lo, Lo, Hi);
break;
@@ -7285,16 +7363,16 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
case ISD::FNEG: {
if (VT == MVT::ppcf128) {
ExpandOp(Node->getOperand(0), Lo, Hi);
- Lo = DAG.getNode(ISD::FNEG, MVT::f64, Lo);
- Hi = DAG.getNode(ISD::FNEG, MVT::f64, Hi);
+ Lo = DAG.getNode(ISD::FNEG, dl, MVT::f64, Lo);
+ Hi = DAG.getNode(ISD::FNEG, dl, MVT::f64, Hi);
break;
}
SDValue Mask = (VT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), VT)
: DAG.getConstantFP(BitsToFloat(1U << 31), VT);
- Mask = DAG.getNode(ISD::BIT_CONVERT, NVT, Mask);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0));
- Lo = DAG.getNode(ISD::XOR, NVT, Lo, Mask);
+ Mask = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Mask);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0));
+ Lo = DAG.getNode(ISD::XOR, dl, NVT, Lo, Mask);
if (getTypeAction(NVT) == Expand)
ExpandOp(Lo, Lo, Hi);
break;
@@ -7315,9 +7393,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
if (getTypeAction(SrcVT) == Promote) {
SDValue Tmp = PromoteOp(Node->getOperand(0));
Tmp = isSigned
- ? DAG.getNode(ISD::SIGN_EXTEND_INREG, Tmp.getValueType(), Tmp,
+ ? DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Tmp.getValueType(), Tmp,
DAG.getValueType(SrcVT))
- : DAG.getZeroExtendInReg(Tmp, SrcVT);
+ : DAG.getZeroExtendInReg(Tmp, dl, SrcVT);
Node = DAG.UpdateNodeOperands(Op, Tmp).getNode();
SrcVT = Node->getOperand(0).getValueType();
}
@@ -7325,19 +7403,20 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
if (VT == MVT::ppcf128 && SrcVT == MVT::i32) {
static const uint64_t zero = 0;
if (isSigned) {
- Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64,
+ Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f64,
Node->getOperand(0)));
Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64);
} else {
static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
- Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64,
+ Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f64,
Node->getOperand(0)));
Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64);
- Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
+ Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi);
// X>=0 ? {(f64)x, 0} : {(f64)x, 0} + 2^32
- ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0),
+ ExpandOp(DAG.getNode(ISD::SELECT_CC, dl,
+ MVT::ppcf128, Node->getOperand(0),
DAG.getConstant(0, MVT::i32),
- DAG.getNode(ISD::FADD, MVT::ppcf128, Hi,
+ DAG.getNode(ISD::FADD, dl, MVT::ppcf128, Hi,
DAG.getConstantFP(
APFloat(APInt(128, 2, TwoE32)),
MVT::ppcf128)),
@@ -7350,13 +7429,14 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
if (VT == MVT::ppcf128 && SrcVT == MVT::i64 && !isSigned) {
// si64->ppcf128 done by libcall, below
static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
- ExpandOp(DAG.getNode(ISD::SINT_TO_FP, MVT::ppcf128, Node->getOperand(0)),
- Lo, Hi);
- Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
+ ExpandOp(DAG.getNode(ISD::SINT_TO_FP, dl, MVT::ppcf128,
+ Node->getOperand(0)), Lo, Hi);
+ Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi);
// x>=0 ? (ppcf128)(i64)x : (ppcf128)(i64)x + 2^64
- ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0),
+ ExpandOp(DAG.getNode(ISD::SELECT_CC, dl, MVT::ppcf128,
+ Node->getOperand(0),
DAG.getConstant(0, MVT::i64),
- DAG.getNode(ISD::FADD, MVT::ppcf128, Hi,
+ DAG.getNode(ISD::FADD, dl, MVT::ppcf128, Hi,
DAG.getConstantFP(
APFloat(APInt(128, 2, TwoE64)),
MVT::ppcf128)),
@@ -7367,7 +7447,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
}
Lo = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, VT,
- Node->getOperand(0));
+ Node->getOperand(0), dl);
if (getTypeAction(Lo.getValueType()) == Expand)
// float to i32 etc. can be 'expanded' to a single node.
ExpandOp(Lo, Lo, Hi);
@@ -7397,6 +7477,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SDValue &Hi) {
assert(Op.getValueType().isVector() && "Cannot split non-vector type!");
SDNode *Node = Op.getNode();
+ DebugLoc dl = Node->getDebugLoc();
unsigned NumElements = Op.getValueType().getVectorNumElements();
assert(NumElements > 1 && "Cannot split a single element vector!");
@@ -7424,8 +7505,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
#endif
assert(0 && "Unhandled operation in SplitVectorOp!");
case ISD::UNDEF:
- Lo = DAG.getNode(ISD::UNDEF, NewVT_Lo);
- Hi = DAG.getNode(ISD::UNDEF, NewVT_Hi);
+ Lo = DAG.getNode(ISD::UNDEF, dl, NewVT_Lo);
+ Hi = DAG.getNode(ISD::UNDEF, dl, NewVT_Hi);
break;
case ISD::BUILD_PAIR:
Lo = Node->getOperand(0);
@@ -7437,16 +7518,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
unsigned Index = Idx->getZExtValue();
SDValue ScalarOp = Node->getOperand(1);
if (Index < NewNumElts_Lo)
- Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp,
+ Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVT_Lo, Lo, ScalarOp,
DAG.getIntPtrConstant(Index));
else
- Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp,
+ Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVT_Hi, Hi, ScalarOp,
DAG.getIntPtrConstant(Index - NewNumElts_Lo));
break;
}
SDValue Tmp = PerformInsertVectorEltInMemory(Node->getOperand(0),
Node->getOperand(1),
- Node->getOperand(2));
+ Node->getOperand(2), dl);
SplitVectorOp(Tmp, Lo, Hi);
break;
}
@@ -7462,7 +7543,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
for (unsigned i = 0; i != NewNumElts_Lo; ++i) {
SDValue IdxNode = Mask.getOperand(i);
if (IdxNode.getOpcode() == ISD::UNDEF) {
- Ops.push_back(DAG.getNode(ISD::UNDEF, NewEltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, dl, NewEltVT));
continue;
}
unsigned Idx = cast<ConstantSDNode>(IdxNode)->getZExtValue();
@@ -7471,16 +7552,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
InVec = Node->getOperand(1);
Idx -= NumElements;
}
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec,
DAG.getConstant(Idx, PtrVT)));
}
- Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size());
+ Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &Ops[0], Ops.size());
Ops.clear();
for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) {
SDValue IdxNode = Mask.getOperand(i);
if (IdxNode.getOpcode() == ISD::UNDEF) {
- Ops.push_back(DAG.getNode(ISD::UNDEF, NewEltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, dl, NewEltVT));
continue;
}
unsigned Idx = cast<ConstantSDNode>(IdxNode)->getZExtValue();
@@ -7489,20 +7570,20 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
InVec = Node->getOperand(1);
Idx -= NumElements;
}
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec,
DAG.getConstant(Idx, PtrVT)));
}
- Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Hi, &Ops[0], Ops.size());
+ Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &Ops[0], Ops.size());
break;
}
case ISD::BUILD_VECTOR: {
SmallVector<SDValue, 8> LoOps(Node->op_begin(),
Node->op_begin()+NewNumElts_Lo);
- Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &LoOps[0], LoOps.size());
+ Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &LoOps[0], LoOps.size());
SmallVector<SDValue, 8> HiOps(Node->op_begin()+NewNumElts_Lo,
Node->op_end());
- Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Hi, &HiOps[0], HiOps.size());
+ Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &HiOps[0], HiOps.size());
break;
}
case ISD::CONCAT_VECTORS: {
@@ -7514,11 +7595,13 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
} else {
SmallVector<SDValue, 8> LoOps(Node->op_begin(),
Node->op_begin()+NewNumSubvectors);
- Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Lo, &LoOps[0], LoOps.size());
+ Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewVT_Lo,
+ &LoOps[0], LoOps.size());
SmallVector<SDValue, 8> HiOps(Node->op_begin()+NewNumSubvectors,
Node->op_end());
- Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Hi, &HiOps[0], HiOps.size());
+ Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewVT_Hi,
+ &HiOps[0], HiOps.size());
}
break;
}
@@ -7527,16 +7610,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SDValue Idx = Op.getOperand(1);
MVT IdxVT = Idx.getValueType();
- Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, NewVT_Lo, Vec, Idx);
+ Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT_Lo, Vec, Idx);
ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx);
if (CIdx) {
- Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, NewVT_Hi, Vec,
+ Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT_Hi, Vec,
DAG.getConstant(CIdx->getZExtValue() + NewNumElts_Lo,
IdxVT));
} else {
- Idx = DAG.getNode(ISD::ADD, IdxVT, Idx,
+ Idx = DAG.getNode(ISD::ADD, dl, IdxVT, Idx,
DAG.getConstant(NewNumElts_Lo, IdxVT));
- Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, NewVT_Hi, Vec, Idx);
+ Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT_Hi, Vec, Idx);
}
break;
}
@@ -7551,12 +7634,12 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
// Handle a vector merge.
SDValue CL, CH;
SplitVectorOp(Cond, CL, CH);
- Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, CL, LL, RL);
- Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, CH, LH, RH);
+ Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, CL, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, CH, LH, RH);
} else {
// Handle a simple select with vector operands.
- Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, Cond, LL, RL);
- Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, Cond, LH, RH);
+ Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, Cond, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, Cond, LH, RH);
}
break;
}
@@ -7570,9 +7653,9 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SplitVectorOp(Node->getOperand(3), RL, RH);
// Handle a simple select with vector operands.
- Lo = DAG.getNode(ISD::SELECT_CC, NewVT_Lo, CondLHS, CondRHS,
+ Lo = DAG.getNode(ISD::SELECT_CC, dl, NewVT_Lo, CondLHS, CondRHS,
LL, RL, CondCode);
- Hi = DAG.getNode(ISD::SELECT_CC, NewVT_Hi, CondLHS, CondRHS,
+ Hi = DAG.getNode(ISD::SELECT_CC, dl, NewVT_Hi, CondLHS, CondRHS,
LH, RH, CondCode);
break;
}
@@ -7580,8 +7663,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SDValue LL, LH, RL, RH;
SplitVectorOp(Node->getOperand(0), LL, LH);
SplitVectorOp(Node->getOperand(1), RL, RH);
- Lo = DAG.getNode(ISD::VSETCC, NewVT_Lo, LL, RL, Node->getOperand(2));
- Hi = DAG.getNode(ISD::VSETCC, NewVT_Hi, LH, RH, Node->getOperand(2));
+ Lo = DAG.getNode(ISD::VSETCC, dl, NewVT_Lo, LL, RL, Node->getOperand(2));
+ Hi = DAG.getNode(ISD::VSETCC, dl, NewVT_Hi, LH, RH, Node->getOperand(2));
break;
}
case ISD::ADD:
@@ -7607,8 +7690,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SplitVectorOp(Node->getOperand(0), LL, LH);
SplitVectorOp(Node->getOperand(1), RL, RH);
- Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, LL, RL);
- Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, LH, RH);
+ Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, LH, RH);
break;
}
case ISD::FP_ROUND:
@@ -7616,8 +7699,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SDValue L, H;
SplitVectorOp(Node->getOperand(0), L, H);
- Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L, Node->getOperand(1));
- Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H, Node->getOperand(1));
+ Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, L, Node->getOperand(1));
+ Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, H, Node->getOperand(1));
break;
}
case ISD::CTTZ:
@@ -7645,8 +7728,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SDValue L, H;
SplitVectorOp(Node->getOperand(0), L, H);
- Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L);
- Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H);
+ Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, L);
+ Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, H);
break;
}
case ISD::CONVERT_RNDSAT: {
@@ -7679,27 +7762,27 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
bool isVolatile = LD->isVolatile();
assert(LD->isUnindexed() && "Indexed vector loads are not supported yet!");
- SDValue Offset = DAG.getNode(ISD::UNDEF, Ptr.getValueType());
+ SDValue Offset = DAG.getNode(ISD::UNDEF, dl, Ptr.getValueType());
MVT MemNewEltVT = MemoryVT.getVectorElementType();
MVT MemNewVT_Lo = MVT::getVectorVT(MemNewEltVT, NewNumElts_Lo);
MVT MemNewVT_Hi = MVT::getVectorVT(MemNewEltVT, NewNumElts_Hi);
- Lo = DAG.getLoad(ISD::UNINDEXED, ExtType,
+ Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType,
NewVT_Lo, Ch, Ptr, Offset,
SV, SVOffset, MemNewVT_Lo, isVolatile, Alignment);
unsigned IncrementSize = NewNumElts_Lo * MemNewEltVT.getSizeInBits()/8;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
- Hi = DAG.getLoad(ISD::UNINDEXED, ExtType,
+ Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType,
NewVT_Hi, Ch, Ptr, Offset,
SV, SVOffset, MemNewVT_Hi, isVolatile, Alignment);
// Build a factor node to remember that this load is independent of the
// other one.
- SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
// Remember that we legalized the chain.
@@ -7720,16 +7803,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SDValue Ptr = DAG.CreateStackTemporary(InOp.getValueType(), LdAlign);
int FI = cast<FrameIndexSDNode>(Ptr.getNode())->getIndex();
- SDValue St = DAG.getStore(DAG.getEntryNode(),
+ SDValue St = DAG.getStore(DAG.getEntryNode(), dl,
InOp, Ptr,
PseudoSourceValue::getFixedStack(FI), 0);
- InOp = DAG.getLoad(Op.getValueType(), St, Ptr,
+ InOp = DAG.getLoad(Op.getValueType(), dl, St, Ptr,
PseudoSourceValue::getFixedStack(FI), 0);
}
// Split the vector and convert each of the pieces now.
SplitVectorOp(InOp, Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT_Lo, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT_Hi, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT_Lo, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT_Hi, Hi);
break;
}
}
@@ -7748,6 +7831,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
assert(Op.getValueType().isVector() && "Bad ScalarizeVectorOp invocation!");
SDNode *Node = Op.getNode();
+ DebugLoc dl = Node->getDebugLoc();
MVT NewVT = Op.getValueType().getVectorElementType();
assert(Op.getValueType().getVectorNumElements() == 1);
@@ -7778,7 +7862,7 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
case ISD::AND:
case ISD::OR:
case ISD::XOR:
- Result = DAG.getNode(Node->getOpcode(),
+ Result = DAG.getNode(Node->getOpcode(), dl,
NewVT,
ScalarizeVectorOp(Node->getOperand(0)),
ScalarizeVectorOp(Node->getOperand(1)));
@@ -7802,7 +7886,7 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
case ISD::ANY_EXTEND:
case ISD::TRUNCATE:
case ISD::FP_EXTEND:
- Result = DAG.getNode(Node->getOpcode(),
+ Result = DAG.getNode(Node->getOpcode(), dl,
NewVT,
ScalarizeVectorOp(Node->getOperand(0)));
break;
@@ -7818,7 +7902,7 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
}
case ISD::FPOWI:
case ISD::FP_ROUND:
- Result = DAG.getNode(Node->getOpcode(),
+ Result = DAG.getNode(Node->getOpcode(), dl,
NewVT,
ScalarizeVectorOp(Node->getOperand(0)),
Node->getOperand(1));
@@ -7835,9 +7919,9 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
bool isVolatile = LD->isVolatile();
assert(LD->isUnindexed() && "Indexed vector loads are not supported yet!");
- SDValue Offset = DAG.getNode(ISD::UNDEF, Ptr.getValueType());
+ SDValue Offset = DAG.getNode(ISD::UNDEF, dl, Ptr.getValueType());
- Result = DAG.getLoad(ISD::UNINDEXED, ExtType,
+ Result = DAG.getLoad(ISD::UNINDEXED, dl, ExtType,
NewVT, Ch, Ptr, Offset, SV, SVOffset,
MemoryVT.getVectorElementType(),
isVolatile, Alignment);
@@ -7868,23 +7952,23 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
break;
}
case ISD::EXTRACT_SUBVECTOR:
- Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, Node->getOperand(0),
- Node->getOperand(1));
+ Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT,
+ Node->getOperand(0), Node->getOperand(1));
break;
case ISD::BIT_CONVERT: {
SDValue Op0 = Op.getOperand(0);
if (Op0.getValueType().getVectorNumElements() == 1)
Op0 = ScalarizeVectorOp(Op0);
- Result = DAG.getNode(ISD::BIT_CONVERT, NewVT, Op0);
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT, Op0);
break;
}
case ISD::SELECT:
- Result = DAG.getNode(ISD::SELECT, NewVT, Op.getOperand(0),
+ Result = DAG.getNode(ISD::SELECT, dl, NewVT, Op.getOperand(0),
ScalarizeVectorOp(Op.getOperand(1)),
ScalarizeVectorOp(Op.getOperand(2)));
break;
case ISD::SELECT_CC:
- Result = DAG.getNode(ISD::SELECT_CC, NewVT, Node->getOperand(0),
+ Result = DAG.getNode(ISD::SELECT_CC, dl, NewVT, Node->getOperand(0),
Node->getOperand(1),
ScalarizeVectorOp(Op.getOperand(2)),
ScalarizeVectorOp(Op.getOperand(3)),
@@ -7893,9 +7977,10 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
case ISD::VSETCC: {
SDValue Op0 = ScalarizeVectorOp(Op.getOperand(0));
SDValue Op1 = ScalarizeVectorOp(Op.getOperand(1));
- Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(Op0.getValueType()),
+ Result = DAG.getNode(ISD::SETCC, dl,
+ TLI.getSetCCResultType(Op0.getValueType()),
Op0, Op1, Op.getOperand(2));
- Result = DAG.getNode(ISD::SELECT, NewVT, Result,
+ Result = DAG.getNode(ISD::SELECT, dl, NewVT, Result,
DAG.getConstant(-1ULL, NewVT),
DAG.getConstant(0ULL, NewVT));
break;
@@ -7920,6 +8005,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
SDValue Result;
SDNode *Node = Op.getNode();
+ DebugLoc dl = Node->getDebugLoc();
MVT EVT = VT.getVectorElementType();
unsigned NumElts = VT.getVectorNumElements();
@@ -7955,20 +8041,21 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
assert(0 && "Unexpected operation in WidenVectorOp!");
break;
case ISD::UNDEF:
- Result = DAG.getNode(ISD::UNDEF, WidenVT);
+ Result = DAG.getNode(ISD::UNDEF, dl, WidenVT);
break;
case ISD::BUILD_VECTOR: {
// Build a vector with undefined for the new nodes
SDValueVector NewOps(Node->op_begin(), Node->op_end());
for (unsigned i = NumElts; i < NewNumElts; ++i) {
- NewOps.push_back(DAG.getNode(ISD::UNDEF,EVT));
+ NewOps.push_back(DAG.getNode(ISD::UNDEF, dl, EVT));
}
- Result = DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &NewOps[0], NewOps.size());
+ Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT,
+ &NewOps[0], NewOps.size());
break;
}
case ISD::INSERT_VECTOR_ELT: {
SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
- Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, WidenVT, Tmp1,
+ Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WidenVT, Tmp1,
Node->getOperand(1), Node->getOperand(2));
break;
}
@@ -7997,14 +8084,14 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
}
}
for (unsigned i = NumElts; i < NewNumElts; ++i) {
- NewOps.push_back(DAG.getNode(ISD::UNDEF,PVT));
+ NewOps.push_back(DAG.getNode(ISD::UNDEF, dl, PVT));
}
- SDValue Tmp3 = DAG.getNode(ISD::BUILD_VECTOR,
+ SDValue Tmp3 = DAG.getNode(ISD::BUILD_VECTOR, dl,
MVT::getVectorVT(PVT, NewOps.size()),
&NewOps[0], NewOps.size());
- Result = DAG.getNode(ISD::VECTOR_SHUFFLE, WidenVT, Tmp1, Tmp2, Tmp3);
+ Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, Tmp1, Tmp2, Tmp3);
break;
}
case ISD::LOAD: {
@@ -8033,7 +8120,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
MVT NewInWidenVT = MVT::getVectorVT(InEltVT, WidenSize / InEltSize);
Tmp1 = WidenVectorOp(Tmp1, NewInWidenVT);
assert(Tmp1.getValueType().getSizeInBits() == WidenVT.getSizeInBits());
- Result = DAG.getNode(ISD::BIT_CONVERT, WidenVT, Tmp1);
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, Tmp1);
} else {
// If the result size is a multiple of the input size, widen the input
// and then convert.
@@ -8042,14 +8129,14 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
"can not widen bit convert that are not multiple of element type");
unsigned NewNumElts = WidenSize / InSize;
SmallVector<SDValue, 16> Ops(NewNumElts);
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT);
Ops[0] = Tmp1;
for (unsigned i = 1; i < NewNumElts; ++i)
Ops[i] = UndefVal;
MVT NewInVT = MVT::getVectorVT(InVT, NewNumElts);
- Result = DAG.getNode(ISD::BUILD_VECTOR, NewInVT, &Ops[0], NewNumElts);
- Result = DAG.getNode(ISD::BIT_CONVERT, WidenVT, Result);
+ Result = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, &Ops[0], NewNumElts);
+ Result = DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, Result);
}
break;
}
@@ -8068,7 +8155,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
MVT TWidenVT = MVT::getVectorVT(TEVT, NewNumElts);
Tmp1 = WidenVectorOp(Tmp1, TWidenVT);
assert(Tmp1.getValueType().getVectorNumElements() == NewNumElts);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1);
+ Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1);
break;
}
@@ -8091,7 +8178,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
SDValue Tmp1;
Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
assert(Tmp1.getValueType() == WidenVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1);
+ Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1);
break;
}
case ISD::CONVERT_RNDSAT: {
@@ -8141,7 +8228,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
SDValue Tmp2 = WidenVectorOp(Node->getOperand(1), WidenVT);
assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1, Tmp2);
break;
}
@@ -8156,14 +8243,14 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
WidenVT.getVectorNumElements());
ShOp = WidenVectorOp(ShOp, NewShVT);
assert(ShOp.getValueType() == NewShVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, ShOp);
+ Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1, ShOp);
break;
}
case ISD::EXTRACT_VECTOR_ELT: {
SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
assert(Tmp1.getValueType() == WidenVT);
- Result = DAG.getNode(Node->getOpcode(), EVT, Tmp1, Node->getOperand(1));
+ Result = DAG.getNode(Node->getOpcode(), dl, EVT, Tmp1, Node->getOperand(1));
break;
}
case ISD::CONCAT_VECTORS: {
@@ -8171,13 +8258,13 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
// We could widen on a multiple of the incoming operand if necessary.
unsigned NumConcat = NewNumElts / NumElts;
assert(NewNumElts % NumElts == 0 && "Can widen only a multiple of vector");
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, VT);
SmallVector<SDValue, 8> MOps;
MOps.push_back(Op);
for (unsigned i = 1; i != NumConcat; ++i) {
MOps.push_back(UndefVal);
}
- Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, WidenVT,
+ Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
&MOps[0], MOps.size()));
break;
}
@@ -8196,18 +8283,18 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
if (Tmp1VTNumElts < NewNumElts)
Result = WidenVectorOp(Tmp1, WidenVT);
else
- Result = DAG.getNode(ISD::EXTRACT_SUBVECTOR, WidenVT, Tmp1, Idx);
+ Result = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, Tmp1, Idx);
}
} else if (NewNumElts % NumElts == 0) {
// Widen the extracted subvector.
unsigned NumConcat = NewNumElts / NumElts;
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, VT);
SmallVector<SDValue, 8> MOps;
MOps.push_back(Op);
for (unsigned i = 1; i != NumConcat; ++i) {
MOps.push_back(UndefVal);
}
- Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, WidenVT,
+ Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
&MOps[0], MOps.size()));
} else {
assert(0 && "can not widen extract subvector");
@@ -8230,7 +8317,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
SDValue Tmp1 = WidenVectorOp(Node->getOperand(1), WidenVT);
SDValue Tmp2 = WidenVectorOp(Node->getOperand(2), WidenVT);
assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Tmp1, Tmp2);
+ Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Cond1, Tmp1, Tmp2);
break;
}
@@ -8252,7 +8339,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
SDValue Tmp2 = WidenVectorOp(Node->getOperand(3), WidenVT);
assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT &&
"operands not widen");
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Cond2, Tmp1,
+ Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Cond1, Cond2, Tmp1,
Tmp2, Node->getOperand(4));
break;
}
@@ -8265,7 +8352,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
MVT TmpWidenVT = MVT::getVectorVT(TmpEVT, NewNumElts);
Tmp1 = WidenVectorOp(Tmp1, TmpWidenVT);
SDValue Tmp2 = WidenVectorOp(Node->getOperand(1), TmpWidenVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2,
+ Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1, Tmp2,
Node->getOperand(2));
break;
}
@@ -8332,7 +8419,8 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain,
unsigned Alignment,
bool isVolatile,
unsigned LdWidth,
- MVT ResType) {
+ MVT ResType,
+ DebugLoc dl) {
// We assume that we have good rules to handle loading power of two loads so
// we break down the operations to power of 2 loads. The strategy is to
// load the largest power of 2 that we can easily transform to a legal vector
@@ -8346,14 +8434,14 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain,
FindWidenVecType(TLI, LdWidth, ResType, EVT, VecEVT);
EVTWidth = EVT.getSizeInBits();
- SDValue LdOp = DAG.getLoad(EVT, Chain, BasePtr, SV, SVOffset,
+ SDValue LdOp = DAG.getLoad(EVT, dl, Chain, BasePtr, SV, SVOffset,
isVolatile, Alignment);
- SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, VecEVT, LdOp);
+ SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VecEVT, LdOp);
LdChain.push_back(LdOp.getValue(1));
// Check if we can load the element with one instruction
if (LdWidth == EVTWidth) {
- return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
}
// The vector element order is endianness dependent.
@@ -8364,7 +8452,7 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain,
while (LdWidth > 0) {
unsigned Increment = EVTWidth / 8;
Offset += Increment;
- BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr,
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
DAG.getIntPtrConstant(Increment));
if (LdWidth < EVTWidth) {
@@ -8375,20 +8463,20 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain,
EVTWidth = EVT.getSizeInBits();
// Readjust position and vector position based on new load type
Idx = Idx * (oEVTWidth/EVTWidth);
- VecOp = DAG.getNode(ISD::BIT_CONVERT, VecEVT, VecOp);
+ VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, VecEVT, VecOp);
}
- SDValue LdOp = DAG.getLoad(EVT, Chain, BasePtr, SV,
+ SDValue LdOp = DAG.getLoad(EVT, dl, Chain, BasePtr, SV,
SVOffset+Offset, isVolatile,
MinAlign(Alignment, Offset));
LdChain.push_back(LdOp.getValue(1));
- VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, VecEVT, VecOp, LdOp,
+ VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecEVT, VecOp, LdOp,
DAG.getIntPtrConstant(Idx++));
LdWidth -= EVTWidth;
}
- return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
}
bool SelectionDAGLegalize::LoadWidenVectorOp(SDValue& Result,
@@ -8404,6 +8492,7 @@ bool SelectionDAGLegalize::LoadWidenVectorOp(SDValue& Result,
// we need to load from.
LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
MVT LdVT = LD->getMemoryVT();
+ DebugLoc dl = LD->getDebugLoc();
assert(LdVT.isVector() && NVT.isVector());
assert(LdVT.getVectorElementType() == NVT.getVectorElementType());
@@ -8419,14 +8508,15 @@ bool SelectionDAGLegalize::LoadWidenVectorOp(SDValue& Result,
// Load value as a large register
SDValueVector LdChain;
Result = genWidenVectorLoads(LdChain, Chain, BasePtr, SV, SVOffset,
- Alignment, isVolatile, LdWidth, NVT);
+ Alignment, isVolatile, LdWidth, NVT, dl);
if (LdChain.size() == 1) {
TFOp = LdChain[0];
return true;
}
else {
- TFOp=DAG.getNode(ISD::TokenFactor, MVT::Other, &LdChain[0], LdChain.size());
+ TFOp=DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &LdChain[0], LdChain.size());
return false;
}
}
@@ -8440,7 +8530,8 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain,
unsigned Alignment,
bool isVolatile,
SDValue ValOp,
- unsigned StWidth) {
+ unsigned StWidth,
+ DebugLoc dl) {
// Breaks the stores into a series of power of 2 width stores. For any
// width, we convert the vector to the vector of element size that we
// want to store. This avoids requiring a stack convert.
@@ -8452,10 +8543,10 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain,
FindWidenVecType(TLI, StWidth, VVT, EVT, VecEVT);
EVTWidth = EVT.getSizeInBits();
- SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, VecEVT, ValOp);
- SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EVT, VecOp,
+ SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, VecEVT, ValOp);
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EVT, VecOp,
DAG.getIntPtrConstant(0));
- SDValue StOp = DAG.getStore(Chain, EOp, BasePtr, SV, SVOffset,
+ SDValue StOp = DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset,
isVolatile, Alignment);
StChain.push_back(StOp);
@@ -8471,7 +8562,7 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain,
while (StWidth > 0) {
unsigned Increment = EVTWidth / 8;
Offset += Increment;
- BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr,
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
DAG.getIntPtrConstant(Increment));
if (StWidth < EVTWidth) {
@@ -8482,12 +8573,12 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain,
EVTWidth = EVT.getSizeInBits();
// Readjust position and vector position based on new load type
Idx = Idx * (oEVTWidth/EVTWidth);
- VecOp = DAG.getNode(ISD::BIT_CONVERT, VecEVT, VecOp);
+ VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, VecEVT, VecOp);
}
- EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EVT, VecOp,
+ EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EVT, VecOp,
DAG.getIntPtrConstant(Idx++));
- StChain.push_back(DAG.getStore(Chain, EOp, BasePtr, SV,
+ StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
SVOffset + Offset, isVolatile,
MinAlign(Alignment, Offset)));
StWidth -= EVTWidth;
@@ -8506,6 +8597,7 @@ SDValue SelectionDAGLegalize::StoreWidenVectorOp(StoreSDNode *ST,
MVT StVT = ST->getMemoryVT();
SDValue ValOp = ST->getValue();
+ DebugLoc dl = ST->getDebugLoc();
// Check if we have widen this node with another value
std::map<SDValue, SDValue>::iterator I = WidenNodes.find(ValOp);
@@ -8517,18 +8609,19 @@ SDValue SelectionDAGLegalize::StoreWidenVectorOp(StoreSDNode *ST,
// It must be true that we the widen vector type is bigger than where
// we need to store.
assert(StVT.isVector() && VVT.isVector());
- assert(StVT.getSizeInBits() < VVT.getSizeInBits());
+ assert(StVT.bitsLT(VVT));
assert(StVT.getVectorElementType() == VVT.getVectorElementType());
// Store value
SDValueVector StChain;
genWidenVectorStores(StChain, Chain, BasePtr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getAlignment(),
- ST->isVolatile(), ValOp, StVT.getSizeInBits());
+ ST->isVolatile(), ValOp, StVT.getSizeInBits(), dl);
if (StChain.size() == 1)
return StChain[0];
else
- return DAG.getNode(ISD::TokenFactor, MVT::Other,&StChain[0],StChain.size());
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &StChain[0], StChain.size());
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 837955117298..53a252baa4b8 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -101,7 +101,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) {
SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) {
// Convert the inputs to integers, and build a new pair out of them.
- return DAG.getNode(ISD::BUILD_PAIR,
+ return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(),
TLI.getTypeToTransformTo(N->getValueType(0)),
BitConvertToInteger(N->getOperand(0)),
BitConvertToInteger(N->getOperand(1)));
@@ -120,7 +120,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1),
NVT);
SDValue Op = GetSoftenedFloat(N->getOperand(0));
- return DAG.getNode(ISD::AND, NVT, Op, Mask);
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), NVT, Op, Mask);
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
@@ -132,7 +132,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
RTLIB::ADD_F64,
RTLIB::ADD_F80,
RTLIB::ADD_PPCF128),
- NVT, Ops, 2, false);
+ NVT, Ops, 2, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
@@ -143,12 +143,13 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
RTLIB::CEIL_F64,
RTLIB::CEIL_F80,
RTLIB::CEIL_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
SDValue LHS = GetSoftenedFloat(N->getOperand(0));
SDValue RHS = BitConvertToInteger(N->getOperand(1));
+ DebugLoc dl = N->getDebugLoc();
MVT LVT = LHS.getValueType();
MVT RVT = RHS.getValueType();
@@ -157,32 +158,32 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
unsigned RSize = RVT.getSizeInBits();
// First get the sign bit of second operand.
- SDValue SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT),
+ SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT),
DAG.getConstant(RSize - 1,
TLI.getShiftAmountTy()));
- SignBit = DAG.getNode(ISD::AND, RVT, RHS, SignBit);
+ SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit);
// Shift right or sign-extend it if the two operands have different types.
int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
if (SizeDiff > 0) {
- SignBit = DAG.getNode(ISD::SRL, RVT, SignBit,
+ SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit,
DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
- SignBit = DAG.getNode(ISD::TRUNCATE, LVT, SignBit);
+ SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit);
} else if (SizeDiff < 0) {
- SignBit = DAG.getNode(ISD::ANY_EXTEND, LVT, SignBit);
- SignBit = DAG.getNode(ISD::SHL, LVT, SignBit,
+ SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit);
+ SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit,
DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
}
// Clear the sign bit of the first operand.
- SDValue Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT),
+ SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT),
DAG.getConstant(LSize - 1,
TLI.getShiftAmountTy()));
- Mask = DAG.getNode(ISD::SUB, LVT, Mask, DAG.getConstant(1, LVT));
- LHS = DAG.getNode(ISD::AND, LVT, LHS, Mask);
+ Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT));
+ LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask);
// Or the value with the sign bit.
- return DAG.getNode(ISD::OR, LVT, LHS, SignBit);
+ return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit);
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) {
@@ -193,7 +194,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) {
RTLIB::COS_F64,
RTLIB::COS_F80,
RTLIB::COS_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) {
@@ -205,7 +206,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) {
RTLIB::DIV_F64,
RTLIB::DIV_F80,
RTLIB::DIV_PPCF128),
- NVT, Ops, 2, false);
+ NVT, Ops, 2, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) {
@@ -216,7 +217,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) {
RTLIB::EXP_F64,
RTLIB::EXP_F80,
RTLIB::EXP_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) {
@@ -227,7 +228,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) {
RTLIB::EXP2_F64,
RTLIB::EXP2_F80,
RTLIB::EXP2_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) {
@@ -238,7 +239,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) {
RTLIB::FLOOR_F64,
RTLIB::FLOOR_F80,
RTLIB::FLOOR_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) {
@@ -249,7 +250,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) {
RTLIB::LOG_F64,
RTLIB::LOG_F80,
RTLIB::LOG_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) {
@@ -260,7 +261,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) {
RTLIB::LOG2_F64,
RTLIB::LOG2_F80,
RTLIB::LOG2_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
@@ -271,7 +272,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
RTLIB::LOG10_F64,
RTLIB::LOG10_F80,
RTLIB::LOG10_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
@@ -283,7 +284,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
RTLIB::MUL_F64,
RTLIB::MUL_F80,
RTLIB::MUL_PPCF128),
- NVT, Ops, 2, false);
+ NVT, Ops, 2, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
@@ -294,7 +295,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
RTLIB::NEARBYINT_F64,
RTLIB::NEARBYINT_F80,
RTLIB::NEARBYINT_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
@@ -307,7 +308,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
RTLIB::SUB_F64,
RTLIB::SUB_F80,
RTLIB::SUB_PPCF128),
- NVT, Ops, 2, false);
+ NVT, Ops, 2, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
@@ -315,7 +316,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
SDValue Op = N->getOperand(0);
RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0));
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
- return MakeLibCall(LC, NVT, &Op, 1, false);
+ return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
@@ -323,7 +324,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
SDValue Op = N->getOperand(0);
RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0));
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!");
- return MakeLibCall(LC, NVT, &Op, 1, false);
+ return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
@@ -335,7 +336,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
RTLIB::POW_F64,
RTLIB::POW_F80,
RTLIB::POW_PPCF128),
- NVT, Ops, 2, false);
+ NVT, Ops, 2, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
@@ -348,7 +349,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
RTLIB::POWI_F64,
RTLIB::POWI_F80,
RTLIB::POWI_PPCF128),
- NVT, Ops, 2, false);
+ NVT, Ops, 2, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) {
@@ -359,7 +360,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) {
RTLIB::RINT_F64,
RTLIB::RINT_F80,
RTLIB::RINT_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) {
@@ -370,7 +371,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) {
RTLIB::SIN_F64,
RTLIB::SIN_F80,
RTLIB::SIN_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) {
@@ -381,7 +382,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) {
RTLIB::SQRT_F64,
RTLIB::SQRT_F80,
RTLIB::SQRT_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
@@ -393,7 +394,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
RTLIB::SUB_F64,
RTLIB::SUB_F80,
RTLIB::SUB_PPCF128),
- NVT, Ops, 2, false);
+ NVT, Ops, 2, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
@@ -404,17 +405,18 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
RTLIB::TRUNC_F64,
RTLIB::TRUNC_F80,
RTLIB::TRUNC_PPCF128),
- NVT, &Op, 1, false);
+ NVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
LoadSDNode *L = cast<LoadSDNode>(N);
MVT VT = N->getValueType(0);
MVT NVT = TLI.getTypeToTransformTo(VT);
+ DebugLoc dl = N->getDebugLoc();
SDValue NewL;
if (L->getExtensionType() == ISD::NON_EXTLOAD) {
- NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(),
+ NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(),
NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
L->getSrcValue(), L->getSrcValueOffset(), NVT,
L->isVolatile(), L->getAlignment());
@@ -425,7 +427,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
}
// Do a non-extending load followed by FP_EXTEND.
- NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD,
+ NewL = DAG.getLoad(L->getAddressingMode(), dl, ISD::NON_EXTLOAD,
L->getMemoryVT(), L->getChain(),
L->getBasePtr(), L->getOffset(),
L->getSrcValue(), L->getSrcValueOffset(),
@@ -434,19 +436,21 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
- return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NewL));
+ return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL));
}
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
SDValue LHS = GetSoftenedFloat(N->getOperand(1));
SDValue RHS = GetSoftenedFloat(N->getOperand(2));
- return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
+ return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
+ LHS.getValueType(), N->getOperand(0),LHS,RHS);
}
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
SDValue LHS = GetSoftenedFloat(N->getOperand(2));
SDValue RHS = GetSoftenedFloat(N->getOperand(3));
- return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
+ return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
+ LHS.getValueType(), N->getOperand(0),
N->getOperand(1), LHS, RHS, N->getOperand(4));
}
@@ -455,6 +459,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
MVT SVT = N->getOperand(0).getValueType();
MVT RVT = N->getValueType(0);
MVT NVT = MVT();
+ DebugLoc dl = N->getDebugLoc();
// If the input is not legal, eg: i1 -> fp, then it needs to be promoted to
// a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly
@@ -470,9 +475,9 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
// Sign/zero extend the argument if the libcall takes a larger type.
- SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+ SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
NVT, N->getOperand(0));
- return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false);
+ return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false, dl);
}
@@ -522,7 +527,7 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
/// SoftenSetCCOperands - Soften the operands of a comparison. This code is
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
- ISD::CondCode &CCCode) {
+ ISD::CondCode &CCCode, DebugLoc dl) {
SDValue LHSInt = GetSoftenedFloat(NewLHS);
SDValue RHSInt = GetSoftenedFloat(NewRHS);
MVT VT = NewLHS.getValueType();
@@ -590,22 +595,22 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
MVT RetVT = MVT::i32; // FIXME: is this the correct return type?
SDValue Ops[2] = { LHSInt, RHSInt };
- NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/);
+ NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/, dl);
NewRHS = DAG.getConstant(0, RetVT);
CCCode = TLI.getCmpLibcallCC(LC1);
if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
- SDValue Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT),
+ SDValue Tmp = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT),
NewLHS, NewRHS, DAG.getCondCode(CCCode));
- NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/);
- NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), NewLHS,
+ NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl);
+ NewLHS = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS,
NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
- NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS);
+ NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS);
NewRHS = SDValue();
}
}
SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) {
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0),
GetSoftenedFloat(N->getOperand(0)));
}
@@ -617,13 +622,13 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
SDValue Op = GetSoftenedFloat(N->getOperand(0));
- return MakeLibCall(LC, RVT, &Op, 1, false);
+ return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
- SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
+ SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If SoftenSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -643,7 +648,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) {
RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
SDValue Op = GetSoftenedFloat(N->getOperand(0));
- return MakeLibCall(LC, RVT, &Op, 1, false);
+ return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
@@ -651,13 +656,13 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
SDValue Op = GetSoftenedFloat(N->getOperand(0));
- return MakeLibCall(LC, RVT, &Op, 1, false);
+ return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
- SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
+ SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If SoftenSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -675,7 +680,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
- SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
+ SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If SoftenSetCCOperands returned a scalar, use it.
if (NewRHS.getNode() == 0) {
@@ -694,15 +699,16 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
assert(OpNo == 1 && "Can only soften the stored value!");
StoreSDNode *ST = cast<StoreSDNode>(N);
SDValue Val = ST->getValue();
+ DebugLoc dl = N->getDebugLoc();
if (ST->isTruncatingStore())
// Do an FP_ROUND followed by a non-truncating store.
- Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, ST->getMemoryVT(),
+ Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(),
Val, DAG.getIntPtrConstant(0)));
else
Val = GetSoftenedFloat(Val);
- return DAG.getStore(ST->getChain(), Val, ST->getBasePtr(),
+ return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(),
ST->getSrcValue(), ST->getSrcValueOffset(),
ST->isVolatile(), ST->getAlignment());
}
@@ -794,12 +800,13 @@ void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
SDValue &Hi) {
assert(N->getValueType(0) == MVT::ppcf128 &&
"Logic only correct for ppcf128!");
+ DebugLoc dl = N->getDebugLoc();
SDValue Tmp;
GetExpandedFloat(N->getOperand(0), Lo, Tmp);
- Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp);
+ Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp);
// Lo = Hi==fabs(Hi) ? Lo : -Lo;
- Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo,
- DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo),
+ Lo = DAG.getNode(ISD::SELECT_CC, dl, Lo.getValueType(), Tmp, Hi, Lo,
+ DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo),
DAG.getCondCode(ISD::SETEQ));
}
@@ -844,7 +851,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo,
RTLIB::DIV_F64,
RTLIB::DIV_F80,
RTLIB::DIV_PPCF128),
- N->getValueType(0), Ops, 2, false);
+ N->getValueType(0), Ops, 2, false,
+ N->getDebugLoc());
assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
"Call lowered wrongly!");
Lo = Call.getOperand(0); Hi = Call.getOperand(1);
@@ -924,7 +932,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
RTLIB::MUL_F64,
RTLIB::MUL_F80,
RTLIB::MUL_PPCF128),
- N->getValueType(0), Ops, 2, false);
+ N->getValueType(0), Ops, 2, false,
+ N->getDebugLoc());
assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
"Call lowered wrongly!");
Lo = Call.getOperand(0); Hi = Call.getOperand(1);
@@ -945,15 +954,16 @@ void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N,
void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo,
SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
GetExpandedFloat(N->getOperand(0), Lo, Hi);
- Lo = DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo);
- Hi = DAG.getNode(ISD::FNEG, Hi.getValueType(), Hi);
+ Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo);
+ Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi);
}
void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
SDValue &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- Hi = DAG.getNode(ISD::FP_EXTEND, NVT, N->getOperand(0));
+ Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0));
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
}
@@ -1020,7 +1030,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo,
RTLIB::SUB_F64,
RTLIB::SUB_F80,
RTLIB::SUB_PPCF128),
- N->getValueType(0), Ops, 2, false);
+ N->getValueType(0), Ops, 2, false,
+ N->getDebugLoc());
assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
"Call lowered wrongly!");
Lo = Call.getOperand(0); Hi = Call.getOperand(1);
@@ -1048,12 +1059,13 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
LoadSDNode *LD = cast<LoadSDNode>(N);
SDValue Chain = LD->getChain();
SDValue Ptr = LD->getBasePtr();
+ DebugLoc dl = N->getDebugLoc();
MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0));
assert(NVT.isByteSized() && "Expanded type not byte sized!");
assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?");
- Hi = DAG.getExtLoad(LD->getExtensionType(), NVT, Chain, Ptr,
+ Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr,
LD->getSrcValue(), LD->getSrcValueOffset(),
LD->getMemoryVT(),
LD->isVolatile(), LD->getAlignment());
@@ -1077,20 +1089,21 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
SDValue Src = N->getOperand(0);
MVT SrcVT = Src.getValueType();
bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
+ DebugLoc dl = N->getDebugLoc();
// First do an SINT_TO_FP, whether the original was signed or unsigned.
// When promoting partial word types to i32 we must honor the signedness,
// though.
if (SrcVT.bitsLE(MVT::i32)) {
// The integer can be represented exactly in an f64.
- Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+ Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
MVT::i32, Src);
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
- Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src);
+ Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src);
} else {
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (SrcVT.bitsLE(MVT::i64)) {
- Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+ Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
MVT::i64, Src);
LC = RTLIB::SINTTOFP_I64_PPCF128;
} else if (SrcVT.bitsLE(MVT::i128)) {
@@ -1099,7 +1112,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
}
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
- Hi = MakeLibCall(LC, VT, &Src, 1, true);
+ Hi = MakeLibCall(LC, VT, &Src, 1, true, dl);
assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR &&
"Call lowered wrongly!");
Lo = Hi.getOperand(0); Hi = Hi.getOperand(1);
@@ -1109,7 +1122,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
return;
// Unsigned - fix up the SINT_TO_FP value just calculated.
- Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
+ Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi);
SrcVT = Src.getValueType();
// x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
@@ -1132,13 +1145,13 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
break;
}
- Lo = DAG.getNode(ISD::FADD, VT, Hi,
+ Lo = DAG.getNode(ISD::FADD, dl, VT, Hi,
DAG.getConstantFP(APFloat(APInt(128, 2, Parts)),
MVT::ppcf128));
- Lo = DAG.getNode(ISD::SELECT_CC, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi,
- DAG.getCondCode(ISD::SETLT));
- Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(1));
- Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(0));
+ Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT),
+ Lo, Hi, DAG.getCondCode(ISD::SETLT));
+ Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(1));
+ Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(0));
}
@@ -1202,7 +1215,8 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
SDValue &NewRHS,
- ISD::CondCode &CCCode) {
+ ISD::CondCode &CCCode,
+ DebugLoc dl) {
SDValue LHSLo, LHSHi, RHSLo, RHSHi;
GetExpandedFloat(NewLHS, LHSLo, LHSHi);
GetExpandedFloat(NewRHS, RHSLo, RHSHi);
@@ -1216,24 +1230,24 @@ void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
// FCMPU crN, lo1, lo2
// The following can be improved, but not that much.
SDValue Tmp1, Tmp2, Tmp3;
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, ISD::SETOEQ);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+ Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
LHSLo, RHSLo, CCCode);
- Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, ISD::SETUNE);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, CCCode);
- Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
- NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
+ Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
+ NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3);
NewRHS = SDValue(); // LHS is the result, not a compare.
}
SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
- FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+ FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If ExpandSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -1254,30 +1268,34 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
SDValue Lo, Hi;
GetExpandedFloat(N->getOperand(0), Lo, Hi);
// Round it the rest of the way (e.g. to f32) if needed.
- return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1));
+ return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(),
+ N->getValueType(0), Hi, N->getOperand(1));
}
SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) {
MVT RVT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
// Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
// PPC (the libcall is not available). FIXME: Do this in a less hacky way.
if (RVT == MVT::i32) {
assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
"Logic only correct for ppcf128!");
- SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128,
+ SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128,
N->getOperand(0), DAG.getValueType(MVT::f64));
- Res = DAG.getNode(ISD::FP_ROUND, MVT::f64, Res, DAG.getIntPtrConstant(1));
- return DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Res);
+ Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res,
+ DAG.getIntPtrConstant(1));
+ return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
}
RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
- return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false);
+ return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false, dl);
}
SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
MVT RVT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
// Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
// PPC (the libcall is not available). FIXME: Do this in a less hacky way.
@@ -1289,27 +1307,28 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128);
// X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
// FIXME: generated code sucks.
- return DAG.getNode(ISD::SELECT_CC, MVT::i32, N->getOperand(0), Tmp,
- DAG.getNode(ISD::ADD, MVT::i32,
- DAG.getNode(ISD::FP_TO_SINT, MVT::i32,
- DAG.getNode(ISD::FSUB,
+ return DAG.getNode(ISD::SELECT_CC, dl, MVT::i32, N->getOperand(0), Tmp,
+ DAG.getNode(ISD::ADD, dl, MVT::i32,
+ DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32,
+ DAG.getNode(ISD::FSUB, dl,
MVT::ppcf128,
N->getOperand(0),
Tmp)),
DAG.getConstant(0x80000000, MVT::i32)),
- DAG.getNode(ISD::FP_TO_SINT, MVT::i32, N->getOperand(0)),
+ DAG.getNode(ISD::FP_TO_SINT, dl,
+ MVT::i32, N->getOperand(0)),
DAG.getCondCode(ISD::SETGE));
}
RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
- return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false);
+ return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false, dl);
}
SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
- FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+ FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If ExpandSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -1327,7 +1346,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
- FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+ FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If ExpandSetCCOperands returned a scalar, use it.
if (NewRHS.getNode() == 0) {
@@ -1359,7 +1378,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
SDValue Lo, Hi;
GetExpandedOp(ST->getValue(), Lo, Hi);
- return DAG.getTruncStore(Chain, Hi, Ptr,
+ return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr,
ST->getSrcValue(), ST->getSrcValueOffset(),
ST->getMemoryVT(),
ST->isVolatile(), ST->getAlignment());
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index b5b249a2254b..f502a947ce7b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -19,6 +19,7 @@
//===----------------------------------------------------------------------===//
#include "LegalizeTypes.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -123,18 +124,21 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
// Sign-extend the new bits, and continue the assertion.
SDValue Op = SExtPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::AssertSext, Op.getValueType(), Op, N->getOperand(1));
+ return DAG.getNode(ISD::AssertSext, N->getDebugLoc(),
+ Op.getValueType(), Op, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
// Zero the new bits, and continue the assertion.
SDValue Op = ZExtPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::AssertZext, Op.getValueType(), Op, N->getOperand(1));
+ return DAG.getNode(ISD::AssertZext, N->getDebugLoc(),
+ Op.getValueType(), Op, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
SDValue Op2 = GetPromotedInteger(N->getOperand(2));
- SDValue Res = DAG.getAtomic(N->getOpcode(), N->getMemoryVT(),
+ SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
+ N->getMemoryVT(),
N->getChain(), N->getBasePtr(),
Op2, N->getSrcValue(), N->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
@@ -161,6 +165,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
MVT NInVT = TLI.getTypeToTransformTo(InVT);
MVT OutVT = N->getValueType(0);
MVT NOutVT = TLI.getTypeToTransformTo(OutVT);
+ DebugLoc dl = N->getDebugLoc();
switch (getTypeAction(InVT)) {
default:
@@ -171,17 +176,18 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
case PromoteInteger:
if (NOutVT.bitsEq(NInVT))
// The input promotes to the same size. Convert the promoted value.
- return DAG.getNode(ISD::BIT_CONVERT, NOutVT, GetPromotedInteger(InOp));
+ return DAG.getNode(ISD::BIT_CONVERT, dl,
+ NOutVT, GetPromotedInteger(InOp));
break;
case SoftenFloat:
// Promote the integer operand by hand.
- return DAG.getNode(ISD::ANY_EXTEND, NOutVT, GetSoftenedFloat(InOp));
+ return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp));
case ExpandInteger:
case ExpandFloat:
break;
case ScalarizeVector:
// Convert the element to an integer and promote it by hand.
- return DAG.getNode(ISD::ANY_EXTEND, NOutVT,
+ return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
BitConvertToInteger(GetScalarizedVector(InOp)));
case SplitVector: {
// For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split
@@ -194,43 +200,46 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
if (TLI.isBigEndian())
std::swap(Lo, Hi);
- InOp = DAG.getNode(ISD::ANY_EXTEND,
+ InOp = DAG.getNode(ISD::ANY_EXTEND, dl,
MVT::getIntegerVT(NOutVT.getSizeInBits()),
JoinIntegers(Lo, Hi));
- return DAG.getNode(ISD::BIT_CONVERT, NOutVT, InOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, InOp);
}
case WidenVector:
if (OutVT.bitsEq(NInVT))
// The input is widened to the same size. Convert to the widened value.
- return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetWidenedVector(InOp));
+ return DAG.getNode(ISD::BIT_CONVERT, dl, OutVT, GetWidenedVector(InOp));
}
// Otherwise, lower the bit-convert to a store/load from the stack.
// Create the stack frame object. Make sure it is aligned for both
// the source and destination types.
SDValue FIPtr = DAG.CreateStackTemporary(InVT, OutVT);
+ int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
+ const Value *SV = PseudoSourceValue::getFixedStack(FI);
// Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0);
// Result is an extending load from the stack slot.
- return DAG.getExtLoad(ISD::EXTLOAD, NOutVT, Store, FIPtr, NULL, 0, OutVT);
+ return DAG.getExtLoad(ISD::EXTLOAD, dl, NOutVT, Store, FIPtr, SV, 0, OutVT);
}
SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
MVT OVT = N->getValueType(0);
MVT NVT = Op.getValueType();
+ DebugLoc dl = N->getDebugLoc();
unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
- return DAG.getNode(ISD::SRL, NVT, DAG.getNode(ISD::BSWAP, NVT, Op),
- DAG.getConstant(DiffBits, TLI.getShiftAmountTy()));
+ return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op),
+ DAG.getConstant(DiffBits, TLI.getPointerTy()));
}
SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
// The pair element type may be legal, or may not promote to the same type as
// the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases.
- return DAG.getNode(ISD::ANY_EXTEND,
+ return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(),
TLI.getTypeToTransformTo(N->getValueType(0)),
JoinIntegers(N->getOperand(0), N->getOperand(1)));
}
@@ -265,7 +274,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
MVT NVT = Op.getValueType();
Op = DAG.getNode(ISD::CTLZ, NVT, Op);
// Subtract off the extra leading bits in the bigger type.
- return DAG.getNode(ISD::SUB, NVT, Op,
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), NVT, Op,
DAG.getConstant(NVT.getSizeInBits() -
OVT.getSizeInBits(), NVT));
}
@@ -273,26 +282,30 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
// Zero extend to the promoted type and do the count there.
SDValue Op = ZExtPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::CTPOP, Op.getValueType(), Op);
+ return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), Op.getValueType(), Op);
}
SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
MVT OVT = N->getValueType(0);
MVT NVT = Op.getValueType();
+ DebugLoc dl = N->getDebugLoc();
// The count is the same in the promoted type except if the original
// value was zero. This can be handled by setting the bit just off
// the top of the original type.
APInt TopBit(NVT.getSizeInBits(), 0);
TopBit.set(OVT.getSizeInBits());
- Op = DAG.getNode(ISD::OR, NVT, Op, DAG.getConstant(TopBit, NVT));
- return DAG.getNode(ISD::CTTZ, NVT, Op);
+ Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
+ return DAG.getNode(ISD::CTTZ, dl, NVT, Op);
}
SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
MVT OldVT = N->getValueType(0);
SDValue OldVec = N->getOperand(0);
+ if (getTypeAction(OldVec.getValueType()) == WidenVector)
+ OldVec = GetWidenedVector(N->getOperand(0));
unsigned OldElts = OldVec.getValueType().getVectorNumElements();
+ DebugLoc dl = N->getDebugLoc();
if (OldElts == 1) {
assert(!isTypeLegal(OldVec.getValueType()) &&
@@ -300,7 +313,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
// It is tempting to follow GetScalarizedVector by a call to
// GetPromotedInteger, but this would be wrong because the
// scalarized value may not yet have been processed.
- return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT),
+ return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT),
GetScalarizedVector(OldVec));
}
@@ -310,34 +323,35 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
assert(OldVT.isSimple() && NewVT.isSimple());
- SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT,
+ SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::getVectorVT(NewVT, OldElts / 2),
OldVec);
// Extract the element at OldIdx / 2 from the new vector.
SDValue OldIdx = N->getOperand(1);
- SDValue NewIdx = DAG.getNode(ISD::SRL, OldIdx.getValueType(), OldIdx,
- DAG.getConstant(1, TLI.getShiftAmountTy()));
- SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, NewIdx);
+ SDValue NewIdx = DAG.getNode(ISD::SRL, dl, OldIdx.getValueType(), OldIdx,
+ DAG.getConstant(1, TLI.getPointerTy()));
+ SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, NewIdx);
// Select the appropriate half of the element: Lo if OldIdx was even,
// Hi if it was odd.
SDValue Lo = Elt;
- SDValue Hi = DAG.getNode(ISD::SRL, NewVT, Elt,
+ SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt,
DAG.getConstant(OldVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
+ TLI.getPointerTy()));
if (TLI.isBigEndian())
std::swap(Lo, Hi);
// Extend to the promoted type.
- SDValue Odd = DAG.getNode(ISD::TRUNCATE, MVT::i1, OldIdx);
- SDValue Res = DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
- return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT), Res);
+ SDValue Odd = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, OldIdx);
+ SDValue Res = DAG.getNode(ISD::SELECT, dl, NewVT, Odd, Hi, Lo);
+ return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), Res);
}
SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
unsigned NewOpc = N->getOpcode();
+ DebugLoc dl = N->getDebugLoc();
// If we're promoting a UINT to a larger size, check to see if the new node
// will be legal. If it isn't, check to see if FP_TO_SINT is legal, since
@@ -345,22 +359,23 @@ SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
// FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
// legal, such as PowerPC.
if (N->getOpcode() == ISD::FP_TO_UINT &&
- !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
- TLI.isOperationLegal(ISD::FP_TO_SINT, NVT))
+ !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) &&
+ TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
NewOpc = ISD::FP_TO_SINT;
- SDValue Res = DAG.getNode(NewOpc, NVT, N->getOperand(0));
+ SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0));
// Assert that the converted value fits in the original type. If it doesn't
// (eg: because the value being converted is too big), then the result of the
// original operation was undefined anyway, so the assert is still correct.
return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ?
- ISD::AssertZext : ISD::AssertSext,
+ ISD::AssertZext : ISD::AssertSext, dl,
NVT, Res, DAG.getValueType(N->getValueType(0)));
}
SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ DebugLoc dl = N->getDebugLoc();
if (getTypeAction(N->getOperand(0).getValueType()) == PromoteInteger) {
SDValue Res = GetPromotedInteger(N->getOperand(0));
@@ -371,7 +386,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
if (NVT == Res.getValueType()) {
// The high bits are not guaranteed to be anything. Insert an extend.
if (N->getOpcode() == ISD::SIGN_EXTEND)
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
DAG.getValueType(N->getOperand(0).getValueType()));
if (N->getOpcode() == ISD::ZERO_EXTEND)
return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
@@ -381,7 +396,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
}
// Otherwise, just extend the original operand all the way to the larger type.
- return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
+ return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
}
SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
@@ -389,7 +404,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
ISD::LoadExtType ExtType =
ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
- SDValue Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(),
+ DebugLoc dl = N->getDebugLoc();
+ SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT(), N->isVolatile(),
N->getAlignment());
@@ -406,7 +422,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
MVT ValueVTs[] = { N->getValueType(0), NVT };
SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
- SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2);
+ SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(),
+ DAG.getVTList(ValueVTs, 2), Ops, 2);
// Modified the sum result - switch anything that used the old sum to use
// the new one.
@@ -425,17 +442,18 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
SDValue RHS = SExtPromotedInteger(N->getOperand(1));
MVT OVT = N->getOperand(0).getValueType();
MVT NVT = LHS.getValueType();
+ DebugLoc dl = N->getDebugLoc();
// Do the arithmetic in the larger type.
unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB;
- SDValue Res = DAG.getNode(Opcode, NVT, LHS, RHS);
+ SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
// Calculate the overflow flag: sign extend the arithmetic result from
// the original type.
- SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
+ SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
DAG.getValueType(OVT));
// Overflowed if and only if this is not equal to Res.
- Ofl = DAG.getSetCC(N->getValueType(1), Ofl, Res, ISD::SETNE);
+ Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
// Use the calculated overflow everywhere.
ReplaceValueWith(SDValue(N, 1), Ofl);
@@ -447,45 +465,50 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
// Sign extend the input.
SDValue LHS = SExtPromotedInteger(N->getOperand(0));
SDValue RHS = SExtPromotedInteger(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
+ LHS.getValueType(), LHS, RHS);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) {
SDValue LHS = GetPromotedInteger(N->getOperand(1));
SDValue RHS = GetPromotedInteger(N->getOperand(2));
- return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
+ return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
+ LHS.getValueType(), N->getOperand(0),LHS,RHS);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
SDValue LHS = GetPromotedInteger(N->getOperand(2));
SDValue RHS = GetPromotedInteger(N->getOperand(3));
- return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
+ return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
+ LHS.getValueType(), N->getOperand(0),
N->getOperand(1), LHS, RHS, N->getOperand(4));
}
SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
MVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType());
assert(isTypeLegal(SVT) && "Illegal SetCC type!");
+ DebugLoc dl = N->getDebugLoc();
// Get the SETCC result using the canonical SETCC type.
- SDValue SetCC = DAG.getNode(ISD::SETCC, SVT, N->getOperand(0),
+ SDValue SetCC = DAG.getNode(ISD::SETCC, dl, SVT, N->getOperand(0),
N->getOperand(1), N->getOperand(2));
// Convert to the expected type.
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
assert(NVT.bitsLE(SVT) && "Integer type overpromoted?");
- return DAG.getNode(ISD::TRUNCATE, NVT, SetCC);
+ return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
- return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)),
+ return DAG.getNode(ISD::SHL, N->getDebugLoc(),
+ TLI.getTypeToTransformTo(N->getValueType(0)),
GetPromotedInteger(N->getOperand(0)), N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), Op,
- N->getOperand(1));
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(),
+ Op.getValueType(), Op, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
@@ -494,13 +517,15 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
// that too is okay if they are integer operations.
SDValue LHS = GetPromotedInteger(N->getOperand(0));
SDValue RHS = GetPromotedInteger(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
+ LHS.getValueType(), LHS, RHS);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
// The input value must be properly sign extended.
SDValue Res = SExtPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::SRA, Res.getValueType(), Res, N->getOperand(1));
+ return DAG.getNode(ISD::SRA, N->getDebugLoc(),
+ Res.getValueType(), Res, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
@@ -508,7 +533,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
MVT VT = N->getValueType(0);
MVT NVT = TLI.getTypeToTransformTo(VT);
SDValue Res = ZExtPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1));
+ return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
@@ -527,7 +552,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
}
// Truncate to NVT instead of VT
- return DAG.getNode(ISD::TRUNCATE, NVT, Res);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), NVT, Res);
}
SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
@@ -540,16 +565,17 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
MVT OVT = N->getOperand(0).getValueType();
MVT NVT = LHS.getValueType();
+ DebugLoc dl = N->getDebugLoc();
// Do the arithmetic in the larger type.
unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB;
- SDValue Res = DAG.getNode(Opcode, NVT, LHS, RHS);
+ SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
// Calculate the overflow flag: zero extend the arithmetic result from
// the original type.
SDValue Ofl = DAG.getZeroExtendInReg(Res, OVT);
// Overflowed if and only if this is not equal to Res.
- Ofl = DAG.getSetCC(N->getValueType(1), Ofl, Res, ISD::SETNE);
+ Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
// Use the calculated overflow everywhere.
ReplaceValueWith(SDValue(N, 1), Ofl);
@@ -561,17 +587,20 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
// Zero extend the input.
SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
+ LHS.getValueType(), LHS, RHS);
}
SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
- return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0)));
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
+ TLI.getTypeToTransformTo(N->getValueType(0)));
}
SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
SDValue Chain = N->getOperand(0); // Get the chain.
SDValue Ptr = N->getOperand(1); // Get the pointer.
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
MVT RegVT = TLI.getRegisterType(VT);
unsigned NumRegs = TLI.getNumRegisters(VT);
@@ -589,14 +618,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
// Assemble the parts in the promoted type.
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, NVT, Parts[0]);
+ SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]);
for (unsigned i = 1; i < NumRegs; ++i) {
- SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, NVT, Parts[i]);
+ SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]);
// Shift it to the right position and "or" it in.
- Part = DAG.getNode(ISD::SHL, NVT, Part,
+ Part = DAG.getNode(ISD::SHL, dl, NVT, Part,
DAG.getConstant(i * RegVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
- Res = DAG.getNode(ISD::OR, NVT, Res, Part);
+ TLI.getPointerTy()));
+ Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part);
}
// Modified the chain result - switch anything that used the old chain to
@@ -655,6 +684,12 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break;
case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
+
+ case ISD::SHL:
+ case ISD::SRA:
+ case ISD::SRL:
+ case ISD::ROTL:
+ case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
}
// If the result is null, the sub-method took care of registering results etc.
@@ -705,7 +740,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+ return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op);
}
SDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
@@ -739,11 +774,11 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
SDValue Lo = ZExtPromotedInteger(N->getOperand(0));
SDValue Hi = GetPromotedInteger(N->getOperand(1));
assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
+ DebugLoc dl = N->getDebugLoc();
- Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi,
- DAG.getConstant(OVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
- return DAG.getNode(ISD::OR, N->getValueType(0), Lo, Hi);
+ Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi,
+ DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy()));
+ return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi);
}
SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
@@ -753,6 +788,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
MVT VecVT = N->getValueType(0);
unsigned NumElts = VecVT.getVectorNumElements();
assert(!(NumElts & 1) && "Legal vector of one illegal element?");
+ DebugLoc dl = N->getDebugLoc();
// Build a vector of half the length out of elements of twice the bitwidth.
// For example <4 x i16> -> <2 x i32>.
@@ -772,12 +808,12 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
NewElts.push_back(JoinIntegers(Lo, Hi));
}
- SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+ SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
MVT::getVectorVT(NewVT, NewElts.size()),
&NewElts[0], NewElts.size());
// Convert the new vector to the old vector type.
- return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec);
}
SDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) {
@@ -860,10 +896,16 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
return DAG.UpdateNodeOperands(SDValue(N, 0), LHS, RHS, N->getOperand(2));
}
+SDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) {
+ return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
+ ZExtPromotedInteger(N->getOperand(1)));
+}
+
SDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
- Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(),
+ DebugLoc dl = N->getDebugLoc();
+ Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(),
Op, DAG.getValueType(N->getOperand(0).getValueType()));
}
@@ -878,18 +920,19 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ DebugLoc dl = N->getDebugLoc();
SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value.
// Truncate the value and store the result.
- return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(),
+ return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getSrcValue(),
SVOffset, N->getMemoryVT(),
isVolatile, Alignment);
}
SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), Op);
}
SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
@@ -899,7 +942,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
- Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+ Op = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op);
return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
}
@@ -989,6 +1032,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
/// and the shift amount is a constant 'Amt'. Expand the operation.
void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
// Expand the incoming operand to be shifted, so that we have its parts
SDValue InL, InH;
GetExpandedInteger(N->getOperand(0), InL, InH);
@@ -1003,24 +1047,26 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
Lo = Hi = DAG.getConstant(0, NVT);
} else if (Amt > NVTBits) {
Lo = DAG.getConstant(0, NVT);
- Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy));
+ Hi = DAG.getNode(ISD::SHL, dl,
+ NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy));
} else if (Amt == NVTBits) {
Lo = DAG.getConstant(0, NVT);
Hi = InL;
} else if (Amt == 1 &&
- TLI.isOperationLegal(ISD::ADDC, TLI.getTypeToExpandTo(NVT))) {
+ TLI.isOperationLegalOrCustom(ISD::ADDC,
+ TLI.getTypeToExpandTo(NVT))) {
// Emit this X << 1 as X+X.
SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
SDValue LoOps[2] = { InL, InL };
- Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
- Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
} else {
- Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy));
- Hi = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SHL, NVT, InH,
+ Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Amt, ShTy));
+ Hi = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SHL, dl, NVT, InH,
DAG.getConstant(Amt, ShTy)),
- DAG.getNode(ISD::SRL, NVT, InL,
+ DAG.getNode(ISD::SRL, dl, NVT, InL,
DAG.getConstant(NVTBits-Amt, ShTy)));
}
return;
@@ -1031,42 +1077,43 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
Lo = DAG.getConstant(0, NVT);
Hi = DAG.getConstant(0, NVT);
} else if (Amt > NVTBits) {
- Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
+ Lo = DAG.getNode(ISD::SRL, dl,
+ NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
Hi = DAG.getConstant(0, NVT);
} else if (Amt == NVTBits) {
Lo = InH;
Hi = DAG.getConstant(0, NVT);
} else {
- Lo = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SRL, NVT, InL,
+ Lo = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SRL, dl, NVT, InL,
DAG.getConstant(Amt, ShTy)),
- DAG.getNode(ISD::SHL, NVT, InH,
+ DAG.getNode(ISD::SHL, dl, NVT, InH,
DAG.getConstant(NVTBits-Amt, ShTy)));
- Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy));
+ Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, DAG.getConstant(Amt, ShTy));
}
return;
}
assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
if (Amt > VTBits) {
- Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH,
+ Hi = Lo = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(NVTBits-1, ShTy));
} else if (Amt > NVTBits) {
- Lo = DAG.getNode(ISD::SRA, NVT, InH,
+ Lo = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(Amt-NVTBits, ShTy));
- Hi = DAG.getNode(ISD::SRA, NVT, InH,
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(NVTBits-1, ShTy));
} else if (Amt == NVTBits) {
Lo = InH;
- Hi = DAG.getNode(ISD::SRA, NVT, InH,
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,
DAG.getConstant(NVTBits-1, ShTy));
} else {
Lo = DAG.getNode(ISD::OR, NVT,
- DAG.getNode(ISD::SRL, NVT, InL,
+ DAG.getNode(ISD::SRL, dl, NVT, InL,
DAG.getConstant(Amt, ShTy)),
- DAG.getNode(ISD::SHL, NVT, InH,
+ DAG.getNode(ISD::SHL, dl, NVT, InH,
DAG.getConstant(NVTBits-Amt, ShTy)));
- Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy));
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Amt, ShTy));
}
}
@@ -1083,6 +1130,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
unsigned NVTBits = NVT.getSizeInBits();
assert(isPowerOf2_32(NVTBits) &&
"Expanded integer type size not a power of two!");
+ DebugLoc dl = N->getDebugLoc();
APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
APInt KnownZero, KnownOne;
@@ -1100,23 +1148,23 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
// can do this as a couple of simple shifts.
if (KnownOne.intersects(HighBitMask)) {
// Mask out the high bit, which we know is set.
- Amt = DAG.getNode(ISD::AND, ShTy, Amt,
+ Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
DAG.getConstant(~HighBitMask, ShTy));
switch (N->getOpcode()) {
default: assert(0 && "Unknown shift");
case ISD::SHL:
Lo = DAG.getConstant(0, NVT); // Low part is zero.
- Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part.
+ Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
return true;
case ISD::SRL:
Hi = DAG.getConstant(0, NVT); // Hi part is zero.
- Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part.
+ Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
return true;
case ISD::SRA:
- Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part.
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part.
DAG.getConstant(NVTBits-1, ShTy));
- Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part.
+ Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
return true;
}
}
@@ -1151,6 +1199,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
// Expand the subcomponents.
SDValue LHSL, LHSH, RHSL, RHSH;
GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
@@ -1166,44 +1215,45 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
// a carry of type MVT::Flag, but there doesn't seem to be any way to
// generate a value of this type in the expanded code sequence.
bool hasCarry =
- TLI.isOperationLegal(N->getOpcode() == ISD::ADD ? ISD::ADDC : ISD::SUBC,
- TLI.getTypeToExpandTo(NVT));
+ TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
+ ISD::ADDC : ISD::SUBC,
+ TLI.getTypeToExpandTo(NVT));
if (hasCarry) {
SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
if (N->getOpcode() == ISD::ADD) {
- Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
} else {
- Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
}
} else {
if (N->getOpcode() == ISD::ADD) {
- Lo = DAG.getNode(ISD::ADD, NVT, LoOps, 2);
- Hi = DAG.getNode(ISD::ADD, NVT, HiOps, 2);
- SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo, LoOps[0],
+ Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2);
+ SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0],
ISD::SETULT);
- SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1,
+ SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1,
DAG.getConstant(1, NVT),
DAG.getConstant(0, NVT));
- SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo, LoOps[1],
+ SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1],
ISD::SETULT);
- SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2,
+ SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2,
DAG.getConstant(1, NVT), Carry1);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, Carry2);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2);
} else {
- Lo = DAG.getNode(ISD::SUB, NVT, LoOps, 2);
- Hi = DAG.getNode(ISD::SUB, NVT, HiOps, 2);
+ Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2);
+ Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2);
SDValue Cmp =
DAG.getSetCC(TLI.getSetCCResultType(LoOps[0].getValueType()),
LoOps[0], LoOps[1], ISD::SETULT);
- SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp,
+ SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp,
DAG.getConstant(1, NVT),
DAG.getConstant(0, NVT));
- Hi = DAG.getNode(ISD::SUB, NVT, Hi, Borrow);
+ Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
}
}
}
@@ -1212,6 +1262,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
SDValue &Lo, SDValue &Hi) {
// Expand the subcomponents.
SDValue LHSL, LHSH, RHSL, RHSH;
+ DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
@@ -1219,13 +1270,13 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
SDValue HiOps[3] = { LHSH, RHSH };
if (N->getOpcode() == ISD::ADDC) {
- Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
} else {
- Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+ Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+ Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
}
// Legalized the flag result - switch anything that used the old flag to
@@ -1237,15 +1288,16 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
SDValue &Lo, SDValue &Hi) {
// Expand the subcomponents.
SDValue LHSL, LHSH, RHSL, RHSH;
+ DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
SDValue HiOps[3] = { LHSH, RHSH };
- Lo = DAG.getNode(N->getOpcode(), VTList, LoOps, 3);
+ Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps, 3);
HiOps[2] = Lo.getValue(1);
- Hi = DAG.getNode(N->getOpcode(), VTList, HiOps, 3);
+ Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
// Legalized the flag result - switch anything that used the old flag to
// use the new one.
@@ -1255,11 +1307,12 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ DebugLoc dl = N->getDebugLoc();
SDValue Op = N->getOperand(0);
if (Op.getValueType().bitsLE(NVT)) {
// The low part is any extension of the input (which degenerates to a copy).
- Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op);
- Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined.
+ Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op);
+ Hi = DAG.getNode(ISD::UNDEF, dl, NVT); // The high part is undefined.
} else {
// For example, extension of an i48 to an i64. The operand type necessarily
// promotes to the result type, so will end up being expanded too.
@@ -1275,6 +1328,7 @@ void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
@@ -1282,18 +1336,19 @@ void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
unsigned EVTBits = EVT.getSizeInBits();
if (NVTBits < EVTBits) {
- Hi = DAG.getNode(ISD::AssertSext, NVT, Hi,
+ Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi,
DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits)));
} else {
- Lo = DAG.getNode(ISD::AssertSext, NVT, Lo, DAG.getValueType(EVT));
+ Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
// The high part replicates the sign bit of Lo, make it explicit.
- Hi = DAG.getNode(ISD::SRA, NVT, Lo,
- DAG.getConstant(NVTBits-1, TLI.getShiftAmountTy()));
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
+ DAG.getConstant(NVTBits-1, TLI.getPointerTy()));
}
}
void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
@@ -1301,10 +1356,10 @@ void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
unsigned EVTBits = EVT.getSizeInBits();
if (NVTBits < EVTBits) {
- Hi = DAG.getNode(ISD::AssertZext, NVT, Hi,
+ Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi,
DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits)));
} else {
- Lo = DAG.getNode(ISD::AssertZext, NVT, Lo, DAG.getValueType(EVT));
+ Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT));
// The high part must be zero, make it explicit.
Hi = DAG.getConstant(0, NVT);
}
@@ -1312,9 +1367,10 @@ void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands.
- Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo);
- Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi);
+ Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo);
+ Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
}
void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
@@ -1328,66 +1384,71 @@ void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
// ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
- SDValue HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), Hi,
+ SDValue HiNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Hi,
DAG.getConstant(0, NVT), ISD::SETNE);
- SDValue LoLZ = DAG.getNode(ISD::CTLZ, NVT, Lo);
- SDValue HiLZ = DAG.getNode(ISD::CTLZ, NVT, Hi);
+ SDValue LoLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Lo);
+ SDValue HiLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi);
- Lo = DAG.getNode(ISD::SELECT, NVT, HiNotZero, HiLZ,
- DAG.getNode(ISD::ADD, NVT, LoLZ,
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, HiNotZero, HiLZ,
+ DAG.getNode(ISD::ADD, dl, NVT, LoLZ,
DAG.getConstant(NVT.getSizeInBits(), NVT)));
Hi = DAG.getConstant(0, NVT);
}
void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
// ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
- Lo = DAG.getNode(ISD::ADD, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo),
- DAG.getNode(ISD::CTPOP, NVT, Hi));
+ Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo),
+ DAG.getNode(ISD::CTPOP, dl, NVT, Hi));
Hi = DAG.getConstant(0, NVT);
}
void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
// cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
- SDValue LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo,
+ SDValue LoNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo,
DAG.getConstant(0, NVT), ISD::SETNE);
- SDValue LoLZ = DAG.getNode(ISD::CTTZ, NVT, Lo);
- SDValue HiLZ = DAG.getNode(ISD::CTTZ, NVT, Hi);
+ SDValue LoLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo);
+ SDValue HiLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Hi);
- Lo = DAG.getNode(ISD::SELECT, NVT, LoNotZero, LoLZ,
- DAG.getNode(ISD::ADD, NVT, HiLZ,
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, LoNotZero, LoLZ,
+ DAG.getNode(ISD::ADD, dl, NVT, HiLZ,
DAG.getConstant(NVT.getSizeInBits(), NVT)));
Hi = DAG.getConstant(0, NVT);
}
void DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo,
SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
MVT VT = N->getValueType(0);
SDValue Op = N->getOperand(0);
RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!");
- SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*sign irrelevant*/), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*irrelevant*/, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo,
SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
MVT VT = N->getValueType(0);
SDValue Op = N->getOperand(0);
RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!");
- SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*sign irrelevant*/), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*irrelevant*/, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
@@ -1407,14 +1468,15 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ DebugLoc dl = N->getDebugLoc();
assert(NVT.isByteSized() && "Expanded type not byte sized!");
if (N->getMemoryVT().bitsLE(NVT)) {
MVT EVT = N->getMemoryVT();
- Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT,
- isVolatile, Alignment);
+ Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+ EVT, isVolatile, Alignment);
// Remember the chain.
Ch = Lo.getValue(1);
@@ -1423,19 +1485,19 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
// The high part is obtained by SRA'ing all but one of the bits of the
// lo part.
unsigned LoSize = Lo.getValueType().getSizeInBits();
- Hi = DAG.getNode(ISD::SRA, NVT, Lo,
- DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
+ DAG.getConstant(LoSize-1, TLI.getPointerTy()));
} else if (ExtType == ISD::ZEXTLOAD) {
// The high part is just a zero.
Hi = DAG.getConstant(0, NVT);
} else {
assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
// The high part is undefined.
- Hi = DAG.getNode(ISD::UNDEF, NVT);
+ Hi = DAG.getNode(ISD::UNDEF, dl, NVT);
}
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
- Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+ Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getSrcValue(), SVOffset,
isVolatile, Alignment);
unsigned ExcessBits =
@@ -1444,15 +1506,15 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits()/8;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
- Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
+ Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(),
SVOffset+IncrementSize, NEVT,
isVolatile, MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
- Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
} else {
// Big-endian - high bits are at low addresses. Favor aligned loads at
@@ -1463,34 +1525,35 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
unsigned ExcessBits = (EBytes - IncrementSize)*8;
// Load both the high bits and maybe some of the low bits.
- Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+ Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits),
isVolatile, Alignment);
// Increment the pointer to the other half.
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
// Load the rest of the low bits.
- Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(),
+ Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, N->getSrcValue(),
SVOffset+IncrementSize,
MVT::getIntegerVT(ExcessBits),
isVolatile, MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
- Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
if (ExcessBits < NVT.getSizeInBits()) {
// Transfer low bits from the bottom of Hi to the top of Lo.
- Lo = DAG.getNode(ISD::OR, NVT, Lo,
- DAG.getNode(ISD::SHL, NVT, Hi,
+ Lo = DAG.getNode(ISD::OR, dl, NVT, Lo,
+ DAG.getNode(ISD::SHL, dl, NVT, Hi,
DAG.getConstant(ExcessBits,
- TLI.getShiftAmountTy())));
+ TLI.getPointerTy())));
// Move high bits to the right position in Hi.
- Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi,
+ Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl,
+ NVT, Hi,
DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
- TLI.getShiftAmountTy()));
+ TLI.getPointerTy()));
}
}
@@ -1501,22 +1564,24 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
SDValue LL, LH, RL, RH;
GetExpandedInteger(N->getOperand(0), LL, LH);
GetExpandedInteger(N->getOperand(1), RL, RH);
- Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL);
- Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH);
+ Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL);
+ Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH);
}
void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT VT = N->getValueType(0);
MVT NVT = TLI.getTypeToTransformTo(VT);
+ DebugLoc dl = N->getDebugLoc();
- bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
- bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
- bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
- bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
+ bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT);
+ bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT);
+ bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT);
+ bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT);
if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
SDValue LL, LH, RL, RH;
GetExpandedInteger(N->getOperand(0), LL, LH);
@@ -1532,14 +1597,14 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
// The inputs are both zero-extended.
if (HasUMUL_LOHI) {
// We can emit a umul_lohi.
- Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
Hi = SDValue(Lo.getNode(), 1);
return;
}
if (HasMULHU) {
// We can emit a mulhu+mul.
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
- Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+ Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
return;
}
}
@@ -1547,36 +1612,36 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
// The input values are both sign-extended.
if (HasSMUL_LOHI) {
// We can emit a smul_lohi.
- Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
Hi = SDValue(Lo.getNode(), 1);
return;
}
if (HasMULHS) {
// We can emit a mulhs+mul.
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
- Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL);
+ Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL);
return;
}
}
if (HasUMUL_LOHI) {
// Lo,Hi = umul LHS, RHS.
- SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI,
+ SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl,
DAG.getVTList(NVT, NVT), LL, RL);
Lo = UMulLOHI;
Hi = UMulLOHI.getValue(1);
- RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
- LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+ RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
+ LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
return;
}
if (HasMULHU) {
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
- Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
- RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
- LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
- Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+ Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
+ RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
+ LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
+ Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
return;
}
}
@@ -1594,12 +1659,13 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!");
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
- SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*sign irrelevant*/), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*irrelevant*/, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i32)
@@ -1611,12 +1677,13 @@ void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
- SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
// If we can emit an efficient shift operation, do so now. Check to see if
// the RHS is a constant.
@@ -1651,7 +1718,7 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) };
MVT VT = LHSL.getValueType();
- Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
+ Lo = DAG.getNode(PartsOpc, dl, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
Hi = Lo.getValue(1);
return;
}
@@ -1694,20 +1761,21 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported shift!");
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
- SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ DebugLoc dl = N->getDebugLoc();
SDValue Op = N->getOperand(0);
if (Op.getValueType().bitsLE(NVT)) {
// The low part is sign extension of the input (degenerates to a copy).
- Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0));
+ Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
// The high part is obtained by SRA'ing all but one of the bits of low part.
unsigned LoSize = NVT.getSizeInBits();
- Hi = DAG.getNode(ISD::SRA, NVT, Lo,
- DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+ Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
+ DAG.getConstant(LoSize-1, TLI.getPointerTy()));
} else {
// For example, extension of an i48 to an i64. The operand type necessarily
// promotes to the result type, so will end up being expanded too.
@@ -1720,32 +1788,33 @@ void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
SplitInteger(Res, Lo, Hi);
unsigned ExcessBits =
Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
- Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
+ Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
}
}
void DAGTypeLegalizer::
ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
if (EVT.bitsLE(Lo.getValueType())) {
// sext_inreg the low part if needed.
- Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo,
+ Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
N->getOperand(1));
// The high part gets the sign extension from the lo-part. This handles
// things like sextinreg V:i64 from i8.
- Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo,
+ Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
- TLI.getShiftAmountTy()));
+ TLI.getPointerTy()));
} else {
// For example, extension of an i48 to an i64. Leave the low part alone,
// sext_inreg the high part.
unsigned ExcessBits =
EVT.getSizeInBits() - Lo.getValueType().getSizeInBits();
- Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
+ Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
}
}
@@ -1753,6 +1822,7 @@ ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i32)
@@ -1764,22 +1834,24 @@ void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
- SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- Lo = DAG.getNode(ISD::TRUNCATE, NVT, N->getOperand(0));
- Hi = DAG.getNode(ISD::SRL, N->getOperand(0).getValueType(), N->getOperand(0),
- DAG.getConstant(NVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
- Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi);
+ DebugLoc dl = N->getDebugLoc();
+ Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
+ Hi = DAG.getNode(ISD::SRL, dl,
+ N->getOperand(0).getValueType(), N->getOperand(0),
+ DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy()));
+ Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i32)
@@ -1791,12 +1863,13 @@ void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
- SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i32)
@@ -1808,16 +1881,17 @@ void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
- SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
SDValue &Lo, SDValue &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ DebugLoc dl = N->getDebugLoc();
SDValue Op = N->getOperand(0);
if (Op.getValueType().bitsLE(NVT)) {
// The low part is zero extension of the input (degenerates to a copy).
- Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0));
+ Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
Hi = DAG.getConstant(0, NVT); // The high part is just a zero.
} else {
// For example, extension of an i48 to an i64. The operand type necessarily
@@ -1860,20 +1934,24 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
assert(0 && "Do not know how to expand this operator's operand!");
abort();
- case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
+ case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
+ case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
+ case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
+ case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
+ case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
+ case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
+ case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
+ case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break;
- case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
- case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
- case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
- case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
- case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
- break;
- case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
- case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break;
+ case ISD::SHL:
+ case ISD::SRA:
+ case ISD::SRL:
+ case ISD::ROTL:
+ case ISD::ROTR: Res = ExpandIntOp_Shift(N); break;
}
// If the result is null, the sub-method took care of registering results etc.
@@ -1895,7 +1973,8 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
SDValue &NewRHS,
- ISD::CondCode &CCCode) {
+ ISD::CondCode &CCCode,
+ DebugLoc dl) {
SDValue LHSLo, LHSHi, RHSLo, RHSHi;
GetExpandedInteger(NewLHS, LHSLo, LHSHi);
GetExpandedInteger(NewRHS, RHSLo, RHSHi);
@@ -1907,16 +1986,17 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) {
if (RHSCST->isAllOnesValue()) {
// Equality comparison to -1.
- NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
+ NewLHS = DAG.getNode(ISD::AND, dl,
+ LHSLo.getValueType(), LHSLo, LHSHi);
NewRHS = RHSLo;
return;
}
}
}
- NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
- NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
- NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS);
+ NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
+ NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
+ NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
return;
}
@@ -1954,14 +2034,15 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
SDValue Tmp1, Tmp2;
Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
- LHSLo, RHSLo, LowCC, false, DagCombineInfo);
+ LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl);
if (!Tmp1.getNode())
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+ Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
LHSLo, RHSLo, LowCC);
Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
- LHSHi, RHSHi, CCCode, false, DagCombineInfo);
+ LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl);
if (!Tmp2.getNode())
- Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi.getValueType()),
+ Tmp2 = DAG.getNode(ISD::SETCC, dl,
+ TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, DAG.getCondCode(CCCode));
ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode());
@@ -1982,11 +2063,12 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
}
NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
- LHSHi, RHSHi, ISD::SETEQ, false, DagCombineInfo);
+ LHSHi, RHSHi, ISD::SETEQ, false,
+ DagCombineInfo, dl);
if (!NewLHS.getNode())
- NewLHS = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
LHSHi, RHSHi, ISD::SETEQ);
- NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
+ NewLHS = DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(),
NewLHS, Tmp1, Tmp2);
NewRHS = SDValue();
}
@@ -1994,7 +2076,7 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
- IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+ IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If ExpandSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -2012,7 +2094,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
- IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+ IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If ExpandSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -2030,7 +2112,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
- IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+ IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
// If ExpandSetCCOperands returned a scalar, use it.
if (NewRHS.getNode() == 0) {
@@ -2044,13 +2126,22 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
DAG.getCondCode(CCCode));
}
+SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
+ // The value being shifted is legal, but the shift amount is too big.
+ // It follows that either the result of the shift is undefined, or the
+ // upper half of the shift amount is zero. Just use the lower half.
+ SDValue Lo, Hi;
+ GetExpandedInteger(N->getOperand(1), Lo, Hi);
+ return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Lo);
+}
+
SDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) {
SDValue Op = N->getOperand(0);
MVT DstVT = N->getValueType(0);
RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Don't know how to expand this SINT_TO_FP!");
- return MakeLibCall(LC, DstVT, &Op, 1, true);
+ return MakeLibCall(LC, DstVT, &Op, 1, true, N->getDebugLoc());
}
SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
@@ -2067,19 +2158,20 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ DebugLoc dl = N->getDebugLoc();
SDValue Lo, Hi;
assert(NVT.isByteSized() && "Expanded type not byte sized!");
if (N->getMemoryVT().bitsLE(NVT)) {
GetExpandedInteger(N->getValue(), Lo, Hi);
- return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+ return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
N->getMemoryVT(), isVolatile, Alignment);
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
GetExpandedInteger(N->getValue(), Lo, Hi);
- Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+ Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
isVolatile, Alignment);
unsigned ExcessBits =
@@ -2088,12 +2180,12 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits()/8;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
- Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
+ Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
SVOffset+IncrementSize, NEVT,
isVolatile, MinAlign(Alignment, IncrementSize));
- return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
} else {
// Big-endian - high bits are at low addresses. Favor aligned stores at
// the cost of some bit-fiddling.
@@ -2107,28 +2199,28 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
if (ExcessBits < NVT.getSizeInBits()) {
// Transfer high bits from the top of Lo to the bottom of Hi.
- Hi = DAG.getNode(ISD::SHL, NVT, Hi,
+ Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
- TLI.getShiftAmountTy()));
- Hi = DAG.getNode(ISD::OR, NVT, Hi,
+ TLI.getPointerTy()));
+ Hi = DAG.getNode(ISD::OR, dl, NVT, Hi,
DAG.getNode(ISD::SRL, NVT, Lo,
DAG.getConstant(ExcessBits,
- TLI.getShiftAmountTy())));
+ TLI.getPointerTy())));
}
// Store both the high bits and maybe some of the low bits.
- Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
+ Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
SVOffset, HiVT, isVolatile, Alignment);
// Increment the pointer to the other half.
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
// Store the lowest ExcessBits bits in the second half.
- Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(),
+ Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(),
SVOffset+IncrementSize,
MVT::getIntegerVT(ExcessBits),
isVolatile, MinAlign(Alignment, IncrementSize));
- return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
}
@@ -2136,17 +2228,18 @@ SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
SDValue InL, InH;
GetExpandedInteger(N->getOperand(0), InL, InH);
// Just truncate the low part of the source.
- return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
+ return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL);
}
SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
SDValue Op = N->getOperand(0);
MVT SrcVT = Op.getValueType();
MVT DstVT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
if (TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
// Do a signed conversion then adjust the result.
- SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, DstVT, Op);
+ SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op);
SignedConv = TLI.LowerOperation(SignedConv, DAG);
// The result of the signed conversion needs adjusting if the 'sign bit' of
@@ -2170,7 +2263,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
// Check whether the sign bit is set.
SDValue Lo, Hi;
GetExpandedInteger(Op, Lo, Hi);
- SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi.getValueType()),
+ SDValue SignSet = DAG.getSetCC(dl,
+ TLI.getSetCCResultType(Hi.getValueType()),
Hi, DAG.getConstant(0, Hi.getValueType()),
ISD::SETLT);
@@ -2182,24 +2276,24 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
SDValue Zero = DAG.getIntPtrConstant(0);
SDValue Four = DAG.getIntPtrConstant(4);
if (TLI.isBigEndian()) std::swap(Zero, Four);
- SDValue Offset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet,
+ SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet,
Zero, Four);
unsigned Alignment =
1 << cast<ConstantPoolSDNode>(FudgePtr)->getAlignment();
- FudgePtr = DAG.getNode(ISD::ADD, TLI.getPointerTy(), FudgePtr, Offset);
+ FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset);
Alignment = std::min(Alignment, 4u);
// Load the value out, extending it from f32 to the destination float type.
// FIXME: Avoid the extend by constructing the right constant pool?
- SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, DstVT, DAG.getEntryNode(),
+ SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(),
FudgePtr, NULL, 0, MVT::f32,
false, Alignment);
- return DAG.getNode(ISD::FADD, DstVT, SignedConv, Fudge);
+ return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge);
}
// Otherwise, use a libcall.
RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Don't know how to expand this UINT_TO_FP!");
- return MakeLibCall(LC, DstVT, &Op, 1, true);
+ return MakeLibCall(LC, DstVT, &Op, 1, true, dl);
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index a4f3917b18a6..83712eec737c 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -81,7 +81,7 @@ void DAGTypeLegalizer::PerformExpensiveChecks() {
// Check that remapped values are only used by nodes marked NewNode.
for (SDNode::use_iterator UI = I->use_begin(), UE = I->use_end();
UI != UE; ++UI)
- if (UI.getUse().getSDValue().getResNo() == i)
+ if (UI.getUse().getResNo() == i)
assert(UI->getNodeId() == NewNode &&
"Remapped value has non-trivial use!");
@@ -328,14 +328,21 @@ ScanOperands:
continue;
// The node morphed - this is equivalent to legalizing by replacing every
- // value of N with the corresponding value of M. So do that now.
- N->setNodeId(ReadyToProcess);
+ // value of N with the corresponding value of M. So do that now. However
+ // there is no need to remember the replacement - morphing will make sure
+ // it is never used non-trivially.
assert(N->getNumValues() == M->getNumValues() &&
"Node morphing changed the number of results!");
for (unsigned i = 0, e = N->getNumValues(); i != e; ++i)
- // Replacing the value takes care of remapping the new value.
- ReplaceValueWith(SDValue(N, i), SDValue(M, i));
- // Fall through.
+ // Replacing the value takes care of remapping the new value. Do the
+ // replacement without recording it in ReplacedValues. This does not
+ // expunge From but that is fine - it is not really a new node.
+ ReplaceValueWithHelper(SDValue(N, i), SDValue(M, i));
+ assert(N->getNodeId() == NewNode && "Unexpected node state!");
+ // The node continues to live on as part of the NewNode fungus that
+ // grows on top of the useful nodes. Nothing more needs to be done
+ // with it - move on to the next node.
+ continue;
}
if (i == NumOperands) {
@@ -668,16 +675,14 @@ namespace {
}
-/// ReplaceValueWith - The specified value was legalized to the specified other
-/// value. Update the DAG and NodeIds replacing any uses of From to use To
-/// instead.
-void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) {
- assert(From.getNode()->getNodeId() == ReadyToProcess &&
- "Only the node being processed may be remapped!");
+/// ReplaceValueWithHelper - Internal helper for ReplaceValueWith. Updates the
+/// DAG causing any uses of From to use To instead, but without expunging From
+/// or recording the replacement in ReplacedValues. Do not call directly unless
+/// you really know what you are doing!
+void DAGTypeLegalizer::ReplaceValueWithHelper(SDValue From, SDValue To) {
assert(From.getNode() != To.getNode() && "Potential legalization loop!");
// If expansion produced new nodes, make sure they are properly marked.
- ExpungeNode(From.getNode());
AnalyzeNewValue(To); // Expunges To.
// Anything that used the old node should now use the new one. Note that this
@@ -686,10 +691,6 @@ void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) {
NodeUpdateListener NUL(*this, NodesToAnalyze);
DAG.ReplaceAllUsesOfValueWith(From, To, &NUL);
- // The old node may still be present in a map like ExpandedIntegers or
- // PromotedIntegers. Inform maps about the replacement.
- ReplacedValues[From] = To;
-
// Process the list of nodes that need to be reanalyzed.
while (!NodesToAnalyze.empty()) {
SDNode *N = NodesToAnalyze.back();
@@ -719,6 +720,25 @@ void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) {
}
}
+/// ReplaceValueWith - The specified value was legalized to the specified other
+/// value. Update the DAG and NodeIds replacing any uses of From to use To
+/// instead.
+void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) {
+ assert(From.getNode()->getNodeId() == ReadyToProcess &&
+ "Only the node being processed may be remapped!");
+
+ // If expansion produced new nodes, make sure they are properly marked.
+ ExpungeNode(From.getNode());
+ AnalyzeNewValue(To); // Expunges To.
+
+ // The old node may still be present in a map like ExpandedIntegers or
+ // PromotedIntegers. Inform maps about the replacement.
+ ReplacedValues[From] = To;
+
+ // Do the replacement.
+ ReplaceValueWithHelper(From, To);
+}
+
void DAGTypeLegalizer::SetPromotedInteger(SDValue Op, SDValue Result) {
AnalyzeNewValue(Result);
@@ -832,18 +852,20 @@ void DAGTypeLegalizer::SetIgnoredNodeResult(SDNode* N) {
/// BitConvertToInteger - Convert to an integer of the same size.
SDValue DAGTypeLegalizer::BitConvertToInteger(SDValue Op) {
unsigned BitWidth = Op.getValueType().getSizeInBits();
- return DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerVT(BitWidth), Op);
+ return DAG.getNode(ISD::BIT_CONVERT, Op.getNode()->getDebugLoc(),
+ MVT::getIntegerVT(BitWidth), Op);
}
SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op,
MVT DestVT) {
+ DebugLoc dl = Op.getNode()->getDebugLoc();
// Create the stack frame object. Make sure it is aligned for both
// 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(), Op, StackPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0);
// Result is a load from the stack slot.
- return DAG.getLoad(DestVT, Store, StackPtr, NULL, 0);
+ return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0);
}
/// CustomLowerResults - Replace the node's results with custom code provided
@@ -900,58 +922,63 @@ void DAGTypeLegalizer::GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT) {
SDValue DAGTypeLegalizer::GetVectorElementPointer(SDValue VecPtr, MVT EltVT,
SDValue Index) {
+ DebugLoc dl = Index.getNode()->getDebugLoc();
// Make sure the index type is big enough to compute in.
if (Index.getValueType().bitsGT(TLI.getPointerTy()))
- Index = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Index);
+ Index = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Index);
else
- Index = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Index);
+ Index = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Index);
// Calculate the element offset and add it to the pointer.
unsigned EltSize = EltVT.getSizeInBits() / 8; // FIXME: should be ABI size.
- Index = DAG.getNode(ISD::MUL, Index.getValueType(), Index,
+ Index = DAG.getNode(ISD::MUL, dl, Index.getValueType(), Index,
DAG.getConstant(EltSize, Index.getValueType()));
- return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr);
+ return DAG.getNode(ISD::ADD, dl, Index.getValueType(), Index, VecPtr);
}
/// JoinIntegers - Build an integer with low bits Lo and high bits Hi.
SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) {
+ // Arbitrarily use dlHi for result DebugLoc
+ DebugLoc dlHi = Hi.getNode()->getDebugLoc();
+ DebugLoc dlLo = Lo.getNode()->getDebugLoc();
MVT LVT = Lo.getValueType();
MVT HVT = Hi.getValueType();
MVT NVT = MVT::getIntegerVT(LVT.getSizeInBits() + HVT.getSizeInBits());
- Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Lo);
- Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, Hi);
- Hi = DAG.getNode(ISD::SHL, NVT, Hi, DAG.getConstant(LVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
- return DAG.getNode(ISD::OR, NVT, Lo, Hi);
+ Lo = DAG.getNode(ISD::ZERO_EXTEND, dlLo, NVT, Lo);
+ Hi = DAG.getNode(ISD::ANY_EXTEND, dlHi, NVT, Hi);
+ Hi = DAG.getNode(ISD::SHL, dlHi, NVT, Hi,
+ DAG.getConstant(LVT.getSizeInBits(), TLI.getPointerTy()));
+ return DAG.getNode(ISD::OR, dlHi, NVT, Lo, Hi);
}
/// LibCallify - Convert the node into a libcall with the same prototype.
SDValue DAGTypeLegalizer::LibCallify(RTLIB::Libcall LC, SDNode *N,
bool isSigned) {
unsigned NumOps = N->getNumOperands();
+ DebugLoc dl = N->getDebugLoc();
if (NumOps == 0) {
- return MakeLibCall(LC, N->getValueType(0), 0, 0, isSigned);
+ return MakeLibCall(LC, N->getValueType(0), 0, 0, isSigned, dl);
} else if (NumOps == 1) {
SDValue Op = N->getOperand(0);
- return MakeLibCall(LC, N->getValueType(0), &Op, 1, isSigned);
+ return MakeLibCall(LC, N->getValueType(0), &Op, 1, isSigned, dl);
} else if (NumOps == 2) {
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
- return MakeLibCall(LC, N->getValueType(0), Ops, 2, isSigned);
+ return MakeLibCall(LC, N->getValueType(0), Ops, 2, isSigned, dl);
}
SmallVector<SDValue, 8> Ops(NumOps);
for (unsigned i = 0; i < NumOps; ++i)
Ops[i] = N->getOperand(i);
- return MakeLibCall(LC, N->getValueType(0), &Ops[0], NumOps, isSigned);
+ return MakeLibCall(LC, N->getValueType(0), &Ops[0], NumOps, isSigned, dl);
}
/// MakeLibCall - Generate a libcall taking the given operands as arguments and
/// returning a result of type RetVT.
SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
const SDValue *Ops, unsigned NumOps,
- bool isSigned) {
+ bool isSigned, DebugLoc dl) {
TargetLowering::ArgListTy Args;
Args.reserve(NumOps);
@@ -969,7 +996,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
const Type *RetTy = RetVT.getTypeForMVT();
std::pair<SDValue,SDValue> CallInfo =
TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
- false, CallingConv::C, false, Callee, Args, DAG);
+ false, CallingConv::C, false, Callee, Args, DAG, dl);
return CallInfo.first;
}
@@ -977,6 +1004,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
/// of the given type. A target boolean is an integer value, not necessarily of
/// type i1, the bits of which conform to getBooleanContents.
SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, MVT VT) {
+ DebugLoc dl = Bool.getNode()->getDebugLoc();
ISD::NodeType ExtendCode;
switch (TLI.getBooleanContents()) {
default:
@@ -995,7 +1023,7 @@ SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, MVT VT) {
break;
}
}
- return DAG.getNode(ExtendCode, VT, Bool);
+ return DAG.getNode(ExtendCode, dl, VT, Bool);
}
/// SplitInteger - Return the lower LoVT bits of Op in Lo and the upper HiVT
@@ -1003,13 +1031,13 @@ SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, MVT VT) {
void DAGTypeLegalizer::SplitInteger(SDValue Op,
MVT LoVT, MVT HiVT,
SDValue &Lo, SDValue &Hi) {
+ DebugLoc dl = Op.getNode()->getDebugLoc();
assert(LoVT.getSizeInBits() + HiVT.getSizeInBits() ==
Op.getValueType().getSizeInBits() && "Invalid integer splitting!");
- Lo = DAG.getNode(ISD::TRUNCATE, LoVT, Op);
- Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op,
- DAG.getConstant(LoVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
- Hi = DAG.getNode(ISD::TRUNCATE, HiVT, Hi);
+ Lo = DAG.getNode(ISD::TRUNCATE, dl, LoVT, Op);
+ Hi = DAG.getNode(ISD::SRL, dl, Op.getValueType(), Op,
+ DAG.getConstant(LoVT.getSizeInBits(), TLI.getPointerTy()));
+ Hi = DAG.getNode(ISD::TRUNCATE, dl, HiVT, Hi);
}
/// SplitInteger - Return the lower and upper halves of Op's bits in a value
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index a2c91cb5bedb..f2d7a71f742a 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -196,9 +196,11 @@ private:
SDValue JoinIntegers(SDValue Lo, SDValue Hi);
SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned);
SDValue MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
- const SDValue *Ops, unsigned NumOps, bool isSigned);
+ const SDValue *Ops, unsigned NumOps, bool isSigned,
+ DebugLoc dl);
SDValue PromoteTargetBoolean(SDValue Bool, MVT VT);
void ReplaceValueWith(SDValue From, SDValue To);
+ void ReplaceValueWithHelper(SDValue From, SDValue To);
void SetIgnoredNodeResult(SDNode* N);
void SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi);
void SplitInteger(SDValue Op, MVT LoVT, MVT HiVT,
@@ -291,6 +293,7 @@ private:
SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo);
SDValue PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo);
SDValue PromoteIntOp_SETCC(SDNode *N, unsigned OpNo);
+ SDValue PromoteIntOp_Shift(SDNode *N);
SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N);
SDValue PromoteIntOp_SINT_TO_FP(SDNode *N);
SDValue PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo);
@@ -354,13 +357,14 @@ private:
SDValue ExpandIntOp_EXTRACT_ELEMENT(SDNode *N);
SDValue ExpandIntOp_SELECT_CC(SDNode *N);
SDValue ExpandIntOp_SETCC(SDNode *N);
+ SDValue ExpandIntOp_Shift(SDNode *N);
SDValue ExpandIntOp_SINT_TO_FP(SDNode *N);
SDValue ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
SDValue ExpandIntOp_TRUNCATE(SDNode *N);
SDValue ExpandIntOp_UINT_TO_FP(SDNode *N);
void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
- ISD::CondCode &CCCode);
+ ISD::CondCode &CCCode, DebugLoc dl);
//===--------------------------------------------------------------------===//
// Float to Integer Conversion Support: LegalizeFloatTypes.cpp
@@ -425,7 +429,7 @@ private:
SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo);
void SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
- ISD::CondCode &CCCode);
+ ISD::CondCode &CCCode, DebugLoc dl);
//===--------------------------------------------------------------------===//
// Float Expansion Support: LegalizeFloatTypes.cpp
@@ -479,7 +483,7 @@ private:
SDValue ExpandFloatOp_STORE(SDNode *N, unsigned OpNo);
void FloatExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
- ISD::CondCode &CCCode);
+ ISD::CondCode &CCCode, DebugLoc dl);
//===--------------------------------------------------------------------===//
// Scalarization Support: LegalizeVectorTypes.cpp
@@ -629,11 +633,12 @@ private:
/// isVolatile: volatile load.
/// LdWidth: width of memory that we want to load.
/// ResType: the wider result result type for the resulting vector.
+ /// dl: DebugLoc to be applied to new nodes
SDValue GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain, SDValue Chain,
SDValue BasePtr, const Value *SV,
int SVOffset, unsigned Alignment,
bool isVolatile, unsigned LdWidth,
- MVT ResType);
+ MVT ResType, DebugLoc dl);
/// Helper genWidenVectorStores - Helper function to generate a set of
/// stores to store a widen vector into non widen memory
@@ -647,11 +652,12 @@ private:
/// isVolatile: volatile lod
/// ValOp: value to store
/// StWidth: width of memory that we want to store
+ /// dl: DebugLoc to be applied to new nodes
void GenWidenVectorStores(SmallVector<SDValue, 16>& StChain, SDValue Chain,
SDValue BasePtr, const Value *SV,
int SVOffset, unsigned Alignment,
bool isVolatile, SDValue ValOp,
- unsigned StWidth);
+ unsigned StWidth, DebugLoc dl);
/// Modifies a vector input (widen or narrows) to a vector of NVT. The
/// input vector must have the same element type as NVT.
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index fb86875a5cdb..916e9c6845b7 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -36,6 +36,7 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
MVT NOutVT = TLI.getTypeToTransformTo(OutVT);
SDValue InOp = N->getOperand(0);
MVT InVT = InOp.getValueType();
+ DebugLoc dl = N->getDebugLoc();
// Handle some special cases efficiently.
switch (getTypeAction(InVT)) {
@@ -47,15 +48,15 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
case SoftenFloat:
// Convert the integer operand instead.
SplitInteger(GetSoftenedFloat(InOp), Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi);
return;
case ExpandInteger:
case ExpandFloat:
// Convert the expanded pieces of the input.
GetExpandedOp(InOp, Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi);
return;
case SplitVector:
// Convert the split parts of the input if it was split in two.
@@ -63,16 +64,16 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
if (Lo.getValueType() == Hi.getValueType()) {
if (TLI.isBigEndian())
std::swap(Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi);
return;
}
break;
case ScalarizeVector:
// Convert the element instead.
SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi);
return;
}
@@ -88,18 +89,18 @@ 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(), InOp, StackPtr, SV, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0);
// Load the first half from the stack slot.
- Lo = DAG.getLoad(NOutVT, Store, StackPtr, SV, 0);
+ Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0);
// Increment the pointer to the other half.
unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
- StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr,
+ StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
DAG.getIntPtrConstant(IncrementSize));
// Load the second half from the stack slot.
- Hi = DAG.getLoad(NOutVT, Store, StackPtr, SV, IncrementSize, false,
+ Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, IncrementSize, false,
MinAlign(Alignment, IncrementSize));
// Handle endianness of the load.
@@ -119,14 +120,15 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_ELEMENT(SDNode *N, SDValue &Lo,
GetExpandedOp(N->getOperand(0), Lo, Hi);
SDValue Part = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ?
Hi : Lo;
+ DebugLoc dl = N->getDebugLoc();
assert(Part.getValueType() == N->getValueType(0) &&
"Type twice as big as expanded type not itself expanded!");
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Part,
+ Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Part,
DAG.getConstant(0, TLI.getPointerTy()));
- Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Part,
+ Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Part,
DAG.getConstant(1, TLI.getPointerTy()));
}
@@ -134,13 +136,14 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo,
SDValue &Hi) {
SDValue OldVec = N->getOperand(0);
unsigned OldElts = OldVec.getValueType().getVectorNumElements();
+ DebugLoc dl = N->getDebugLoc();
// Convert to a vector of the expanded element type, for example
// <3 x i64> -> <6 x i32>.
MVT OldVT = N->getValueType(0);
MVT NewVT = TLI.getTypeToTransformTo(OldVT);
- SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT,
+ SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::getVectorVT(NewVT, 2*OldElts),
OldVec);
@@ -149,14 +152,14 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo,
// Make sure the type of Idx is big enough to hold the new values.
if (Idx.getValueType().bitsLT(TLI.getPointerTy()))
- Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
+ Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx);
Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
- Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
+ Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
- Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,
+ Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
DAG.getConstant(1, Idx.getValueType()));
- Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
+ Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
if (TLI.isBigEndian())
std::swap(Lo, Hi);
@@ -165,6 +168,7 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo,
void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
SDValue &Hi) {
assert(ISD::isNormalLoad(N) && "This routine only for normal loads!");
+ DebugLoc dl = N->getDebugLoc();
LoadSDNode *LD = cast<LoadSDNode>(N);
MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0));
@@ -176,19 +180,20 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
assert(NVT.isByteSized() && "Expanded type not byte sized!");
- Lo = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset,
+ Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset,
isVolatile, Alignment);
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits() / 8;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
- Hi = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset+IncrementSize,
+ Hi = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(),
+ SVOffset+IncrementSize,
isVolatile, MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
- Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
// Handle endianness of the load.
@@ -223,6 +228,7 @@ void DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
//===--------------------------------------------------------------------===//
SDValue DAGTypeLegalizer::ExpandOp_BIT_CONVERT(SDNode *N) {
+ DebugLoc dl = N->getDebugLoc();
if (N->getValueType(0).isVector()) {
// An illegal expanding type is being converted to a legal vector type.
// Make a two element vector out of the expanded parts and convert that
@@ -239,8 +245,8 @@ SDValue DAGTypeLegalizer::ExpandOp_BIT_CONVERT(SDNode *N) {
if (TLI.isBigEndian())
std::swap(Parts[0], Parts[1]);
- SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2);
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec);
+ SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, Parts, 2);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, N->getValueType(0), Vec);
}
}
@@ -254,6 +260,7 @@ SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
unsigned NumElts = VecVT.getVectorNumElements();
MVT OldVT = N->getOperand(0).getValueType();
MVT NewVT = TLI.getTypeToTransformTo(OldVT);
+ DebugLoc dl = N->getDebugLoc();
// Build a vector of twice the length out of the expanded elements.
// For example <3 x i64> -> <6 x i32>.
@@ -269,12 +276,12 @@ SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
NewElts.push_back(Hi);
}
- SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+ SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
MVT::getVectorVT(NewVT, NewElts.size()),
&NewElts[0], NewElts.size());
// Convert the new vector to the old vector type.
- return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec);
}
SDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
@@ -287,6 +294,7 @@ SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
// The vector type is legal but the element type needs expansion.
MVT VecVT = N->getValueType(0);
unsigned NumElts = VecVT.getVectorNumElements();
+ DebugLoc dl = N->getDebugLoc();
SDValue Val = N->getOperand(1);
MVT OldEVT = Val.getValueType();
@@ -298,7 +306,8 @@ SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
// Bitconvert to a vector of twice the length with elements of the expanded
// type, insert the expanded vector elements, and then convert back.
MVT NewVecVT = MVT::getVectorVT(NewEVT, NumElts*2);
- SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, N->getOperand(0));
+ SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl,
+ NewVecVT, N->getOperand(0));
SDValue Lo, Hi;
GetExpandedOp(Val, Lo, Hi);
@@ -306,29 +315,32 @@ SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
std::swap(Lo, Hi);
SDValue Idx = N->getOperand(2);
- Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
- NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, NewVec, Lo, Idx);
- Idx = DAG.getNode(ISD::ADD,Idx.getValueType(), Idx, DAG.getIntPtrConstant(1));
- NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, NewVec, Hi, Idx);
+ Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
+ NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx);
+ Idx = DAG.getNode(ISD::ADD, dl,
+ Idx.getValueType(), Idx, DAG.getIntPtrConstant(1));
+ NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx);
// Convert the new vector to the old vector type.
- return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec);
}
SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
+ DebugLoc dl = N->getDebugLoc();
MVT VT = N->getValueType(0);
unsigned NumElts = VT.getVectorNumElements();
SmallVector<SDValue, 16> Ops(NumElts);
Ops[0] = N->getOperand(0);
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, Ops[0].getValueType());
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, Ops[0].getValueType());
for (unsigned i = 1; i < NumElts; ++i)
Ops[i] = UndefVal;
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
}
SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
assert(ISD::isNormalStore(N) && "This routine only for normal stores!");
assert(OpNo == 1 && "Can only expand the stored value so far");
+ DebugLoc dl = N->getDebugLoc();
StoreSDNode *St = cast<StoreSDNode>(N);
MVT NVT = TLI.getTypeToTransformTo(St->getValue().getValueType());
@@ -347,16 +359,17 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
if (TLI.isBigEndian())
std::swap(Lo, Hi);
- Lo = DAG.getStore(Chain, Lo, Ptr, St->getSrcValue(), SVOffset,
+ Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getSrcValue(), SVOffset,
isVolatile, Alignment);
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
- Hi = DAG.getStore(Chain, Hi, Ptr, St->getSrcValue(), SVOffset + IncrementSize,
+ Hi = DAG.getStore(Chain, dl, Hi, Ptr, St->getSrcValue(),
+ SVOffset + IncrementSize,
isVolatile, MinAlign(Alignment, IncrementSize));
- return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
@@ -393,29 +406,32 @@ void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N,
void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo,
SDValue &Hi) {
SDValue LL, LH, RL, RH;
+ DebugLoc dl = N->getDebugLoc();
GetSplitOp(N->getOperand(1), LL, LH);
GetSplitOp(N->getOperand(2), RL, RH);
SDValue Cond = N->getOperand(0);
- Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
- Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
+ Lo = DAG.getNode(ISD::SELECT, dl, LL.getValueType(), Cond, LL, RL);
+ Hi = DAG.getNode(ISD::SELECT, dl, LH.getValueType(), Cond, LH, RH);
}
void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
SDValue &Hi) {
SDValue LL, LH, RL, RH;
+ DebugLoc dl = N->getDebugLoc();
GetSplitOp(N->getOperand(2), LL, LH);
GetSplitOp(N->getOperand(3), RL, RH);
- Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+ Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0),
N->getOperand(1), LL, RL, N->getOperand(4));
- Hi = DAG.getNode(ISD::SELECT_CC, LH.getValueType(), N->getOperand(0),
+ Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0),
N->getOperand(1), LH, RH, N->getOperand(4));
}
void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
MVT LoVT, HiVT;
+ DebugLoc dl = N->getDebugLoc();
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
- Lo = DAG.getNode(ISD::UNDEF, LoVT);
- Hi = DAG.getNode(ISD::UNDEF, HiVT);
+ Lo = DAG.getNode(ISD::UNDEF, dl, LoVT);
+ Hi = DAG.getNode(ISD::UNDEF, dl, HiVT);
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 3823f65263a1..8ae42ababc89 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -21,6 +21,7 @@
//===----------------------------------------------------------------------===//
#include "LegalizeTypes.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Target/TargetData.h"
using namespace llvm;
@@ -105,23 +106,21 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) {
SDValue LHS = GetScalarizedVector(N->getOperand(0));
SDValue RHS = GetScalarizedVector(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
+ LHS.getValueType(), LHS, RHS);
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_ShiftOp(SDNode *N) {
SDValue LHS = GetScalarizedVector(N->getOperand(0));
SDValue ShiftAmt = GetScalarizedVector(N->getOperand(1));
- if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType()))
- ShiftAmt = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt);
- else if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType()))
- ShiftAmt = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), ShiftAmt);
-
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, ShiftAmt);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
+ LHS.getValueType(), LHS, ShiftAmt);
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) {
MVT NewVT = N->getValueType(0).getVectorElementType();
- return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(),
+ NewVT, N->getOperand(0));
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) {
@@ -135,14 +134,15 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) {
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
- return DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(),
N->getValueType(0).getVectorElementType(),
N->getOperand(0), N->getOperand(1));
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) {
SDValue Op = GetScalarizedVector(N->getOperand(0));
- return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
+ return DAG.getNode(ISD::FPOWI, N->getDebugLoc(),
+ Op.getValueType(), Op, N->getOperand(1));
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
@@ -152,17 +152,18 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
MVT EltVT = N->getValueType(0).getVectorElementType();
if (Op.getValueType() != EltVT)
// FIXME: Can this happen for floating point types?
- Op = DAG.getNode(ISD::TRUNCATE, EltVT, Op);
+ Op = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), EltVT, Op);
return Op;
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
assert(N->isUnindexed() && "Indexed vector load?");
- SDValue Result = DAG.getLoad(ISD::UNINDEXED, N->getExtensionType(),
+ SDValue Result = DAG.getLoad(ISD::UNINDEXED, N->getDebugLoc(),
+ N->getExtensionType(),
N->getValueType(0).getVectorElementType(),
N->getChain(), N->getBasePtr(),
- DAG.getNode(ISD::UNDEF,
+ DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
N->getBasePtr().getValueType()),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT().getVectorElementType(),
@@ -178,7 +179,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
// Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
MVT DestVT = N->getValueType(0).getVectorElementType();
SDValue Op = GetScalarizedVector(N->getOperand(0));
- return DAG.getNode(N->getOpcode(), DestVT, Op);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(), DestVT, Op);
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) {
@@ -187,27 +188,30 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) {
SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) {
SDValue LHS = GetScalarizedVector(N->getOperand(1));
- return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS,
+ return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
+ LHS.getValueType(), N->getOperand(0), LHS,
GetScalarizedVector(N->getOperand(2)));
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) {
SDValue LHS = GetScalarizedVector(N->getOperand(2));
- return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(),
+ return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), LHS.getValueType(),
N->getOperand(0), N->getOperand(1),
LHS, GetScalarizedVector(N->getOperand(3)),
N->getOperand(4));
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) {
- return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType());
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
+ N->getValueType(0).getVectorElementType());
}
SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) {
// Figure out if the scalar is the LHS or RHS and return it.
SDValue Arg = N->getOperand(2).getOperand(0);
if (Arg.getOpcode() == ISD::UNDEF)
- return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType());
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
+ N->getValueType(0).getVectorElementType());
unsigned Op = !cast<ConstantSDNode>(Arg)->isNullValue();
return GetScalarizedVector(N->getOperand(Op));
}
@@ -217,9 +221,10 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) {
SDValue RHS = GetScalarizedVector(N->getOperand(1));
MVT NVT = N->getValueType(0).getVectorElementType();
MVT SVT = TLI.getSetCCResultType(LHS.getValueType());
+ DebugLoc dl = N->getDebugLoc();
// Turn it into a scalar SETCC.
- SDValue Res = DAG.getNode(ISD::SETCC, SVT, LHS, RHS, N->getOperand(2));
+ SDValue Res = DAG.getNode(ISD::SETCC, dl, SVT, LHS, RHS, N->getOperand(2));
// VSETCC always returns a sign-extended value, while SETCC may not. The
// SETCC result type may not match the vector element type. Correct these.
@@ -228,18 +233,18 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) {
// Ensure the SETCC result is sign-extended.
if (TLI.getBooleanContents() !=
TargetLowering::ZeroOrNegativeOneBooleanContent)
- Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, SVT, Res,
+ Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, SVT, Res,
DAG.getValueType(MVT::i1));
// Truncate to the final type.
- return DAG.getNode(ISD::TRUNCATE, NVT, Res);
+ return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res);
} else {
// The SETCC result type is smaller than the vector element type.
// If the SetCC result is not sign-extended, chop it down to MVT::i1.
if (TLI.getBooleanContents() !=
TargetLowering::ZeroOrNegativeOneBooleanContent)
- Res = DAG.getNode(ISD::TRUNCATE, MVT::i1, Res);
+ Res = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, Res);
// Sign extend to the final type.
- return DAG.getNode(ISD::SIGN_EXTEND, NVT, Res);
+ return DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Res);
}
}
@@ -296,7 +301,8 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
/// to be scalarized, it must be <1 x ty>. Convert the element instead.
SDValue DAGTypeLegalizer::ScalarizeVecOp_BIT_CONVERT(SDNode *N) {
SDValue Elt = GetScalarizedVector(N->getOperand(0));
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(),
+ N->getValueType(0), Elt);
}
/// ScalarizeVecOp_CONCAT_VECTORS - The vectors to concatenate have length one -
@@ -305,7 +311,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) {
SmallVector<SDValue, 8> Ops(N->getNumOperands());
for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i)
Ops[i] = GetScalarizedVector(N->getOperand(i));
- return DAG.getNode(ISD::BUILD_VECTOR, N->getValueType(0),
+ return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), N->getValueType(0),
&Ops[0], Ops.size());
}
@@ -321,16 +327,17 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
assert(N->isUnindexed() && "Indexed store of one-element vector?");
assert(OpNo == 1 && "Do not know how to scalarize this operand!");
+ DebugLoc dl = N->getDebugLoc();
if (N->isTruncatingStore())
- return DAG.getTruncStore(N->getChain(),
+ return DAG.getTruncStore(N->getChain(), dl,
GetScalarizedVector(N->getOperand(1)),
N->getBasePtr(),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT().getVectorElementType(),
N->isVolatile(), N->getAlignment());
- return DAG.getStore(N->getChain(), GetScalarizedVector(N->getOperand(1)),
+ return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
N->isVolatile(), N->getAlignment());
}
@@ -426,9 +433,10 @@ void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo,
GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
SDValue RHSLo, RHSHi;
GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
+ DebugLoc dl = N->getDebugLoc();
- Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo);
- Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
+ Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo, RHSLo);
+ Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi, RHSHi);
}
void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
@@ -437,6 +445,7 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
// scalar value.
MVT LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+ DebugLoc dl = N->getDebugLoc();
SDValue InOp = N->getOperand(0);
MVT InVT = InOp.getValueType();
@@ -459,8 +468,8 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
GetExpandedOp(InOp, Lo, Hi);
if (TLI.isBigEndian())
std::swap(Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi);
return;
}
break;
@@ -468,8 +477,8 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
// If the input is a vector that needs to be split, convert each split
// piece of the input now.
GetSplitVector(InOp, Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi);
return;
}
@@ -483,25 +492,27 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
if (TLI.isBigEndian())
std::swap(Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi);
}
void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo,
SDValue &Hi) {
MVT LoVT, HiVT;
+ DebugLoc dl = N->getDebugLoc();
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
unsigned LoNumElts = LoVT.getVectorNumElements();
SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
- Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size());
+ Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, &LoOps[0], LoOps.size());
SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
- Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
+ Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, HiVT, &HiOps[0], HiOps.size());
}
void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
SDValue &Hi) {
assert(!(N->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS");
+ DebugLoc dl = N->getDebugLoc();
unsigned NumSubvectors = N->getNumOperands() / 2;
if (NumSubvectors == 1) {
Lo = N->getOperand(0);
@@ -513,10 +524,10 @@ void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
- Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size());
+ Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, &LoOps[0], LoOps.size());
SmallVector<SDValue, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
- Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
+ Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HiVT, &HiOps[0], HiOps.size());
}
void DAGTypeLegalizer::SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo,
@@ -543,6 +554,7 @@ void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
SDValue Vec = N->getOperand(0);
SDValue Idx = N->getOperand(1);
MVT IdxVT = Idx.getValueType();
+ DebugLoc dl = N->getDebugLoc();
MVT LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
@@ -550,17 +562,18 @@ void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
// size unless the original vector type was split in two.
assert(LoVT == HiVT && "Non power-of-two vectors not supported!");
- Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, LoVT, Vec, Idx);
- Idx = DAG.getNode(ISD::ADD, IdxVT, Idx,
+ Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx);
+ Idx = DAG.getNode(ISD::ADD, dl, IdxVT, Idx,
DAG.getConstant(LoVT.getVectorNumElements(), IdxVT));
- Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, HiVT, Vec, Idx);
+ Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec, Idx);
}
void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo,
SDValue &Hi) {
+ DebugLoc dl = N->getDebugLoc();
GetSplitVector(N->getOperand(0), Lo, Hi);
- Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
- Hi = DAG.getNode(ISD::FPOWI, Hi.getValueType(), Hi, N->getOperand(1));
+ Lo = DAG.getNode(ISD::FPOWI, dl, Lo.getValueType(), Lo, N->getOperand(1));
+ Hi = DAG.getNode(ISD::FPOWI, dl, Hi.getValueType(), Hi, N->getOperand(1));
}
void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
@@ -568,15 +581,17 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
SDValue Vec = N->getOperand(0);
SDValue Elt = N->getOperand(1);
SDValue Idx = N->getOperand(2);
+ DebugLoc dl = N->getDebugLoc();
GetSplitVector(Vec, Lo, Hi);
if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
unsigned IdxVal = CIdx->getZExtValue();
unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
if (IdxVal < LoNumElts)
- Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, Elt, Idx);
+ Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl,
+ Lo.getValueType(), Lo, Elt, Idx);
else
- Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, Elt,
+ Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt,
DAG.getIntPtrConstant(IdxVal - LoNumElts));
return;
}
@@ -585,40 +600,42 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
MVT VecVT = Vec.getValueType();
MVT EltVT = VecVT.getVectorElementType();
SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
- SDValue Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 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.getTypeForMVT());
- Store = DAG.getTruncStore(Store, Elt, EltPtr, NULL, 0, EltVT);
+ Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT);
// Load the Lo part from the stack slot.
- Lo = DAG.getLoad(Lo.getValueType(), Store, StackPtr, NULL, 0);
+ Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0);
// Increment the pointer to the other part.
unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8;
- StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr,
+ StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
DAG.getIntPtrConstant(IncrementSize));
// Load the Hi part from the stack slot.
- Hi = DAG.getLoad(Hi.getValueType(), Store, StackPtr, NULL, 0, false,
+ Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, NULL, 0, false,
MinAlign(Alignment, IncrementSize));
}
void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo,
SDValue &Hi) {
MVT LoVT, HiVT;
+ DebugLoc dl = N->getDebugLoc();
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
- Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, LoVT, N->getOperand(0));
- Hi = DAG.getNode(ISD::UNDEF, HiVT);
+ Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LoVT, N->getOperand(0));
+ Hi = DAG.getNode(ISD::UNDEF, dl, HiVT);
}
void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
SDValue &Hi) {
assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!");
MVT LoVT, HiVT;
+ DebugLoc dl = LD->getDebugLoc();
GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
ISD::LoadExtType ExtType = LD->getExtensionType();
@@ -634,20 +651,20 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
MVT LoMemVT, HiMemVT;
GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT);
- Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, LoVT, Ch, Ptr, Offset,
+ Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, LoVT, Ch, Ptr, Offset,
SV, SVOffset, LoMemVT, isVolatile, Alignment);
unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
- Hi = DAG.getLoad(ISD::UNINDEXED, ExtType, HiVT, Ch, Ptr, Offset,
+ Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, HiVT, Ch, Ptr, Offset,
SV, SVOffset, HiMemVT, isVolatile, Alignment);
// Build a factor node to remember that this load is independent of the
// other one.
- Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
// Legalized the chain result - switch anything that used the old chain to
@@ -659,6 +676,7 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
SDValue &Hi) {
// Get the dest types - they may not match the input types, e.g. int_to_fp.
MVT LoVT, HiVT;
+ DebugLoc dl = N->getDebugLoc();
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
// Split the input.
@@ -669,9 +687,9 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
assert(LoVT == HiVT && "Legal non-power-of-two vector type?");
MVT InNVT = MVT::getVectorVT(InVT.getVectorElementType(),
LoVT.getVectorNumElements());
- Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, InNVT, N->getOperand(0),
+ Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0),
DAG.getIntPtrConstant(0));
- Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, InNVT, N->getOperand(0),
+ Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0),
DAG.getIntPtrConstant(InNVT.getVectorNumElements()));
break;
}
@@ -680,14 +698,15 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
break;
}
- Lo = DAG.getNode(N->getOpcode(), LoVT, Lo);
- Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
+ Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo);
+ Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi);
}
void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
SDValue &Hi) {
// The low and high parts of the original input give four input vectors.
SDValue Inputs[4];
+ DebugLoc dl = N->getDebugLoc();
GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]);
GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]);
MVT NewVT = Inputs[0].getValueType();
@@ -724,7 +743,7 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
if (Input >= array_lengthof(Inputs)) {
// The mask element does not index into any input vector.
- Ops.push_back(DAG.getNode(ISD::UNDEF, IdxVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, dl, IdxVT));
continue;
}
@@ -772,7 +791,7 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
if (Input >= array_lengthof(Inputs)) {
// The mask element is "undef" or indexes off the end of the input.
- Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT));
continue;
}
@@ -780,25 +799,25 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
Idx -= Input * NewElts;
// Extract the vector element by hand.
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT,
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
Inputs[Input], DAG.getIntPtrConstant(Idx)));
}
// Construct the Lo/Hi output using a BUILD_VECTOR.
- Output = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &Ops[0], Ops.size());
+ Output = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, &Ops[0], Ops.size());
} else if (InputUsed[0] == -1U) {
// No input vectors were used! The result is undefined.
- Output = DAG.getNode(ISD::UNDEF, NewVT);
+ Output = DAG.getNode(ISD::UNDEF, dl, NewVT);
} else {
// At least one input vector was used. Create a new shuffle vector.
- SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR,
+ SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl,
MVT::getVectorVT(IdxVT, Ops.size()),
&Ops[0], Ops.size());
SDValue Op0 = Inputs[InputUsed[0]];
// If only one input was used, use an undefined vector for the other.
SDValue Op1 = InputUsed[1] == -1U ?
- DAG.getNode(ISD::UNDEF, NewVT) : Inputs[InputUsed[1]];
- Output = DAG.getNode(ISD::VECTOR_SHUFFLE, NewVT, Op0, Op1, NewMask);
+ DAG.getNode(ISD::UNDEF, dl, NewVT) : Inputs[InputUsed[1]];
+ Output = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, NewVT, Op0, Op1, NewMask);
}
Ops.clear();
@@ -808,14 +827,15 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
void DAGTypeLegalizer::SplitVecRes_VSETCC(SDNode *N, SDValue &Lo,
SDValue &Hi) {
MVT LoVT, HiVT;
+ DebugLoc dl = N->getDebugLoc();
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
SDValue LL, LH, RL, RH;
GetSplitVector(N->getOperand(0), LL, LH);
GetSplitVector(N->getOperand(1), RL, RH);
- Lo = DAG.getNode(ISD::VSETCC, LoVT, LL, RL, N->getOperand(2));
- Hi = DAG.getNode(ISD::VSETCC, HiVT, LH, RH, N->getOperand(2));
+ Lo = DAG.getNode(ISD::VSETCC, dl, LoVT, LL, RL, N->getOperand(2));
+ Hi = DAG.getNode(ISD::VSETCC, dl, HiVT, LH, RH, N->getOperand(2));
}
@@ -878,6 +898,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) {
// The result has a legal vector type, but the input needs splitting.
MVT ResVT = N->getValueType(0);
SDValue Lo, Hi;
+ DebugLoc dl = N->getDebugLoc();
GetSplitVector(N->getOperand(0), Lo, Hi);
assert(Lo.getValueType() == Hi.getValueType() &&
"Returns legal non-power-of-two vector type?");
@@ -886,10 +907,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) {
MVT OutVT = MVT::getVectorVT(ResVT.getVectorElementType(),
InVT.getVectorNumElements());
- Lo = DAG.getNode(N->getOpcode(), OutVT, Lo);
- Hi = DAG.getNode(N->getOpcode(), OutVT, Hi);
+ Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo);
+ Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi);
- return DAG.getNode(ISD::CONCAT_VECTORS, ResVT, Lo, Hi);
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
}
SDValue DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) {
@@ -904,7 +925,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) {
if (TLI.isBigEndian())
std::swap(Lo, Hi);
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0),
JoinIntegers(Lo, Hi));
}
@@ -913,6 +934,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
// is a constant.
MVT SubVT = N->getValueType(0);
SDValue Idx = N->getOperand(1);
+ DebugLoc dl = N->getDebugLoc();
SDValue Lo, Hi;
GetSplitVector(N->getOperand(0), Lo, Hi);
@@ -922,9 +944,9 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
if (IdxVal < LoElts) {
assert(IdxVal + SubVT.getVectorNumElements() <= LoElts &&
"Extracted subvector crosses vector split!");
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Lo, Idx);
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx);
} else {
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Hi,
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Hi,
DAG.getConstant(IdxVal - LoElts, Idx.getValueType()));
}
}
@@ -953,17 +975,21 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
// Store the vector to the stack.
MVT EltVT = VecVT.getVectorElementType();
+ DebugLoc dl = N->getDebugLoc();
SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
- SDValue Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
+ int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
+ const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0);
// Load back the required element.
StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
- return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0);
+ return DAG.getLoad(EltVT, dl, Store, StackPtr, SV, 0);
}
SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
assert(N->isUnindexed() && "Indexed store of vector?");
assert(OpNo == 1 && "Can only split the stored value");
+ DebugLoc dl = N->getDebugLoc();
bool isTruncating = N->isTruncatingStore();
SDValue Ch = N->getChain();
@@ -981,31 +1007,32 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
if (isTruncating)
- Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+ Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
LoMemVT, isVol, Alignment);
else
- Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+ Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
isVol, Alignment);
// Increment the pointer to the other half.
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
if (isTruncating)
- Hi = DAG.getTruncStore(Ch, Hi, Ptr,
+ Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
N->getSrcValue(), SVOffset+IncrementSize,
HiMemVT,
isVol, MinAlign(Alignment, IncrementSize));
else
- Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
+ Hi = DAG.getStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
isVol, MinAlign(Alignment, IncrementSize));
- return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
assert(OpNo == 2 && "Shuffle source type differs from result type?");
SDValue Mask = N->getOperand(2);
+ DebugLoc dl = N->getDebugLoc();
unsigned MaskLength = Mask.getValueType().getVectorNumElements();
unsigned LargestMaskEntryPlusOne = 2 * MaskLength;
unsigned MinimumBitWidth = Log2_32_Ceil(LargestMaskEntryPlusOne);
@@ -1044,7 +1071,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
for (unsigned i = 0; i < MaskLength; ++i) {
SDValue Arg = Mask.getOperand(i);
if (Arg.getOpcode() == ISD::UNDEF) {
- Ops[i] = DAG.getNode(ISD::UNDEF, OpVT);
+ Ops[i] = DAG.getNode(ISD::UNDEF, dl, OpVT);
} else {
uint64_t Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
Ops[i] = DAG.getConstant(Idx, OpVT);
@@ -1052,7 +1079,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
}
return DAG.UpdateNodeOperands(SDValue(N,0),
N->getOperand(0), N->getOperand(1),
- DAG.getNode(ISD::BUILD_VECTOR,
+ DAG.getNode(ISD::BUILD_VECTOR, dl,
VecVT, &Ops[0], Ops.size()));
}
@@ -1152,11 +1179,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
SDValue InOp1 = GetWidenedVector(N->getOperand(0));
SDValue InOp2 = GetWidenedVector(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), WidenVT, InOp1, InOp2);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp1, InOp2);
}
SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
SDValue InOp = N->getOperand(0);
+ DebugLoc dl = N->getDebugLoc();
MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
unsigned WidenNumElts = WidenVT.getVectorNumElements();
@@ -1173,7 +1201,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
InVT = InOp.getValueType();
InVTNumElts = InVT.getVectorNumElements();
if (InVTNumElts == WidenNumElts)
- return DAG.getNode(Opcode, WidenVT, InOp);
+ return DAG.getNode(Opcode, dl, WidenVT, InOp);
}
if (TLI.isTypeLegal(InWidenVT)) {
@@ -1187,19 +1215,19 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
unsigned NumConcat = WidenNumElts/InVTNumElts;
SmallVector<SDValue, 16> Ops(NumConcat);
Ops[0] = InOp;
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT);
for (unsigned i = 1; i != NumConcat; ++i)
Ops[i] = UndefVal;
- return DAG.getNode(Opcode, WidenVT,
- DAG.getNode(ISD::CONCAT_VECTORS, InWidenVT,
+ return DAG.getNode(Opcode, dl, WidenVT,
+ DAG.getNode(ISD::CONCAT_VECTORS, dl, InWidenVT,
&Ops[0], NumConcat));
}
if (InVTNumElts % WidenNumElts == 0) {
// Extract the input and convert the shorten input vector.
- return DAG.getNode(Opcode, WidenVT,
- DAG.getNode(ISD::EXTRACT_SUBVECTOR, InWidenVT, InOp,
- DAG.getIntPtrConstant(0)));
+ return DAG.getNode(Opcode, dl, WidenVT,
+ DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InWidenVT,
+ InOp, DAG.getIntPtrConstant(0)));
}
}
@@ -1209,15 +1237,15 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
unsigned MinElts = std::min(InVTNumElts, WidenNumElts);
unsigned i;
for (i=0; i < MinElts; ++i)
- Ops[i] = DAG.getNode(Opcode, EltVT,
- DAG.getNode(ISD::EXTRACT_VECTOR_ELT, InEltVT, InOp,
+ Ops[i] = DAG.getNode(Opcode, dl, EltVT,
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
DAG.getIntPtrConstant(i)));
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
for (; i < WidenNumElts; ++i)
Ops[i] = UndefVal;
- return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], WidenNumElts);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
}
SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) {
@@ -1235,14 +1263,14 @@ SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) {
if (ShVT != ShWidenVT)
ShOp = ModifyToType(ShOp, ShWidenVT);
- return DAG.getNode(N->getOpcode(), WidenVT, InOp, ShOp);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp, ShOp);
}
SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) {
// Unary op widening.
MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
SDValue InOp = GetWidenedVector(N->getOperand(0));
- return DAG.getNode(N->getOpcode(), WidenVT, InOp);
+ return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp);
}
SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) {
@@ -1250,6 +1278,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) {
MVT InVT = InOp.getValueType();
MVT VT = N->getValueType(0);
MVT WidenVT = TLI.getTypeToTransformTo(VT);
+ DebugLoc dl = N->getDebugLoc();
switch (getTypeAction(InVT)) {
default:
@@ -1263,7 +1292,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) {
InOp = GetPromotedInteger(InOp);
InVT = InOp.getValueType();
if (WidenVT.bitsEq(InVT))
- return DAG.getNode(ISD::BIT_CONVERT, WidenVT, InOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, InOp);
break;
case SoftenFloat:
case ExpandInteger:
@@ -1278,7 +1307,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) {
InVT = InOp.getValueType();
if (WidenVT.bitsEq(InVT))
// The input widens to the same size. Convert to the widen value.
- return DAG.getNode(ISD::BIT_CONVERT, WidenVT, InOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, InOp);
break;
}
@@ -1311,10 +1340,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) {
SDValue NewVec;
if (InVT.isVector())
- NewVec = DAG.getNode(ISD::CONCAT_VECTORS, NewInVT, &Ops[0], NewNumElts);
+ NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl,
+ NewInVT, &Ops[0], NewNumElts);
else
- NewVec = DAG.getNode(ISD::BUILD_VECTOR, NewInVT, &Ops[0], NewNumElts);
- return DAG.getNode(ISD::BIT_CONVERT, WidenVT, NewVec);
+ NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
+ NewInVT, &Ops[0], NewNumElts);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, NewVec);
}
}
@@ -1322,15 +1353,18 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) {
// from the stack. Create the stack frame object. Make sure it is aligned
// for both the source and destination types.
SDValue FIPtr = DAG.CreateStackTemporary(InVT, WidenVT);
+ int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
+ const Value *SV = PseudoSourceValue::getFixedStack(FI);
// Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0);
// Result is a load from the stack slot.
- return DAG.getLoad(WidenVT, Store, FIPtr, NULL, 0);
+ return DAG.getLoad(WidenVT, dl, Store, FIPtr, SV, 0);
}
SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) {
+ DebugLoc dl = N->getDebugLoc();
// Build a vector with undefined for the new nodes.
MVT VT = N->getValueType(0);
MVT EltVT = VT.getVectorElementType();
@@ -1342,14 +1376,15 @@ SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) {
SmallVector<SDValue, 16> NewOps(N->op_begin(), N->op_end());
NewOps.reserve(WidenNumElts);
for (unsigned i = NumElts; i < WidenNumElts; ++i)
- NewOps.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+ NewOps.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT));
- return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &NewOps[0], NewOps.size());
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &NewOps[0], NewOps.size());
}
SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
MVT InVT = N->getOperand(0).getValueType();
MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ DebugLoc dl = N->getDebugLoc();
unsigned WidenNumElts = WidenVT.getVectorNumElements();
unsigned NumOperands = N->getNumOperands();
@@ -1359,13 +1394,13 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
// Add undef vectors to widen to correct length.
unsigned NumConcat = WidenVT.getVectorNumElements() /
InVT.getVectorNumElements();
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT);
SmallVector<SDValue, 16> Ops(NumConcat);
for (unsigned i=0; i < NumOperands; ++i)
Ops[i] = N->getOperand(i);
for (unsigned i = NumOperands; i != NumConcat; ++i)
Ops[i] = UndefVal;
- return DAG.getNode(ISD::CONCAT_VECTORS, WidenVT, &Ops[0], NumConcat);
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &Ops[0], NumConcat);
}
} else {
InputWidened = true;
@@ -1389,10 +1424,10 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
MaskOps[i] = DAG.getConstant(i, PtrVT);
MaskOps[i+WidenNumElts/2] = DAG.getConstant(i+WidenNumElts, PtrVT);
}
- SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR,
+ SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR, dl,
MVT::getVectorVT(PtrVT, WidenNumElts),
&MaskOps[0], WidenNumElts);
- return DAG.getNode(ISD::VECTOR_SHUFFLE, WidenVT,
+ return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT,
GetWidenedVector(N->getOperand(0)),
GetWidenedVector(N->getOperand(1)), Mask);
}
@@ -1409,13 +1444,13 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
if (InputWidened)
InOp = GetWidenedVector(InOp);
for (unsigned j=0; j < NumInElts; ++j)
- Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp,
+ Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
DAG.getIntPtrConstant(j));
}
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
for (; Idx < WidenNumElts; ++Idx)
Ops[Idx] = UndefVal;
- return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], WidenNumElts);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
}
SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) {
@@ -1501,6 +1536,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
unsigned WidenNumElts = WidenVT.getVectorNumElements();
SDValue InOp = N->getOperand(0);
SDValue Idx = N->getOperand(1);
+ DebugLoc dl = N->getDebugLoc();
if (getTypeAction(InOp.getValueType()) == WidenVector)
InOp = GetWidenedVector(InOp);
@@ -1517,7 +1553,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
// Check if we can extract from the vector.
unsigned InNumElts = InVT.getVectorNumElements();
if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, WidenVT, InOp, Idx);
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx);
}
// We could try widening the input to the right length but for now, extract
@@ -1530,26 +1566,27 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
if (CIdx) {
unsigned IdxVal = CIdx->getZExtValue();
for (i=0; i < NumElts; ++i)
- Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp,
+ Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
DAG.getConstant(IdxVal+i, IdxVT));
} else {
- Ops[0] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, Idx);
+ Ops[0] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, Idx);
for (i=1; i < NumElts; ++i) {
- SDValue NewIdx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,
+ SDValue NewIdx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
DAG.getConstant(i, IdxVT));
- Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, NewIdx);
+ Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, NewIdx);
}
}
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
for (; i < WidenNumElts; ++i)
Ops[i] = UndefVal;
- return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], WidenNumElts);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
}
SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
SDValue InOp = GetWidenedVector(N->getOperand(0));
- return DAG.getNode(ISD::INSERT_VECTOR_ELT, InOp.getValueType(), InOp,
+ return DAG.getNode(ISD::INSERT_VECTOR_ELT, N->getDebugLoc(),
+ InOp.getValueType(), InOp,
N->getOperand(1), N->getOperand(2));
}
@@ -1557,6 +1594,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
LoadSDNode *LD = cast<LoadSDNode>(N);
MVT WidenVT = TLI.getTypeToTransformTo(LD->getValueType(0));
MVT LdVT = LD->getMemoryVT();
+ DebugLoc dl = N->getDebugLoc();
assert(LdVT.isVector() && WidenVT.isVector());
// Load information
@@ -1582,30 +1620,30 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
unsigned WidenNumElts = WidenVT.getVectorNumElements();
SmallVector<SDValue, 16> Ops(WidenNumElts);
unsigned Increment = LdEltVT.getSizeInBits() / 8;
- Ops[0] = DAG.getExtLoad(ExtType, EltVT, Chain, BasePtr, SV, SVOffset,
+ Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset,
LdEltVT, isVolatile, 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, BasePtr.getValueType(),
+ SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
BasePtr, DAG.getIntPtrConstant(Offset));
- Ops[i] = DAG.getExtLoad(ExtType, EltVT, Chain, NewBasePtr, SV,
+ Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV,
SVOffset + Offset, LdEltVT, isVolatile, Align);
LdChain.push_back(Ops[i].getValue(1));
}
// Fill the rest with undefs
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
for (; i != WidenNumElts; ++i)
Ops[i] = UndefVal;
- Result = DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], Ops.size());
+ Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size());
} else {
assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
unsigned int LdWidth = LdVT.getSizeInBits();
Result = GenWidenVectorLoads(LdChain, Chain, BasePtr, SV, SVOffset,
- Align, isVolatile, LdWidth, WidenVT);
-}
+ Align, isVolatile, LdWidth, WidenVT, dl);
+ }
// If we generate a single load, we can use that for the chain. Otherwise,
// build a factor node to remember the multiple loads are independent and
@@ -1614,7 +1652,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
if (LdChain.size() == 1)
NewChain = LdChain[0];
else
- NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, &LdChain[0],
+ NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LdChain[0],
LdChain.size());
// Modified the chain - switch anything that used the old chain to use
@@ -1626,7 +1664,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
SDValue DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode *N) {
MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
- return DAG.getNode(ISD::SCALAR_TO_VECTOR, WidenVT, N->getOperand(0));
+ return DAG.getNode(ISD::SCALAR_TO_VECTOR, N->getDebugLoc(),
+ WidenVT, N->getOperand(0));
}
SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
@@ -1648,24 +1687,27 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
SDValue InOp1 = GetWidenedVector(N->getOperand(1));
SDValue InOp2 = GetWidenedVector(N->getOperand(2));
assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT);
- return DAG.getNode(ISD::SELECT, WidenVT, Cond1, InOp1, InOp2);
+ return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
+ WidenVT, Cond1, InOp1, InOp2);
}
SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) {
SDValue InOp1 = GetWidenedVector(N->getOperand(2));
SDValue InOp2 = GetWidenedVector(N->getOperand(3));
- return DAG.getNode(ISD::SELECT_CC, InOp1.getValueType(), N->getOperand(0),
+ return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
+ InOp1.getValueType(), N->getOperand(0),
N->getOperand(1), InOp1, InOp2, N->getOperand(4));
}
SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) {
MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
- return DAG.getNode(ISD::UNDEF, WidenVT);
+ return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), WidenVT);
}
SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) {
MVT VT = N->getValueType(0);
unsigned NumElts = VT.getVectorNumElements();
+ DebugLoc dl = N->getDebugLoc();
MVT WidenVT = TLI.getTypeToTransformTo(VT);
unsigned WidenNumElts = WidenVT.getVectorNumElements();
@@ -1690,12 +1732,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) {
}
}
for (unsigned i = NumElts; i < WidenNumElts; ++i)
- MaskOps[i] = DAG.getNode(ISD::UNDEF, IdxVT);
- SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR,
+ MaskOps[i] = DAG.getNode(ISD::UNDEF, dl, IdxVT);
+ SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl,
MVT::getVectorVT(IdxVT, WidenNumElts),
&MaskOps[0], WidenNumElts);
- return DAG.getNode(ISD::VECTOR_SHUFFLE, WidenVT, InOp1, InOp2, NewMask);
+ return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, InOp1, InOp2, NewMask);
}
SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) {
@@ -1714,7 +1756,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) {
assert(InOp1.getValueType() == WidenInVT &&
InOp2.getValueType() == WidenInVT &&
"Input not widened to expected type!");
- return DAG.getNode(ISD::VSETCC, WidenVT, InOp1, InOp2, N->getOperand(2));
+ return DAG.getNode(ISD::VSETCC, N->getDebugLoc(),
+ WidenVT, InOp1, InOp2, N->getOperand(2));
}
@@ -1770,6 +1813,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
// into some scalar code and create a nasty build vector.
MVT VT = N->getValueType(0);
MVT EltVT = VT.getVectorElementType();
+ DebugLoc dl = N->getDebugLoc();
unsigned NumElts = VT.getVectorNumElements();
SDValue InOp = N->getOperand(0);
if (getTypeAction(InOp.getValueType()) == WidenVector)
@@ -1780,17 +1824,18 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
unsigned Opcode = N->getOpcode();
SmallVector<SDValue, 16> Ops(NumElts);
for (unsigned i=0; i < NumElts; ++i)
- Ops[i] = DAG.getNode(Opcode, EltVT,
- DAG.getNode(ISD::EXTRACT_VECTOR_ELT, InEltVT, InOp,
+ Ops[i] = DAG.getNode(Opcode, dl, EltVT,
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
DAG.getIntPtrConstant(i)));
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
}
SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) {
MVT VT = N->getValueType(0);
SDValue InOp = GetWidenedVector(N->getOperand(0));
MVT InWidenVT = InOp.getValueType();
+ DebugLoc dl = N->getDebugLoc();
// Check if we can convert between two legal vector types and extract.
unsigned InWidenSize = InWidenVT.getSizeInBits();
@@ -1799,8 +1844,8 @@ SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) {
unsigned NewNumElts = InWidenSize / Size;
MVT NewVT = MVT::getVectorVT(VT, NewNumElts);
if (TLI.isTypeLegal(NewVT)) {
- SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, NewVT, InOp);
- return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, BitOp,
+ SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT, InOp);
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp,
DAG.getIntPtrConstant(0));
}
}
@@ -1809,12 +1854,14 @@ SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) {
// frame object. Make sure it is aligned for both the source and destination
// types.
SDValue FIPtr = DAG.CreateStackTemporary(InWidenVT, VT);
+ int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
+ const Value *SV = PseudoSourceValue::getFixedStack(FI);
// Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0);
// Result is a load from the stack slot.
- return DAG.getLoad(VT, Store, FIPtr, NULL, 0);
+ return DAG.getLoad(VT, dl, Store, FIPtr, SV, 0);
}
SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
@@ -1823,6 +1870,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
// nasty build vector.
MVT VT = N->getValueType(0);
MVT EltVT = VT.getVectorElementType();
+ DebugLoc dl = N->getDebugLoc();
unsigned NumElts = VT.getVectorNumElements();
SmallVector<SDValue, 16> Ops(NumElts);
@@ -1836,16 +1884,17 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
if (getTypeAction(InOp.getValueType()) == WidenVector)
InOp = GetWidenedVector(InOp);
for (unsigned j=0; j < NumInElts; ++j)
- Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp,
+ Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
DAG.getIntPtrConstant(j));
}
- return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
}
SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
SDValue InOp = GetWidenedVector(N->getOperand(0));
MVT EltVT = InOp.getValueType().getVectorElementType();
- return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, N->getOperand(1));
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(),
+ EltVT, InOp, N->getOperand(1));
}
SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
@@ -1859,13 +1908,14 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
unsigned Align = ST->getAlignment();
bool isVolatile = ST->isVolatile();
SDValue ValOp = GetWidenedVector(ST->getValue());
+ DebugLoc dl = N->getDebugLoc();
MVT StVT = ST->getMemoryVT();
MVT ValVT = ValOp.getValueType();
// It must be true that we the widen vector type is bigger than where
// we need to store.
assert(StVT.isVector() && ValOp.getValueType().isVector());
- assert(StVT.getSizeInBits() < ValOp.getValueType().getSizeInBits());
+ assert(StVT.bitsLT(ValOp.getValueType()));
SmallVector<SDValue, 16> StChain;
if (ST->isTruncatingStore()) {
@@ -1876,18 +1926,18 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
MVT ValEltVT = ValVT.getVectorElementType();
unsigned Increment = ValEltVT.getSizeInBits() / 8;
unsigned NumElts = StVT.getVectorNumElements();
- SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, ValEltVT, ValOp,
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
DAG.getIntPtrConstant(0));
- StChain.push_back(DAG.getTruncStore(Chain, EOp, BasePtr, SV,
+ StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV,
SVOffset, StEltVT,
isVolatile, Align));
unsigned Offset = Increment;
for (unsigned i=1; i < NumElts; ++i, Offset += Increment) {
- SDValue NewBasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(),
+ SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
BasePtr, DAG.getIntPtrConstant(Offset));
- SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, ValEltVT, ValOp,
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
DAG.getIntPtrConstant(0));
- StChain.push_back(DAG.getTruncStore(Chain, EOp, NewBasePtr, SV,
+ StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV,
SVOffset + Offset, StEltVT,
isVolatile, MinAlign(Align, Offset)));
}
@@ -1896,12 +1946,13 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
assert(StVT.getVectorElementType() == ValVT.getVectorElementType());
// Store value
GenWidenVectorStores(StChain, Chain, BasePtr, SV, SVOffset,
- Align, isVolatile, ValOp, StVT.getSizeInBits());
+ Align, isVolatile, ValOp, StVT.getSizeInBits(), dl);
}
if (StChain.size() == 1)
return StChain[0];
else
- return DAG.getNode(ISD::TokenFactor, MVT::Other,&StChain[0],StChain.size());
+ return DAG.getNode(ISD::TokenFactor, dl,
+ MVT::Other,&StChain[0],StChain.size());
}
//===----------------------------------------------------------------------===//
@@ -1960,7 +2011,8 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
unsigned Alignment,
bool isVolatile,
unsigned LdWidth,
- MVT ResType) {
+ MVT ResType,
+ DebugLoc dl) {
// The strategy assumes that we can efficiently load powers of two widths.
// The routines chops the vector into the largest power of 2 load and
// can be inserted into a legal vector and then cast the result into the
@@ -1975,14 +2027,14 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
FindAssocWidenVecType(TLI, LdWidth, ResType, NewEltVT, NewVecVT);
NewEltVTWidth = NewEltVT.getSizeInBits();
- SDValue LdOp = DAG.getLoad(NewEltVT, Chain, BasePtr, SV, SVOffset, isVolatile,
- Alignment);
- SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, NewVecVT, LdOp);
+ SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV, SVOffset,
+ isVolatile, Alignment);
+ SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
LdChain.push_back(LdOp.getValue(1));
// Check if we can load the element with one instruction
if (LdWidth == NewEltVTWidth) {
- return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
}
unsigned Idx = 1;
@@ -1992,7 +2044,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
while (LdWidth > 0) {
unsigned Increment = NewEltVTWidth / 8;
Offset += Increment;
- BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr,
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
DAG.getIntPtrConstant(Increment));
if (LdWidth < NewEltVTWidth) {
@@ -2003,20 +2055,20 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
NewEltVTWidth = NewEltVT.getSizeInBits();
// Readjust position and vector position based on new load type
Idx = Idx * (oNewEltVTWidth/NewEltVTWidth);
- VecOp = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, VecOp);
+ VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp);
}
- SDValue LdOp = DAG.getLoad(NewEltVT, Chain, BasePtr, SV,
+ SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV,
SVOffset+Offset, isVolatile,
MinAlign(Alignment, Offset));
LdChain.push_back(LdOp.getValue(1));
- VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, VecOp, LdOp,
+ VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOp,
DAG.getIntPtrConstant(Idx++));
LdWidth -= NewEltVTWidth;
}
- return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
}
void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
@@ -2027,7 +2079,8 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
unsigned Alignment,
bool isVolatile,
SDValue ValOp,
- unsigned StWidth) {
+ unsigned StWidth,
+ DebugLoc dl) {
// Breaks the stores into a series of power of 2 width stores. For any
// width, we convert the vector to the vector of element size that we
// want to store. This avoids requiring a stack convert.
@@ -2039,10 +2092,10 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
FindAssocWidenVecType(TLI, StWidth, WidenVT, NewEltVT, NewVecVT);
unsigned NewEltVTWidth = NewEltVT.getSizeInBits();
- SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, ValOp);
- SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, VecOp,
+ SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, ValOp);
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp,
DAG.getIntPtrConstant(0));
- SDValue StOp = DAG.getStore(Chain, EOp, BasePtr, SV, SVOffset,
+ SDValue StOp = DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset,
isVolatile, Alignment);
StChain.push_back(StOp);
@@ -2058,7 +2111,7 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
while (StWidth > 0) {
unsigned Increment = NewEltVTWidth / 8;
Offset += Increment;
- BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr,
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
DAG.getIntPtrConstant(Increment));
if (StWidth < NewEltVTWidth) {
@@ -2069,12 +2122,12 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
NewEltVTWidth = NewEltVT.getSizeInBits();
// Readjust position and vector position based on new load type
Idx = Idx * (oNewEltVTWidth/NewEltVTWidth);
- VecOp = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, VecOp);
+ VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp);
}
- EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, VecOp,
+ EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp,
DAG.getIntPtrConstant(Idx++));
- StChain.push_back(DAG.getStore(Chain, EOp, BasePtr, SV,
+ StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
SVOffset + Offset, isVolatile,
MinAlign(Alignment, Offset)));
StWidth -= NewEltVTWidth;
@@ -2089,6 +2142,7 @@ SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) {
MVT InVT = InOp.getValueType();
assert(InVT.getVectorElementType() == NVT.getVectorElementType() &&
"input and widen element type must match");
+ DebugLoc dl = InOp.getNode()->getDebugLoc();
// Check if InOp already has the right width.
if (InVT == NVT)
@@ -2099,16 +2153,16 @@ SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) {
if (WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0) {
unsigned NumConcat = WidenNumElts / InNumElts;
SmallVector<SDValue, 16> Ops(NumConcat);
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT);
Ops[0] = InOp;
for (unsigned i = 1; i != NumConcat; ++i)
Ops[i] = UndefVal;
- return DAG.getNode(ISD::CONCAT_VECTORS, NVT, &Ops[0], NumConcat);
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, &Ops[0], NumConcat);
}
if (WidenNumElts < InNumElts && InNumElts % WidenNumElts)
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, NVT, InOp,
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NVT, InOp,
DAG.getIntPtrConstant(0));
// Fall back to extract and build.
@@ -2117,11 +2171,11 @@ SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) {
unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
unsigned Idx;
for (Idx = 0; Idx < MinNumElts; ++Idx)
- Ops[Idx] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp,
+ Ops[Idx] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
DAG.getIntPtrConstant(Idx));
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
for ( ; Idx < WidenNumElts; ++Idx)
Ops[Idx] = UndefVal;
- return DAG.getNode(ISD::BUILD_VECTOR, NVT, &Ops[0], WidenNumElts);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, &Ops[0], WidenNumElts);
}
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index bd786daedb7e..5eaf596c3d89 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -91,7 +91,7 @@ public:
return Topo.IsReachable(SU, TargetSU);
}
- /// willCreateCycle - Returns true if adding an edge from SU to TargetSU will
+ /// WillCreateCycle - Returns true if adding an edge from SU to TargetSU will
/// create a cycle.
bool WillCreateCycle(SUnit *SU, SUnit *TargetSU) {
return Topo.WillCreateCycle(SU, TargetSU);
@@ -114,8 +114,8 @@ public:
}
private:
- void ReleasePred(SUnit *SU, SDep *PredEdge);
- void ReleaseSucc(SUnit *SU, SDep *SuccEdge);
+ void ReleasePred(SUnit *SU, const SDep *PredEdge);
+ void ReleaseSucc(SUnit *SU, const SDep *SuccEdge);
void CapturePred(SDep *PredEdge);
void ScheduleNodeBottomUp(SUnit*, unsigned);
void ScheduleNodeTopDown(SUnit*, unsigned);
@@ -192,7 +192,7 @@ void ScheduleDAGRRList::Schedule() {
/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
/// the AvailableQueue if the count reaches zero. Also update its cycle bound.
-void ScheduleDAGRRList::ReleasePred(SUnit *SU, SDep *PredEdge) {
+void ScheduleDAGRRList::ReleasePred(SUnit *SU, const SDep *PredEdge) {
SUnit *PredSU = PredEdge->getSUnit();
--PredSU->NumSuccsLeft;
@@ -312,8 +312,7 @@ void ScheduleDAGRRList::UnscheduleNodeBottomUp(SUnit *SU) {
}
/// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in
-/// BTCycle in order to schedule a specific node. Returns the last unscheduled
-/// SUnit. Also returns if a successor is unscheduled in the process.
+/// BTCycle in order to schedule a specific node.
void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle,
unsigned &CurCycle) {
SUnit *OldSU = NULL;
@@ -327,11 +326,7 @@ void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle,
--CurCycle;
}
-
- if (SU->isSucc(OldSU)) {
- assert(false && "Something is wrong!");
- abort();
- }
+ assert(!SU->isSucc(OldSU) && "Something is wrong!");
++NumBacktracks;
}
@@ -751,10 +746,7 @@ void ScheduleDAGRRList::ListScheduleBottomUp() {
CurSU = NewDef;
}
- if (!CurSU) {
- assert(false && "Unable to resolve live physical register dependencies!");
- abort();
- }
+ assert(CurSU && "Unable to resolve live physical register dependencies!");
}
// Add the nodes that aren't ready back onto the available list.
@@ -785,7 +777,7 @@ void ScheduleDAGRRList::ListScheduleBottomUp() {
/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
/// the AvailableQueue if the count reaches zero. Also update its cycle bound.
-void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) {
+void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, const SDep *SuccEdge) {
SUnit *SuccSU = SuccEdge->getSUnit();
--SuccSU->NumPredsLeft;
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
index 2fa53e08e220..06cae7d496e8 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
@@ -219,7 +219,7 @@ unsigned ScheduleDAGSDNodes::getVR(SDValue Op,
const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType());
VReg = MRI.createVirtualRegister(RC);
}
- BuildMI(BB, TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg);
+ BuildMI(BB, Op.getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF),VReg);
return VReg;
}
@@ -333,33 +333,6 @@ void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op,
}
}
-/// getSubRegisterRegClass - Returns the register class of specified register
-/// class' "SubIdx"'th sub-register class.
-static const TargetRegisterClass*
-getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx) {
- // Pick the register class of the subregister
- TargetRegisterInfo::regclass_iterator I =
- TRC->subregclasses_begin() + SubIdx-1;
- assert(I < TRC->subregclasses_end() &&
- "Invalid subregister index for register class");
- return *I;
-}
-
-/// getSuperRegisterRegClass - Returns the register class of a superreg A whose
-/// "SubIdx"'th sub-register class is the specified register class and whose
-/// type matches the specified type.
-static const TargetRegisterClass*
-getSuperRegisterRegClass(const TargetRegisterClass *TRC,
- unsigned SubIdx, MVT VT) {
- // Pick the register class of the superegister for this type
- for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(),
- E = TRC->superregclasses_end(); I != E; ++I)
- if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC)
- return *I;
- assert(false && "Couldn't find the register class");
- return 0;
-}
-
/// EmitSubregNode - Generate machine code for subreg nodes.
///
void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,
@@ -386,12 +359,11 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,
unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
// Create the extract_subreg machine instruction.
- MachineInstr *MI = BuildMI(MF, TII->get(TargetInstrInfo::EXTRACT_SUBREG));
+ MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(),
+ TII->get(TargetInstrInfo::EXTRACT_SUBREG));
// Figure out the register class to create for the destreg.
- unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
- const TargetRegisterClass *TRC = MRI.getRegClass(VReg);
- const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx);
+ const TargetRegisterClass *SRC = TLI->getRegClassFor(Node->getValueType(0));
if (VRBase) {
// Grab the destination register
@@ -416,7 +388,6 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,
SDValue N0 = Node->getOperand(0);
SDValue N1 = Node->getOperand(1);
SDValue N2 = Node->getOperand(2);
- unsigned SubReg = getVR(N1, VRBaseMap);
unsigned SubIdx = cast<ConstantSDNode>(N2)->getZExtValue();
@@ -425,14 +396,13 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,
if (VRBase) {
TRC = MRI.getRegClass(VRBase);
} else {
- TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx,
- Node->getValueType(0));
+ TRC = TLI->getRegClassFor(Node->getValueType(0));
assert(TRC && "Couldn't determine register class for insert_subreg");
VRBase = MRI.createVirtualRegister(TRC); // Create the reg
}
// Create the insert_subreg or subreg_to_reg machine instruction.
- MachineInstr *MI = BuildMI(MF, TII->get(Opc));
+ MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), TII->get(Opc));
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
// If creating a subreg_to_reg, then the first input operand
@@ -489,7 +459,7 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
#endif
// Create the new machine instruction.
- MachineInstr *MI = BuildMI(MF, II);
+ MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), II);
// Add result register values for things that are defined by this
// instruction.
@@ -510,8 +480,9 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
// specific inserter which may returns a new basic block.
BB = TLI->EmitInstrWithCustomInserter(MI, BB);
Begin = End = BB->end();
- } else
+ } else {
BB->insert(End, MI);
+ }
// Additional results must be an physical register def.
if (HasPhysRegOuts) {
@@ -574,7 +545,8 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
--NumOps; // Ignore the flag operand.
// Create the inline asm machine instruction.
- MachineInstr *MI = BuildMI(MF, TII->get(TargetInstrInfo::INLINEASM));
+ MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(),
+ TII->get(TargetInstrInfo::INLINEASM));
// Add the asm string as an external symbol operand.
const char *AsmStr =
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e3fcc2c2166b..c34211505ac2 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -342,8 +342,8 @@ static void AddNodeIDOperands(FoldingSetNodeID &ID,
static void AddNodeIDOperands(FoldingSetNodeID &ID,
const SDUse *Ops, unsigned NumOps) {
for (; NumOps; --NumOps, ++Ops) {
- ID.AddPointer(Ops->getVal());
- ID.AddInteger(Ops->getSDValue().getResNo());
+ ID.AddPointer(Ops->getNode());
+ ID.AddInteger(Ops->getResNo());
}
}
@@ -429,18 +429,14 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
}
case ISD::LOAD: {
const LoadSDNode *LD = cast<LoadSDNode>(N);
- ID.AddInteger(LD->getAddressingMode());
- ID.AddInteger(LD->getExtensionType());
ID.AddInteger(LD->getMemoryVT().getRawBits());
- ID.AddInteger(LD->getRawFlags());
+ ID.AddInteger(LD->getRawSubclassData());
break;
}
case ISD::STORE: {
const StoreSDNode *ST = cast<StoreSDNode>(N);
- ID.AddInteger(ST->getAddressingMode());
- ID.AddInteger(ST->isTruncatingStore());
ID.AddInteger(ST->getMemoryVT().getRawBits());
- ID.AddInteger(ST->getRawFlags());
+ ID.AddInteger(ST->getRawSubclassData());
break;
}
case ISD::ATOMIC_CMP_SWAP:
@@ -456,7 +452,8 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
case ISD::ATOMIC_LOAD_UMIN:
case ISD::ATOMIC_LOAD_UMAX: {
const AtomicSDNode *AT = cast<AtomicSDNode>(N);
- ID.AddInteger(AT->getRawFlags());
+ ID.AddInteger(AT->getMemoryVT().getRawBits());
+ ID.AddInteger(AT->getRawSubclassData());
break;
}
} // end switch (N->getOpcode())
@@ -476,11 +473,20 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {
}
/// encodeMemSDNodeFlags - Generic routine for computing a value for use in
-/// the CSE map that carries both alignment and volatility information.
+/// the CSE map that carries alignment, volatility, indexing mode, and
+/// extension/truncation information.
///
static inline unsigned
-encodeMemSDNodeFlags(bool isVolatile, unsigned Alignment) {
- return isVolatile | ((Log2_32(Alignment) + 1) << 1);
+encodeMemSDNodeFlags(int ConvType, ISD::MemIndexedMode AM,
+ bool isVolatile, unsigned Alignment) {
+ 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) |
+ ((Log2_32(Alignment) + 1) << 6);
}
//===----------------------------------------------------------------------===//
@@ -538,8 +544,7 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,
// Process the worklist, deleting the nodes and adding their uses to the
// worklist.
while (!DeadNodes.empty()) {
- SDNode *N = DeadNodes.back();
- DeadNodes.pop_back();
+ SDNode *N = DeadNodes.pop_back_val();
if (UpdateListener)
UpdateListener->NodeDeleted(N, 0);
@@ -549,10 +554,11 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,
// Next, brutally remove the operand list. This is safe to do, as there are
// no cycles in the graph.
- for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
- SDNode *Operand = I->getVal();
- Operand->removeUser(std::distance(N->op_begin(), I), N);
-
+ for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) {
+ SDUse &Use = *I++;
+ SDNode *Operand = Use.getNode();
+ Use.set(SDValue());
+
// Now that we removed this operand, see if there are no uses of it left.
if (Operand->use_empty())
DeadNodes.push_back(Operand);
@@ -568,8 +574,6 @@ void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){
}
void SelectionDAG::DeleteNode(SDNode *N) {
- assert(N->use_empty() && "Cannot delete a node that is not dead!");
-
// First take this out of the appropriate CSE map.
RemoveNodeFromCSEMaps(N);
@@ -579,11 +583,11 @@ void SelectionDAG::DeleteNode(SDNode *N) {
}
void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) {
- assert(N != AllNodes.begin());
+ assert(N != AllNodes.begin() && "Cannot delete the entry node!");
+ assert(N->use_empty() && "Cannot delete a node that is not dead!");
// Drop all of the operands and decrement used node's use counts.
- for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
- I->getVal()->removeUser(std::distance(N->op_begin(), I), N);
+ N->DropOperands();
DeallocateNode(N);
}
@@ -652,20 +656,36 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
return Erased;
}
-/// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps. It
-/// has been taken out and modified in some way. If the specified node already
-/// exists in the CSE maps, do not modify the maps, but return the existing node
-/// instead. If it doesn't exist, add it and return null.
+/// AddModifiedNodeToCSEMaps - The specified node has been removed from the CSE
+/// maps and modified in place. Add it back to the CSE maps, unless an identical
+/// node already exists, in which case transfer all its users to the existing
+/// node. This transfer can potentially trigger recursive merging.
///
-SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) {
- assert(N->getNumOperands() && "This is a leaf node!");
-
- if (doNotCSE(N))
- return 0;
+void
+SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N,
+ DAGUpdateListener *UpdateListener) {
+ // For node types that aren't CSE'd, just act as if no identical node
+ // already exists.
+ if (!doNotCSE(N)) {
+ SDNode *Existing = CSEMap.GetOrInsertNode(N);
+ if (Existing != N) {
+ // If there was already an existing matching node, use ReplaceAllUsesWith
+ // to replace the dead one with the existing one. This can cause
+ // recursive merging of other unrelated nodes down the line.
+ ReplaceAllUsesWith(N, Existing, UpdateListener);
+
+ // N is now dead. Inform the listener if it exists and delete it.
+ if (UpdateListener)
+ UpdateListener->NodeDeleted(N, Existing);
+ DeleteNodeNotInCSEMaps(N);
+ return;
+ }
+ }
- SDNode *New = CSEMap.GetOrInsertNode(N);
- if (New != N) return New; // Node already existed.
- return 0;
+ // If the node doesn't already exist, we updated it. Inform a listener if
+ // it exists.
+ if (UpdateListener)
+ UpdateListener->NodeUpdated(N);
}
/// FindModifiedNodeSlot - Find a slot for the specified node if its operands
@@ -748,7 +768,7 @@ void SelectionDAG::VerifyNode(SDNode *N) {
// following checks at least makes it possible to legalize most of the time.
// MVT EltVT = N->getValueType(0).getVectorElementType();
// for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
-// assert(I->getSDValue().getValueType() == EltVT &&
+// assert(I->getValueType() == EltVT &&
// "Wrong operand type!");
break;
}
@@ -804,7 +824,7 @@ void SelectionDAG::clear() {
std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(),
static_cast<SDNode*>(0));
- EntryNode.Uses = 0;
+ EntryNode.UseList = 0;
AllNodes.push_back(&EntryNode);
Root = getEntryNode();
}
@@ -817,8 +837,35 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, MVT VT) {
getConstant(Imm, Op.getValueType()));
}
+SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, DebugLoc DL, MVT VT) {
+ if (Op.getValueType() == VT) return Op;
+ APInt Imm = APInt::getLowBitsSet(Op.getValueSizeInBits(),
+ VT.getSizeInBits());
+ return getNode(ISD::AND, DL, Op.getValueType(), Op,
+ getConstant(Imm, Op.getValueType()));
+}
+
+/// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
+///
+SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) {
+ SDValue NegOne;
+ if (VT.isVector()) {
+ MVT EltVT = VT.getVectorElementType();
+ SDValue NegOneElt =
+ getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), EltVT);
+ std::vector<SDValue> NegOnes(VT.getVectorNumElements(), NegOneElt);
+ NegOne = getNode(ISD::BUILD_VECTOR, DL, VT, &NegOnes[0], NegOnes.size());
+ } else {
+ NegOne = getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT);
+ }
+ return getNode(ISD::XOR, DL, VT, Val, NegOne);
+}
+
SDValue SelectionDAG::getConstant(uint64_t Val, MVT VT, bool isT) {
MVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT;
+ 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!");
return getConstant(APInt(EltVT.getSizeInBits(), Val), VT, isT);
}
@@ -938,7 +985,7 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV,
ID.AddInteger(Offset);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
+ return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<GlobalAddressSDNode>();
new (N) GlobalAddressSDNode(isTargetGA, GV, VT, Offset);
CSEMap.InsertNode(N, IP);
@@ -1036,6 +1083,20 @@ SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
return SDValue(N, 0);
}
+SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl) {
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::BasicBlock, getVTList(MVT::Other), 0, 0);
+ ID.AddPointer(MBB);
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode *N = NodeAllocator.Allocate<BasicBlockSDNode>();
+ new (N) BasicBlockSDNode(MBB, dl);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getArgFlags(ISD::ArgFlagsTy Flags) {
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::ARG_FLAGS, getVTList(MVT::Other), 0, 0);
@@ -1073,6 +1134,15 @@ SDValue SelectionDAG::getExternalSymbol(const char *Sym, MVT VT) {
return SDValue(N, 0);
}
+SDValue SelectionDAG::getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT) {
+ SDNode *&N = ExternalSymbols[Sym];
+ if (N) return SDValue(N, 0);
+ N = NodeAllocator.Allocate<ExternalSymbolSDNode>();
+ new (N) ExternalSymbolSDNode(false, dl, Sym, VT);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, MVT VT) {
SDNode *&N = TargetExternalSymbols[Sym];
if (N) return SDValue(N, 0);
@@ -1082,6 +1152,16 @@ SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, MVT VT) {
return SDValue(N, 0);
}
+SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, DebugLoc dl,
+ MVT VT) {
+ SDNode *&N = TargetExternalSymbols[Sym];
+ if (N) return SDValue(N, 0);
+ N = NodeAllocator.Allocate<ExternalSymbolSDNode>();
+ new (N) ExternalSymbolSDNode(true, dl, Sym, VT);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
if ((unsigned)Cond >= CondCodeNodes.size())
CondCodeNodes.resize(Cond+1);
@@ -1154,6 +1234,23 @@ SDValue SelectionDAG::getLabel(unsigned Opcode,
return SDValue(N, 0);
}
+SDValue SelectionDAG::getLabel(unsigned Opcode, DebugLoc dl,
+ SDValue Root,
+ unsigned LabelID) {
+ FoldingSetNodeID ID;
+ SDValue Ops[] = { Root };
+ AddNodeIDNode(ID, Opcode, getVTList(MVT::Other), &Ops[0], 1);
+ ID.AddInteger(LabelID);
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode *N = NodeAllocator.Allocate<LabelSDNode>();
+ new (N) LabelSDNode(Opcode, dl, Root, LabelID);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getSrcValue(const Value *V) {
assert((!V || isa<PointerType>(V->getType())) &&
"SrcValue is not a pointer?");
@@ -1195,6 +1292,17 @@ SDValue SelectionDAG::getMemOperand(const MachineMemOperand &MO) {
return SDValue(N, 0);
}
+/// getShiftAmountOperand - Return the specified value casted to
+/// the target's desired shift amount type.
+SDValue SelectionDAG::getShiftAmountOperand(SDValue Op) {
+ MVT OpTy = Op.getValueType();
+ MVT ShTy = TLI.getShiftAmountTy();
+ if (OpTy == ShTy || OpTy.isVector()) return Op;
+
+ ISD::NodeType Opcode = OpTy.bitsGT(ShTy) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
+ return getNode(Opcode, ShTy, Op);
+}
+
/// CreateStackTemporary - Create a stack temporary, suitable for holding the
/// specified value type.
SDValue SelectionDAG::CreateStackTemporary(MVT VT, unsigned minAlign) {
@@ -1225,7 +1333,7 @@ SDValue SelectionDAG::CreateStackTemporary(MVT VT1, MVT VT2) {
}
SDValue SelectionDAG::FoldSetCC(MVT VT, SDValue N1,
- SDValue N2, ISD::CondCode Cond) {
+ SDValue N2, ISD::CondCode Cond, DebugLoc dl) {
// These setcc operations always fold.
switch (Cond) {
default: break;
@@ -1278,29 +1386,29 @@ SDValue SelectionDAG::FoldSetCC(MVT VT, SDValue N1,
switch (Cond) {
default: break;
case ISD::SETEQ: if (R==APFloat::cmpUnordered)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, dl, VT);
// fall through
case ISD::SETOEQ: return getConstant(R==APFloat::cmpEqual, VT);
case ISD::SETNE: if (R==APFloat::cmpUnordered)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, dl, VT);
// fall through
case ISD::SETONE: return getConstant(R==APFloat::cmpGreaterThan ||
R==APFloat::cmpLessThan, VT);
case ISD::SETLT: if (R==APFloat::cmpUnordered)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, dl, VT);
// fall through
case ISD::SETOLT: return getConstant(R==APFloat::cmpLessThan, VT);
case ISD::SETGT: if (R==APFloat::cmpUnordered)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, dl, VT);
// fall through
case ISD::SETOGT: return getConstant(R==APFloat::cmpGreaterThan, VT);
case ISD::SETLE: if (R==APFloat::cmpUnordered)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, dl, VT);
// fall through
case ISD::SETOLE: return getConstant(R==APFloat::cmpLessThan ||
R==APFloat::cmpEqual, VT);
case ISD::SETGE: if (R==APFloat::cmpUnordered)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, dl, VT);
// fall through
case ISD::SETOGE: return getConstant(R==APFloat::cmpGreaterThan ||
R==APFloat::cmpEqual, VT);
@@ -1318,7 +1426,7 @@ SDValue SelectionDAG::FoldSetCC(MVT VT, SDValue N1,
}
} else {
// Ensure that the constant occurs on the RHS.
- return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond));
+ return getSetCC(dl, VT, N2, N1, ISD::getSetCCSwappedOperands(Cond));
}
}
@@ -2041,10 +2149,11 @@ bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const {
/// element of the result of the vector shuffle.
SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) {
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
SDValue PermMask = N->getOperand(2);
SDValue Idx = PermMask.getOperand(i);
if (Idx.getOpcode() == ISD::UNDEF)
- return getNode(ISD::UNDEF, VT.getVectorElementType());
+ return getNode(ISD::UNDEF, dl, VT.getVectorElementType());
unsigned Index = cast<ConstantSDNode>(Idx)->getZExtValue();
unsigned NumElems = PermMask.getNumOperands();
SDValue V = (Index < NumElems) ? N->getOperand(0) : N->getOperand(1);
@@ -2058,7 +2167,7 @@ SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) {
}
if (V.getOpcode() == ISD::SCALAR_TO_VECTOR)
return (Index == 0) ? V.getOperand(0)
- : getNode(ISD::UNDEF, VT.getVectorElementType());
+ : getNode(ISD::UNDEF, dl, VT.getVectorElementType());
if (V.getOpcode() == ISD::BUILD_VECTOR)
return V.getOperand(Index);
if (V.getOpcode() == ISD::VECTOR_SHUFFLE)
@@ -2070,13 +2179,17 @@ SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) {
/// getNode - Gets or creates the specified node.
///
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT) {
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opcode, getVTList(VT), 0, 0);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<SDNode>();
- new (N) SDNode(Opcode, SDNode::getSDVTList(VT));
+ new (N) SDNode(Opcode, DL, SDNode::getSDVTList(VT));
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
@@ -2087,6 +2200,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT) {
}
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, Operand);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
+ MVT VT, SDValue Operand) {
// Constant fold unary operations with an integer constant operand.
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Operand.getNode())) {
const APInt &Val = C->getAPIntValue();
@@ -2183,7 +2301,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
Operand.getValueType().isFloatingPoint() && "Invalid FP cast!");
if (Operand.getValueType() == VT) return Operand; // noop conversion.
if (Operand.getOpcode() == ISD::UNDEF)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, DL, VT);
break;
case ISD::SIGN_EXTEND:
assert(VT.isInteger() && Operand.getValueType().isInteger() &&
@@ -2192,7 +2310,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
assert(Operand.getValueType().bitsLT(VT)
&& "Invalid sext node, dst < src!");
if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND)
- return getNode(OpOpcode, VT, Operand.getNode()->getOperand(0));
+ return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0));
break;
case ISD::ZERO_EXTEND:
assert(VT.isInteger() && Operand.getValueType().isInteger() &&
@@ -2201,7 +2319,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
assert(Operand.getValueType().bitsLT(VT)
&& "Invalid zext node, dst < src!");
if (OpOpcode == ISD::ZERO_EXTEND) // (zext (zext x)) -> (zext x)
- return getNode(ISD::ZERO_EXTEND, VT, Operand.getNode()->getOperand(0));
+ return getNode(ISD::ZERO_EXTEND, DL, VT,
+ Operand.getNode()->getOperand(0));
break;
case ISD::ANY_EXTEND:
assert(VT.isInteger() && Operand.getValueType().isInteger() &&
@@ -2211,7 +2330,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
&& "Invalid anyext node, dst < src!");
if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND)
// (ext (zext x)) -> (zext x) and (ext (sext x)) -> (sext x)
- return getNode(OpOpcode, VT, Operand.getNode()->getOperand(0));
+ return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0));
break;
case ISD::TRUNCATE:
assert(VT.isInteger() && Operand.getValueType().isInteger() &&
@@ -2220,14 +2339,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
assert(Operand.getValueType().bitsGT(VT)
&& "Invalid truncate node, src < dst!");
if (OpOpcode == ISD::TRUNCATE)
- return getNode(ISD::TRUNCATE, VT, Operand.getNode()->getOperand(0));
+ return getNode(ISD::TRUNCATE, DL, VT, Operand.getNode()->getOperand(0));
else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND ||
OpOpcode == ISD::ANY_EXTEND) {
// If the source is smaller than the dest, we still need an extend.
if (Operand.getNode()->getOperand(0).getValueType().bitsLT(VT))
- return getNode(OpOpcode, VT, Operand.getNode()->getOperand(0));
+ return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0));
else if (Operand.getNode()->getOperand(0).getValueType().bitsGT(VT))
- return getNode(ISD::TRUNCATE, VT, Operand.getNode()->getOperand(0));
+ return getNode(ISD::TRUNCATE, DL, VT, Operand.getNode()->getOperand(0));
else
return Operand.getNode()->getOperand(0);
}
@@ -2238,16 +2357,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
&& "Cannot BIT_CONVERT between types of different sizes!");
if (VT == Operand.getValueType()) return Operand; // noop conversion.
if (OpOpcode == ISD::BIT_CONVERT) // bitconv(bitconv(x)) -> bitconv(x)
- return getNode(ISD::BIT_CONVERT, VT, Operand.getOperand(0));
+ return getNode(ISD::BIT_CONVERT, DL, VT, Operand.getOperand(0));
if (OpOpcode == ISD::UNDEF)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, DL, VT);
break;
case ISD::SCALAR_TO_VECTOR:
assert(VT.isVector() && !Operand.getValueType().isVector() &&
VT.getVectorElementType() == Operand.getValueType() &&
"Illegal SCALAR_TO_VECTOR node!");
if (OpOpcode == ISD::UNDEF)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, DL, VT);
// scalar_to_vector(extract_vector_elt V, 0) -> V, top bits are undefined.
if (OpOpcode == ISD::EXTRACT_VECTOR_ELT &&
isa<ConstantSDNode>(Operand.getOperand(1)) &&
@@ -2256,15 +2375,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
return Operand.getOperand(0);
break;
case ISD::FNEG:
- if (OpOpcode == ISD::FSUB) // -(X-Y) -> (Y-X)
- return getNode(ISD::FSUB, VT, Operand.getNode()->getOperand(1),
+ // -(X-Y) -> (Y-X) is unsafe because when X==Y, -0.0 != +0.0
+ if (UnsafeFPMath && OpOpcode == ISD::FSUB)
+ return getNode(ISD::FSUB, DL, VT, Operand.getNode()->getOperand(1),
Operand.getNode()->getOperand(0));
if (OpOpcode == ISD::FNEG) // --X -> X
return Operand.getNode()->getOperand(0);
break;
case ISD::FABS:
if (OpOpcode == ISD::FNEG) // abs(-X) -> abs(X)
- return getNode(ISD::FABS, VT, Operand.getNode()->getOperand(0));
+ return getNode(ISD::FABS, DL, VT, Operand.getNode()->getOperand(0));
break;
}
@@ -2278,11 +2398,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
N = NodeAllocator.Allocate<UnarySDNode>();
- new (N) UnarySDNode(Opcode, VTs, Operand);
+ new (N) UnarySDNode(Opcode, DL, VTs, Operand);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<UnarySDNode>();
- new (N) UnarySDNode(Opcode, VTs, Operand);
+ new (N) UnarySDNode(Opcode, DL, VTs, Operand);
}
AllNodes.push_back(N);
@@ -2330,6 +2450,11 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode,
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SDValue N1, SDValue N2) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ SDValue N1, SDValue N2) {
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode());
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.getNode());
switch (Opcode) {
@@ -2349,7 +2474,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
N2.getOpcode() == ISD::BUILD_VECTOR) {
SmallVector<SDValue, 16> Elts(N1.getNode()->op_begin(), N1.getNode()->op_end());
Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end());
- return getNode(ISD::BUILD_VECTOR, VT, &Elts[0], Elts.size());
+ return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size());
}
break;
case ISD::AND:
@@ -2422,9 +2547,6 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
"Shift operators return type must be the same as their first arg");
assert(VT.isInteger() && N2.getValueType().isInteger() &&
"Shifts only work on integers");
- assert((N2.getValueType() == TLI.getShiftAmountTy() ||
- (N2.getValueType().isVector() && N2.getValueType().isInteger())) &&
- "Wrong type for shift amount");
// Always fold shifts of i1 values so the code generator doesn't need to
// handle them. Since we know the size of the shift has to be less than the
@@ -2478,7 +2600,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
case ISD::EXTRACT_VECTOR_ELT:
// EXTRACT_VECTOR_ELT of an UNDEF is an UNDEF.
if (N1.getOpcode() == ISD::UNDEF)
- return getNode(ISD::UNDEF, VT);
+ return getNode(ISD::UNDEF, DL, VT);
// EXTRACT_VECTOR_ELT of CONCAT_VECTORS is often formed while lowering is
// expanding copies of large vectors from registers.
@@ -2487,7 +2609,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
N1.getNumOperands() > 0) {
unsigned Factor =
N1.getOperand(0).getValueType().getVectorNumElements();
- return getNode(ISD::EXTRACT_VECTOR_ELT, VT,
+ return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT,
N1.getOperand(N2C->getZExtValue() / Factor),
getConstant(N2C->getZExtValue() % Factor,
N2.getValueType()));
@@ -2501,10 +2623,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
// EXTRACT_VECTOR_ELT of INSERT_VECTOR_ELT is often formed when vector
// operations are lowered to scalars.
if (N1.getOpcode() == ISD::INSERT_VECTOR_ELT) {
+ // If the indices are the same, return the inserted element.
if (N1.getOperand(2) == N2)
return N1.getOperand(1);
- else
- return getNode(ISD::EXTRACT_VECTOR_ELT, VT, N1.getOperand(0), N2);
+ // If the indices are known different, extract the element from
+ // the original vector.
+ else if (isa<ConstantSDNode>(N1.getOperand(2)) &&
+ isa<ConstantSDNode>(N2))
+ return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(0), N2);
}
break;
case ISD::EXTRACT_ELEMENT:
@@ -2653,7 +2779,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
return N1;
case ISD::OR:
if (!VT.isVector())
- return getConstant(VT.getIntegerVTBitMask(), VT);
+ return getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT);
// For vectors, we can't easily build an all one vector, just return
// the LHS.
return N1;
@@ -2673,11 +2799,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
N = NodeAllocator.Allocate<BinarySDNode>();
- new (N) BinarySDNode(Opcode, VTs, N1, N2);
+ new (N) BinarySDNode(Opcode, DL, VTs, N1, N2);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<BinarySDNode>();
- new (N) BinarySDNode(Opcode, VTs, N1, N2);
+ new (N) BinarySDNode(Opcode, DL, VTs, N1, N2);
}
AllNodes.push_back(N);
@@ -2689,6 +2815,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SDValue N1, SDValue N2, SDValue N3) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2, N3);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ SDValue N1, SDValue N2, SDValue N3) {
// Perform various simplifications.
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode());
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.getNode());
@@ -2702,12 +2833,12 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SmallVector<SDValue, 16> Elts(N1.getNode()->op_begin(), N1.getNode()->op_end());
Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end());
Elts.insert(Elts.end(), N3.getNode()->op_begin(), N3.getNode()->op_end());
- return getNode(ISD::BUILD_VECTOR, VT, &Elts[0], Elts.size());
+ return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size());
}
break;
case ISD::SETCC: {
// Use FoldSetCC to simplify SETCC's.
- SDValue Simp = FoldSetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get());
+ SDValue Simp = FoldSetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get(), DL);
if (Simp.getNode()) return Simp;
break;
}
@@ -2724,7 +2855,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
case ISD::BRCOND:
if (N2C) {
if (N2C->getZExtValue()) // Unconditional branch
- return getNode(ISD::BR, MVT::Other, N1, N3);
+ return getNode(ISD::BR, DL, MVT::Other, N1, N3);
else
return N1; // Never-taken branch
}
@@ -2755,11 +2886,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
N = NodeAllocator.Allocate<TernarySDNode>();
- new (N) TernarySDNode(Opcode, VTs, N1, N2, N3);
+ new (N) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<TernarySDNode>();
- new (N) TernarySDNode(Opcode, VTs, N1, N2, N3);
+ new (N) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
}
AllNodes.push_back(N);
#ifndef NDEBUG
@@ -2771,15 +2902,27 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SDValue N1, SDValue N2, SDValue N3,
SDValue N4) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2, N3, N4);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ SDValue N1, SDValue N2, SDValue N3,
+ SDValue N4) {
SDValue Ops[] = { N1, N2, N3, N4 };
- return getNode(Opcode, VT, Ops, 4);
+ return getNode(Opcode, DL, VT, Ops, 4);
}
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SDValue N1, SDValue N2, SDValue N3,
SDValue N4, SDValue N5) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2, N3, N4, N5);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ SDValue N1, SDValue N2, SDValue N3,
+ SDValue N4, SDValue N5) {
SDValue Ops[] = { N1, N2, N3, N4, N5 };
- return getNode(Opcode, VT, Ops, 5);
+ return getNode(Opcode, DL, VT, Ops, 5);
}
/// getMemsetValue - Vectorized representation of the memset value
@@ -2848,7 +2991,8 @@ static SDValue getMemsetStringVal(MVT VT, SelectionDAG &DAG,
static SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset,
SelectionDAG &DAG) {
MVT VT = Base.getValueType();
- return DAG.getNode(ISD::ADD, VT, Base, DAG.getConstant(Offset, VT));
+ return DAG.getNode(ISD::ADD, Base.getNode()->getDebugLoc(),
+ VT, Base, DAG.getConstant(Offset, VT));
}
/// isMemSrcFromString - Returns true if memcpy source is a string constant.
@@ -3158,11 +3302,12 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, SDValue Dst,
Entry.Node = Dst; Args.push_back(Entry);
Entry.Node = Src; Args.push_back(Entry);
Entry.Node = Size; Args.push_back(Entry);
+ // FIXME: pass in DebugLoc
std::pair<SDValue,SDValue> CallResult =
TLI.LowerCallTo(Chain, Type::VoidTy,
false, false, false, false, CallingConv::C, false,
getExternalSymbol("memcpy", TLI.getPointerTy()),
- Args, *this);
+ Args, *this, DebugLoc::getUnknownLoc());
return CallResult.second;
}
@@ -3203,11 +3348,12 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, SDValue Dst,
Entry.Node = Dst; Args.push_back(Entry);
Entry.Node = Src; Args.push_back(Entry);
Entry.Node = Size; Args.push_back(Entry);
+ // FIXME: pass in DebugLoc
std::pair<SDValue,SDValue> CallResult =
TLI.LowerCallTo(Chain, Type::VoidTy,
false, false, false, false, CallingConv::C, false,
getExternalSymbol("memmove", TLI.getPointerTy()),
- Args, *this);
+ Args, *this, DebugLoc::getUnknownLoc());
return CallResult.second;
}
@@ -3254,11 +3400,12 @@ SDValue SelectionDAG::getMemset(SDValue Chain, SDValue Dst,
Args.push_back(Entry);
Entry.Node = Size; Entry.Ty = IntPtrTy; Entry.isSExt = false;
Args.push_back(Entry);
+ // FIXME: pass in DebugLoc
std::pair<SDValue,SDValue> CallResult =
TLI.LowerCallTo(Chain, Type::VoidTy,
false, false, false, false, CallingConv::C, false,
getExternalSymbol("memset", TLI.getPointerTy()),
- Args, *this);
+ Args, *this, DebugLoc::getUnknownLoc());
return CallResult.second;
}
@@ -3277,6 +3424,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
SDVTList VTs = getVTList(VT, MVT::Other);
FoldingSetNodeID ID;
+ ID.AddInteger(MemVT.getRawBits());
SDValue Ops[] = {Chain, Ptr, Cmp, Swp};
AddNodeIDNode(ID, Opcode, VTs, Ops, 4);
void* IP = 0;
@@ -3290,6 +3438,35 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
return SDValue(N, 0);
}
+SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT,
+ SDValue Chain,
+ SDValue Ptr, SDValue Cmp,
+ SDValue Swp, const Value* PtrVal,
+ unsigned Alignment) {
+ assert(Opcode == ISD::ATOMIC_CMP_SWAP && "Invalid Atomic Op");
+ assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types");
+
+ MVT VT = Cmp.getValueType();
+
+ if (Alignment == 0) // Ensure that codegen never sees alignment 0
+ Alignment = getMVTAlignment(MemVT);
+
+ SDVTList VTs = getVTList(VT, MVT::Other);
+ FoldingSetNodeID ID;
+ ID.AddInteger(MemVT.getRawBits());
+ SDValue Ops[] = {Chain, Ptr, Cmp, Swp};
+ AddNodeIDNode(ID, Opcode, VTs, Ops, 4);
+ void* IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode* N = NodeAllocator.Allocate<AtomicSDNode>();
+ new (N) AtomicSDNode(Opcode, dl, VTs, MemVT,
+ Chain, Ptr, Cmp, Swp, PtrVal, Alignment);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
SDValue Chain,
SDValue Ptr, SDValue Val,
@@ -3315,6 +3492,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
SDVTList VTs = getVTList(VT, MVT::Other);
FoldingSetNodeID ID;
+ ID.AddInteger(MemVT.getRawBits());
SDValue Ops[] = {Chain, Ptr, Val};
AddNodeIDNode(ID, Opcode, VTs, Ops, 3);
void* IP = 0;
@@ -3328,6 +3506,45 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
return SDValue(N, 0);
}
+SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT,
+ SDValue Chain,
+ SDValue Ptr, SDValue Val,
+ const Value* PtrVal,
+ unsigned Alignment) {
+ assert((Opcode == ISD::ATOMIC_LOAD_ADD ||
+ Opcode == ISD::ATOMIC_LOAD_SUB ||
+ Opcode == ISD::ATOMIC_LOAD_AND ||
+ Opcode == ISD::ATOMIC_LOAD_OR ||
+ Opcode == ISD::ATOMIC_LOAD_XOR ||
+ Opcode == ISD::ATOMIC_LOAD_NAND ||
+ Opcode == ISD::ATOMIC_LOAD_MIN ||
+ Opcode == ISD::ATOMIC_LOAD_MAX ||
+ Opcode == ISD::ATOMIC_LOAD_UMIN ||
+ Opcode == ISD::ATOMIC_LOAD_UMAX ||
+ Opcode == ISD::ATOMIC_SWAP) &&
+ "Invalid Atomic Op");
+
+ MVT VT = Val.getValueType();
+
+ if (Alignment == 0) // Ensure that codegen never sees alignment 0
+ Alignment = getMVTAlignment(MemVT);
+
+ SDVTList VTs = getVTList(VT, MVT::Other);
+ FoldingSetNodeID ID;
+ ID.AddInteger(MemVT.getRawBits());
+ SDValue Ops[] = {Chain, Ptr, Val};
+ AddNodeIDNode(ID, Opcode, VTs, Ops, 3);
+ void* IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode* N = NodeAllocator.Allocate<AtomicSDNode>();
+ new (N) AtomicSDNode(Opcode, dl, VTs, MemVT,
+ Chain, Ptr, Val, PtrVal, Alignment);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
/// getMergeValues - Create a MERGE_VALUES node from the given operands.
/// Allowed to return something different (and simpler) if Simplify is true.
SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps) {
@@ -3341,6 +3558,20 @@ SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps) {
return getNode(ISD::MERGE_VALUES, getVTList(&VTs[0], NumOps), Ops, NumOps);
}
+/// DebugLoc-aware version.
+SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps,
+ DebugLoc dl) {
+ if (NumOps == 1)
+ return Ops[0];
+
+ SmallVector<MVT, 4> VTs;
+ VTs.reserve(NumOps);
+ for (unsigned i = 0; i < NumOps; ++i)
+ VTs.push_back(Ops[i].getValueType());
+ return getNode(ISD::MERGE_VALUES, dl, getVTList(&VTs[0], NumOps),
+ Ops, NumOps);
+}
+
SDValue
SelectionDAG::getMemIntrinsicNode(unsigned Opcode,
const MVT *VTs, unsigned NumVTs,
@@ -3354,6 +3585,18 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode,
}
SDValue
+SelectionDAG::getMemIntrinsicNode(unsigned Opcode, DebugLoc dl,
+ const MVT *VTs, unsigned NumVTs,
+ const SDValue *Ops, unsigned NumOps,
+ MVT MemVT, const Value *srcValue, int SVOff,
+ unsigned Align, bool Vol,
+ bool ReadMem, bool WriteMem) {
+ return getMemIntrinsicNode(Opcode, dl, makeVTList(VTs, NumVTs), Ops, NumOps,
+ MemVT, srcValue, SVOff, Align, Vol,
+ ReadMem, WriteMem);
+}
+
+SDValue
SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDVTList VTList,
const SDValue *Ops, unsigned NumOps,
MVT MemVT, const Value *srcValue, int SVOff,
@@ -3382,6 +3625,34 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDVTList VTList,
}
SDValue
+SelectionDAG::getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
+ const SDValue *Ops, unsigned NumOps,
+ MVT MemVT, const Value *srcValue, int SVOff,
+ unsigned Align, bool Vol,
+ bool ReadMem, bool WriteMem) {
+ // Memoize the node unless it returns a flag.
+ MemIntrinsicSDNode *N;
+ if (VTList.VTs[VTList.NumVTs-1] != MVT::Flag) {
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps);
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+
+ N = NodeAllocator.Allocate<MemIntrinsicSDNode>();
+ new (N) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps, MemVT,
+ srcValue, SVOff, Align, Vol, ReadMem, WriteMem);
+ CSEMap.InsertNode(N, IP);
+ } else {
+ N = NodeAllocator.Allocate<MemIntrinsicSDNode>();
+ new (N) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps, MemVT,
+ srcValue, SVOff, Align, Vol, ReadMem, WriteMem);
+ }
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
+SDValue
SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
bool IsInreg, SDVTList VTs,
const SDValue *Operands, unsigned NumOperands) {
@@ -3407,6 +3678,31 @@ SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
}
SDValue
+SelectionDAG::getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
+ bool IsTailCall, bool IsInreg, SDVTList VTs,
+ const SDValue *Operands, unsigned NumOperands) {
+ // Do not include isTailCall in the folding set profile.
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::CALL, VTs, Operands, NumOperands);
+ ID.AddInteger(CallingConv);
+ ID.AddInteger(IsVarArgs);
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {
+ // Instead of including isTailCall in the folding set, we just
+ // set the flag of the existing node.
+ if (!IsTailCall)
+ cast<CallSDNode>(E)->setNotTailCall();
+ return SDValue(E, 0);
+ }
+ SDNode *N = NodeAllocator.Allocate<CallSDNode>();
+ new (N) CallSDNode(CallingConv, dl, IsVarArgs, IsTailCall, IsInreg,
+ VTs, Operands, NumOperands);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
+SDValue
SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
MVT VT, SDValue Chain,
SDValue Ptr, SDValue Offset,
@@ -3442,10 +3738,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
SDValue Ops[] = { Chain, Ptr, Offset };
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
- ID.AddInteger(AM);
- ID.AddInteger(ExtType);
ID.AddInteger(EVT.getRawBits());
- ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+ ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, isVolatile, Alignment));
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
@@ -3457,6 +3751,55 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
return SDValue(N, 0);
}
+SDValue
+SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
+ ISD::LoadExtType ExtType, MVT VT, SDValue Chain,
+ SDValue Ptr, SDValue Offset,
+ const Value *SV, int SVOffset, MVT EVT,
+ bool isVolatile, unsigned Alignment) {
+ if (Alignment == 0) // Ensure that codegen never sees alignment 0
+ Alignment = getMVTAlignment(VT);
+
+ if (VT == EVT) {
+ ExtType = ISD::NON_EXTLOAD;
+ } else if (ExtType == ISD::NON_EXTLOAD) {
+ assert(VT == EVT && "Non-extending load from different memory type!");
+ } else {
+ // Extending load.
+ if (VT.isVector())
+ assert(EVT.getVectorNumElements() == VT.getVectorNumElements() &&
+ "Invalid vector extload!");
+ else
+ assert(EVT.bitsLT(VT) &&
+ "Should only be an extending load, not truncating!");
+ assert((ExtType == ISD::EXTLOAD || VT.isInteger()) &&
+ "Cannot sign/zero extend a FP/Vector load!");
+ assert(VT.isInteger() == EVT.isInteger() &&
+ "Cannot convert from FP to Int or Int -> FP!");
+ }
+
+ bool Indexed = AM != ISD::UNINDEXED;
+ assert((Indexed || Offset.getOpcode() == ISD::UNDEF) &&
+ "Unindexed load with an offset!");
+
+ SDVTList VTs = Indexed ?
+ getVTList(VT, Ptr.getValueType(), MVT::Other) : getVTList(VT, MVT::Other);
+ SDValue Ops[] = { Chain, Ptr, Offset };
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
+ ID.AddInteger(EVT.getRawBits());
+ ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, isVolatile, Alignment));
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode *N = NodeAllocator.Allocate<LoadSDNode>();
+ new (N) LoadSDNode(Ops, dl, VTs, AM, ExtType, EVT, SV, SVOffset,
+ Alignment, isVolatile);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getLoad(MVT VT,
SDValue Chain, SDValue Ptr,
const Value *SV, int SVOffset,
@@ -3466,6 +3809,15 @@ SDValue SelectionDAG::getLoad(MVT VT,
SV, SVOffset, VT, isVolatile, Alignment);
}
+SDValue SelectionDAG::getLoad(MVT VT, DebugLoc dl,
+ SDValue Chain, SDValue Ptr,
+ const Value *SV, int SVOffset,
+ bool isVolatile, unsigned Alignment) {
+ SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
+ return getLoad(ISD::UNINDEXED, dl, ISD::NON_EXTLOAD, VT, Chain, Ptr, Undef,
+ SV, SVOffset, VT, isVolatile, Alignment);
+}
+
SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT VT,
SDValue Chain, SDValue Ptr,
const Value *SV,
@@ -3476,6 +3828,16 @@ SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT VT,
SV, SVOffset, EVT, isVolatile, Alignment);
}
+SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, MVT VT,
+ SDValue Chain, SDValue Ptr,
+ const Value *SV,
+ int SVOffset, MVT EVT,
+ bool isVolatile, unsigned Alignment) {
+ SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
+ return getLoad(ISD::UNINDEXED, dl, ExtType, VT, Chain, Ptr, Undef,
+ SV, SVOffset, EVT, isVolatile, Alignment);
+}
+
SDValue
SelectionDAG::getIndexedLoad(SDValue OrigLoad, SDValue Base,
SDValue Offset, ISD::MemIndexedMode AM) {
@@ -3488,6 +3850,18 @@ SelectionDAG::getIndexedLoad(SDValue OrigLoad, SDValue Base,
LD->isVolatile(), LD->getAlignment());
}
+SDValue
+SelectionDAG::getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
+ SDValue Offset, ISD::MemIndexedMode AM) {
+ LoadSDNode *LD = cast<LoadSDNode>(OrigLoad);
+ assert(LD->getOffset().getOpcode() == ISD::UNDEF &&
+ "Load is already a indexed load!");
+ return getLoad(AM, dl, LD->getExtensionType(), OrigLoad.getValueType(),
+ LD->getChain(), Base, Offset, LD->getSrcValue(),
+ LD->getSrcValueOffset(), LD->getMemoryVT(),
+ LD->isVolatile(), LD->getAlignment());
+}
+
SDValue SelectionDAG::getStore(SDValue Chain, SDValue Val,
SDValue Ptr, const Value *SV, int SVOffset,
bool isVolatile, unsigned Alignment) {
@@ -3501,10 +3875,9 @@ SDValue SelectionDAG::getStore(SDValue Chain, SDValue Val,
SDValue Ops[] = { Chain, Val, Ptr, Undef };
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
- ID.AddInteger(ISD::UNINDEXED);
- ID.AddInteger(false);
ID.AddInteger(VT.getRawBits());
- ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+ ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED,
+ isVolatile, Alignment));
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
@@ -3516,6 +3889,33 @@ SDValue SelectionDAG::getStore(SDValue Chain, SDValue Val,
return SDValue(N, 0);
}
+SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
+ SDValue Ptr, const Value *SV, int SVOffset,
+ bool isVolatile, unsigned Alignment) {
+ MVT VT = Val.getValueType();
+
+ if (Alignment == 0) // Ensure that codegen never sees alignment 0
+ Alignment = getMVTAlignment(VT);
+
+ SDVTList VTs = getVTList(MVT::Other);
+ SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
+ SDValue Ops[] = { Chain, Val, Ptr, Undef };
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
+ ID.AddInteger(VT.getRawBits());
+ ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED,
+ isVolatile, Alignment));
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode *N = NodeAllocator.Allocate<StoreSDNode>();
+ new (N) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED, false,
+ VT, SV, SVOffset, Alignment, isVolatile);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getTruncStore(SDValue Chain, SDValue Val,
SDValue Ptr, const Value *SV,
int SVOffset, MVT SVT,
@@ -3537,10 +3937,9 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, SDValue Val,
SDValue Ops[] = { Chain, Val, Ptr, Undef };
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
- ID.AddInteger(ISD::UNINDEXED);
- ID.AddInteger(1);
ID.AddInteger(SVT.getRawBits());
- ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
+ ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED,
+ isVolatile, Alignment));
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
@@ -3552,6 +3951,41 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, SDValue Val,
return SDValue(N, 0);
}
+SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
+ SDValue Ptr, const Value *SV,
+ int SVOffset, MVT SVT,
+ bool isVolatile, unsigned Alignment) {
+ MVT VT = Val.getValueType();
+
+ if (VT == SVT)
+ return getStore(Chain, dl, Val, Ptr, SV, SVOffset, isVolatile, Alignment);
+
+ assert(VT.bitsGT(SVT) && "Not a truncation?");
+ assert(VT.isInteger() == SVT.isInteger() &&
+ "Can't do FP-INT conversion!");
+
+ if (Alignment == 0) // Ensure that codegen never sees alignment 0
+ Alignment = getMVTAlignment(VT);
+
+ SDVTList VTs = getVTList(MVT::Other);
+ SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
+ SDValue Ops[] = { Chain, Val, Ptr, Undef };
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
+ ID.AddInteger(SVT.getRawBits());
+ ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED,
+ isVolatile, Alignment));
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode *N = NodeAllocator.Allocate<StoreSDNode>();
+ new (N) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED, true,
+ SVT, SV, SVOffset, Alignment, isVolatile);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue
SelectionDAG::getIndexedStore(SDValue OrigStore, SDValue Base,
SDValue Offset, ISD::MemIndexedMode AM) {
@@ -3562,10 +3996,8 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, SDValue Base,
SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
- ID.AddInteger(AM);
- ID.AddInteger(ST->isTruncatingStore());
ID.AddInteger(ST->getMemoryVT().getRawBits());
- ID.AddInteger(ST->getRawFlags());
+ ID.AddInteger(ST->getRawSubclassData());
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
@@ -3579,6 +4011,31 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, SDValue Base,
return SDValue(N, 0);
}
+SDValue
+SelectionDAG::getIndexedStore(SDValue OrigStore, DebugLoc dl, SDValue Base,
+ SDValue Offset, ISD::MemIndexedMode AM) {
+ StoreSDNode *ST = cast<StoreSDNode>(OrigStore);
+ assert(ST->getOffset().getOpcode() == ISD::UNDEF &&
+ "Store is already a indexed store!");
+ SDVTList VTs = getVTList(Base.getValueType(), MVT::Other);
+ SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
+ ID.AddInteger(ST->getMemoryVT().getRawBits());
+ ID.AddInteger(ST->getRawSubclassData());
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDValue(E, 0);
+ SDNode *N = NodeAllocator.Allocate<StoreSDNode>();
+ new (N) StoreSDNode(Ops, dl, VTs, AM,
+ ST->isTruncatingStore(), ST->getMemoryVT(),
+ ST->getSrcValue(), ST->getSrcValueOffset(),
+ ST->getAlignment(), ST->isVolatile());
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getVAArg(MVT VT,
SDValue Chain, SDValue Ptr,
SDValue SV) {
@@ -3588,27 +4045,37 @@ SDValue SelectionDAG::getVAArg(MVT VT,
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
const SDUse *Ops, unsigned NumOps) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, Ops, NumOps);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ const SDUse *Ops, unsigned NumOps) {
switch (NumOps) {
- case 0: return getNode(Opcode, VT);
- case 1: return getNode(Opcode, VT, Ops[0]);
- case 2: return getNode(Opcode, VT, Ops[0], Ops[1]);
- case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]);
+ case 0: return getNode(Opcode, DL, VT);
+ case 1: return getNode(Opcode, DL, VT, Ops[0]);
+ case 2: return getNode(Opcode, DL, VT, Ops[0], Ops[1]);
+ case 3: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Ops[2]);
default: break;
}
// Copy from an SDUse array into an SDValue array for use with
// the regular getNode logic.
SmallVector<SDValue, 8> NewOps(Ops, Ops + NumOps);
- return getNode(Opcode, VT, &NewOps[0], NumOps);
+ return getNode(Opcode, DL, VT, &NewOps[0], NumOps);
}
SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
const SDValue *Ops, unsigned NumOps) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, Ops, NumOps);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
+ const SDValue *Ops, unsigned NumOps) {
switch (NumOps) {
- case 0: return getNode(Opcode, VT);
- case 1: return getNode(Opcode, VT, Ops[0]);
- case 2: return getNode(Opcode, VT, Ops[0], Ops[1]);
- case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]);
+ case 0: return getNode(Opcode, DL, VT);
+ case 1: return getNode(Opcode, DL, VT, Ops[0]);
+ case 2: return getNode(Opcode, DL, VT, Ops[0], Ops[1]);
+ case 3: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Ops[2]);
default: break;
}
@@ -3635,19 +4102,23 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
// Memoize nodes.
SDNode *N;
SDVTList VTs = getVTList(VT);
+
if (VT != MVT::Flag) {
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opcode, VTs, Ops, NumOps);
void *IP = 0;
+
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
+
N = NodeAllocator.Allocate<SDNode>();
- new (N) SDNode(Opcode, VTs, Ops, NumOps);
+ new (N) SDNode(Opcode, DL, VTs, Ops, NumOps);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<SDNode>();
- new (N) SDNode(Opcode, VTs, Ops, NumOps);
+ new (N) SDNode(Opcode, DL, VTs, Ops, NumOps);
}
+
AllNodes.push_back(N);
#ifndef NDEBUG
VerifyNode(N);
@@ -3658,22 +4129,39 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
SDValue SelectionDAG::getNode(unsigned Opcode,
const std::vector<MVT> &ResultTys,
const SDValue *Ops, unsigned NumOps) {
- return getNode(Opcode, getNodeValueTypes(ResultTys), ResultTys.size(),
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), ResultTys, Ops, NumOps);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
+ const std::vector<MVT> &ResultTys,
+ const SDValue *Ops, unsigned NumOps) {
+ return getNode(Opcode, DL, getNodeValueTypes(ResultTys), ResultTys.size(),
Ops, NumOps);
}
SDValue SelectionDAG::getNode(unsigned Opcode,
const MVT *VTs, unsigned NumVTs,
const SDValue *Ops, unsigned NumOps) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTs, NumVTs, Ops, NumOps);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
+ const MVT *VTs, unsigned NumVTs,
+ const SDValue *Ops, unsigned NumOps) {
if (NumVTs == 1)
- return getNode(Opcode, VTs[0], Ops, NumOps);
- return getNode(Opcode, makeVTList(VTs, NumVTs), Ops, NumOps);
+ return getNode(Opcode, DL, VTs[0], Ops, NumOps);
+ return getNode(Opcode, DL, makeVTList(VTs, NumVTs), Ops, NumOps);
}
SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
const SDValue *Ops, unsigned NumOps) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, Ops, NumOps);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
+ const SDValue *Ops, unsigned NumOps) {
if (VTList.NumVTs == 1)
- return getNode(Opcode, VTList.VTs[0], Ops, NumOps);
+ return getNode(Opcode, DL, VTList.VTs[0], Ops, NumOps);
switch (Opcode) {
// FIXME: figure out how to safely handle things like
@@ -3685,14 +4173,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
case ISD::SHL_PARTS:
if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG &&
cast<VTSDNode>(N3.getOperand(1))->getVT() != MVT::i1)
- return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
+ return getNode(Opcode, DL, VT, N1, N2, N3.getOperand(0));
else if (N3.getOpcode() == ISD::AND)
if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N3.getOperand(1))) {
// If the and is only masking out bits that cannot effect the shift,
// eliminate the and.
unsigned NumBits = VT.getSizeInBits()*2;
if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1)
- return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
+ return getNode(Opcode, DL, VT, N1, N2, N3.getOperand(0));
}
break;
#endif
@@ -3708,31 +4196,31 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
return SDValue(E, 0);
if (NumOps == 1) {
N = NodeAllocator.Allocate<UnarySDNode>();
- new (N) UnarySDNode(Opcode, VTList, Ops[0]);
+ new (N) UnarySDNode(Opcode, DL, VTList, Ops[0]);
} else if (NumOps == 2) {
N = NodeAllocator.Allocate<BinarySDNode>();
- new (N) BinarySDNode(Opcode, VTList, Ops[0], Ops[1]);
+ new (N) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
} else if (NumOps == 3) {
N = NodeAllocator.Allocate<TernarySDNode>();
- new (N) TernarySDNode(Opcode, VTList, Ops[0], Ops[1], Ops[2]);
+ new (N) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1], Ops[2]);
} else {
N = NodeAllocator.Allocate<SDNode>();
- new (N) SDNode(Opcode, VTList, Ops, NumOps);
+ new (N) SDNode(Opcode, DL, VTList, Ops, NumOps);
}
CSEMap.InsertNode(N, IP);
} else {
if (NumOps == 1) {
N = NodeAllocator.Allocate<UnarySDNode>();
- new (N) UnarySDNode(Opcode, VTList, Ops[0]);
+ new (N) UnarySDNode(Opcode, DL, VTList, Ops[0]);
} else if (NumOps == 2) {
N = NodeAllocator.Allocate<BinarySDNode>();
- new (N) BinarySDNode(Opcode, VTList, Ops[0], Ops[1]);
+ new (N) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
} else if (NumOps == 3) {
N = NodeAllocator.Allocate<TernarySDNode>();
- new (N) TernarySDNode(Opcode, VTList, Ops[0], Ops[1], Ops[2]);
+ new (N) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1], Ops[2]);
} else {
N = NodeAllocator.Allocate<SDNode>();
- new (N) SDNode(Opcode, VTList, Ops, NumOps);
+ new (N) SDNode(Opcode, DL, VTList, Ops, NumOps);
}
}
AllNodes.push_back(N);
@@ -3743,39 +4231,70 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
}
SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList) {
- return getNode(Opcode, VTList, 0, 0);
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList) {
+ return getNode(Opcode, DL, VTList, 0, 0);
}
SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
- SDValue N1) {
+ SDValue N1) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
+ SDValue N1) {
SDValue Ops[] = { N1 };
- return getNode(Opcode, VTList, Ops, 1);
+ return getNode(Opcode, DL, VTList, Ops, 1);
}
SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
SDValue N1, SDValue N2) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
+ SDValue N1, SDValue N2) {
SDValue Ops[] = { N1, N2 };
- return getNode(Opcode, VTList, Ops, 2);
+ return getNode(Opcode, DL, VTList, Ops, 2);
}
SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
SDValue N1, SDValue N2, SDValue N3) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2, N3);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
+ SDValue N1, SDValue N2, SDValue N3) {
SDValue Ops[] = { N1, N2, N3 };
- return getNode(Opcode, VTList, Ops, 3);
+ return getNode(Opcode, DL, VTList, Ops, 3);
}
SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
SDValue N1, SDValue N2, SDValue N3,
SDValue N4) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2, N3, N4);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
+ SDValue N1, SDValue N2, SDValue N3,
+ SDValue N4) {
SDValue Ops[] = { N1, N2, N3, N4 };
- return getNode(Opcode, VTList, Ops, 4);
+ return getNode(Opcode, DL, VTList, Ops, 4);
}
SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
SDValue N1, SDValue N2, SDValue N3,
SDValue N4, SDValue N5) {
+ return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2, N3, N4, N5);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
+ SDValue N1, SDValue N2, SDValue N3,
+ SDValue N4, SDValue N5) {
SDValue Ops[] = { N1, N2, N3, N4, N5 };
- return getNode(Opcode, VTList, Ops, 5);
+ return getNode(Opcode, DL, VTList, Ops, 5);
}
SDVTList SelectionDAG::getVTList(MVT VT) {
@@ -3885,10 +4404,7 @@ SDValue SelectionDAG::UpdateNodeOperands(SDValue InN, SDValue Op) {
InsertPos = 0;
// Now we update the operands.
- N->OperandList[0].getVal()->removeUser(0, N);
- N->OperandList[0] = Op;
- N->OperandList[0].setUser(N);
- Op.getNode()->addUser(0, N);
+ N->OperandList[0].set(Op);
// If this gets put into a CSE map, add it.
if (InsertPos) CSEMap.InsertNode(N, InsertPos);
@@ -3915,18 +4431,10 @@ UpdateNodeOperands(SDValue InN, SDValue Op1, SDValue Op2) {
InsertPos = 0;
// Now we update the operands.
- if (N->OperandList[0] != Op1) {
- N->OperandList[0].getVal()->removeUser(0, N);
- N->OperandList[0] = Op1;
- N->OperandList[0].setUser(N);
- Op1.getNode()->addUser(0, N);
- }
- if (N->OperandList[1] != Op2) {
- N->OperandList[1].getVal()->removeUser(1, N);
- N->OperandList[1] = Op2;
- N->OperandList[1].setUser(N);
- Op2.getNode()->addUser(1, N);
- }
+ if (N->OperandList[0] != Op1)
+ N->OperandList[0].set(Op1);
+ if (N->OperandList[1] != Op2)
+ N->OperandList[1].set(Op2);
// If this gets put into a CSE map, add it.
if (InsertPos) CSEMap.InsertNode(N, InsertPos);
@@ -3982,14 +4490,9 @@ UpdateNodeOperands(SDValue InN, const SDValue *Ops, unsigned NumOps) {
InsertPos = 0;
// Now we update the operands.
- for (unsigned i = 0; i != NumOps; ++i) {
- if (N->OperandList[i] != Ops[i]) {
- N->OperandList[i].getVal()->removeUser(i, N);
- N->OperandList[i] = Ops[i];
- N->OperandList[i].setUser(N);
- Ops[i].getNode()->addUser(i, N);
- }
- }
+ for (unsigned i = 0; i != NumOps; ++i)
+ if (N->OperandList[i] != Ops[i])
+ N->OperandList[i].set(Ops[i]);
// If this gets put into a CSE map, add it.
if (InsertPos) CSEMap.InsertNode(N, InsertPos);
@@ -4001,10 +4504,10 @@ UpdateNodeOperands(SDValue InN, const SDValue *Ops, unsigned NumOps) {
void SDNode::DropOperands() {
// Unlike the code in MorphNodeTo that does this, we don't need to
// watch for dead nodes here.
- for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
- I->getVal()->removeUser(std::distance(op_begin(), I), this);
-
- NumOperands = 0;
+ for (op_iterator I = op_begin(), E = op_end(); I != E; ) {
+ SDUse &Use = *I++;
+ Use.set(SDValue());
+ }
}
/// SelectNodeTo - These are wrappers around MorphNodeTo that accept a
@@ -4229,10 +4732,10 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
// Clear the operands list, updating used nodes to remove this from their
// use list. Keep track of any operands that become dead as a result.
SmallPtrSet<SDNode*, 16> DeadNodeSet;
- for (SDNode::op_iterator B = N->op_begin(), I = B, E = N->op_end();
- I != E; ++I) {
- SDNode *Used = I->getVal();
- Used->removeUser(std::distance(B, I), N);
+ for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) {
+ SDUse &Use = *I++;
+ SDNode *Used = Use.getNode();
+ Use.set(SDValue());
if (Used->use_empty())
DeadNodeSet.insert(Used);
}
@@ -4258,10 +4761,8 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
// Assign the new operands.
N->NumOperands = NumOps;
for (unsigned i = 0, e = NumOps; i != e; ++i) {
- N->OperandList[i] = Ops[i];
N->OperandList[i].setUser(N);
- SDNode *ToUse = N->OperandList[i].getVal();
- ToUse->addUser(i, N);
+ N->OperandList[i].setInitial(Ops[i]);
}
// Delete any nodes that are still dead after adding the uses for the
@@ -4288,32 +4789,70 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT) {
return getNode(~Opcode, VT).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT) {
+ return getNode(~Opcode, dl, VT).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT, SDValue Op1) {
return getNode(~Opcode, VT, Op1).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
+ SDValue Op1) {
+ return getNode(~Opcode, dl, VT, Op1).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
SDValue Op1, SDValue Op2) {
return getNode(~Opcode, VT, Op1, Op2).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
+ SDValue Op1, SDValue Op2) {
+ return getNode(~Opcode, dl, VT, Op1, Op2).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
SDValue Op1, SDValue Op2,
SDValue Op3) {
return getNode(~Opcode, VT, Op1, Op2, Op3).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3) {
+ return getNode(~Opcode, dl, VT, Op1, Op2, Op3).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
const SDValue *Ops, unsigned NumOps) {
return getNode(~Opcode, VT, Ops, NumOps).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
+ const SDValue *Ops, unsigned NumOps) {
+ return getNode(~Opcode, dl, VT, Ops, NumOps).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2) {
const MVT *VTs = getNodeValueTypes(VT1, VT2);
SDValue Op;
return getNode(~Opcode, VTs, 2, &Op, 0).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
+ MVT VT1, MVT VT2) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2);
+ SDValue Op;
+ return getNode(~Opcode, dl, VTs, 2, &Op, 0).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
MVT VT2, SDValue Op1) {
const MVT *VTs = getNodeValueTypes(VT1, VT2);
return getNode(~Opcode, VTs, 2, &Op1, 1).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
+ MVT VT2, SDValue Op1) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2);
+ return getNode(~Opcode, dl, VTs, 2, &Op1, 1).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
MVT VT2, SDValue Op1,
SDValue Op2) {
@@ -4321,6 +4860,14 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
SDValue Ops[] = { Op1, Op2 };
return getNode(~Opcode, VTs, 2, Ops, 2).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
+ MVT VT2, SDValue Op1,
+ SDValue Op2) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2);
+ SDValue Ops[] = { Op1, Op2 };
+ return getNode(~Opcode, dl, VTs, 2, Ops, 2).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
MVT VT2, SDValue Op1,
SDValue Op2, SDValue Op3) {
@@ -4328,17 +4875,40 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
SDValue Ops[] = { Op1, Op2, Op3 };
return getNode(~Opcode, VTs, 2, Ops, 3).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
+ MVT VT2, SDValue Op1,
+ SDValue Op2, SDValue Op3) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2);
+ SDValue Ops[] = { Op1, Op2, Op3 };
+ return getNode(~Opcode, dl, VTs, 2, Ops, 3).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
const SDValue *Ops, unsigned NumOps) {
const MVT *VTs = getNodeValueTypes(VT1, VT2);
return getNode(~Opcode, VTs, 2, Ops, NumOps).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
+ MVT VT1, MVT VT2,
+ const SDValue *Ops, unsigned NumOps) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2);
+ return getNode(~Opcode, dl, VTs, 2, Ops, NumOps).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
SDValue Op1, SDValue Op2) {
const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
SDValue Ops[] = { Op1, Op2 };
return getNode(~Opcode, VTs, 3, Ops, 2).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
+ MVT VT1, MVT VT2, MVT VT3,
+ SDValue Op1, SDValue Op2) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
+ SDValue Ops[] = { Op1, Op2 };
+ return getNode(~Opcode, dl, VTs, 3, Ops, 2).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
SDValue Op1, SDValue Op2,
SDValue Op3) {
@@ -4346,11 +4916,27 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
SDValue Ops[] = { Op1, Op2, Op3 };
return getNode(~Opcode, VTs, 3, Ops, 3).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
+ MVT VT1, MVT VT2, MVT VT3,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
+ SDValue Ops[] = { Op1, Op2, Op3 };
+ return getNode(~Opcode, dl, VTs, 3, Ops, 3).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
const SDValue *Ops, unsigned NumOps) {
const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
+ MVT VT1, MVT VT2, MVT VT3,
+ const SDValue *Ops, unsigned NumOps) {
+ const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
+ return getNode(~Opcode, dl, VTs, 3, Ops, NumOps).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
MVT VT2, MVT VT3, MVT VT4,
const SDValue *Ops, unsigned NumOps) {
@@ -4362,6 +4948,18 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
const MVT *VTs = getNodeValueTypes(VTList);
return getNode(~Opcode, VTs, 4, Ops, NumOps).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
+ MVT VT2, MVT VT3, MVT VT4,
+ const SDValue *Ops, unsigned NumOps) {
+ std::vector<MVT> VTList;
+ VTList.push_back(VT1);
+ VTList.push_back(VT2);
+ VTList.push_back(VT3);
+ VTList.push_back(VT4);
+ const MVT *VTs = getNodeValueTypes(VTList);
+ return getNode(~Opcode, dl, VTs, 4, Ops, NumOps).getNode();
+}
+
SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
const std::vector<MVT> &ResultTys,
const SDValue *Ops, unsigned NumOps) {
@@ -4369,6 +4967,13 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
return getNode(~Opcode, VTs, ResultTys.size(),
Ops, NumOps).getNode();
}
+SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
+ const std::vector<MVT> &ResultTys,
+ const SDValue *Ops, unsigned NumOps) {
+ const MVT *VTs = getNodeValueTypes(ResultTys);
+ return getNode(~Opcode, dl, VTs, ResultTys.size(),
+ Ops, NumOps).getNode();
+}
/// getNodeIfExists - Get the specified node if it's already available, or
/// else return NULL.
@@ -4384,7 +4989,6 @@ SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
return NULL;
}
-
/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG.
///
@@ -4397,43 +5001,33 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To,
"Cannot replace with this method!");
assert(From != To.getNode() && "Cannot replace uses of with self");
- // Iterate over all the existing uses of From. This specifically avoids
- // visiting any new uses of From that arrise while the replacement is
- // happening, because any such uses would be the result of CSE: If an
- // existing node looks like From after one of its operands is replaced
- // by To, we don't want to replace of all its users with To too.
- // See PR3018 for more info.
+ // Iterate over all the existing uses of From. New uses will be added
+ // to the beginning of the use list, which we avoid visiting.
+ // This specifically avoids visiting uses of From that arise while the
+ // replacement is happening, because any such uses would be the result
+ // of CSE: If an existing node looks like From after one of its operands
+ // 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();
while (UI != UE) {
- SDNode *U = *UI;
- do ++UI; while (UI != UE && *UI == U);
+ SDNode *User = *UI;
// This node is about to morph, remove its old self from the CSE maps.
- RemoveNodeFromCSEMaps(U);
- int operandNum = 0;
- for (SDNode::op_iterator I = U->op_begin(), E = U->op_end();
- I != E; ++I, ++operandNum)
- if (I->getVal() == From) {
- From->removeUser(operandNum, U);
- *I = To;
- I->setUser(U);
- To.getNode()->addUser(operandNum, U);
- }
-
- // Now that we have modified U, add it back to the CSE maps. If it already
- // exists there, recursively merge the results together.
- if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
- ReplaceAllUsesWith(U, Existing, UpdateListener);
- // U is now dead. Inform the listener if it exists and delete it.
- if (UpdateListener)
- UpdateListener->NodeDeleted(U, Existing);
- DeleteNodeNotInCSEMaps(U);
- } else {
- // If the node doesn't already exist, we updated it. Inform a listener if
- // it exists.
- if (UpdateListener)
- UpdateListener->NodeUpdated(U);
- }
+ RemoveNodeFromCSEMaps(User);
+
+ // A user can appear in a use list multiple times, and when this
+ // happens the uses are usually next to each other in the list.
+ // To help reduce the number of CSE recomputations, process all
+ // the uses of this user that we can find this way.
+ do {
+ SDUse &Use = UI.getUse();
+ ++UI;
+ Use.set(To);
+ } while (UI != UE && *UI == User);
+
+ // 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);
}
}
@@ -4457,34 +5051,24 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,
// the ReplaceAllUsesWith above.
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
while (UI != UE) {
- SDNode *U = *UI;
- do ++UI; while (UI != UE && *UI == U);
+ SDNode *User = *UI;
// This node is about to morph, remove its old self from the CSE maps.
- RemoveNodeFromCSEMaps(U);
- int operandNum = 0;
- for (SDNode::op_iterator I = U->op_begin(), E = U->op_end();
- I != E; ++I, ++operandNum)
- if (I->getVal() == From) {
- From->removeUser(operandNum, U);
- I->getSDValue().setNode(To);
- To->addUser(operandNum, U);
- }
+ RemoveNodeFromCSEMaps(User);
- // Now that we have modified U, add it back to the CSE maps. If it already
- // exists there, recursively merge the results together.
- if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
- ReplaceAllUsesWith(U, Existing, UpdateListener);
- // U is now dead. Inform the listener if it exists and delete it.
- if (UpdateListener)
- UpdateListener->NodeDeleted(U, Existing);
- DeleteNodeNotInCSEMaps(U);
- } else {
- // If the node doesn't already exist, we updated it. Inform a listener if
- // it exists.
- if (UpdateListener)
- UpdateListener->NodeUpdated(U);
- }
+ // A user can appear in a use list multiple times, and when this
+ // happens the uses are usually next to each other in the list.
+ // To help reduce the number of CSE recomputations, process all
+ // the uses of this user that we can find this way.
+ do {
+ SDUse &Use = UI.getUse();
+ ++UI;
+ Use.setNode(To);
+ } while (UI != UE && *UI == User);
+
+ // 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);
}
}
@@ -4503,42 +5087,31 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
// the ReplaceAllUsesWith above.
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
while (UI != UE) {
- SDNode *U = *UI;
- do ++UI; while (UI != UE && *UI == U);
+ SDNode *User = *UI;
// This node is about to morph, remove its old self from the CSE maps.
- RemoveNodeFromCSEMaps(U);
- int operandNum = 0;
- for (SDNode::op_iterator I = U->op_begin(), E = U->op_end();
- I != E; ++I, ++operandNum)
- if (I->getVal() == From) {
- const SDValue &ToOp = To[I->getSDValue().getResNo()];
- From->removeUser(operandNum, U);
- *I = ToOp;
- I->setUser(U);
- ToOp.getNode()->addUser(operandNum, U);
- }
+ RemoveNodeFromCSEMaps(User);
- // Now that we have modified U, add it back to the CSE maps. If it already
- // exists there, recursively merge the results together.
- if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
- ReplaceAllUsesWith(U, Existing, UpdateListener);
- // U is now dead. Inform the listener if it exists and delete it.
- if (UpdateListener)
- UpdateListener->NodeDeleted(U, Existing);
- DeleteNodeNotInCSEMaps(U);
- } else {
- // If the node doesn't already exist, we updated it. Inform a listener if
- // it exists.
- if (UpdateListener)
- UpdateListener->NodeUpdated(U);
- }
+ // A user can appear in a use list multiple times, and when this
+ // happens the uses are usually next to each other in the list.
+ // To help reduce the number of CSE recomputations, process all
+ // the uses of this user that we can find this way.
+ do {
+ SDUse &Use = UI.getUse();
+ const SDValue &ToOp = To[Use.getResNo()];
+ ++UI;
+ Use.set(ToOp);
+ } while (UI != UE && *UI == User);
+
+ // 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);
}
}
/// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
-/// uses of other values produced by From.getVal() alone. The Deleted vector is
-/// handled the same way as for ReplaceAllUsesWith.
+/// uses of other values produced by From.getNode() alone. The Deleted
+/// vector is handled the same way as for ReplaceAllUsesWith.
void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
DAGUpdateListener *UpdateListener){
// Handle the really simple, really trivial case efficiently.
@@ -4550,60 +5123,67 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
return;
}
- // Get all of the users of From.getNode(). We want these in a nice,
- // deterministically ordered and uniqued set, so we use a SmallSetVector.
- SmallSetVector<SDNode*, 16> Users(From.getNode()->use_begin(), From.getNode()->use_end());
+ // Iterate over just the existing users of From. See the comments in
+ // the ReplaceAllUsesWith above.
+ SDNode::use_iterator UI = From.getNode()->use_begin(),
+ UE = From.getNode()->use_end();
+ while (UI != UE) {
+ SDNode *User = *UI;
+ bool UserRemovedFromCSEMaps = false;
+
+ // A user can appear in a use list multiple times, and when this
+ // happens the uses are usually next to each other in the list.
+ // To help reduce the number of CSE recomputations, process all
+ // the uses of this user that we can find this way.
+ do {
+ SDUse &Use = UI.getUse();
+
+ // Skip uses of different values from the same node.
+ if (Use.getResNo() != From.getResNo()) {
+ ++UI;
+ continue;
+ }
- while (!Users.empty()) {
- // We know that this user uses some value of From. If it is the right
- // value, update it.
- SDNode *User = Users.back();
- Users.pop_back();
-
- // Scan for an operand that matches From.
- SDNode::op_iterator Op = User->op_begin(), E = User->op_end();
- for (; Op != E; ++Op)
- if (*Op == From) break;
-
- // If there are no matches, the user must use some other result of From.
- if (Op == E) continue;
-
- // Okay, we know this user needs to be updated. Remove its old self
- // from the CSE maps.
- RemoveNodeFromCSEMaps(User);
-
- // Update all operands that match "From" in case there are multiple uses.
- for (; Op != E; ++Op) {
- if (*Op == From) {
- From.getNode()->removeUser(Op-User->op_begin(), User);
- *Op = To;
- Op->setUser(User);
- To.getNode()->addUser(Op-User->op_begin(), User);
+ // If this node hasn't been modified yet, it's still in the CSE maps,
+ // so remove its old self from the CSE maps.
+ if (!UserRemovedFromCSEMaps) {
+ RemoveNodeFromCSEMaps(User);
+ UserRemovedFromCSEMaps = true;
}
- }
-
+
+ ++UI;
+ Use.set(To);
+ } while (UI != UE && *UI == User);
+
+ // We are iterating over all uses of the From node, so if a use
+ // doesn't use the specific value, no changes are made.
+ if (!UserRemovedFromCSEMaps)
+ continue;
+
// Now that we have modified User, add it back to the CSE maps. If it
// already exists there, recursively merge the results together.
- SDNode *Existing = AddNonLeafNodeToCSEMaps(User);
- if (!Existing) {
- if (UpdateListener) UpdateListener->NodeUpdated(User);
- continue; // Continue on to next user.
- }
-
- // If there was already an existing matching node, use ReplaceAllUsesWith
- // to replace the dead one with the existing one. This can cause
- // recursive merging of other unrelated nodes down the line.
- ReplaceAllUsesWith(User, Existing, UpdateListener);
-
- // User is now dead. Notify a listener if present.
- if (UpdateListener) UpdateListener->NodeDeleted(User, Existing);
- DeleteNodeNotInCSEMaps(User);
+ AddModifiedNodeToCSEMaps(User, UpdateListener);
+ }
+}
+
+namespace {
+ /// UseMemo - This class is used by SelectionDAG::ReplaceAllUsesOfValuesWith
+ /// to record information about a use.
+ struct UseMemo {
+ SDNode *User;
+ unsigned Index;
+ SDUse *Use;
+ };
+
+ /// operator< - Sort Memos by User.
+ bool operator<(const UseMemo &L, const UseMemo &R) {
+ return (intptr_t)L.User < (intptr_t)R.User;
}
}
/// ReplaceAllUsesOfValuesWith - Replace any uses of From with To, leaving
-/// uses of other values produced by From.getVal() alone. The same value may
-/// appear in both the From and To list. The Deleted vector is
+/// uses of other values produced by From.getNode() alone. The same value
+/// may appear in both the From and To list. The Deleted vector is
/// handled the same way as for ReplaceAllUsesWith.
void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,
const SDValue *To,
@@ -4613,57 +5193,50 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,
if (Num == 1)
return ReplaceAllUsesOfValueWith(*From, *To, UpdateListener);
- SmallVector<std::pair<SDNode *, unsigned>, 16> Users;
- for (unsigned i = 0; i != Num; ++i)
- for (SDNode::use_iterator UI = From[i].getNode()->use_begin(),
- E = From[i].getNode()->use_end(); UI != E; ++UI)
- Users.push_back(std::make_pair(*UI, i));
+ // Read up all the uses and make records of them. This helps
+ // processing new uses that are introduced during the
+ // replacement process.
+ SmallVector<UseMemo, 4> Uses;
+ for (unsigned i = 0; i != Num; ++i) {
+ unsigned FromResNo = From[i].getResNo();
+ SDNode *FromNode = From[i].getNode();
+ for (SDNode::use_iterator UI = FromNode->use_begin(),
+ E = FromNode->use_end(); UI != E; ++UI) {
+ SDUse &Use = UI.getUse();
+ if (Use.getResNo() == FromResNo) {
+ UseMemo Memo = { *UI, i, &Use };
+ Uses.push_back(Memo);
+ }
+ }
+ }
- while (!Users.empty()) {
+ // Sort the uses, so that all the uses from a given User are together.
+ std::sort(Uses.begin(), Uses.end());
+
+ for (unsigned UseIndex = 0, UseIndexEnd = Uses.size();
+ UseIndex != UseIndexEnd; ) {
// We know that this user uses some value of From. If it is the right
// value, update it.
- SDNode *User = Users.back().first;
- unsigned i = Users.back().second;
- Users.pop_back();
-
- // Scan for an operand that matches From.
- SDNode::op_iterator Op = User->op_begin(), E = User->op_end();
- for (; Op != E; ++Op)
- if (*Op == From[i]) break;
-
- // If there are no matches, the user must use some other result of From.
- if (Op == E) continue;
-
- // Okay, we know this user needs to be updated. Remove its old self
- // from the CSE maps.
+ SDNode *User = Uses[UseIndex].User;
+
+ // This node is about to morph, remove its old self from the CSE maps.
RemoveNodeFromCSEMaps(User);
-
- // Update all operands that match "From" in case there are multiple uses.
- for (; Op != E; ++Op) {
- if (*Op == From[i]) {
- From[i].getNode()->removeUser(Op-User->op_begin(), User);
- *Op = To[i];
- Op->setUser(User);
- To[i].getNode()->addUser(Op-User->op_begin(), User);
- }
- }
-
+
+ // The Uses array is sorted, so all the uses for a given User
+ // are next to each other in the list.
+ // To help reduce the number of CSE recomputations, process all
+ // the uses of this user that we can find this way.
+ do {
+ unsigned i = Uses[UseIndex].Index;
+ SDUse &Use = *Uses[UseIndex].Use;
+ ++UseIndex;
+
+ Use.set(To[i]);
+ } while (UseIndex != UseIndexEnd && Uses[UseIndex].User == User);
+
// Now that we have modified User, add it back to the CSE maps. If it
// already exists there, recursively merge the results together.
- SDNode *Existing = AddNonLeafNodeToCSEMaps(User);
- if (!Existing) {
- if (UpdateListener) UpdateListener->NodeUpdated(User);
- continue; // Continue on to next user.
- }
-
- // If there was already an existing matching node, use ReplaceAllUsesWith
- // to replace the dead one with the existing one. This can cause
- // recursive merging of other unrelated nodes down the line.
- ReplaceAllUsesWith(User, Existing, UpdateListener);
-
- // User is now dead. Notify a listener if present.
- if (UpdateListener) UpdateListener->NodeDeleted(User, Existing);
- DeleteNodeNotInCSEMaps(User);
+ AddModifiedNodeToCSEMaps(User, UpdateListener);
}
}
@@ -4765,9 +5338,8 @@ GlobalAddressSDNode::GlobalAddressSDNode(bool isTarget, const GlobalValue *GA,
MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, MVT memvt,
const Value *srcValue, int SVO,
unsigned alignment, bool vol)
- : SDNode(Opc, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO),
- Flags(encodeMemSDNodeFlags(vol, alignment)) {
-
+ : SDNode(Opc, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+ SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
assert(getAlignment() == alignment && "Alignment representation error!");
assert(isVolatile() == vol && "Volatile representation error!");
@@ -4777,8 +5349,30 @@ MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops,
unsigned NumOps, MVT memvt, const Value *srcValue,
int SVO, unsigned alignment, bool vol)
: SDNode(Opc, VTs, Ops, NumOps),
- MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO),
- Flags(vol | ((Log2_32(alignment) + 1) << 1)) {
+ MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+ SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
+ assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
+ assert(getAlignment() == alignment && "Alignment representation error!");
+ assert(isVolatile() == vol && "Volatile representation error!");
+}
+
+MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT memvt,
+ const Value *srcValue, int SVO,
+ unsigned alignment, bool vol)
+ : SDNode(Opc, dl, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+ SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
+ assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
+ assert(getAlignment() == alignment && "Alignment representation error!");
+ assert(isVolatile() == vol && "Volatile representation error!");
+}
+
+MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
+ const SDValue *Ops,
+ unsigned NumOps, MVT memvt, const Value *srcValue,
+ int SVO, unsigned alignment, bool vol)
+ : SDNode(Opc, dl, VTs, Ops, NumOps),
+ MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) {
+ SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment);
assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!");
assert(getAlignment() == alignment && "Alignment representation error!");
assert(isVolatile() == vol && "Volatile representation error!");
@@ -4843,7 +5437,7 @@ bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const {
// TODO: Only iterate over uses of a given value of the node
for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
- if (UI.getUse().getSDValue().getResNo() == Value) {
+ if (UI.getUse().getResNo() == Value) {
if (NUses == 0)
return false;
--NUses;
@@ -4861,7 +5455,7 @@ bool SDNode::hasAnyUseOfValue(unsigned Value) const {
assert(Value < getNumValues() && "Bad value!");
for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI)
- if (UI.getUse().getSDValue().getResNo() == Value)
+ if (UI.getUse().getResNo() == Value)
return true;
return false;
@@ -4894,7 +5488,7 @@ bool SDValue::isOperandOf(SDNode *N) const {
bool SDNode::isOperandOf(SDNode *N) const {
for (unsigned i = 0, e = N->NumOperands; i != e; ++i)
- if (this == N->OperandList[i].getVal())
+ if (this == N->OperandList[i].getNode())
return true;
return false;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index f971069e82f5..87d6d2fa5c7a 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -216,14 +216,14 @@ namespace llvm {
/// 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,
+ SDValue getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
SDValue &Chain, SDValue *Flag) const;
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
/// specified value into the registers specified by this object. 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.
- void getCopyToRegs(SDValue Val, SelectionDAG &DAG,
+ void getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
SDValue &Chain, SDValue *Flag) const;
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
@@ -271,6 +271,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli)
}
void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
+ SelectionDAG &DAG,
bool EnableFastISel) {
Fn = &fn;
MF = &mf;
@@ -320,8 +321,53 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
// Create Machine PHI nodes for LLVM PHI nodes, lowering them as
// appropriate.
PHINode *PN;
- for (BasicBlock::iterator I = BB->begin();(PN = dyn_cast<PHINode>(I)); ++I){
- if (PN->use_empty()) continue;
+ DebugLoc DL;
+ for (BasicBlock::iterator
+ I = BB->begin(), E = BB->end(); I != E; ++I) {
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (Function *F = CI->getCalledFunction()) {
+ switch (F->getIntrinsicID()) {
+ default: break;
+ case Intrinsic::dbg_stoppoint: {
+ DwarfWriter *DW = DAG.getDwarfWriter();
+ DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
+
+ if (DW && DW->ValidDebugInfo(SPI->getContext())) {
+ DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
+ unsigned SrcFile = DW->RecordSource(CU.getDirectory(),
+ CU.getFilename());
+ unsigned idx = MF->getOrCreateDebugLocID(SrcFile,
+ SPI->getLine(),
+ SPI->getColumn());
+ DL = DebugLoc::get(idx);
+ }
+
+ break;
+ }
+ case Intrinsic::dbg_func_start: {
+ DwarfWriter *DW = DAG.getDwarfWriter();
+ if (DW) {
+ DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
+ Value *SP = FSI->getSubprogram();
+
+ if (DW->ValidDebugInfo(SP)) {
+ DISubprogram Subprogram(cast<GlobalVariable>(SP));
+ DICompileUnit CU(Subprogram.getCompileUnit());
+ unsigned SrcFile = DW->RecordSource(CU.getDirectory(),
+ CU.getFilename());
+ unsigned Line = Subprogram.getLineNumber();
+ DL = DebugLoc::get(MF->getOrCreateDebugLocID(SrcFile, Line, 0));
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ PN = dyn_cast<PHINode>(I);
+ if (!PN || PN->use_empty()) continue;
unsigned PHIReg = ValueMap[PN];
assert(PHIReg && "PHI node does not have an assigned virtual register!");
@@ -333,7 +379,7 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
unsigned NumRegisters = TLI.getNumRegisters(VT);
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
for (unsigned i = 0; i != NumRegisters; ++i)
- BuildMI(MBB, TII->get(TargetInstrInfo::PHI), PHIReg+i);
+ BuildMI(MBB, DL, TII->get(TargetInstrInfo::PHI), PHIReg + i);
PHIReg += NumRegisters;
}
}
@@ -374,12 +420,10 @@ unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) {
/// 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,
- const SDValue *Parts,
- unsigned NumParts,
- MVT PartVT,
- MVT ValueVT,
- ISD::NodeType AssertOp = ISD::DELETED_NODE) {
+static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl,
+ const SDValue *Parts,
+ unsigned NumParts, MVT PartVT, MVT ValueVT,
+ ISD::NodeType AssertOp = ISD::DELETED_NODE) {
assert(NumParts > 0 && "No parts to assemble!");
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue Val = Parts[0];
@@ -403,34 +447,35 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
MVT::getFloatingPointVT(RoundBits/2);
if (RoundParts > 2) {
- Lo = getCopyFromParts(DAG, Parts, RoundParts/2, PartVT, HalfVT);
- Hi = getCopyFromParts(DAG, Parts+RoundParts/2, RoundParts/2,
+ Lo = getCopyFromParts(DAG, dl, Parts, RoundParts/2, PartVT, HalfVT);
+ Hi = getCopyFromParts(DAG, dl, Parts+RoundParts/2, RoundParts/2,
PartVT, HalfVT);
} else {
- Lo = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[0]);
- Hi = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[1]);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, dl, HalfVT, Parts[0]);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HalfVT, Parts[1]);
}
if (TLI.isBigEndian())
std::swap(Lo, Hi);
- Val = DAG.getNode(ISD::BUILD_PAIR, RoundVT, Lo, Hi);
+ Val = DAG.getNode(ISD::BUILD_PAIR, dl, RoundVT, Lo, Hi);
if (RoundParts < NumParts) {
// Assemble the trailing non-power-of-2 part.
unsigned OddParts = NumParts - RoundParts;
MVT OddVT = MVT::getIntegerVT(OddParts * PartBits);
- Hi = getCopyFromParts(DAG, Parts+RoundParts, OddParts, PartVT, OddVT);
+ Hi = getCopyFromParts(DAG, dl,
+ Parts+RoundParts, OddParts, PartVT, OddVT);
// Combine the round and odd parts.
Lo = Val;
if (TLI.isBigEndian())
std::swap(Lo, Hi);
MVT TotalVT = MVT::getIntegerVT(NumParts * PartBits);
- Hi = DAG.getNode(ISD::ANY_EXTEND, TotalVT, Hi);
- Hi = DAG.getNode(ISD::SHL, TotalVT, Hi,
+ Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi);
+ Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi,
DAG.getConstant(Lo.getValueType().getSizeInBits(),
- TLI.getShiftAmountTy()));
- Lo = DAG.getNode(ISD::ZERO_EXTEND, TotalVT, Lo);
- Val = DAG.getNode(ISD::OR, TotalVT, Lo, Hi);
+ TLI.getPointerTy()));
+ Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo);
+ Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi);
}
} else {
// Handle a multi-element vector.
@@ -451,7 +496,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
// If the register was not expanded, truncate or copy the value,
// as appropriate.
for (unsigned i = 0; i != NumParts; ++i)
- Ops[i] = getCopyFromParts(DAG, &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 operands
@@ -460,14 +505,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
"Must expand into a divisible number of parts!");
unsigned Factor = NumParts / NumIntermediates;
for (unsigned i = 0; i != NumIntermediates; ++i)
- Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
+ Ops[i] = getCopyFromParts(DAG, dl, &Parts[i * Factor], Factor,
PartVT, IntermediateVT);
}
// Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
// operands.
Val = DAG.getNode(IntermediateVT.isVector() ?
- ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR,
+ ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, dl,
ValueVT, &Ops[0], NumIntermediates);
}
}
@@ -480,14 +525,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
if (PartVT.isVector()) {
assert(ValueVT.isVector() && "Unknown vector conversion!");
- return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
}
if (ValueVT.isVector()) {
assert(ValueVT.getVectorElementType() == PartVT &&
ValueVT.getVectorNumElements() == 1 &&
"Only trivial scalar-to-vector conversions should get here!");
- return DAG.getNode(ISD::BUILD_VECTOR, ValueVT, Val);
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val);
}
if (PartVT.isInteger() &&
@@ -497,24 +542,24 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
// indicate whether the truncated bits will always be
// zero or sign-extension.
if (AssertOp != ISD::DELETED_NODE)
- Val = DAG.getNode(AssertOp, PartVT, Val,
+ Val = DAG.getNode(AssertOp, dl, PartVT, Val,
DAG.getValueType(ValueVT));
- return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ return DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
} else {
- return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+ return DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val);
}
}
if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
if (ValueVT.bitsLT(Val.getValueType()))
// FP_ROUND's are always exact here.
- return DAG.getNode(ISD::FP_ROUND, ValueVT, Val,
+ return DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val,
DAG.getIntPtrConstant(1));
- return DAG.getNode(ISD::FP_EXTEND, ValueVT, Val);
+ return DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val);
}
if (PartVT.getSizeInBits() == ValueVT.getSizeInBits())
- return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
assert(0 && "Unknown mismatch!");
return SDValue();
@@ -523,7 +568,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
/// 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, SDValue Val,
+static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, SDValue Val,
SDValue *Parts, unsigned NumParts, MVT PartVT,
ISD::NodeType ExtendKind = ISD::ANY_EXTEND) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
@@ -546,22 +591,22 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
// If the parts cover more bits than the value has, promote the value.
if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
assert(NumParts == 1 && "Do not know what to promote to!");
- Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
+ Val = DAG.getNode(ISD::FP_EXTEND, dl, PartVT, Val);
} else if (PartVT.isInteger() && ValueVT.isInteger()) {
ValueVT = MVT::getIntegerVT(NumParts * PartBits);
- Val = DAG.getNode(ExtendKind, ValueVT, Val);
+ Val = DAG.getNode(ExtendKind, dl, ValueVT, Val);
} else {
assert(0 && "Unknown mismatch!");
}
} else if (PartBits == ValueVT.getSizeInBits()) {
// Different types of the same size.
assert(NumParts == 1 && PartVT != ValueVT);
- Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+ Val = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Val);
} else if (NumParts * PartBits < ValueVT.getSizeInBits()) {
// If the parts cover less bits than value has, truncate the value.
if (PartVT.isInteger() && ValueVT.isInteger()) {
ValueVT = MVT::getIntegerVT(NumParts * PartBits);
- Val = DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
} else {
assert(0 && "Unknown mismatch!");
}
@@ -586,21 +631,21 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
unsigned RoundParts = 1 << Log2_32(NumParts);
unsigned RoundBits = RoundParts * PartBits;
unsigned OddParts = NumParts - RoundParts;
- SDValue OddVal = DAG.getNode(ISD::SRL, ValueVT, Val,
- DAG.getConstant(RoundBits,
- TLI.getShiftAmountTy()));
- getCopyToParts(DAG, OddVal, Parts + RoundParts, OddParts, PartVT);
+ SDValue OddVal = DAG.getNode(ISD::SRL, dl, ValueVT, Val,
+ DAG.getConstant(RoundBits,
+ TLI.getPointerTy()));
+ getCopyToParts(DAG, dl, OddVal, Parts + RoundParts, OddParts, PartVT);
if (TLI.isBigEndian())
// The odd parts were reversed by getCopyToParts - unreverse them.
std::reverse(Parts + RoundParts, Parts + NumParts);
NumParts = RoundParts;
ValueVT = MVT::getIntegerVT(NumParts * PartBits);
- Val = DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
}
// The number of parts is a power of 2. Repeatedly bisect the value using
// EXTRACT_ELEMENT.
- Parts[0] = DAG.getNode(ISD::BIT_CONVERT,
+ Parts[0] = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::getIntegerVT(ValueVT.getSizeInBits()),
Val);
for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) {
@@ -610,14 +655,18 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
SDValue &Part0 = Parts[i];
SDValue &Part1 = Parts[i+StepSize/2];
- Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Part0,
+ Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
+ ThisVT, Part0,
DAG.getConstant(1, PtrVT));
- Part0 = DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Part0,
+ Part0 = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
+ ThisVT, Part0,
DAG.getConstant(0, PtrVT));
if (ThisBits == PartBits && ThisVT != PartVT) {
- Part0 = DAG.getNode(ISD::BIT_CONVERT, PartVT, Part0);
- Part1 = DAG.getNode(ISD::BIT_CONVERT, PartVT, Part1);
+ Part0 = DAG.getNode(ISD::BIT_CONVERT, dl,
+ PartVT, Part0);
+ Part1 = DAG.getNode(ISD::BIT_CONVERT, dl,
+ PartVT, Part1);
}
}
}
@@ -632,12 +681,13 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
if (NumParts == 1) {
if (PartVT != ValueVT) {
if (PartVT.isVector()) {
- Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+ Val = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Val);
} else {
assert(ValueVT.getVectorElementType() == PartVT &&
ValueVT.getVectorNumElements() == 1 &&
"Only trivial vector-to-scalar conversions should get here!");
- Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, PartVT, Val,
+ Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
+ PartVT, Val,
DAG.getConstant(0, PtrVT));
}
}
@@ -662,12 +712,12 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
SmallVector<SDValue, 8> Ops(NumIntermediates);
for (unsigned i = 0; i != NumIntermediates; ++i)
if (IntermediateVT.isVector())
- Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
+ Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl,
IntermediateVT, Val,
DAG.getConstant(i * (NumElements / NumIntermediates),
PtrVT));
else
- Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+ Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
IntermediateVT, Val,
DAG.getConstant(i, PtrVT));
@@ -676,7 +726,7 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
// If the register was not expanded, promote or copy the value,
// as appropriate.
for (unsigned i = 0; i != NumParts; ++i)
- getCopyToParts(DAG, 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.
@@ -684,7 +734,7 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
"Must expand into a divisible number of parts!");
unsigned Factor = NumParts / NumIntermediates;
for (unsigned i = 0; i != NumIntermediates; ++i)
- getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
+ getCopyToParts(DAG, dl, Ops[i], &Parts[i * Factor], Factor, PartVT);
}
}
@@ -725,7 +775,7 @@ SDValue SelectionDAGLowering::getRoot() {
}
// Otherwise, we have to make a token factor node.
- SDValue Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
+ SDValue Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other,
&PendingLoads[0], PendingLoads.size());
PendingLoads.clear();
DAG.setRoot(Root);
@@ -755,7 +805,7 @@ SDValue SelectionDAGLowering::getControlRoot() {
PendingExports.push_back(Root);
}
- Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
+ Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other,
&PendingExports[0],
PendingExports.size());
PendingExports.clear();
@@ -815,7 +865,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
if (isa<UndefValue>(C) && !isa<VectorType>(V->getType()) &&
!V->getType()->isAggregateType())
- return N = DAG.getNode(ISD::UNDEF, VT);
+ return N = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), VT);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
visit(CE->getOpcode(), *CE);
@@ -848,7 +898,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
for (unsigned i = 0; i != NumElts; ++i) {
MVT EltVT = ValueVTs[i];
if (isa<UndefValue>(C))
- Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
+ Constants[i] = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), EltVT);
else if (EltVT.isFloatingPoint())
Constants[i] = DAG.getConstantFP(0, EltVT);
else
@@ -873,7 +923,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
SDValue Op;
if (isa<UndefValue>(C))
- Op = DAG.getNode(ISD::UNDEF, EltVT);
+ Op = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), EltVT);
else if (EltVT.isFloatingPoint())
Op = DAG.getConstantFP(0, EltVT);
else
@@ -882,7 +932,8 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
}
// Create a BUILD_VECTOR node.
- return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
+ return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
+ VT, &Ops[0], Ops.size());
}
// If this is a static alloca, generate it as the frameindex instead of
@@ -899,13 +950,14 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
RegsForValue RFV(TLI, InReg, V->getType());
SDValue Chain = DAG.getEntryNode();
- return RFV.getCopyFromRegs(DAG, Chain, NULL);
+ return RFV.getCopyFromRegs(DAG, getCurDebugLoc(), Chain, NULL);
}
void SelectionDAGLowering::visitRet(ReturnInst &I) {
if (I.getNumOperands() == 0) {
- DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getControlRoot()));
+ DAG.setRoot(DAG.getNode(ISD::RET, getCurDebugLoc(),
+ MVT::Other, getControlRoot()));
return;
}
@@ -941,7 +993,8 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
else if (F->paramHasAttr(0, Attribute::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
- getCopyToParts(DAG, SDValue(RetOp.getNode(), RetOp.getResNo() + j),
+ getCopyToParts(DAG, getCurDebugLoc(),
+ SDValue(RetOp.getNode(), RetOp.getResNo() + j),
&Parts[0], NumParts, PartVT, ExtendKind);
// 'inreg' on function refers to return value
@@ -954,7 +1007,7 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
}
}
}
- DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
+ DAG.setRoot(DAG.getNode(ISD::RET, getCurDebugLoc(), MVT::Other,
&NewValues[0], NewValues.size()));
}
@@ -1194,7 +1247,8 @@ void SelectionDAGLowering::visitBr(BranchInst &I) {
// If this is not a fall-through branch, emit the branch.
if (Succ0MBB != NextBlock)
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(),
+ MVT::Other, getControlRoot(),
DAG.getBasicBlock(Succ0MBB)));
return;
}
@@ -1273,7 +1327,8 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
Cond = CondLHS;
else if (CB.CmpRHS == ConstantInt::getFalse() && CB.CC == ISD::SETEQ) {
SDValue True = DAG.getConstant(1, CondLHS.getValueType());
- Cond = DAG.getNode(ISD::XOR, CondLHS.getValueType(), CondLHS, True);
+ Cond = DAG.getNode(ISD::XOR, getCurDebugLoc(),
+ CondLHS.getValueType(), CondLHS, True);
} else
Cond = DAG.getSetCC(MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
} else {
@@ -1288,7 +1343,8 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(true)) {
Cond = DAG.getSetCC(MVT::i1, CmpOp, DAG.getConstant(High, VT), ISD::SETLE);
} else {
- SDValue SUB = DAG.getNode(ISD::SUB, VT, CmpOp, DAG.getConstant(Low, VT));
+ SDValue SUB = DAG.getNode(ISD::SUB, getCurDebugLoc(),
+ VT, CmpOp, DAG.getConstant(Low, VT));
Cond = DAG.getSetCC(MVT::i1, SUB,
DAG.getConstant(High-Low, VT), ISD::SETULE);
}
@@ -1310,10 +1366,12 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
if (CB.TrueBB == NextBlock) {
std::swap(CB.TrueBB, CB.FalseBB);
SDValue True = DAG.getConstant(1, Cond.getValueType());
- Cond = DAG.getNode(ISD::XOR, Cond.getValueType(), Cond, True);
+ Cond = DAG.getNode(ISD::XOR, getCurDebugLoc(),
+ Cond.getValueType(), Cond, True);
}
- SDValue BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(), Cond,
- DAG.getBasicBlock(CB.TrueBB));
+ SDValue BrCond = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
+ MVT::Other, getControlRoot(), Cond,
+ DAG.getBasicBlock(CB.TrueBB));
// If the branch was constant folded, fix up the CFG.
if (BrCond.getOpcode() == ISD::BR) {
@@ -1327,7 +1385,7 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
if (CB.FalseBB == NextBlock)
DAG.setRoot(BrCond);
else
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond,
DAG.getBasicBlock(CB.FalseBB)));
}
}
@@ -1339,9 +1397,9 @@ void SelectionDAGLowering::visitJumpTable(JumpTable &JT) {
MVT PTy = TLI.getPointerTy();
SDValue Index = DAG.getCopyFromReg(getControlRoot(), JT.Reg, PTy);
SDValue Table = DAG.getJumpTable(JT.JTI, PTy);
- DAG.setRoot(DAG.getNode(ISD::BR_JT, MVT::Other, Index.getValue(1),
+ DAG.setRoot(DAG.getNode(ISD::BR_JT, getCurDebugLoc(),
+ MVT::Other, Index.getValue(1),
Table, Index));
- return;
}
/// visitJumpTableHeader - This function emits necessary code to produce index
@@ -1353,7 +1411,7 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT,
// difference between smallest and largest cases.
SDValue SwitchOp = getValue(JTH.SValue);
MVT VT = SwitchOp.getValueType();
- SDValue SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
+ SDValue SUB = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp,
DAG.getConstant(JTH.First, VT));
// The SDNode we just created, which holds the value being switched on minus
@@ -1362,9 +1420,11 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT,
// This value may be smaller or larger than the target's pointer type, and
// therefore require extension or truncating.
if (VT.bitsGT(TLI.getPointerTy()))
- SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
+ SwitchOp = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(),
+ TLI.getPointerTy(), SUB);
else
- SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
+ SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
+ TLI.getPointerTy(), SUB);
unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), JumpTableReg, SwitchOp);
@@ -1384,16 +1444,15 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT,
if (++BBI != CurMBB->getParent()->end())
NextBlock = BBI;
- SDValue BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
+ SDValue BrCond = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
+ MVT::Other, CopyTo, CMP,
DAG.getBasicBlock(JT.Default));
if (JT.MBB == NextBlock)
DAG.setRoot(BrCond);
else
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond,
DAG.getBasicBlock(JT.MBB)));
-
- return;
}
/// visitBitTestHeader - This function emits necessary code to produce value
@@ -1402,7 +1461,7 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
// Subtract the minimum value
SDValue SwitchOp = getValue(B.SValue);
MVT VT = SwitchOp.getValueType();
- SDValue SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
+ SDValue SUB = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp,
DAG.getConstant(B.First, VT));
// Check range
@@ -1411,19 +1470,15 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
ISD::SETUGT);
SDValue ShiftOp;
- if (VT.bitsGT(TLI.getShiftAmountTy()))
- ShiftOp = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), SUB);
+ if (VT.bitsGT(TLI.getPointerTy()))
+ ShiftOp = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(),
+ TLI.getPointerTy(), SUB);
else
- ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), SUB);
-
- // Make desired shift
- SDValue SwitchVal = DAG.getNode(ISD::SHL, TLI.getPointerTy(),
- DAG.getConstant(1, TLI.getPointerTy()),
- ShiftOp);
+ ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
+ TLI.getPointerTy(), SUB);
- unsigned SwitchReg = FuncInfo.MakeReg(TLI.getPointerTy());
- SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), SwitchReg, SwitchVal);
- B.Reg = SwitchReg;
+ B.Reg = FuncInfo.MakeReg(TLI.getPointerTy());
+ SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), B.Reg, ShiftOp);
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
@@ -1437,27 +1492,32 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
CurMBB->addSuccessor(B.Default);
CurMBB->addSuccessor(MBB);
- SDValue BrRange = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, RangeCmp,
+ SDValue BrRange = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
+ MVT::Other, CopyTo, RangeCmp,
DAG.getBasicBlock(B.Default));
if (MBB == NextBlock)
DAG.setRoot(BrRange);
else
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, CopyTo,
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, CopyTo,
DAG.getBasicBlock(MBB)));
-
- return;
}
/// visitBitTestCase - this function produces one "bit test"
void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
unsigned Reg,
BitTestCase &B) {
- // Emit bit tests and jumps
- SDValue SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg,
- TLI.getPointerTy());
+ // Make desired shift
+ SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), Reg,
+ TLI.getPointerTy());
+ SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(),
+ TLI.getPointerTy(),
+ DAG.getConstant(1, TLI.getPointerTy()),
+ ShiftOp);
- SDValue AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal,
+ // Emit bit tests and jumps
+ SDValue AndOp = DAG.getNode(ISD::AND, getCurDebugLoc(),
+ TLI.getPointerTy(), SwitchVal,
DAG.getConstant(B.Mask, TLI.getPointerTy()));
SDValue AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp.getValueType()),
AndOp, DAG.getConstant(0, TLI.getPointerTy()),
@@ -1466,7 +1526,8 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
CurMBB->addSuccessor(B.TargetBB);
CurMBB->addSuccessor(NextMBB);
- SDValue BrAnd = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(),
+ SDValue BrAnd = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
+ MVT::Other, getControlRoot(),
AndCmp, DAG.getBasicBlock(B.TargetBB));
// Set NextBlock to be the MBB immediately after the current one, if any.
@@ -1479,10 +1540,8 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
if (NextMBB == NextBlock)
DAG.setRoot(BrAnd);
else
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrAnd,
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrAnd,
DAG.getBasicBlock(NextMBB)));
-
- return;
}
void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
@@ -1509,7 +1568,8 @@ void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
CurMBB->addSuccessor(LandingPad);
// Drop into normal successor.
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(),
+ MVT::Other, getControlRoot(),
DAG.getBasicBlock(Return)));
}
@@ -1600,8 +1660,8 @@ bool SelectionDAGLowering::handleSmallSwitchRange(CaseRec& CR,
static inline bool areJTsAllowed(const TargetLowering &TLI) {
return !DisableJumpTables &&
- (TLI.isOperationLegal(ISD::BR_JT, MVT::Other) ||
- TLI.isOperationLegal(ISD::BRIND, MVT::Other));
+ (TLI.isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) ||
+ TLI.isOperationLegalOrCustom(ISD::BRIND, MVT::Other));
}
static APInt ComputeRange(const APInt &First, const APInt &Last) {
@@ -2012,7 +2072,8 @@ void SelectionDAGLowering::visitSwitch(SwitchInst &SI) {
// If this is not a fall-through branch, emit the branch.
CurMBB->addSuccessor(Default);
if (Default != NextBlock)
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(),
+ MVT::Other, getControlRoot(),
DAG.getBasicBlock(Default)));
return;
}
@@ -2074,7 +2135,8 @@ void SelectionDAGLowering::visitSub(User &I) {
Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size());
if (CV == CNZ) {
SDValue Op2 = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
+ setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(),
+ Op2.getValueType(), Op2));
return;
}
}
@@ -2084,7 +2146,8 @@ void SelectionDAGLowering::visitSub(User &I) {
if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) {
SDValue Op2 = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
+ setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(),
+ Op2.getValueType(), Op2));
return;
}
}
@@ -2096,20 +2159,24 @@ void SelectionDAGLowering::visitBinary(User &I, unsigned OpCode) {
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(OpCode, Op1.getValueType(), Op1, Op2));
+ setValue(&I, DAG.getNode(OpCode, getCurDebugLoc(),
+ Op1.getValueType(), Op1, Op2));
}
void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
if (!isa<VectorType>(I.getType())) {
- if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
- Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
- else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
- Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
+ if (TLI.getPointerTy().bitsLT(Op2.getValueType()))
+ Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(),
+ TLI.getPointerTy(), Op2);
+ else if (TLI.getPointerTy().bitsGT(Op2.getValueType()))
+ Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(),
+ TLI.getPointerTy(), Op2);
}
- setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
+ setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(),
+ Op1.getValueType(), Op1, Op2));
}
void SelectionDAGLowering::visitICmp(User &I) {
@@ -2173,11 +2240,12 @@ void SelectionDAGLowering::visitSelect(User &I) {
SDValue FalseVal = getValue(I.getOperand(2));
for (unsigned i = 0; i != NumValues; ++i)
- Values[i] = DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond,
+ Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(),
+ TrueVal.getValueType(), Cond,
SDValue(TrueVal.getNode(), TrueVal.getResNo() + i),
SDValue(FalseVal.getNode(), FalseVal.getResNo() + i));
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
DAG.getVTList(&ValueVTs[0], NumValues),
&Values[0], NumValues));
}
@@ -2188,7 +2256,7 @@ void SelectionDAGLowering::visitTrunc(User &I) {
// TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest).
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitZExt(User &I) {
@@ -2196,7 +2264,7 @@ void SelectionDAGLowering::visitZExt(User &I) {
// ZExt also can't be a cast to bool for same reason. So, nothing much to do
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitSExt(User &I) {
@@ -2204,49 +2272,50 @@ void SelectionDAGLowering::visitSExt(User &I) {
// SExt also can't be a cast to bool for same reason. So, nothing much to do
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitFPTrunc(User &I) {
// FPTrunc is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N, DAG.getIntPtrConstant(0)));
+ setValue(&I, DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(),
+ DestVT, N, DAG.getIntPtrConstant(0)));
}
void SelectionDAGLowering::visitFPExt(User &I){
// FPTrunc is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::FP_EXTEND, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitFPToUI(User &I) {
// FPToUI is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitFPToSI(User &I) {
// FPToSI is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitUIToFP(User &I) {
// UIToFP is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitSIToFP(User &I){
// SIToFP is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
MVT DestVT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGLowering::visitPtrToInt(User &I) {
@@ -2257,10 +2326,10 @@ void SelectionDAGLowering::visitPtrToInt(User &I) {
MVT DestVT = TLI.getValueType(I.getType());
SDValue Result;
if (DestVT.bitsLT(SrcVT))
- Result = DAG.getNode(ISD::TRUNCATE, DestVT, N);
+ Result = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N);
else
// Note: ZERO_EXTEND can handle cases where the sizes are equal too
- Result = DAG.getNode(ISD::ZERO_EXTEND, DestVT, N);
+ Result = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N);
setValue(&I, Result);
}
@@ -2271,10 +2340,11 @@ void SelectionDAGLowering::visitIntToPtr(User &I) {
MVT SrcVT = N.getValueType();
MVT DestVT = TLI.getValueType(I.getType());
if (DestVT.bitsLT(SrcVT))
- setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N));
else
// Note: ZERO_EXTEND can handle cases where the sizes are equal too
- setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
+ setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
+ DestVT, N));
}
void SelectionDAGLowering::visitBitCast(User &I) {
@@ -2284,7 +2354,8 @@ void SelectionDAGLowering::visitBitCast(User &I) {
// BitCast assures us that source and destination are the same size so this
// is either a BIT_CONVERT or a no-op.
if (DestVT != N.getValueType())
- setValue(&I, DAG.getNode(ISD::BIT_CONVERT, DestVT, N)); // convert types
+ setValue(&I, DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(),
+ DestVT, N)); // convert types
else
setValue(&I, N); // noop cast.
}
@@ -2292,19 +2363,21 @@ void SelectionDAGLowering::visitBitCast(User &I) {
void SelectionDAGLowering::visitInsertElement(User &I) {
SDValue InVec = getValue(I.getOperand(0));
SDValue InVal = getValue(I.getOperand(1));
- SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
+ SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
+ TLI.getPointerTy(),
getValue(I.getOperand(2)));
- setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT,
+ setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(),
TLI.getValueType(I.getType()),
InVec, InVal, InIdx));
}
void SelectionDAGLowering::visitExtractElement(User &I) {
SDValue InVec = getValue(I.getOperand(0));
- SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
+ SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
+ TLI.getPointerTy(),
getValue(I.getOperand(1)));
- setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+ setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(),
TLI.getValueType(I.getType()), InVec, InIdx));
}
@@ -2334,7 +2407,8 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
int SrcNumElts = SrcVT.getVectorNumElements();
if (SrcNumElts == MaskNumElts) {
- setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
+ setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(),
+ VT, Src1, Src2, Mask));
return;
}
@@ -2347,13 +2421,14 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
// lengths match.
if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) {
// The shuffle is concatenating two vectors together.
- setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, Src1, Src2));
+ setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(),
+ VT, Src1, Src2));
return;
}
// Pad both vectors with undefs to make them the same length as the mask.
unsigned NumConcat = MaskNumElts / SrcNumElts;
- SDValue UndefVal = DAG.getNode(ISD::UNDEF, SrcVT);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), SrcVT);
SDValue* MOps1 = new SDValue[NumConcat];
SDValue* MOps2 = new SDValue[NumConcat];
@@ -2363,8 +2438,10 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
MOps1[i] = UndefVal;
MOps2[i] = UndefVal;
}
- Src1 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps1, NumConcat);
- Src2 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps2, NumConcat);
+ Src1 = DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(),
+ VT, MOps1, NumConcat);
+ Src2 = DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(),
+ VT, MOps2, NumConcat);
delete [] MOps1;
delete [] MOps2;
@@ -2383,10 +2460,12 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
MaskEltVT));
}
}
- Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(),
+ Mask = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
+ Mask.getValueType(),
&MappedOps[0], MappedOps.size());
- setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
+ setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(),
+ VT, Src1, Src2, Mask));
return;
}
@@ -2451,7 +2530,8 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
}
if (RangeUse[0] == 0 && RangeUse[0] == 0) {
- setValue(&I, DAG.getNode(ISD::UNDEF, VT)); // Vectors are not used.
+ setValue(&I, DAG.getNode(ISD::UNDEF,
+ getCurDebugLoc(), VT)); // Vectors are not used.
return;
}
else if (RangeUse[0] < 2 && RangeUse[1] < 2) {
@@ -2459,10 +2539,10 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
for (int Input=0; Input < 2; ++Input) {
SDValue& Src = Input == 0 ? Src1 : Src2;
if (RangeUse[Input] == 0) {
- Src = DAG.getNode(ISD::UNDEF, VT);
+ Src = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), VT);
} else {
- Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, Src,
- DAG.getIntPtrConstant(StartIdx[Input]));
+ Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, getCurDebugLoc(), VT,
+ Src, DAG.getIntPtrConstant(StartIdx[Input]));
}
}
// Calculate new mask.
@@ -2481,9 +2561,11 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
}
}
}
- Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(),
+ Mask = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
+ Mask.getValueType(),
&MappedOps[0], MappedOps.size());
- setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
+ setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(),
+ VT, Src1, Src2, Mask));
return;
}
}
@@ -2497,19 +2579,21 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
for (int i = 0; i != MaskNumElts; ++i) {
SDValue Arg = Mask.getOperand(i);
if (Arg.getOpcode() == ISD::UNDEF) {
- Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+ Ops.push_back(DAG.getNode(ISD::UNDEF, getCurDebugLoc(), EltVT));
} else {
assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
int Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
if (Idx < SrcNumElts)
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src1,
- DAG.getConstant(Idx, PtrVT)));
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(),
+ EltVT, Src1, DAG.getConstant(Idx, PtrVT)));
else
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src2,
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(),
+ EltVT, Src2,
DAG.getConstant(Idx - SrcNumElts, PtrVT)));
}
}
- setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()));
+ setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
+ VT, &Ops[0], Ops.size()));
}
void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {
@@ -2537,18 +2621,21 @@ void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {
unsigned i = 0;
// Copy the beginning value(s) from the original aggregate.
for (; i != LinearIndex; ++i)
- Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
+ Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, getCurDebugLoc(),
+ AggValueVTs[i]) :
SDValue(Agg.getNode(), Agg.getResNo() + i);
// Copy values from the inserted value(s).
for (; i != LinearIndex + NumValValues; ++i)
- Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
+ Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, getCurDebugLoc(),
+ AggValueVTs[i]) :
SDValue(Val.getNode(), Val.getResNo() + i - LinearIndex);
// Copy remaining value(s) from the original aggregate.
for (; i != NumAggValues; ++i)
- Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
+ Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, getCurDebugLoc(),
+ AggValueVTs[i]) :
SDValue(Agg.getNode(), Agg.getResNo() + i);
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
DAG.getVTList(&AggValueVTs[0], NumAggValues),
&Values[0], NumAggValues));
}
@@ -2573,11 +2660,11 @@ void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) {
for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i)
Values[i - LinearIndex] =
OutOfUndef ?
- DAG.getNode(ISD::UNDEF,
+ DAG.getNode(ISD::UNDEF, getCurDebugLoc(),
Agg.getNode()->getValueType(Agg.getResNo() + i)) :
SDValue(Agg.getNode(), Agg.getResNo() + i);
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
DAG.getVTList(&ValValueVTs[0], NumValValues),
&Values[0], NumValValues));
}
@@ -2595,7 +2682,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
if (Field) {
// N = N + Offset
uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field);
- N = DAG.getNode(ISD::ADD, N.getValueType(), N,
+ N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N,
DAG.getIntPtrConstant(Offset));
}
Ty = StTy->getElementType(Field);
@@ -2607,7 +2694,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
if (CI->getZExtValue() == 0) continue;
uint64_t Offs =
TD->getTypePaddedSize(Ty)*cast<ConstantInt>(CI)->getSExtValue();
- N = DAG.getNode(ISD::ADD, N.getValueType(), N,
+ N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N,
DAG.getIntPtrConstant(Offs));
continue;
}
@@ -2619,24 +2706,29 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
// If the index is smaller or larger than intptr_t, truncate or extend
// it.
if (IdxN.getValueType().bitsLT(N.getValueType()))
- IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN);
+ IdxN = DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(),
+ N.getValueType(), IdxN);
else if (IdxN.getValueType().bitsGT(N.getValueType()))
- IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN);
+ IdxN = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(),
+ N.getValueType(), IdxN);
// If this is a multiply by a power of two, turn it into a shl
// immediately. This is a very common case.
if (ElementSize != 1) {
if (isPowerOf2_64(ElementSize)) {
unsigned Amt = Log2_64(ElementSize);
- IdxN = DAG.getNode(ISD::SHL, N.getValueType(), IdxN,
- DAG.getConstant(Amt, TLI.getShiftAmountTy()));
+ IdxN = DAG.getNode(ISD::SHL, getCurDebugLoc(),
+ N.getValueType(), IdxN,
+ DAG.getConstant(Amt, TLI.getPointerTy()));
} else {
SDValue Scale = DAG.getIntPtrConstant(ElementSize);
- IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale);
+ IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(),
+ N.getValueType(), IdxN, Scale);
}
}
- N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN);
+ N = DAG.getNode(ISD::ADD, getCurDebugLoc(),
+ N.getValueType(), N, IdxN);
}
}
setValue(&I, N);
@@ -2657,11 +2749,13 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
SDValue AllocSize = getValue(I.getArraySize());
MVT IntPtr = TLI.getPointerTy();
if (IntPtr.bitsLT(AllocSize.getValueType()))
- AllocSize = DAG.getNode(ISD::TRUNCATE, IntPtr, AllocSize);
+ AllocSize = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(),
+ IntPtr, AllocSize);
else if (IntPtr.bitsGT(AllocSize.getValueType()))
- AllocSize = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, AllocSize);
+ AllocSize = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
+ IntPtr, AllocSize);
- AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize,
+ AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), IntPtr, AllocSize,
DAG.getIntPtrConstant(TySize));
// Handle alignment. If the requested alignment is less than or equal to
@@ -2674,16 +2768,19 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
// Round the size of the allocation up to the stack alignment size
// by add SA-1 to the size.
- AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize,
+ AllocSize = DAG.getNode(ISD::ADD, getCurDebugLoc(),
+ AllocSize.getValueType(), AllocSize,
DAG.getIntPtrConstant(StackAlign-1));
// Mask out the low bits for alignment purposes.
- AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
+ AllocSize = DAG.getNode(ISD::AND, getCurDebugLoc(),
+ AllocSize.getValueType(), AllocSize,
DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1)));
SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) };
const MVT *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(),
MVT::Other);
- SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, 2, Ops, 3);
+ SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, getCurDebugLoc(),
+ VTs, 2, Ops, 3);
setValue(&I, DSA);
DAG.setRoot(DSA.getValue(1));
@@ -2725,8 +2822,9 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
SmallVector<SDValue, 4> Chains(NumValues);
MVT PtrVT = Ptr.getValueType();
for (unsigned i = 0; i != NumValues; ++i) {
- SDValue L = DAG.getLoad(ValueVTs[i], Root,
- DAG.getNode(ISD::ADD, PtrVT, Ptr,
+ SDValue L = DAG.getLoad(ValueVTs[i], getCurDebugLoc(), Root,
+ DAG.getNode(ISD::ADD, getCurDebugLoc(),
+ PtrVT, Ptr,
DAG.getConstant(Offsets[i], PtrVT)),
SV, Offsets[i],
isVolatile, Alignment);
@@ -2735,7 +2833,8 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
}
if (!ConstantMemory) {
- SDValue Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
+ SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
+ MVT::Other,
&Chains[0], NumValues);
if (isVolatile)
DAG.setRoot(Chain);
@@ -2743,7 +2842,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
PendingLoads.push_back(Chain);
}
- setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
DAG.getVTList(&ValueVTs[0], NumValues),
&Values[0], NumValues));
}
@@ -2772,13 +2871,16 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
bool isVolatile = I.isVolatile();
unsigned Alignment = I.getAlignment();
for (unsigned i = 0; i != NumValues; ++i)
- Chains[i] = DAG.getStore(Root, SDValue(Src.getNode(), Src.getResNo() + i),
- DAG.getNode(ISD::ADD, PtrVT, Ptr,
+ Chains[i] = DAG.getStore(Root, getCurDebugLoc(),
+ SDValue(Src.getNode(), Src.getResNo() + i),
+ DAG.getNode(ISD::ADD, getCurDebugLoc(),
+ PtrVT, Ptr,
DAG.getConstant(Offsets[i], PtrVT)),
PtrV, Offsets[i],
isVolatile, Alignment);
- DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumValues));
+ DAG.setRoot(DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
+ MVT::Other, &Chains[0], NumValues));
}
/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
@@ -2838,20 +2940,24 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
SDValue Result;
if (IsTgtIntrinsic) {
// This is target intrinsic that touches memory
- Result = DAG.getMemIntrinsicNode(Info.opc, VTList, VTs.size(),
+ Result = DAG.getMemIntrinsicNode(Info.opc, getCurDebugLoc(),
+ VTList, VTs.size(),
&Ops[0], Ops.size(),
Info.memVT, Info.ptrVal, Info.offset,
Info.align, Info.vol,
Info.readMem, Info.writeMem);
}
else if (!HasChain)
- Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VTList, VTs.size(),
+ Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurDebugLoc(),
+ VTList, VTs.size(),
&Ops[0], Ops.size());
else if (I.getType() != Type::VoidTy)
- Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, VTList, VTs.size(),
+ Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurDebugLoc(),
+ VTList, VTs.size(),
&Ops[0], Ops.size());
else
- Result = DAG.getNode(ISD::INTRINSIC_VOID, VTList, VTs.size(),
+ Result = DAG.getNode(ISD::INTRINSIC_VOID, getCurDebugLoc(),
+ VTList, VTs.size(),
&Ops[0], Ops.size());
if (HasChain) {
@@ -2864,7 +2970,7 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
if (I.getType() != Type::VoidTy) {
if (const VectorType *PTy = dyn_cast<VectorType>(I.getType())) {
MVT VT = TLI.getValueType(PTy);
- Result = DAG.getNode(ISD::BIT_CONVERT, VT, Result);
+ Result = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), VT, Result);
}
setValue(&I, Result);
}
@@ -2944,12 +3050,12 @@ void AddCatchInfo(CallInst &I, MachineModuleInfo *MMI,
///
/// where Op is the hexidecimal representation of floating point value.
static SDValue
-GetSignificand(SelectionDAG &DAG, SDValue Op) {
- SDValue t1 = DAG.getNode(ISD::AND, MVT::i32, Op,
+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, MVT::i32, t1,
+ SDValue t2 = DAG.getNode(ISD::OR, dl, MVT::i32, t1,
DAG.getConstant(0x3f800000, MVT::i32));
- return DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t2);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2);
}
/// GetExponent - Get the exponent:
@@ -2958,14 +3064,15 @@ GetSignificand(SelectionDAG &DAG, SDValue Op) {
///
/// where Op is the hexidecimal representation of floating point value.
static SDValue
-GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI) {
- SDValue t0 = DAG.getNode(ISD::AND, MVT::i32, Op,
+GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI,
+ DebugLoc dl) {
+ SDValue t0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op,
DAG.getConstant(0x7f800000, MVT::i32));
- SDValue t1 = DAG.getNode(ISD::SRL, MVT::i32, t0,
- DAG.getConstant(23, TLI.getShiftAmountTy()));
- SDValue t2 = DAG.getNode(ISD::SUB, MVT::i32, t1,
+ SDValue t1 = DAG.getNode(ISD::SRL, dl, MVT::i32, t0,
+ DAG.getConstant(23, TLI.getPointerTy()));
+ SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1,
DAG.getConstant(127, MVT::i32));
- return DAG.getNode(ISD::SINT_TO_FP, MVT::f32, t2);
+ return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2);
}
/// getF32Constant - Get 32-bit floating point constant.
@@ -2981,7 +3088,8 @@ const char *
SelectionDAGLowering::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) {
SDValue Root = getRoot();
SDValue L =
- DAG.getAtomic(Op, getValue(I.getOperand(2)).getValueType().getSimpleVT(),
+ DAG.getAtomic(Op, getCurDebugLoc(),
+ getValue(I.getOperand(2)).getValueType().getSimpleVT(),
Root,
getValue(I.getOperand(1)),
getValue(I.getOperand(2)),
@@ -3000,7 +3108,8 @@ SelectionDAGLowering::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) {
MVT ValueVTs[] = { Op1.getValueType(), MVT::i1 };
SDValue Ops[] = { Op1, Op2 };
- SDValue Result = DAG.getNode(Op, DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
+ SDValue Result = DAG.getNode(Op, getCurDebugLoc(),
+ DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
setValue(&I, Result);
return 0;
@@ -3011,6 +3120,7 @@ SelectionDAGLowering::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) {
void
SelectionDAGLowering::visitExp(CallInst &I) {
SDValue result;
+ DebugLoc dl = getCurDebugLoc();
if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
@@ -3021,17 +3131,17 @@ SelectionDAGLowering::visitExp(CallInst &I) {
//
// #define LOG2OFe 1.4426950f
// IntegerPartOfX = ((int32_t)(X * LOG2OFe));
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, Op,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op,
getF32Constant(DAG, 0x3fb8aa3b));
- SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, MVT::i32, t0);
+ SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, t0);
// FractionalPartOfX = (X * LOG2OFe) - (float)IntegerPartOfX;
- SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, MVT::f32, IntegerPartOfX);
- SDValue X = DAG.getNode(ISD::FSUB, MVT::f32, t0, t1);
+ SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
+ SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
// IntegerPartOfX <<= 23;
- IntegerPartOfX = DAG.getNode(ISD::SHL, MVT::i32, IntegerPartOfX,
- DAG.getConstant(23, TLI.getShiftAmountTy()));
+ IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
+ DAG.getConstant(23, TLI.getPointerTy()));
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3041,20 +3151,20 @@ SelectionDAGLowering::visitExp(CallInst &I) {
// (0.735607626f + 0.252464424f * x) * x;
//
// error 0.0144103317, which is 6 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3e814304));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3f3c50c8));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f7f5e7e));
- SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t5);
+ SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, dl,MVT::i32, t5);
// Add the exponent into the result in integer domain.
- SDValue t6 = DAG.getNode(ISD::ADD, MVT::i32,
+ SDValue t6 = DAG.getNode(ISD::ADD, dl, MVT::i32,
TwoToFracPartOfX, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t6);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t6);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3064,23 +3174,23 @@ SelectionDAGLowering::visitExp(CallInst &I) {
// (0.224338339f + 0.792043434e-1f * x) * x) * x;
//
// 0.000107046256 error, which is 13 to 14 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3da235e3));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3e65b8f3));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f324b07));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3f7ff8fd));
- SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t7);
+ SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, dl,MVT::i32, t7);
// Add the exponent into the result in integer domain.
- SDValue t8 = DAG.getNode(ISD::ADD, MVT::i32,
+ SDValue t8 = DAG.getNode(ISD::ADD, dl, MVT::i32,
TwoToFracPartOfX, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t8);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t8);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3093,36 +3203,37 @@ SelectionDAGLowering::visitExp(CallInst &I) {
// (0.136028312e-2f + 0.157059148e-3f *x)*x)*x)*x)*x)*x;
//
// error 2.47208000*10^(-7), which is better than 18 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3924b03e));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3ab24b87));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3c1d8c17));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3d634a1d));
- SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
- SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
+ SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
+ SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
getF32Constant(DAG, 0x3e75fe14));
- SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
- SDValue t11 = DAG.getNode(ISD::FADD, MVT::f32, t10,
+ SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
+ SDValue t11 = DAG.getNode(ISD::FADD, dl, MVT::f32, t10,
getF32Constant(DAG, 0x3f317234));
- SDValue t12 = DAG.getNode(ISD::FMUL, MVT::f32, t11, X);
- SDValue t13 = DAG.getNode(ISD::FADD, MVT::f32, t12,
+ SDValue t12 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t11, X);
+ SDValue t13 = DAG.getNode(ISD::FADD, dl, MVT::f32, t12,
getF32Constant(DAG, 0x3f800000));
- SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t13);
+ SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, dl,
+ MVT::i32, t13);
// Add the exponent into the result in integer domain.
- SDValue t14 = DAG.getNode(ISD::ADD, MVT::i32,
+ SDValue t14 = DAG.getNode(ISD::ADD, dl, MVT::i32,
TwoToFracPartOfX, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t14);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t14);
}
} else {
// No special expansion.
- result = DAG.getNode(ISD::FEXP,
+ result = DAG.getNode(ISD::FEXP, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
}
@@ -3135,20 +3246,21 @@ SelectionDAGLowering::visitExp(CallInst &I) {
void
SelectionDAGLowering::visitLog(CallInst &I) {
SDValue result;
+ DebugLoc dl = getCurDebugLoc();
if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
SDValue Op = getValue(I.getOperand(1));
- SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
+ 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);
- SDValue LogOfExponent = DAG.getNode(ISD::FMUL, MVT::f32, Exp,
+ 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);
+ SDValue X = GetSignificand(DAG, Op1, dl);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3158,15 +3270,16 @@ SelectionDAGLowering::visitLog(CallInst &I) {
// (1.4034025f - 0.23903021f * x) * x;
//
// error 0.0034276066, which is better than 8 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0xbe74c456));
- SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3fb3a2b1));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3f949a29));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, LogOfMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, LogOfMantissa);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3177,21 +3290,22 @@ SelectionDAGLowering::visitLog(CallInst &I) {
// (0.44717955f - 0.56570851e-1f * x) * x) * x) * x;
//
// error 0.000061011436, which is 14 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0xbd67b6d6));
- SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3ee4f4b8));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3fbc278b));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x40348e95));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3fdef31a));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, LogOfMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, LogOfMantissa);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3204,31 +3318,32 @@ SelectionDAGLowering::visitLog(CallInst &I) {
// (0.19073739f - 0.17809712e-1f * x) * x) * x) * x) * x)*x;
//
// error 0.0000023660568, which is better than 18 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0xbc91e5ac));
- SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3e4350aa));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3f60d3e3));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x4011cdf0));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FSUB, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
getF32Constant(DAG, 0x406cfd1c));
- SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
- SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
+ SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
+ SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
getF32Constant(DAG, 0x408797cb));
- SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
- SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t10,
+ SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
+ SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t10,
getF32Constant(DAG, 0x4006dcab));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, LogOfMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, LogOfMantissa);
}
} else {
// No special expansion.
- result = DAG.getNode(ISD::FLOG,
+ result = DAG.getNode(ISD::FLOG, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
}
@@ -3241,18 +3356,19 @@ SelectionDAGLowering::visitLog(CallInst &I) {
void
SelectionDAGLowering::visitLog2(CallInst &I) {
SDValue result;
+ DebugLoc dl = getCurDebugLoc();
if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
SDValue Op = getValue(I.getOperand(1));
- SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
+ SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
// Get the exponent.
- SDValue LogOfExponent = GetExponent(DAG, Op1, TLI);
+ 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);
+ SDValue X = GetSignificand(DAG, Op1, dl);
// Different possible minimax approximations of significand in
// floating-point for various degrees of accuracy over [1,2].
@@ -3262,15 +3378,16 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
// Log2ofMantissa = -1.6749035f + (2.0246817f - .34484768f * x) * x;
//
// error 0.0049451742, which is more than 7 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0xbeb08fe0));
- SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
getF32Constant(DAG, 0x40019463));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3fd6633d));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log2ofMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, Log2ofMantissa);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3281,21 +3398,22 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
// (.645142248f - 0.816157886e-1f * x) * x) * x) * x;
//
// error 0.0000876136000, which is better than 13 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0xbda7262e));
- SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3f25280b));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
getF32Constant(DAG, 0x4007b923));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x40823e2f));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
getF32Constant(DAG, 0x4020d29c));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log2ofMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, Log2ofMantissa);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3309,31 +3427,32 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
// 0.25691327e-1f * x) * x) * x) * x) * x) * x;
//
// error 0.0000018516, which is better than 18 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0xbcd2769e));
- SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3e8ce0b9));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3fa22ae7));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x40525723));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FSUB, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
getF32Constant(DAG, 0x40aaf200));
- SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
- SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
+ SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
+ SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
getF32Constant(DAG, 0x40c39dad));
- SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
- SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t10,
+ SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
+ SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t10,
getF32Constant(DAG, 0x4042902c));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log2ofMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, Log2ofMantissa);
}
} else {
// No special expansion.
- result = DAG.getNode(ISD::FLOG2,
+ result = DAG.getNode(ISD::FLOG2, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
}
@@ -3346,20 +3465,21 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
void
SelectionDAGLowering::visitLog10(CallInst &I) {
SDValue result;
+ DebugLoc dl = getCurDebugLoc();
if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
SDValue Op = getValue(I.getOperand(1));
- SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
+ 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);
- SDValue LogOfExponent = DAG.getNode(ISD::FMUL, MVT::f32, Exp,
+ 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);
+ SDValue X = GetSignificand(DAG, Op1, dl);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3369,15 +3489,16 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
// (0.60948995f - 0.10380950f * x) * x;
//
// error 0.0014886165, which is 6 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0xbdd49a13));
- SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3f1c0789));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3f011300));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log10ofMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, Log10ofMantissa);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3387,18 +3508,19 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
// (-0.31664806f + 0.47637168e-1f * x) * x) * x;
//
// error 0.00019228036, which is better than 12 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3d431f31));
- SDValue t1 = DAG.getNode(ISD::FSUB, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3ea21fb2));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3f6ae232));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f25f7c3));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log10ofMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, Log10ofMantissa);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3410,28 +3532,29 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
// (-0.12539807f + 0.13508273e-1f * x) * x) * x) * x) * x;
//
// error 0.0000037995730, which is better than 18 bits
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3c5d51ce));
- SDValue t1 = DAG.getNode(ISD::FSUB, MVT::f32, t0,
+ SDValue t1 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0,
getF32Constant(DAG, 0x3e00685a));
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3efb6798));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FSUB, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f88d192));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3fc4316c));
- SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
- SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t8,
+ SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
+ SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t8,
getF32Constant(DAG, 0x3f57ce70));
- result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log10ofMantissa);
+ result = DAG.getNode(ISD::FADD, dl,
+ MVT::f32, LogOfExponent, Log10ofMantissa);
}
} else {
// No special expansion.
- result = DAG.getNode(ISD::FLOG10,
+ result = DAG.getNode(ISD::FLOG10, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
}
@@ -3444,20 +3567,21 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
void
SelectionDAGLowering::visitExp2(CallInst &I) {
SDValue result;
+ DebugLoc dl = getCurDebugLoc();
if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
SDValue Op = getValue(I.getOperand(1));
- SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Op);
+ SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Op);
// FractionalPartOfX = x - (float)IntegerPartOfX;
- SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, MVT::f32, IntegerPartOfX);
- SDValue X = DAG.getNode(ISD::FSUB, MVT::f32, Op, t1);
+ SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
+ SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, Op, t1);
// IntegerPartOfX <<= 23;
- IntegerPartOfX = DAG.getNode(ISD::SHL, MVT::i32, IntegerPartOfX,
- DAG.getConstant(23, TLI.getShiftAmountTy()));
+ IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
+ DAG.getConstant(23, TLI.getPointerTy()));
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3467,18 +3591,19 @@ SelectionDAGLowering::visitExp2(CallInst &I) {
// (0.735607626f + 0.252464424f * x) * x;
//
// error 0.0144103317, which is 6 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3e814304));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3f3c50c8));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f7f5e7e));
- SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t5);
+ SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t5);
SDValue TwoToFractionalPartOfX =
- DAG.getNode(ISD::ADD, MVT::i32, t6, IntegerPartOfX);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, t6, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl,
+ MVT::f32, TwoToFractionalPartOfX);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3488,21 +3613,22 @@ SelectionDAGLowering::visitExp2(CallInst &I) {
// (0.224338339f + 0.792043434e-1f * x) * x) * x;
//
// error 0.000107046256, which is 13 to 14 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3da235e3));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3e65b8f3));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f324b07));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3f7ff8fd));
- SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t7);
+ SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t7);
SDValue TwoToFractionalPartOfX =
- DAG.getNode(ISD::ADD, MVT::i32, t8, IntegerPartOfX);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, t8, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl,
+ MVT::f32, TwoToFractionalPartOfX);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3514,34 +3640,35 @@ SelectionDAGLowering::visitExp2(CallInst &I) {
// (0.961591928e-2f +
// (0.136028312e-2f + 0.157059148e-3f *x)*x)*x)*x)*x)*x;
// error 2.47208000*10^(-7), which is better than 18 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3924b03e));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3ab24b87));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3c1d8c17));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3d634a1d));
- SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
- SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
+ SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
+ SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
getF32Constant(DAG, 0x3e75fe14));
- SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
- SDValue t11 = DAG.getNode(ISD::FADD, MVT::f32, t10,
+ SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
+ SDValue t11 = DAG.getNode(ISD::FADD, dl, MVT::f32, t10,
getF32Constant(DAG, 0x3f317234));
- SDValue t12 = DAG.getNode(ISD::FMUL, MVT::f32, t11, X);
- SDValue t13 = DAG.getNode(ISD::FADD, MVT::f32, t12,
+ SDValue t12 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t11, X);
+ SDValue t13 = DAG.getNode(ISD::FADD, dl, MVT::f32, t12,
getF32Constant(DAG, 0x3f800000));
- SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t13);
+ SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t13);
SDValue TwoToFractionalPartOfX =
- DAG.getNode(ISD::ADD, MVT::i32, t14, IntegerPartOfX);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, t14, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl,
+ MVT::f32, TwoToFractionalPartOfX);
}
} else {
// No special expansion.
- result = DAG.getNode(ISD::FEXP2,
+ result = DAG.getNode(ISD::FEXP2, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
}
@@ -3555,6 +3682,7 @@ void
SelectionDAGLowering::visitPow(CallInst &I) {
SDValue result;
Value *Val = I.getOperand(1);
+ DebugLoc dl = getCurDebugLoc();
bool IsExp10 = false;
if (getValue(Val).getValueType() == MVT::f32 &&
@@ -3576,17 +3704,17 @@ SelectionDAGLowering::visitPow(CallInst &I) {
//
// #define LOG2OF10 3.3219281f
// IntegerPartOfX = (int32_t)(x * LOG2OF10);
- SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, Op,
+ SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op,
getF32Constant(DAG, 0x40549a78));
- SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, MVT::i32, t0);
+ SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, t0);
// FractionalPartOfX = x - (float)IntegerPartOfX;
- SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, MVT::f32, IntegerPartOfX);
- SDValue X = DAG.getNode(ISD::FSUB, MVT::f32, t0, t1);
+ SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
+ SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
// IntegerPartOfX <<= 23;
- IntegerPartOfX = DAG.getNode(ISD::SHL, MVT::i32, IntegerPartOfX,
- DAG.getConstant(23, TLI.getShiftAmountTy()));
+ IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
+ DAG.getConstant(23, TLI.getPointerTy()));
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3596,18 +3724,19 @@ SelectionDAGLowering::visitPow(CallInst &I) {
// (0.735607626f + 0.252464424f * x) * x;
//
// error 0.0144103317, which is 6 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3e814304));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3f3c50c8));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f7f5e7e));
- SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t5);
+ SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t5);
SDValue TwoToFractionalPartOfX =
- DAG.getNode(ISD::ADD, MVT::i32, t6, IntegerPartOfX);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, t6, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl,
+ MVT::f32, TwoToFractionalPartOfX);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3617,21 +3746,22 @@ SelectionDAGLowering::visitPow(CallInst &I) {
// (0.224338339f + 0.792043434e-1f * x) * x) * x;
//
// error 0.000107046256, which is 13 to 14 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3da235e3));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3e65b8f3));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3f324b07));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3f7ff8fd));
- SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t7);
+ SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t7);
SDValue TwoToFractionalPartOfX =
- DAG.getNode(ISD::ADD, MVT::i32, t8, IntegerPartOfX);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, t8, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl,
+ MVT::f32, TwoToFractionalPartOfX);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3643,34 +3773,35 @@ SelectionDAGLowering::visitPow(CallInst &I) {
// (0.961591928e-2f +
// (0.136028312e-2f + 0.157059148e-3f *x)*x)*x)*x)*x)*x;
// error 2.47208000*10^(-7), which is better than 18 bits
- SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
+ SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
getF32Constant(DAG, 0x3924b03e));
- SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
+ SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
getF32Constant(DAG, 0x3ab24b87));
- SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
- SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
+ SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
+ SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
getF32Constant(DAG, 0x3c1d8c17));
- SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
- SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
+ SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
+ SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
getF32Constant(DAG, 0x3d634a1d));
- SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
- SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
+ SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
+ SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
getF32Constant(DAG, 0x3e75fe14));
- SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
- SDValue t11 = DAG.getNode(ISD::FADD, MVT::f32, t10,
+ SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
+ SDValue t11 = DAG.getNode(ISD::FADD, dl, MVT::f32, t10,
getF32Constant(DAG, 0x3f317234));
- SDValue t12 = DAG.getNode(ISD::FMUL, MVT::f32, t11, X);
- SDValue t13 = DAG.getNode(ISD::FADD, MVT::f32, t12,
+ SDValue t12 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t11, X);
+ SDValue t13 = DAG.getNode(ISD::FADD, dl, MVT::f32, t12,
getF32Constant(DAG, 0x3f800000));
- SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t13);
+ SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t13);
SDValue TwoToFractionalPartOfX =
- DAG.getNode(ISD::ADD, MVT::i32, t14, IntegerPartOfX);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, t14, IntegerPartOfX);
- result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
+ result = DAG.getNode(ISD::BIT_CONVERT, dl,
+ MVT::f32, TwoToFractionalPartOfX);
}
} else {
// No special expansion.
- result = DAG.getNode(ISD::FPOW,
+ result = DAG.getNode(ISD::FPOW, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)),
getValue(I.getOperand(2)));
@@ -3684,6 +3815,7 @@ SelectionDAGLowering::visitPow(CallInst &I) {
/// otherwise lower it and return null.
const char *
SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
+ DebugLoc dl = getCurDebugLoc();
switch (Intrinsic) {
default:
// By default, turn this into a target intrinsic node.
@@ -3693,11 +3825,11 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::vaend: visitVAEnd(I); return 0;
case Intrinsic::vacopy: visitVACopy(I); return 0;
case Intrinsic::returnaddress:
- setValue(&I, DAG.getNode(ISD::RETURNADDR, TLI.getPointerTy(),
+ setValue(&I, DAG.getNode(ISD::RETURNADDR, dl, TLI.getPointerTy(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::frameaddress:
- setValue(&I, DAG.getNode(ISD::FRAMEADDR, TLI.getPointerTy(),
+ setValue(&I, DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::setjmp:
@@ -3749,11 +3881,19 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::dbg_stoppoint: {
DwarfWriter *DW = DAG.getDwarfWriter();
DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
- if (DW && DW->ValidDebugInfo(SPI.getContext()))
+ if (DW && DW->ValidDebugInfo(SPI.getContext())) {
DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
SPI.getLine(),
SPI.getColumn(),
SPI.getContext()));
+ DICompileUnit CU(cast<GlobalVariable>(SPI.getContext()));
+ unsigned SrcFile = DW->RecordSource(CU.getDirectory(), CU.getFilename());
+ unsigned idx = DAG.getMachineFunction().
+ getOrCreateDebugLocID(SrcFile,
+ SPI.getLine(),
+ SPI.getColumn());
+ setCurDebugLoc(DebugLoc::get(idx));
+ }
return 0;
}
case Intrinsic::dbg_region_start: {
@@ -3790,13 +3930,18 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
unsigned SrcFile = DW->RecordSource(CompileUnit.getDirectory(),
CompileUnit.getFilename());
+
// Record the source line but does not create a label for the normal
// function start. It will be emitted at asm emission time. However,
// create a label if this is a beginning of inlined function.
- unsigned LabelID =
- DW->RecordSourceLine(Subprogram.getLineNumber(), 0, SrcFile);
+ unsigned Line = Subprogram.getLineNumber();
+ unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
+
if (DW->getRecordSourceLineCount() != 1)
DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
+
+ setCurDebugLoc(DebugLoc::get(DAG.getMachineFunction().
+ getOrCreateDebugLocID(SrcFile, Line, 0)));
}
return 0;
@@ -3806,7 +3951,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
Value *Variable = DI.getVariable();
if (DW && DW->ValidDebugInfo(Variable))
- DAG.setRoot(DAG.getNode(ISD::DECLARE, MVT::Other, getRoot(),
+ DAG.setRoot(DAG.getNode(ISD::DECLARE, dl, MVT::Other, getRoot(),
getValue(DI.getAddress()), getValue(Variable)));
return 0;
}
@@ -3821,7 +3966,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
SDValue Ops[1];
Ops[0] = DAG.getRoot();
- SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, VTs, Ops, 1);
+ SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, dl, VTs, Ops, 1);
setValue(&I, Op);
DAG.setRoot(Op.getValue(1));
return 0;
@@ -3850,7 +3995,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue Ops[2];
Ops[0] = getValue(I.getOperand(1));
Ops[1] = getRoot();
- SDValue Op = DAG.getNode(ISD::EHSELECTION, VTs, Ops, 2);
+ SDValue Op = DAG.getNode(ISD::EHSELECTION, dl, VTs, Ops, 2);
setValue(&I, Op);
DAG.setRoot(Op.getValue(1));
} else {
@@ -3884,7 +4029,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::eh_return_i64:
if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
MMI->setCallsEHReturn(true);
- DAG.setRoot(DAG.getNode(ISD::EH_RETURN,
+ DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl,
MVT::Other,
getControlRoot(),
getValue(I.getOperand(1)),
@@ -3905,20 +4050,20 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
MVT VT = getValue(I.getOperand(1)).getValueType();
SDValue CfaArg;
if (VT.bitsGT(TLI.getPointerTy()))
- CfaArg = DAG.getNode(ISD::TRUNCATE,
+ CfaArg = DAG.getNode(ISD::TRUNCATE, dl,
TLI.getPointerTy(), getValue(I.getOperand(1)));
else
- CfaArg = DAG.getNode(ISD::SIGN_EXTEND,
+ CfaArg = DAG.getNode(ISD::SIGN_EXTEND, dl,
TLI.getPointerTy(), getValue(I.getOperand(1)));
- SDValue Offset = DAG.getNode(ISD::ADD,
+ SDValue Offset = DAG.getNode(ISD::ADD, dl,
TLI.getPointerTy(),
- DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET,
+ DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET, dl,
TLI.getPointerTy()),
CfaArg);
- setValue(&I, DAG.getNode(ISD::ADD,
+ setValue(&I, DAG.getNode(ISD::ADD, dl,
TLI.getPointerTy(),
- DAG.getNode(ISD::FRAMEADDR,
+ DAG.getNode(ISD::FRAMEADDR, dl,
TLI.getPointerTy(),
DAG.getConstant(0,
TLI.getPointerTy())),
@@ -3959,23 +4104,23 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
case Intrinsic::sqrt:
- setValue(&I, DAG.getNode(ISD::FSQRT,
+ setValue(&I, DAG.getNode(ISD::FSQRT, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::powi:
- setValue(&I, DAG.getNode(ISD::FPOWI,
+ setValue(&I, DAG.getNode(ISD::FPOWI, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)),
getValue(I.getOperand(2))));
return 0;
case Intrinsic::sin:
- setValue(&I, DAG.getNode(ISD::FSIN,
+ setValue(&I, DAG.getNode(ISD::FSIN, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::cos:
- setValue(&I, DAG.getNode(ISD::FCOS,
+ setValue(&I, DAG.getNode(ISD::FCOS, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
@@ -3999,12 +4144,12 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0;
case Intrinsic::pcmarker: {
SDValue Tmp = getValue(I.getOperand(1));
- DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp));
+ DAG.setRoot(DAG.getNode(ISD::PCMARKER, dl, MVT::Other, getRoot(), Tmp));
return 0;
}
case Intrinsic::readcyclecounter: {
SDValue Op = getRoot();
- SDValue Tmp = DAG.getNode(ISD::READCYCLECOUNTER,
+ SDValue Tmp = DAG.getNode(ISD::READCYCLECOUNTER, dl,
DAG.getNodeValueTypes(MVT::i64, MVT::Other), 2,
&Op, 1);
setValue(&I, Tmp);
@@ -4022,34 +4167,34 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
abort();
}
case Intrinsic::bswap:
- setValue(&I, DAG.getNode(ISD::BSWAP,
+ setValue(&I, DAG.getNode(ISD::BSWAP, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::cttz: {
SDValue Arg = getValue(I.getOperand(1));
MVT Ty = Arg.getValueType();
- SDValue result = DAG.getNode(ISD::CTTZ, Ty, Arg);
+ SDValue result = DAG.getNode(ISD::CTTZ, dl, Ty, Arg);
setValue(&I, result);
return 0;
}
case Intrinsic::ctlz: {
SDValue Arg = getValue(I.getOperand(1));
MVT Ty = Arg.getValueType();
- SDValue result = DAG.getNode(ISD::CTLZ, Ty, Arg);
+ SDValue result = DAG.getNode(ISD::CTLZ, dl, Ty, Arg);
setValue(&I, result);
return 0;
}
case Intrinsic::ctpop: {
SDValue Arg = getValue(I.getOperand(1));
MVT Ty = Arg.getValueType();
- SDValue result = DAG.getNode(ISD::CTPOP, Ty, Arg);
+ SDValue result = DAG.getNode(ISD::CTPOP, dl, Ty, Arg);
setValue(&I, result);
return 0;
}
case Intrinsic::stacksave: {
SDValue Op = getRoot();
- SDValue Tmp = DAG.getNode(ISD::STACKSAVE,
+ SDValue Tmp = DAG.getNode(ISD::STACKSAVE, dl,
DAG.getNodeValueTypes(TLI.getPointerTy(), MVT::Other), 2, &Op, 1);
setValue(&I, Tmp);
DAG.setRoot(Tmp.getValue(1));
@@ -4057,7 +4202,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
case Intrinsic::stackrestore: {
SDValue Tmp = getValue(I.getOperand(1));
- DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, MVT::Other, getRoot(), Tmp));
+ DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, dl, MVT::Other, getRoot(), Tmp));
return 0;
}
case Intrinsic::stackprotector: {
@@ -4075,7 +4220,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue FIN = DAG.getFrameIndex(FI, PtrTy);
// Store the stack protector onto the stack.
- SDValue Result = DAG.getStore(getRoot(), Src, FIN,
+ SDValue Result = DAG.getStore(getRoot(), getCurDebugLoc(), Src, FIN,
PseudoSourceValue::getFixedStack(FI),
0, true);
setValue(&I, Result);
@@ -4097,7 +4242,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Ops[4] = DAG.getSrcValue(I.getOperand(1));
Ops[5] = DAG.getSrcValue(F);
- SDValue Tmp = DAG.getNode(ISD::TRAMPOLINE,
+ SDValue Tmp = DAG.getNode(ISD::TRAMPOLINE, dl,
DAG.getNodeValueTypes(TLI.getPointerTy(),
MVT::Other), 2,
Ops, 6);
@@ -4123,12 +4268,12 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0;
case Intrinsic::flt_rounds: {
- setValue(&I, DAG.getNode(ISD::FLT_ROUNDS_, MVT::i32));
+ setValue(&I, DAG.getNode(ISD::FLT_ROUNDS_, dl, MVT::i32));
return 0;
}
case Intrinsic::trap: {
- DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot()));
+ DAG.setRoot(DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot()));
return 0;
}
@@ -4151,7 +4296,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Ops[1] = getValue(I.getOperand(1));
Ops[2] = getValue(I.getOperand(2));
Ops[3] = getValue(I.getOperand(3));
- DAG.setRoot(DAG.getNode(ISD::PREFETCH, MVT::Other, &Ops[0], 4));
+ DAG.setRoot(DAG.getNode(ISD::PREFETCH, dl, MVT::Other, &Ops[0], 4));
return 0;
}
@@ -4161,13 +4306,13 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
for (int x = 1; x < 6; ++x)
Ops[x] = getValue(I.getOperand(x));
- DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, MVT::Other, &Ops[0], 6));
+ DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6));
return 0;
}
case Intrinsic::atomic_cmp_swap: {
SDValue Root = getRoot();
SDValue L =
- DAG.getAtomic(ISD::ATOMIC_CMP_SWAP,
+ DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, getCurDebugLoc(),
getValue(I.getOperand(2)).getValueType().getSimpleVT(),
Root,
getValue(I.getOperand(1)),
@@ -4248,7 +4393,7 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee,
CS.paramHasAttr(0, Attribute::InReg),
CS.getCallingConv(),
IsTailCall && PerformTailCallOpt,
- Callee, Args, DAG);
+ Callee, Args, DAG, getCurDebugLoc());
if (CS.getType() != Type::VoidTy)
setValue(CS.getInstruction(), Result.first);
DAG.setRoot(Result.second);
@@ -4290,8 +4435,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
I.getType() == I.getOperand(2)->getType()) {
SDValue LHS = getValue(I.getOperand(1));
SDValue RHS = getValue(I.getOperand(2));
- setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(),
- LHS, RHS));
+ setValue(&I, DAG.getNode(ISD::FCOPYSIGN, getCurDebugLoc(),
+ LHS.getValueType(), LHS, RHS));
return;
}
} else if (NameStr[0] == 'f' &&
@@ -4302,7 +4447,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType()) {
SDValue Tmp = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp));
+ setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(),
+ Tmp.getValueType(), Tmp));
return;
}
} else if (NameStr[0] == 's' &&
@@ -4313,7 +4459,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType()) {
SDValue Tmp = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp));
+ setValue(&I, DAG.getNode(ISD::FSIN, getCurDebugLoc(),
+ Tmp.getValueType(), Tmp));
return;
}
} else if (NameStr[0] == 'c' &&
@@ -4324,7 +4471,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType()) {
SDValue Tmp = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp));
+ setValue(&I, DAG.getNode(ISD::FCOS, getCurDebugLoc(),
+ Tmp.getValueType(), Tmp));
return;
}
}
@@ -4348,7 +4496,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
/// this value and returns the result as a ValueVT 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 RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
+SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
SDValue &Chain,
SDValue *Flag) const {
// Assemble the legal parts into the final values.
@@ -4406,7 +4554,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32
if (FromVT != MVT::Other) {
- P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext,
+ P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, dl,
RegisterVT, P, DAG.getValueType(FromVT));
}
@@ -4416,13 +4564,13 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
Parts[i] = P;
}
- Values[Value] = getCopyFromParts(DAG, Parts.begin(), NumRegs, RegisterVT,
- ValueVT);
+ Values[Value] = getCopyFromParts(DAG, dl, Parts.begin(),
+ NumRegs, RegisterVT, ValueVT);
Part += NumRegs;
Parts.clear();
}
- return DAG.getNode(ISD::MERGE_VALUES,
+ return DAG.getNode(ISD::MERGE_VALUES, dl,
DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
&Values[0], ValueVTs.size());
}
@@ -4431,7 +4579,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
/// specified value into the registers specified by this object. 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.
-void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
+void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
SDValue &Chain, SDValue *Flag) const {
// Get the list of the values's legal parts.
unsigned NumRegs = Regs.size();
@@ -4441,7 +4589,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
unsigned NumParts = TLI->getNumRegisters(ValueVT);
MVT RegisterVT = RegVTs[Value];
- getCopyToParts(DAG, Val.getValue(Val.getResNo() + Value),
+ getCopyToParts(DAG, dl, Val.getValue(Val.getResNo() + Value),
&Parts[Part], NumParts, RegisterVT);
Part += NumParts;
}
@@ -4472,7 +4620,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
// = op c3, ..., f2
Chain = Chains[NumRegs-1];
else
- Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumRegs);
+ Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Chains[0], NumRegs);
}
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
@@ -4684,8 +4832,8 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
// vector types).
MVT RegVT = *PhysReg.second->vt_begin();
if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
- OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, RegVT,
- OpInfo.CallOperand);
+ OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(),
+ RegVT, OpInfo.CallOperand);
OpInfo.ConstraintVT = RegVT;
} else if (RegVT.isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) {
// If the input is a FP value and we want it in FP registers, do a
@@ -4693,8 +4841,8 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
// into i64, which can be passed with two i32 values on a 32-bit
// machine.
RegVT = MVT::getIntegerVT(OpInfo.ConstraintVT.getSizeInBits());
- OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, RegVT,
- OpInfo.CallOperand);
+ OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(),
+ RegVT, OpInfo.CallOperand);
OpInfo.ConstraintVT = RegVT;
}
}
@@ -4959,7 +5107,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
MachineFunction &MF = DAG.getMachineFunction();
int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align);
SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
- Chain = DAG.getStore(Chain, OpInfo.CallOperand, StackSlot, NULL, 0);
+ Chain = DAG.getStore(Chain, getCurDebugLoc(),
+ OpInfo.CallOperand, StackSlot, NULL, 0);
OpInfo.CallOperand = StackSlot;
}
@@ -5088,7 +5237,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
}
// Use the produced MatchedRegs object to
- MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
+ MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
+ Chain, &Flag);
MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
break;
} else {
@@ -5147,7 +5297,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
exit(1);
}
- OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
+ OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
+ Chain, &Flag);
OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/,
DAG, AsmNodeOperands);
@@ -5168,7 +5319,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
AsmNodeOperands[0] = Chain;
if (Flag.getNode()) AsmNodeOperands.push_back(Flag);
- Chain = DAG.getNode(ISD::INLINEASM,
+ Chain = DAG.getNode(ISD::INLINEASM, getCurDebugLoc(),
DAG.getNodeValueTypes(MVT::Other, MVT::Flag), 2,
&AsmNodeOperands[0], AsmNodeOperands.size());
Flag = Chain.getValue(1);
@@ -5176,7 +5327,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
// If this asm returns a register value, copy the result from that register
// and set it as the value of the call.
if (!RetValRegs.Regs.empty()) {
- SDValue Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag);
+ SDValue Val = RetValRegs.getCopyFromRegs(DAG, getCurDebugLoc(),
+ Chain, &Flag);
// FIXME: Why don't we do this for inline asms with MRVs?
if (CS.getType()->isSingleValueType() && CS.getType()->isSized()) {
@@ -5188,14 +5340,15 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
// not have the same VT as was expected. Convert it to the right type
// with bit_convert.
if (ResultType != Val.getValueType() && Val.getValueType().isVector()) {
- Val = DAG.getNode(ISD::BIT_CONVERT, ResultType, Val);
+ Val = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(),
+ ResultType, Val);
} else if (ResultType != Val.getValueType() &&
ResultType.isInteger() && Val.getValueType().isInteger()) {
// If a result value was tied to an input value, the computed result may
// have a wider width than the expected result. Extract the relevant
// portion.
- Val = DAG.getNode(ISD::TRUNCATE, ResultType, Val);
+ Val = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), ResultType, Val);
}
assert(ResultType == Val.getValueType() && "Asm result value mismatch!");
@@ -5211,18 +5364,20 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) {
RegsForValue &OutRegs = IndirectStoresToEmit[i].first;
Value *Ptr = IndirectStoresToEmit[i].second;
- SDValue OutVal = OutRegs.getCopyFromRegs(DAG, Chain, &Flag);
+ SDValue OutVal = OutRegs.getCopyFromRegs(DAG, getCurDebugLoc(),
+ Chain, &Flag);
StoresToEmit.push_back(std::make_pair(OutVal, Ptr));
}
// Emit the non-flagged stores from the physregs.
SmallVector<SDValue, 8> OutChains;
for (unsigned i = 0, e = StoresToEmit.size(); i != e; ++i)
- OutChains.push_back(DAG.getStore(Chain, StoresToEmit[i].first,
+ OutChains.push_back(DAG.getStore(Chain, getCurDebugLoc(),
+ StoresToEmit[i].first,
getValue(StoresToEmit[i].second),
StoresToEmit[i].second, 0));
if (!OutChains.empty())
- Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
+ Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other,
&OutChains[0], OutChains.size());
DAG.setRoot(Chain);
}
@@ -5234,13 +5389,13 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
MVT IntPtr = TLI.getPointerTy();
if (IntPtr.bitsLT(Src.getValueType()))
- Src = DAG.getNode(ISD::TRUNCATE, IntPtr, Src);
+ Src = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), IntPtr, Src);
else if (IntPtr.bitsGT(Src.getValueType()))
- Src = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, Src);
+ Src = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), IntPtr, Src);
// Scale the source by the type size.
uint64_t ElementSize = TD->getTypePaddedSize(I.getType()->getElementType());
- Src = DAG.getNode(ISD::MUL, Src.getValueType(),
+ Src = DAG.getNode(ISD::MUL, getCurDebugLoc(), Src.getValueType(),
Src, DAG.getIntPtrConstant(ElementSize));
TargetLowering::ArgListTy Args;
@@ -5253,7 +5408,7 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, false,
CallingConv::C, PerformTailCallOpt,
DAG.getExternalSymbol("malloc", IntPtr),
- Args, DAG);
+ Args, DAG, getCurDebugLoc());
setValue(&I, Result.first); // Pointers always fit in registers
DAG.setRoot(Result.second);
}
@@ -5268,12 +5423,14 @@ void SelectionDAGLowering::visitFree(FreeInst &I) {
std::pair<SDValue,SDValue> Result =
TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false, false,
CallingConv::C, PerformTailCallOpt,
- DAG.getExternalSymbol("free", IntPtr), Args, DAG);
+ DAG.getExternalSymbol("free", IntPtr), Args, DAG,
+ getCurDebugLoc());
DAG.setRoot(Result.second);
}
void SelectionDAGLowering::visitVAStart(CallInst &I) {
- DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(),
+ DAG.setRoot(DAG.getNode(ISD::VASTART, getCurDebugLoc(),
+ MVT::Other, getRoot(),
getValue(I.getOperand(1)),
DAG.getSrcValue(I.getOperand(1))));
}
@@ -5287,13 +5444,15 @@ void SelectionDAGLowering::visitVAArg(VAArgInst &I) {
}
void SelectionDAGLowering::visitVAEnd(CallInst &I) {
- DAG.setRoot(DAG.getNode(ISD::VAEND, MVT::Other, getRoot(),
+ DAG.setRoot(DAG.getNode(ISD::VAEND, getCurDebugLoc(),
+ MVT::Other, getRoot(),
getValue(I.getOperand(1)),
DAG.getSrcValue(I.getOperand(1))));
}
void SelectionDAGLowering::visitVACopy(CallInst &I) {
- DAG.setRoot(DAG.getNode(ISD::VACOPY, MVT::Other, getRoot(),
+ DAG.setRoot(DAG.getNode(ISD::VACOPY, getCurDebugLoc(),
+ MVT::Other, getRoot(),
getValue(I.getOperand(1)),
getValue(I.getOperand(2)),
DAG.getSrcValue(I.getOperand(1)),
@@ -5305,7 +5464,8 @@ void SelectionDAGLowering::visitVACopy(CallInst &I) {
/// targets are migrated to using FORMAL_ARGUMENTS, this hook should be
/// integrated into SDISel.
void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &ArgValues) {
+ SmallVectorImpl<SDValue> &ArgValues,
+ DebugLoc dl) {
// Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node.
SmallVector<SDValue, 3+16> Ops;
Ops.push_back(DAG.getRoot());
@@ -5370,7 +5530,7 @@ void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
RetVals.push_back(MVT::Other);
// Create the node.
- SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS,
+ SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS, dl,
DAG.getVTList(&RetVals[0], RetVals.size()),
&Ops[0], Ops.size()).getNode();
@@ -5420,8 +5580,8 @@ void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
else if (F.paramHasAttr(Idx, Attribute::ZExt))
AssertOp = ISD::AssertZext;
- ArgValues.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
- AssertOp));
+ ArgValues.push_back(getCopyFromParts(DAG, dl, &Parts[0], NumParts,
+ PartVT, VT, AssertOp));
}
}
assert(i == NumArgRegs && "Argument register count mismatch!");
@@ -5438,7 +5598,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
bool isInreg,
unsigned CallingConv, bool isTailCall,
SDValue Callee,
- ArgListTy &Args, SelectionDAG &DAG) {
+ ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl) {
assert((!isTailCall || PerformTailCallOpt) &&
"isTailCall set when tail-call optimizations are disabled!");
@@ -5495,7 +5655,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
else if (Args[i].isZExt)
ExtendKind = ISD::ZERO_EXTEND;
- getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind);
+ getCopyToParts(DAG, dl, Op, &Parts[0], NumParts, PartVT, ExtendKind);
for (unsigned i = 0; i != NumParts; ++i) {
// if it isn't first piece, alignment must be 1
@@ -5529,7 +5689,8 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
LoweredRetTys.push_back(MVT::Other); // Always has a chain.
// Create the CALL node.
- SDValue Res = DAG.getCall(CallingConv, isVarArg, isTailCall, isInreg,
+ SDValue Res = DAG.getCall(CallingConv, dl,
+ isVarArg, isTailCall, isInreg,
DAG.getVTList(&LoweredRetTys[0],
LoweredRetTys.size()),
&Ops[0], Ops.size()
@@ -5556,11 +5717,11 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
for (; RegNo != RegNoEnd; ++RegNo)
Results.push_back(Res.getValue(RegNo));
SDValue ReturnValue =
- getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT,
+ getCopyFromParts(DAG, dl, &Results[0], NumRegs, RegisterVT, VT,
AssertOp);
ReturnValues.push_back(ReturnValue);
}
- Res = DAG.getNode(ISD::MERGE_VALUES,
+ Res = DAG.getNode(ISD::MERGE_VALUES, dl,
DAG.getVTList(&RetTys[0], RetTys.size()),
&ReturnValues[0], ReturnValues.size());
}
@@ -5592,7 +5753,7 @@ void SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, unsigned Reg) {
RegsForValue RFV(TLI, Reg, V->getType());
SDValue Chain = DAG.getEntryNode();
- RFV.getCopyToRegs(Op, DAG, Chain, 0);
+ RFV.getCopyToRegs(Op, DAG, getCurDebugLoc(), Chain, 0);
PendingExports.push_back(Chain);
}
@@ -5604,7 +5765,7 @@ LowerArguments(BasicBlock *LLVMBB) {
Function &F = *LLVMBB->getParent();
SDValue OldRoot = SDL->DAG.getRoot();
SmallVector<SDValue, 16> Args;
- TLI.LowerArguments(F, SDL->DAG, Args);
+ TLI.LowerArguments(F, SDL->DAG, Args, SDL->getCurDebugLoc());
unsigned a = 0;
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h
index 4d450cb60dbd..487c796321fd 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h
@@ -20,8 +20,8 @@
#ifndef NDEBUG
#include "llvm/ADT/SmallSet.h"
#endif
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/CallSite.h"
#include <vector>
#include <set>
@@ -95,7 +95,8 @@ public:
/// set - Initialize this FunctionLoweringInfo with the given Function
/// and its associated MachineFunction.
///
- void set(Function &Fn, MachineFunction &MF, bool EnableFastISel);
+ void set(Function &Fn, MachineFunction &MF, SelectionDAG &DAG,
+ bool EnableFastISel);
/// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap;
@@ -164,6 +165,9 @@ public:
class SelectionDAGLowering {
MachineBasicBlock *CurMBB;
+ /// CurDebugLoc - current file + line number. Changes as we build the DAG.
+ DebugLoc CurDebugLoc;
+
DenseMap<const Value*, SDValue> NodeMap;
/// PendingLoads - Loads are not emitted to the program immediately. We bunch
@@ -356,7 +360,8 @@ public:
SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli,
FunctionLoweringInfo &funcinfo)
- : TLI(tli), DAG(dag), FuncInfo(funcinfo) {
+ : CurDebugLoc(DebugLoc::getUnknownLoc()),
+ TLI(tli), DAG(dag), FuncInfo(funcinfo) {
}
void init(GCFunctionInfo *gfi, AliasAnalysis &aa);
@@ -382,6 +387,8 @@ public:
///
SDValue getControlRoot();
+ DebugLoc getCurDebugLoc() const { return CurDebugLoc; }
+
void CopyValueToVirtualRegister(Value *V, unsigned Reg);
void visit(Instruction &I);
@@ -531,6 +538,8 @@ private:
const char *implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op);
const char *implVisitAluOverflow(CallInst &I, ISD::NodeType Op);
+
+ void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; }
};
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index ca0cd6e8f515..9c53fc9362c0 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -313,9 +313,9 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
RegInfo = &MF->getRegInfo();
DOUT << "\n\n\n=== " << Fn.getName() << "\n";
- FuncInfo->set(Fn, *MF, EnableFastISel);
- MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ FuncInfo->set(Fn, *MF, *CurDAG, EnableFastISel);
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
CurDAG->init(*MF, MMI, DW);
SDL->init(GFI, *AA);
@@ -743,7 +743,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
unsigned LabelID = MMI->addLandingPad(BB);
const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL);
- BuildMI(BB, II).addImm(LabelID);
+ BuildMI(BB, SDL->getCurDebugLoc(), II).addImm(LabelID);
// Mark exception register as live in.
unsigned Reg = TLI.getExceptionAddressRegister();
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 364a12177ff2..0f7db6e5393e 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -724,7 +724,7 @@ TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDValue Op,
const APInt &Demanded) {
// FIXME: ISD::SELECT, ISD::SELECT_CC
- switch(Op.getOpcode()) {
+ switch (Op.getOpcode()) {
default: break;
case ISD::AND:
case ISD::OR:
@@ -760,6 +760,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
assert(Op.getValueSizeInBits() == BitWidth &&
"Mask size mismatches value type size!");
APInt NewMask = DemandedMask;
+ DebugLoc dl = Op.getNode()->getDebugLoc();
// Don't know anything.
KnownZero = KnownOne = APInt(BitWidth, 0);
@@ -778,7 +779,8 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
} else if (DemandedMask == 0) {
// Not demanding any bits from Op.
if (Op.getOpcode() != ISD::UNDEF)
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::UNDEF, Op.getValueType()));
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::UNDEF, dl,
+ Op.getValueType()));
return false;
} else if (Depth == 6) { // Limit search depth.
return false;
@@ -905,8 +907,8 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if ((KnownOne & KnownOne2) == KnownOne) {
MVT VT = Op.getValueType();
SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, VT);
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, VT, Op.getOperand(0),
- ANDC));
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT,
+ Op.getOperand(0), ANDC));
}
}
@@ -919,7 +921,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if (Expanded.isAllOnesValue()) {
if (Expanded != C->getAPIntValue()) {
MVT VT = Op.getValueType();
- SDValue New = TLO.DAG.getNode(Op.getOpcode(), VT, Op.getOperand(0),
+ SDValue New = TLO.DAG.getNode(Op.getOpcode(), dl,VT, Op.getOperand(0),
TLO.DAG.getConstant(Expanded, VT));
return TLO.CombineTo(Op, New);
}
@@ -995,7 +997,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
SDValue NewSA =
TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType());
MVT VT = Op.getValueType();
- return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT,
+ return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT,
InOp.getOperand(0), NewSA));
}
}
@@ -1036,7 +1038,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
SDValue NewSA =
TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType());
- return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT,
+ return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT,
InOp.getOperand(0), NewSA));
}
}
@@ -1054,6 +1056,14 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
break;
case ISD::SRA:
+ // If this is an arithmetic shift right and only the low-bit is set, we can
+ // always convert this into a logical shr, even if the shift amount is
+ // variable. The low bit of the shift cannot be an input sign bit unless
+ // the shift amount is >= the size of the datatype, which is undefined.
+ if (DemandedMask == 1)
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, Op.getValueType(),
+ Op.getOperand(0), Op.getOperand(1)));
+
if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
MVT VT = Op.getValueType();
unsigned ShAmt = SA->getZExtValue();
@@ -1083,7 +1093,8 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If the input sign bit is known to be zero, or if none of the top bits
// are demanded, turn this into an unsigned shift right.
if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) {
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, VT, Op.getOperand(0),
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT,
+ Op.getOperand(0),
Op.getOperand(1)));
} else if (KnownOne.intersects(SignBit)) { // New bits are known one.
KnownOne |= HighBits;
@@ -1124,7 +1135,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If the input sign bit is known zero, convert this into a zero extension.
if (KnownZero.intersects(InSignBit))
return TLO.CombineTo(Op,
- TLO.DAG.getZeroExtendInReg(Op.getOperand(0), EVT));
+ TLO.DAG.getZeroExtendInReg(Op.getOperand(0),dl,EVT));
if (KnownOne.intersects(InSignBit)) { // Input sign bit known set
KnownOne |= NewBits;
@@ -1144,7 +1155,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
APInt NewBits =
APInt::getHighBitsSet(BitWidth, BitWidth - OperandBitWidth) & NewMask;
if (!NewBits.intersects(NewMask))
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND,
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND, dl,
Op.getValueType(),
Op.getOperand(0)));
@@ -1166,8 +1177,9 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If none of the top bits are demanded, convert this into an any_extend.
if (NewBits == 0)
- return TLO.CombineTo(Op,TLO.DAG.getNode(ISD::ANY_EXTEND,Op.getValueType(),
- Op.getOperand(0)));
+ return TLO.CombineTo(Op,TLO.DAG.getNode(ISD::ANY_EXTEND, dl,
+ Op.getValueType(),
+ Op.getOperand(0)));
// Since some of the sign extended bits are demanded, we know that the sign
// bit is demanded.
@@ -1183,7 +1195,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If the sign bit is known zero, convert this to a zero extend.
if (KnownZero.intersects(InSignBit))
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND,
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, dl,
Op.getValueType(),
Op.getOperand(0)));
@@ -1239,11 +1251,13 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if (ShAmt->getZExtValue() < BitWidth && !(HighBits & NewMask)) {
// None of the shifted in bits are needed. Add a truncate of the
// shift input, then shift it.
- SDValue NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE,
+ SDValue NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, dl,
Op.getValueType(),
In.getOperand(0));
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL,Op.getValueType(),
- NewTrunc, In.getOperand(1)));
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl,
+ Op.getValueType(),
+ NewTrunc,
+ In.getOperand(1)));
}
}
break;
@@ -1332,13 +1346,28 @@ unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
return 1;
}
+static bool ValueHasAtMostOneBitSet(SDValue Val, const SelectionDAG &DAG) {
+ // Logical shift right or left won't ever introduce new set bits.
+ // We check for this case because we don't care which bits are
+ // set, but ComputeMaskedBits won't know anything unless it can
+ // determine which specific bits may be set.
+ if (Val.getOpcode() == ISD::SHL || Val.getOpcode() == ISD::SRL)
+ return ValueHasAtMostOneBitSet(Val.getOperand(0), DAG);
+
+ MVT OpVT = Val.getValueType();
+ unsigned BitWidth = OpVT.getSizeInBits();
+ APInt Mask = APInt::getAllOnesValue(BitWidth);
+ APInt KnownZero, KnownOne;
+ DAG.ComputeMaskedBits(Val, Mask, KnownZero, KnownOne);
+ return KnownZero.countPopulation() == BitWidth - 1;
+}
/// SimplifySetCC - Try to simplify a setcc built with the specified operands
/// and cc. If it is unable to simplify it, return a null SDValue.
SDValue
TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
ISD::CondCode Cond, bool foldBooleans,
- DAGCombinerInfo &DCI) const {
+ DAGCombinerInfo &DCI, DebugLoc dl) const {
SelectionDAG &DAG = DCI.DAG;
// These setcc operations always fold.
@@ -1353,7 +1382,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
const APInt &C1 = N1C->getAPIntValue();
if (isa<ConstantSDNode>(N0.getNode())) {
- return DAG.FoldSetCC(VT, N0, N1, Cond);
+ return DAG.FoldSetCC(VT, N0, N1, Cond, dl);
} else {
// If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an
// equality comparison, then we're just comparing whether X itself is
@@ -1374,7 +1403,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
Cond = ISD::SETEQ;
}
SDValue Zero = DAG.getConstant(0, N0.getValueType());
- return DAG.getSetCC(VT, N0.getOperand(0).getOperand(0),
+ return DAG.getSetCC(dl, VT, N0.getOperand(0).getOperand(0),
Zero, Cond);
}
}
@@ -1419,16 +1448,17 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
MVT PtrType = Lod->getOperand(1).getValueType();
SDValue Ptr = Lod->getBasePtr();
if (bestOffset != 0)
- Ptr = DAG.getNode(ISD::ADD, PtrType, Lod->getBasePtr(),
+ Ptr = DAG.getNode(ISD::ADD, dl, PtrType, Lod->getBasePtr(),
DAG.getConstant(bestOffset, PtrType));
unsigned NewAlign = MinAlign(Lod->getAlignment(), bestOffset);
- SDValue NewLoad = DAG.getLoad(newVT, Lod->getChain(), Ptr,
+ SDValue NewLoad = DAG.getLoad(newVT, dl, Lod->getChain(), Ptr,
Lod->getSrcValue(),
Lod->getSrcValueOffset() + bestOffset,
false, NewAlign);
- return DAG.getSetCC(VT, DAG.getNode(ISD::AND, newVT, NewLoad,
+ return DAG.getSetCC(dl, VT,
+ DAG.getNode(ISD::AND, dl, newVT, NewLoad,
DAG.getConstant(bestMask, newVT)),
- DAG.getConstant(0LL, newVT), Cond);
+ DAG.getConstant(0LL, newVT), Cond);
}
}
}
@@ -1469,7 +1499,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
case ISD::SETUGE:
case ISD::SETULT:
case ISD::SETULE:
- return DAG.getSetCC(VT, N0.getOperand(0),
+ return DAG.getSetCC(dl, VT, N0.getOperand(0),
DAG.getConstant(APInt(C1).trunc(InSize),
N0.getOperand(0).getValueType()),
Cond);
@@ -1497,13 +1527,13 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
ZextOp = N0.getOperand(0);
} else {
APInt Imm = APInt::getLowBitsSet(ExtDstTyBits, ExtSrcTyBits);
- ZextOp = DAG.getNode(ISD::AND, Op0Ty, N0.getOperand(0),
+ ZextOp = DAG.getNode(ISD::AND, dl, Op0Ty, N0.getOperand(0),
DAG.getConstant(Imm, Op0Ty));
}
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(ZextOp.getNode());
// Otherwise, make this a use of a zext.
- return DAG.getSetCC(VT, ZextOp,
+ return DAG.getSetCC(dl, VT, ZextOp,
DAG.getConstant(C1 & APInt::getLowBitsSet(
ExtDstTyBits,
ExtSrcTyBits),
@@ -1522,7 +1552,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
CC = ISD::getSetCCInverse(CC,
N0.getOperand(0).getValueType().isInteger());
- return DAG.getSetCC(VT, N0.getOperand(0), N0.getOperand(1), CC);
+ return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
}
if ((N0.getOpcode() == ISD::XOR ||
@@ -1545,11 +1575,11 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
assert(N0.getOpcode() == ISD::AND &&
N0.getOperand(0).getOpcode() == ISD::XOR);
// ((X^1)&1)^1 -> X & 1
- Val = DAG.getNode(ISD::AND, N0.getValueType(),
+ Val = DAG.getNode(ISD::AND, dl, N0.getValueType(),
N0.getOperand(0).getOperand(0),
N0.getOperand(1));
}
- return DAG.getSetCC(VT, Val, N1,
+ return DAG.getSetCC(dl, VT, Val, N1,
Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
}
}
@@ -1569,15 +1599,17 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
if (Cond == ISD::SETGE || Cond == ISD::SETUGE) {
if (C1 == MinVal) return DAG.getConstant(1, VT); // X >= MIN --> true
// X >= C0 --> X > (C0-1)
- return DAG.getSetCC(VT, N0, DAG.getConstant(C1-1, N1.getValueType()),
- (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT);
+ return DAG.getSetCC(dl, VT, N0,
+ DAG.getConstant(C1-1, N1.getValueType()),
+ (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT);
}
if (Cond == ISD::SETLE || Cond == ISD::SETULE) {
if (C1 == MaxVal) return DAG.getConstant(1, VT); // X <= MAX --> true
// X <= C0 --> X < (C0+1)
- return DAG.getSetCC(VT, N0, DAG.getConstant(C1+1, N1.getValueType()),
- (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT);
+ return DAG.getSetCC(dl, VT, N0,
+ DAG.getConstant(C1+1, N1.getValueType()),
+ (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT);
}
if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal)
@@ -1591,19 +1623,21 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
// Canonicalize setgt X, Min --> setne X, Min
if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MinVal)
- return DAG.getSetCC(VT, N0, N1, ISD::SETNE);
+ return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE);
// Canonicalize setlt X, Max --> setne X, Max
if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MaxVal)
- return DAG.getSetCC(VT, N0, N1, ISD::SETNE);
+ return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE);
// If we have setult X, 1, turn it into seteq X, 0
if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal+1)
- return DAG.getSetCC(VT, N0, DAG.getConstant(MinVal, N0.getValueType()),
- ISD::SETEQ);
+ return DAG.getSetCC(dl, VT, N0,
+ DAG.getConstant(MinVal, N0.getValueType()),
+ ISD::SETEQ);
// If we have setugt X, Max-1, turn it into seteq X, Max
else if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MaxVal-1)
- return DAG.getSetCC(VT, N0, DAG.getConstant(MaxVal, N0.getValueType()),
- ISD::SETEQ);
+ return DAG.getSetCC(dl, VT, N0,
+ DAG.getConstant(MaxVal, N0.getValueType()),
+ ISD::SETEQ);
// If we have "setcc X, C0", check to see if we can shrink the immediate
// by changing cc.
@@ -1611,7 +1645,8 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
// SETUGT X, SINTMAX -> SETLT X, 0
if (Cond == ISD::SETUGT &&
C1 == APInt::getSignedMaxValue(OperandBitSize))
- return DAG.getSetCC(VT, N0, DAG.getConstant(0, N1.getValueType()),
+ return DAG.getSetCC(dl, VT, N0,
+ DAG.getConstant(0, N1.getValueType()),
ISD::SETLT);
// SETULT X, SINTMIN -> SETGT X, -1
@@ -1620,7 +1655,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
SDValue ConstMinusOne =
DAG.getConstant(APInt::getAllOnesValue(OperandBitSize),
N1.getValueType());
- return DAG.getSetCC(VT, N0, ConstMinusOne, ISD::SETGT);
+ return DAG.getSetCC(dl, VT, N0, ConstMinusOne, ISD::SETGT);
}
// Fold bit comparisons when we can.
@@ -1628,31 +1663,33 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
VT == N0.getValueType() && N0.getOpcode() == ISD::AND)
if (ConstantSDNode *AndRHS =
dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
+ MVT ShiftTy = DCI.isBeforeLegalize() ?
+ getPointerTy() : getShiftAmountTy();
if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3
// Perform the xform if the AND RHS is a single bit.
if (isPowerOf2_64(AndRHS->getZExtValue())) {
- return DAG.getNode(ISD::SRL, VT, N0,
- DAG.getConstant(Log2_64(AndRHS->getZExtValue()),
- getShiftAmountTy()));
+ return DAG.getNode(ISD::SRL, dl, VT, N0,
+ DAG.getConstant(Log2_64(AndRHS->getZExtValue()),
+ ShiftTy));
}
} else if (Cond == ISD::SETEQ && C1 == AndRHS->getZExtValue()) {
// (X & 8) == 8 --> (X & 8) >> 3
// Perform the xform if C1 is a single bit.
if (C1.isPowerOf2()) {
- return DAG.getNode(ISD::SRL, VT, N0,
- DAG.getConstant(C1.logBase2(), getShiftAmountTy()));
+ return DAG.getNode(ISD::SRL, dl, VT, N0,
+ DAG.getConstant(C1.logBase2(), ShiftTy));
}
}
}
}
} else if (isa<ConstantSDNode>(N0.getNode())) {
// Ensure that the constant occurs on the RHS.
- return DAG.getSetCC(VT, N1, N0, ISD::getSetCCSwappedOperands(Cond));
+ return DAG.getSetCC(dl, VT, N1, N0, ISD::getSetCCSwappedOperands(Cond));
}
if (isa<ConstantFPSDNode>(N0.getNode())) {
// Constant fold or commute setcc.
- SDValue O = DAG.FoldSetCC(VT, N0, N1, Cond);
+ SDValue O = DAG.FoldSetCC(VT, N0, N1, Cond, dl);
if (O.getNode()) return O;
} else if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1.getNode())) {
// If the RHS of an FP comparison is a constant, simplify it away in
@@ -1675,7 +1712,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
// have SETO(x,x) instead of SETO(x, 0.0) because this avoids having to
// materialize 0.0.
if (Cond == ISD::SETO || Cond == ISD::SETUO)
- return DAG.getSetCC(VT, N0, N0, Cond);
+ return DAG.getSetCC(dl, VT, N0, N0, Cond);
}
if (N0 == N1) {
@@ -1691,7 +1728,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
// if it is not already.
ISD::CondCode NewCond = UOF == 0 ? ISD::SETO : ISD::SETUO;
if (NewCond != Cond)
- return DAG.getSetCC(VT, N0, N1, NewCond);
+ return DAG.getSetCC(dl, VT, N0, N1, NewCond);
}
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
@@ -1701,15 +1738,17 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
// Simplify (X+Y) == (X+Z) --> Y == Z
if (N0.getOpcode() == N1.getOpcode()) {
if (N0.getOperand(0) == N1.getOperand(0))
- return DAG.getSetCC(VT, N0.getOperand(1), N1.getOperand(1), Cond);
+ return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(1), Cond);
if (N0.getOperand(1) == N1.getOperand(1))
- return DAG.getSetCC(VT, N0.getOperand(0), N1.getOperand(0), Cond);
+ return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(0), Cond);
if (DAG.isCommutativeBinOp(N0.getOpcode())) {
// If X op Y == Y op X, try other combinations.
if (N0.getOperand(0) == N1.getOperand(1))
- return DAG.getSetCC(VT, N0.getOperand(1), N1.getOperand(0), Cond);
+ return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(0),
+ Cond);
if (N0.getOperand(1) == N1.getOperand(0))
- return DAG.getSetCC(VT, N0.getOperand(0), N1.getOperand(1), Cond);
+ return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(1),
+ Cond);
}
}
@@ -1717,7 +1756,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
if (ConstantSDNode *LHSR = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
// Turn (X+C1) == C2 --> X == C2-C1
if (N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse()) {
- return DAG.getSetCC(VT, N0.getOperand(0),
+ return DAG.getSetCC(dl, VT, N0.getOperand(0),
DAG.getConstant(RHSC->getAPIntValue()-
LHSR->getAPIntValue(),
N0.getValueType()), Cond);
@@ -1729,7 +1768,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
// performing the inversion.
if (DAG.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getAPIntValue()))
return
- DAG.getSetCC(VT, N0.getOperand(0),
+ DAG.getSetCC(dl, VT, N0.getOperand(0),
DAG.getConstant(LHSR->getAPIntValue() ^
RHSC->getAPIntValue(),
N0.getValueType()),
@@ -1740,7 +1779,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
if (ConstantSDNode *SUBC = dyn_cast<ConstantSDNode>(N0.getOperand(0))) {
if (N0.getOpcode() == ISD::SUB && N0.getNode()->hasOneUse()) {
return
- DAG.getSetCC(VT, N0.getOperand(1),
+ DAG.getSetCC(dl, VT, N0.getOperand(1),
DAG.getConstant(SUBC->getAPIntValue() -
RHSC->getAPIntValue(),
N0.getValueType()),
@@ -1751,21 +1790,21 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
// Simplify (X+Z) == X --> Z == 0
if (N0.getOperand(0) == N1)
- return DAG.getSetCC(VT, N0.getOperand(1),
+ return DAG.getSetCC(dl, VT, N0.getOperand(1),
DAG.getConstant(0, N0.getValueType()), Cond);
if (N0.getOperand(1) == N1) {
if (DAG.isCommutativeBinOp(N0.getOpcode()))
- return DAG.getSetCC(VT, N0.getOperand(0),
+ return DAG.getSetCC(dl, VT, N0.getOperand(0),
DAG.getConstant(0, N0.getValueType()), Cond);
else if (N0.getNode()->hasOneUse()) {
assert(N0.getOpcode() == ISD::SUB && "Unexpected operation!");
// (Z-X) == X --> Z == X<<1
- SDValue SH = DAG.getNode(ISD::SHL, N1.getValueType(),
+ SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(),
N1,
DAG.getConstant(1, getShiftAmountTy()));
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(SH.getNode());
- return DAG.getSetCC(VT, N0.getOperand(0), SH, Cond);
+ return DAG.getSetCC(dl, VT, N0.getOperand(0), SH, Cond);
}
}
}
@@ -1774,23 +1813,41 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
N1.getOpcode() == ISD::XOR) {
// Simplify X == (X+Z) --> Z == 0
if (N1.getOperand(0) == N0) {
- return DAG.getSetCC(VT, N1.getOperand(1),
+ return DAG.getSetCC(dl, VT, N1.getOperand(1),
DAG.getConstant(0, N1.getValueType()), Cond);
} else if (N1.getOperand(1) == N0) {
if (DAG.isCommutativeBinOp(N1.getOpcode())) {
- return DAG.getSetCC(VT, N1.getOperand(0),
+ return DAG.getSetCC(dl, VT, N1.getOperand(0),
DAG.getConstant(0, N1.getValueType()), Cond);
} else if (N1.getNode()->hasOneUse()) {
assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!");
// X == (Z-X) --> X<<1 == Z
- SDValue SH = DAG.getNode(ISD::SHL, N1.getValueType(), N0,
+ SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(), N0,
DAG.getConstant(1, getShiftAmountTy()));
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(SH.getNode());
- return DAG.getSetCC(VT, SH, N1.getOperand(0), Cond);
+ return DAG.getSetCC(dl, VT, SH, N1.getOperand(0), Cond);
}
}
}
+
+ // Simplify x&y == y to x&y != 0 if y has exactly one bit set.
+ if (N0.getOpcode() == ISD::AND)
+ if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
+ if (ValueHasAtMostOneBitSet(N1, DAG)) {
+ Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
+ SDValue Zero = DAG.getConstant(0, N1.getValueType());
+ return DAG.getSetCC(dl, VT, N0, Zero, Cond);
+ }
+ }
+ if (N1.getOpcode() == ISD::AND)
+ if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) {
+ if (ValueHasAtMostOneBitSet(N0, DAG)) {
+ Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
+ SDValue Zero = DAG.getConstant(0, N0.getValueType());
+ return DAG.getSetCC(dl, VT, N1, Zero, Cond);
+ }
+ }
}
// Fold away ALL boolean setcc's.
@@ -1798,47 +1855,47 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
if (N0.getValueType() == MVT::i1 && foldBooleans) {
switch (Cond) {
default: assert(0 && "Unknown integer setcc!");
- case ISD::SETEQ: // X == Y -> (X^Y)^1
- Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, N1);
- N0 = DAG.getNode(ISD::XOR, MVT::i1, Temp, DAG.getConstant(1, MVT::i1));
+ case ISD::SETEQ: // X == Y -> ~(X^Y)
+ Temp = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1);
+ N0 = DAG.getNOT(dl, Temp, MVT::i1);
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(Temp.getNode());
break;
case ISD::SETNE: // X != Y --> (X^Y)
- N0 = DAG.getNode(ISD::XOR, MVT::i1, N0, N1);
+ N0 = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1);
break;
- case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> X^1 & Y
- case ISD::SETULT: // X <u Y --> X == 0 & Y == 1 --> X^1 & Y
- Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1));
+ case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> ~X & Y
+ case ISD::SETULT: // X <u Y --> X == 0 & Y == 1 --> ~X & Y
+ Temp = DAG.getNOT(dl, N0, MVT::i1);
N0 = DAG.getNode(ISD::AND, MVT::i1, N1, Temp);
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(Temp.getNode());
break;
- case ISD::SETLT: // X <s Y --> X == 1 & Y == 0 --> Y^1 & X
- case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> Y^1 & X
- Temp = DAG.getNode(ISD::XOR, MVT::i1, N1, DAG.getConstant(1, MVT::i1));
- N0 = DAG.getNode(ISD::AND, MVT::i1, N0, Temp);
+ case ISD::SETLT: // X <s Y --> X == 1 & Y == 0 --> ~Y & X
+ case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> ~Y & X
+ Temp = DAG.getNOT(dl, N1, MVT::i1);
+ N0 = DAG.getNode(ISD::AND, dl, MVT::i1, N0, Temp);
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(Temp.getNode());
break;
- case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> X^1 | Y
- case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> X^1 | Y
- Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1));
- N0 = DAG.getNode(ISD::OR, MVT::i1, N1, Temp);
+ case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> ~X | Y
+ case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> ~X | Y
+ Temp = DAG.getNOT(dl, N0, MVT::i1);
+ N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N1, Temp);
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(Temp.getNode());
break;
- case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> Y^1 | X
- case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> Y^1 | X
- Temp = DAG.getNode(ISD::XOR, MVT::i1, N1, DAG.getConstant(1, MVT::i1));
- N0 = DAG.getNode(ISD::OR, MVT::i1, N0, Temp);
+ case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> ~Y | X
+ case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> ~Y | X
+ Temp = DAG.getNOT(dl, N1, MVT::i1);
+ N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N0, Temp);
break;
}
if (VT != MVT::i1) {
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(N0.getNode());
// FIXME: If running after legalize, we probably can't do this.
- N0 = DAG.getNode(ISD::ZERO_EXTEND, VT, N0);
+ N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, N0);
}
return N0;
}
@@ -2353,6 +2410,7 @@ static ms magic(const APInt& d) {
SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
std::vector<SDNode*>* Created) const {
MVT VT = N->getValueType(0);
+ DebugLoc dl= N->getDebugLoc();
// Check to see if we can do this.
// FIXME: We should be more aggressive here.
@@ -2365,41 +2423,41 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
// Multiply the numerator (operand 0) by the magic value
// FIXME: We should support doing a MUL in a wider type
SDValue Q;
- if (isOperationLegal(ISD::MULHS, VT))
- Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0),
+ if (isOperationLegalOrCustom(ISD::MULHS, VT))
+ Q = DAG.getNode(ISD::MULHS, dl, VT, N->getOperand(0),
DAG.getConstant(magics.m, VT));
- else if (isOperationLegal(ISD::SMUL_LOHI, VT))
- Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(VT, VT),
+ else if (isOperationLegalOrCustom(ISD::SMUL_LOHI, VT))
+ Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT),
N->getOperand(0),
DAG.getConstant(magics.m, VT)).getNode(), 1);
else
return SDValue(); // No mulhs or equvialent
// If d > 0 and m < 0, add the numerator
if (d.isStrictlyPositive() && magics.m.isNegative()) {
- Q = DAG.getNode(ISD::ADD, VT, Q, N->getOperand(0));
+ Q = DAG.getNode(ISD::ADD, dl, VT, Q, N->getOperand(0));
if (Created)
Created->push_back(Q.getNode());
}
// If d < 0 and m > 0, subtract the numerator.
if (d.isNegative() && magics.m.isStrictlyPositive()) {
- Q = DAG.getNode(ISD::SUB, VT, Q, N->getOperand(0));
+ Q = DAG.getNode(ISD::SUB, dl, VT, Q, N->getOperand(0));
if (Created)
Created->push_back(Q.getNode());
}
// Shift right algebraic if shift value is nonzero
if (magics.s > 0) {
- Q = DAG.getNode(ISD::SRA, VT, Q,
+ Q = DAG.getNode(ISD::SRA, dl, VT, Q,
DAG.getConstant(magics.s, getShiftAmountTy()));
if (Created)
Created->push_back(Q.getNode());
}
// Extract the sign bit and add it to the quotient
SDValue T =
- DAG.getNode(ISD::SRL, VT, Q, DAG.getConstant(VT.getSizeInBits()-1,
+ DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(VT.getSizeInBits()-1,
getShiftAmountTy()));
if (Created)
Created->push_back(T.getNode());
- return DAG.getNode(ISD::ADD, VT, Q, T);
+ return DAG.getNode(ISD::ADD, dl, VT, Q, T);
}
/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant,
@@ -2409,6 +2467,7 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
std::vector<SDNode*>* Created) const {
MVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
// Check to see if we can do this.
// FIXME: We should be more aggressive here.
@@ -2423,11 +2482,11 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
// Multiply the numerator (operand 0) by the magic value
// FIXME: We should support doing a MUL in a wider type
SDValue Q;
- if (isOperationLegal(ISD::MULHU, VT))
- Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0),
+ if (isOperationLegalOrCustom(ISD::MULHU, VT))
+ Q = DAG.getNode(ISD::MULHU, dl, VT, N->getOperand(0),
DAG.getConstant(magics.m, VT));
- else if (isOperationLegal(ISD::UMUL_LOHI, VT))
- Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(VT, VT),
+ else if (isOperationLegalOrCustom(ISD::UMUL_LOHI, VT))
+ Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT),
N->getOperand(0),
DAG.getConstant(magics.m, VT)).getNode(), 1);
else
@@ -2438,20 +2497,20 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
if (magics.a == 0) {
assert(magics.s < N1C->getAPIntValue().getBitWidth() &&
"We shouldn't generate an undefined shift!");
- return DAG.getNode(ISD::SRL, VT, Q,
+ return DAG.getNode(ISD::SRL, dl, VT, Q,
DAG.getConstant(magics.s, getShiftAmountTy()));
} else {
- SDValue NPQ = DAG.getNode(ISD::SUB, VT, N->getOperand(0), Q);
+ SDValue NPQ = DAG.getNode(ISD::SUB, dl, VT, N->getOperand(0), Q);
if (Created)
Created->push_back(NPQ.getNode());
- NPQ = DAG.getNode(ISD::SRL, VT, NPQ,
+ NPQ = DAG.getNode(ISD::SRL, dl, VT, NPQ,
DAG.getConstant(1, getShiftAmountTy()));
if (Created)
Created->push_back(NPQ.getNode());
- NPQ = DAG.getNode(ISD::ADD, VT, NPQ, Q);
+ NPQ = DAG.getNode(ISD::ADD, dl, VT, NPQ, Q);
if (Created)
Created->push_back(NPQ.getNode());
- return DAG.getNode(ISD::SRL, VT, NPQ,
+ return DAG.getNode(ISD::SRL, dl, VT, NPQ,
DAG.getConstant(magics.s-1, getShiftAmountTy()));
}
}
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 637d74b9a1ab..f3ffc69cccbe 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -36,7 +36,7 @@
using namespace llvm;
STATISTIC(numJoins , "Number of interval joins performed");
-STATISTIC(numSubJoins , "Number of subclass joins performed");
+STATISTIC(numCrossRCs , "Number of cross class joins performed");
STATISTIC(numCommutes , "Number of instruction commuting performed");
STATISTIC(numExtends , "Number of copies extended");
STATISTIC(NumReMats , "Number of instructions re-materialized");
@@ -55,8 +55,8 @@ NewHeuristic("new-coalescer-heuristic",
cl::init(false), cl::Hidden);
static cl::opt<bool>
-CrossClassJoin("join-subclass-copies",
- cl::desc("Coalesce copies to sub- register class"),
+CrossClassJoin("join-cross-class-copies",
+ cl::desc("Coalesce cross register class copies"),
cl::init(false), cl::Hidden);
static RegisterPass<SimpleRegisterCoalescing>
@@ -953,38 +953,24 @@ static unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
return 0;
}
-/// isProfitableToCoalesceToSubRC - Given that register class of DstReg is
-/// a subset of the register class of SrcReg, return true if it's profitable
-/// to coalesce the two registers.
+/// isWinToJoinCrossClass - Return true if it's profitable to coalesce
+/// two virtual registers from different register classes.
bool
-SimpleRegisterCoalescing::isProfitableToCoalesceToSubRC(unsigned SrcReg,
- unsigned DstReg,
- MachineBasicBlock *MBB){
- if (!CrossClassJoin)
- return false;
-
- // First let's make sure all uses are in the same MBB.
- for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(SrcReg),
- RE = mri_->reg_end(); RI != RE; ++RI) {
- MachineInstr &MI = *RI;
- if (MI.getParent() != MBB)
- return false;
- }
- for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(DstReg),
- RE = mri_->reg_end(); RI != RE; ++RI) {
- MachineInstr &MI = *RI;
- if (MI.getParent() != MBB)
- return false;
- }
-
+SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned LargeReg,
+ unsigned SmallReg,
+ unsigned Threshold) {
// Then make sure the intervals are *short*.
- LiveInterval &SrcInt = li_->getInterval(SrcReg);
- LiveInterval &DstInt = li_->getInterval(DstReg);
- unsigned SrcSize = li_->getApproximateInstructionCount(SrcInt);
- unsigned DstSize = li_->getApproximateInstructionCount(DstInt);
- const TargetRegisterClass *RC = mri_->getRegClass(DstReg);
- unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
- return (SrcSize + DstSize) <= Threshold;
+ LiveInterval &LargeInt = li_->getInterval(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_begin(SmallReg),
+ mri_->use_end()) / SmallSize <
+ (float)std::distance(mri_->use_begin(LargeReg),
+ mri_->use_end()) / LargeSize)
+ return false;
+ return true;
}
/// HasIncompatibleSubRegDefUse - If we are trying to coalesce a virtual
@@ -1047,15 +1033,9 @@ SimpleRegisterCoalescing::HasIncompatibleSubRegDefUse(MachineInstr *CopyMI,
/// an extract_subreg where dst is a physical register, e.g.
/// cl = EXTRACT_SUBREG reg1024, 1
bool
-SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(MachineInstr *CopyMI,
- unsigned DstReg, unsigned SrcReg,
- unsigned SubIdx, unsigned &RealDstReg) {
- if (CopyMI->getOperand(1).getSubReg()) {
- DOUT << "\tSrc of extract_subreg already coalesced with reg"
- << " of a super-class.\n";
- return false; // Not coalescable.
- }
-
+SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(unsigned DstReg,
+ unsigned SrcReg, unsigned SubIdx,
+ unsigned &RealDstReg) {
const TargetRegisterClass *RC = mri_->getRegClass(SrcReg);
RealDstReg = getMatchingSuperReg(DstReg, SubIdx, RC, tri_);
assert(RealDstReg && "Invalid extract_subreg instruction!");
@@ -1083,14 +1063,9 @@ SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(MachineInstr *CopyMI,
/// an insert_subreg where src is a physical register, e.g.
/// reg1024 = INSERT_SUBREG reg1024, c1, 0
bool
-SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(MachineInstr *CopyMI,
- unsigned DstReg, unsigned SrcReg,
- unsigned SubIdx, unsigned &RealSrcReg) {
- if (CopyMI->getOperand(1).getSubReg()) {
- DOUT << "\tSrc of insert_subreg already coalesced with reg"
- << " of a super-class.\n";
- return false; // Not coalescable.
- }
+SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(unsigned DstReg,
+ unsigned SrcReg, unsigned SubIdx,
+ unsigned &RealSrcReg) {
const TargetRegisterClass *RC = mri_->getRegClass(DstReg);
RealSrcReg = getMatchingSuperReg(SrcReg, SubIdx, RC, tri_);
assert(RealSrcReg && "Invalid extract_subreg instruction!");
@@ -1111,7 +1086,6 @@ SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(MachineInstr *CopyMI,
return true;
}
-
/// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
/// which are the src/dst of the copy instruction CopyMI. This returns true
/// if the copy was successfully coalesced away. If it is not currently
@@ -1172,7 +1146,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
}
// Should be non-null only when coalescing to a sub-register class.
- const TargetRegisterClass *SubRC = NULL;
+ bool CrossRC = false;
+ const TargetRegisterClass *NewRC = NULL;
MachineBasicBlock *CopyMBB = CopyMI->getParent();
unsigned RealDstReg = 0;
unsigned RealSrcReg = 0;
@@ -1206,13 +1181,17 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
DstReg = tri_->getSubReg(DstReg, SubIdx);
SubIdx = 0;
} else if ((DstIsPhys && isExtSubReg) || (SrcIsPhys && isInsSubReg)) {
+ if (CopyMI->getOperand(1).getSubReg()) {
+ DOUT << "\tSrc of extract_subreg already coalesced with reg"
+ << " of a super-class.\n";
+ return false; // Not coalescable.
+ }
+
if (isExtSubReg) {
- if (!CanJoinExtractSubRegToPhysReg(CopyMI, DstReg, SrcReg, SubIdx,
- RealDstReg))
+ if (!CanJoinExtractSubRegToPhysReg(DstReg, SrcReg, SubIdx, RealDstReg))
return false; // Not coalescable
} else {
- if (!CanJoinInsertSubRegToPhysReg(CopyMI, DstReg, SrcReg, SubIdx,
- RealSrcReg))
+ if (!CanJoinInsertSubRegToPhysReg(DstReg, SrcReg, SubIdx, RealSrcReg))
return false; // Not coalescable
}
SubIdx = 0;
@@ -1220,8 +1199,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
unsigned OldSubIdx = isExtSubReg ? CopyMI->getOperand(0).getSubReg()
: CopyMI->getOperand(2).getSubReg();
if (OldSubIdx) {
- if (OldSubIdx == SubIdx &&
- !differingRegisterClasses(SrcReg, DstReg, SubRC))
+ if (OldSubIdx == SubIdx && !differingRegisterClasses(SrcReg, DstReg))
// r1024<2> = EXTRACT_SUBREG r1025, 2. Then r1024 has already been
// coalesced to a larger register so the subreg indices cancel out.
// Also check if the other larger register is of the same register
@@ -1235,41 +1213,95 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
if (SubIdx) {
unsigned LargeReg = isExtSubReg ? SrcReg : DstReg;
unsigned SmallReg = isExtSubReg ? DstReg : SrcReg;
- unsigned LargeRegSize =
- li_->getApproximateInstructionCount(li_->getInterval(LargeReg));
- unsigned SmallRegSize =
- li_->getApproximateInstructionCount(li_->getInterval(SmallReg));
- const TargetRegisterClass *RC = mri_->getRegClass(SmallReg);
- unsigned Threshold = allocatableRCRegs_[RC].count();
- // Be conservative. If both sides are virtual registers, do not coalesce
- // if this will cause a high use density interval to target a smaller
- // set of registers.
- if (SmallRegSize > Threshold || LargeRegSize > Threshold) {
- if ((float)std::distance(mri_->use_begin(SmallReg),
- mri_->use_end()) / SmallRegSize <
- (float)std::distance(mri_->use_begin(LargeReg),
- mri_->use_end()) / LargeRegSize) {
- Again = true; // May be possible to coalesce later.
- return false;
- }
+ unsigned Limit= allocatableRCRegs_[mri_->getRegClass(SmallReg)].count();
+ if (!isWinToJoinCrossClass(LargeReg, SmallReg, Limit)) {
+ Again = true; // May be possible to coalesce later.
+ return false;
}
}
}
- } else if (differingRegisterClasses(SrcReg, DstReg, SubRC)) {
- // FIXME: What if the resul of a EXTRACT_SUBREG is then coalesced
+ } else if (differingRegisterClasses(SrcReg, DstReg)) {
+ if (!CrossClassJoin)
+ return false;
+ CrossRC = true;
+
+ // FIXME: What if the result of a EXTRACT_SUBREG is then coalesced
// with another? If it's the resulting destination register, then
// the subidx must be propagated to uses (but only those defined
// by the EXTRACT_SUBREG). If it's being coalesced into another
// register, it should be safe because register is assumed to have
// the register class of the super-register.
- if (!SubRC || !isProfitableToCoalesceToSubRC(SrcReg, DstReg, CopyMBB)) {
- // If they are not of the same register class, we cannot join them.
+ // Process moves where one of the registers have a sub-register index.
+ MachineOperand *DstMO = CopyMI->findRegisterDefOperand(DstReg);
+ if (DstMO->getSubReg())
+ // FIXME: Can we handle this?
+ return false;
+ MachineOperand *SrcMO = CopyMI->findRegisterUseOperand(SrcReg);
+ SubIdx = SrcMO->getSubReg();
+ if (SubIdx) {
+ // This is not a extract_subreg but it looks like one.
+ // e.g. %cl = MOV16rr %reg1024:2
+ isExtSubReg = true;
+ if (DstIsPhys) {
+ if (!CanJoinExtractSubRegToPhysReg(DstReg, SrcReg, SubIdx,RealDstReg))
+ return false; // Not coalescable
+ SubIdx = 0;
+ }
+ }
+
+ const TargetRegisterClass *SrcRC= SrcIsPhys ? 0 : mri_->getRegClass(SrcReg);
+ const TargetRegisterClass *DstRC= DstIsPhys ? 0 : mri_->getRegClass(DstReg);
+ unsigned LargeReg = SrcReg;
+ unsigned SmallReg = DstReg;
+ unsigned Limit = 0;
+
+ // Now determine the register class of the joined register.
+ if (isExtSubReg) {
+ if (SubIdx && DstRC && DstRC->isASubClass()) {
+ // This is a move to a sub-register class. However, the source is a
+ // sub-register of a larger register class. We don't know what should
+ // the register class be. FIXME.
+ Again = true;
+ return false;
+ }
+ Limit = allocatableRCRegs_[DstRC].count();
+ } else if (!SrcIsPhys && !SrcIsPhys) {
+ unsigned SrcSize = SrcRC->getSize();
+ unsigned DstSize = DstRC->getSize();
+ if (SrcSize < DstSize)
+ // For example X86::MOVSD2PDrr copies from FR64 to VR128.
+ NewRC = DstRC;
+ else if (DstSize > SrcSize) {
+ NewRC = SrcRC;
+ std::swap(LargeReg, SmallReg);
+ } else {
+ unsigned SrcNumRegs = SrcRC->getNumRegs();
+ unsigned DstNumRegs = DstRC->getNumRegs();
+ if (DstNumRegs < SrcNumRegs)
+ // Sub-register class?
+ NewRC = DstRC;
+ else if (SrcNumRegs < DstNumRegs) {
+ NewRC = SrcRC;
+ std::swap(LargeReg, SmallReg);
+ } else
+ // No idea what's the right register class to use.
+ return false;
+ }
+ }
+
+ // If we are joining two virtual registers and the resulting register
+ // class is more restrictive (fewer register, smaller size). Check if it's
+ // worth doing the merge.
+ if (!SrcIsPhys && !DstIsPhys &&
+ (isExtSubReg || DstRC->isASubClass()) &&
+ !isWinToJoinCrossClass(LargeReg, SmallReg,
+ allocatableRCRegs_[NewRC].count())) {
DOUT << "\tSrc/Dest are different register classes.\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
- // but later r1024 is assigned EAX then r1025 may be coalesced with EAX.
+ // But later r1024 is assigned EAX then r1025 may be coalesced with EAX.
Again = true; // May be possible to coalesce later.
return false;
}
@@ -1417,9 +1449,10 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// Coalescing to a virtual register that is of a sub-register class of the
// other. Make sure the resulting register is set to the right register class.
- if (SubRC) {
- mri_->setRegClass(DstReg, SubRC);
- ++numSubJoins;
+ if (CrossRC) {
+ ++numCrossRCs;
+ if (NewRC)
+ mri_->setRegClass(DstReg, NewRC);
}
if (NewHeuristic) {
@@ -2208,14 +2241,10 @@ void SimpleRegisterCoalescing::joinIntervals() {
}
/// Return true if the two specified registers belong to different register
-/// classes. The registers may be either phys or virt regs. In the
-/// case where both registers are virtual registers, it would also returns
-/// true by reference the RegB register class in SubRC if it is a subset of
-/// RegA's register class.
+/// classes. The registers may be either phys or virt regs.
bool
-SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA, unsigned RegB,
- const TargetRegisterClass *&SubRC) const {
-
+SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA,
+ unsigned RegB) const {
// Get the register classes for the first reg.
if (TargetRegisterInfo::isPhysicalRegister(RegA)) {
assert(TargetRegisterInfo::isVirtualRegister(RegB) &&
@@ -2227,10 +2256,7 @@ SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA, unsigned RegB,
const TargetRegisterClass *RegClassA = mri_->getRegClass(RegA);
if (TargetRegisterInfo::isVirtualRegister(RegB)) {
const TargetRegisterClass *RegClassB = mri_->getRegClass(RegB);
- if (RegClassA == RegClassB)
- return false;
- SubRC = (RegClassA->hasSubClass(RegClassB)) ? RegClassB : NULL;
- return true;
+ return RegClassA != RegClassB;
}
return !RegClassA->contains(RegB);
}
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.h b/lib/CodeGen/SimpleRegisterCoalescing.h
index a4f0fa3f2feb..cce5cebd9e6f 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.h
+++ b/lib/CodeGen/SimpleRegisterCoalescing.h
@@ -173,12 +173,8 @@ namespace llvm {
bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS);
/// Return true if the two specified registers belong to different register
- /// classes. The registers may be either phys or virt regs. In the
- /// case where both registers are virtual registers, it would also returns
- /// true by reference the RegB register class in SubRC if it is a subset of
- /// RegA's register class.
- bool differingRegisterClasses(unsigned RegA, unsigned RegB,
- const TargetRegisterClass *&SubRC) const;
+ /// classes. The registers may be either phys or virt regs.
+ bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;
/// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy. If
@@ -219,11 +215,10 @@ namespace llvm {
/// identity copies so they will be removed.
void RemoveCopiesFromValNo(LiveInterval &li, VNInfo *VNI);
- /// isProfitableToCoalesceToSubRC - Given that register class of DstReg is
- /// a subset of the register class of SrcReg, return true if it's profitable
- /// to coalesce the two registers.
- bool isProfitableToCoalesceToSubRC(unsigned SrcReg, unsigned DstReg,
- MachineBasicBlock *MBB);
+ /// isWinToJoinCrossClass - Return true if it's profitable to coalesce
+ /// two virtual registers from different register classes.
+ bool isWinToJoinCrossClass(unsigned LargeReg, unsigned SmallReg,
+ unsigned Threshold);
/// HasIncompatibleSubRegDefUse - If we are trying to coalesce a virtual
/// register with a physical register, check if any of the virtual register
@@ -235,15 +230,13 @@ namespace llvm {
/// CanJoinExtractSubRegToPhysReg - Return true if it's possible to coalesce
/// an extract_subreg where dst is a physical register, e.g.
/// cl = EXTRACT_SUBREG reg1024, 1
- bool CanJoinExtractSubRegToPhysReg(MachineInstr *CopyMI,
- unsigned DstReg, unsigned SrcReg,
+ bool CanJoinExtractSubRegToPhysReg(unsigned DstReg, unsigned SrcReg,
unsigned SubIdx, unsigned &RealDstReg);
/// CanJoinInsertSubRegToPhysReg - Return true if it's possible to coalesce
/// an insert_subreg where src is a physical register, e.g.
/// reg1024 = INSERT_SUBREG reg1024, c1, 0
- bool CanJoinInsertSubRegToPhysReg(MachineInstr *CopyMI,
- unsigned DstReg, unsigned SrcReg,
+ bool CanJoinInsertSubRegToPhysReg(unsigned DstReg, unsigned SrcReg,
unsigned SubIdx, unsigned &RealDstReg);
/// RangeIsDefinedByCopyFromReg - Return true if the specified live range of
diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp
index c28b045b2ec5..a213400dcbdf 100644
--- a/lib/CodeGen/TargetInstrInfoImpl.cpp
+++ b/lib/CodeGen/TargetInstrInfoImpl.cpp
@@ -44,7 +44,7 @@ MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI,
unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg();
bool Reg0IsDead = MI->getOperand(0).isDead();
MachineFunction &MF = *MI->getParent()->getParent();
- return BuildMI(MF, MI->getDesc())
+ return BuildMI(MF, MI->getDebugLoc(), MI->getDesc())
.addReg(Reg0, true, false, false, Reg0IsDead)
.addReg(Reg2, false, false, Reg2IsKill)
.addReg(Reg1, false, false, Reg1IsKill);
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp
index 1d97f6798228..794f772101e9 100644
--- a/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -49,6 +49,7 @@ using namespace llvm;
STATISTIC(NumTwoAddressInstrs, "Number of two-address instructions");
STATISTIC(NumCommuted , "Number of instructions commuted to coalesce");
+STATISTIC(NumAggrCommuted , "Number of instructions aggressively commuted");
STATISTIC(NumConvertedTo3Addr, "Number of instructions promoted to 3-address");
STATISTIC(Num3AddrSunk, "Number of 3-address instructions sunk");
STATISTIC(NumReMats, "Number of instructions re-materialized");
@@ -69,6 +70,20 @@ namespace {
MachineInstr *MI, MachineInstr *DefMI,
MachineBasicBlock *MBB, unsigned Loc,
DenseMap<MachineInstr*, unsigned> &DistanceMap);
+
+ bool NoUseAfterLastDef(unsigned Reg, MachineBasicBlock *MBB, unsigned Dist,
+ DenseMap<MachineInstr*, unsigned> &DistanceMap,
+ unsigned &LastDef);
+
+ bool isProfitableToCommute(unsigned regB, unsigned regC,
+ MachineInstr *MI, MachineBasicBlock *MBB,
+ unsigned Dist,
+ DenseMap<MachineInstr*, unsigned> &DistanceMap);
+
+ bool CommuteInstruction(MachineBasicBlock::iterator &mi,
+ MachineFunction::iterator &mbbi,
+ unsigned RegC, unsigned Dist,
+ DenseMap<MachineInstr*, unsigned> &DistanceMap);
public:
static char ID; // Pass identification, replacement for typeid
TwoAddressInstructionPass() : MachineFunctionPass(&ID) {}
@@ -225,8 +240,6 @@ TwoAddressInstructionPass::isProfitableToReMat(unsigned Reg,
for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
UE = MRI->use_end(); UI != UE; ++UI) {
MachineOperand &UseMO = UI.getOperand();
- if (!UseMO.isUse())
- continue;
MachineInstr *UseMI = UseMO.getParent();
MachineBasicBlock *UseMBB = UseMI->getParent();
if (UseMBB == MBB) {
@@ -250,6 +263,114 @@ TwoAddressInstructionPass::isProfitableToReMat(unsigned Reg,
return MBB == DefMI->getParent();
}
+/// NoUseAfterLastDef - Return true if there are no intervening uses between the
+/// last instruction in the MBB that defines the specified register and the
+/// two-address instruction which is being processed. It also returns the last
+/// def location by reference
+bool TwoAddressInstructionPass::NoUseAfterLastDef(unsigned Reg,
+ MachineBasicBlock *MBB, unsigned Dist,
+ DenseMap<MachineInstr*, unsigned> &DistanceMap,
+ unsigned &LastDef) {
+ LastDef = 0;
+ unsigned LastUse = Dist;
+ for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(Reg),
+ E = MRI->reg_end(); I != E; ++I) {
+ MachineOperand &MO = I.getOperand();
+ MachineInstr *MI = MO.getParent();
+ if (MI->getParent() != MBB)
+ continue;
+ DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
+ if (DI == DistanceMap.end())
+ continue;
+ if (MO.isUse() && DI->second < LastUse)
+ LastUse = DI->second;
+ if (MO.isDef() && DI->second > LastDef)
+ LastDef = DI->second;
+ }
+
+ return !(LastUse > LastDef && LastUse < Dist);
+}
+
+/// isProfitableToReMat - Return true if it's potentially profitable to commute
+/// the two-address instruction that's being processed.
+bool
+TwoAddressInstructionPass::isProfitableToCommute(unsigned regB, unsigned regC,
+ MachineInstr *MI, MachineBasicBlock *MBB,
+ unsigned Dist, DenseMap<MachineInstr*, unsigned> &DistanceMap) {
+ // Determine if it's profitable to commute this two address instruction. In
+ // general, we want no uses between this instruction and the definition of
+ // the two-address register.
+ // e.g.
+ // %reg1028<def> = EXTRACT_SUBREG %reg1027<kill>, 1
+ // %reg1029<def> = MOV8rr %reg1028
+ // %reg1029<def> = SHR8ri %reg1029, 7, %EFLAGS<imp-def,dead>
+ // insert => %reg1030<def> = MOV8rr %reg1028
+ // %reg1030<def> = ADD8rr %reg1028<kill>, %reg1029<kill>, %EFLAGS<imp-def,dead>
+ // In this case, it might not be possible to coalesce the second MOV8rr
+ // instruction if the first one is coalesced. So it would be profitable to
+ // commute it:
+ // %reg1028<def> = EXTRACT_SUBREG %reg1027<kill>, 1
+ // %reg1029<def> = MOV8rr %reg1028
+ // %reg1029<def> = SHR8ri %reg1029, 7, %EFLAGS<imp-def,dead>
+ // insert => %reg1030<def> = MOV8rr %reg1029
+ // %reg1030<def> = ADD8rr %reg1029<kill>, %reg1028<kill>, %EFLAGS<imp-def,dead>
+
+ if (!MI->killsRegister(regC))
+ return false;
+
+ // Ok, we have something like:
+ // %reg1030<def> = ADD8rr %reg1028<kill>, %reg1029<kill>, %EFLAGS<imp-def,dead>
+ // let's see if it's worth commuting it.
+
+ // If there is a use of regC between its last def (could be livein) and this
+ // instruction, then bail.
+ unsigned LastDefC = 0;
+ if (!NoUseAfterLastDef(regC, MBB, Dist, DistanceMap, LastDefC))
+ return false;
+
+ // If there is a use of regB between its last def (could be livein) and this
+ // instruction, then go ahead and make this transformation.
+ unsigned LastDefB = 0;
+ if (!NoUseAfterLastDef(regB, MBB, Dist, DistanceMap, LastDefB))
+ return true;
+
+ // Since there are no intervening uses for both registers, then commute
+ // if the def of regC is closer. Its live interval is shorter.
+ return LastDefB && LastDefC && LastDefC > LastDefB;
+}
+
+/// CommuteInstruction - Commute a two-address instruction and update the basic
+/// block, distance map, and live variables if needed. Return true if it is
+/// successful.
+bool
+TwoAddressInstructionPass::CommuteInstruction(MachineBasicBlock::iterator &mi,
+ MachineFunction::iterator &mbbi,
+ unsigned RegC, unsigned Dist,
+ DenseMap<MachineInstr*, unsigned> &DistanceMap) {
+ MachineInstr *MI = mi;
+ DOUT << "2addr: COMMUTING : " << *MI;
+ MachineInstr *NewMI = TII->commuteInstruction(MI);
+
+ if (NewMI == 0) {
+ DOUT << "2addr: COMMUTING FAILED!\n";
+ return false;
+ }
+
+ DOUT << "2addr: COMMUTED TO: " << *NewMI;
+ // If the instruction changed to commute it, update livevar.
+ if (NewMI != MI) {
+ if (LV)
+ // Update live variables
+ LV->replaceKillInstruction(RegC, MI, NewMI);
+
+ mbbi->insert(mi, NewMI); // Insert the new inst
+ mbbi->erase(mi); // Nuke the old inst.
+ mi = NewMI;
+ DistanceMap.insert(std::make_pair(NewMI, Dist));
+ }
+ return true;
+}
+
/// runOnMachineFunction - Reduce two-address instructions to two operands.
///
bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
@@ -258,7 +379,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
MRI = &MF.getRegInfo();
TII = TM.getInstrInfo();
TRI = TM.getRegisterInfo();
- LV = getAnalysisToUpdate<LiveVariables>();
+ LV = getAnalysisIfAvailable<LiveVariables>();
bool MadeChange = false;
@@ -337,27 +458,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
assert(mi->getOperand(3-si).isReg() &&
"Not a proper commutative instruction!");
unsigned regC = mi->getOperand(3-si).getReg();
-
if (mi->killsRegister(regC)) {
- DOUT << "2addr: COMMUTING : " << *mi;
- MachineInstr *NewMI = TII->commuteInstruction(mi);
-
- if (NewMI == 0) {
- DOUT << "2addr: COMMUTING FAILED!\n";
- } else {
- DOUT << "2addr: COMMUTED TO: " << *NewMI;
- // If the instruction changed to commute it, update livevar.
- if (NewMI != mi) {
- if (LV)
- // Update live variables
- LV->replaceKillInstruction(regC, mi, NewMI);
-
- mbbi->insert(mi, NewMI); // Insert the new inst
- mbbi->erase(mi); // Nuke the old inst.
- mi = NewMI;
- DistanceMap.insert(std::make_pair(NewMI, Dist));
- }
-
+ if (CommuteInstruction(mi, mbbi, regC, Dist, DistanceMap)) {
++NumCommuted;
regB = regC;
goto InstructionRearranged;
@@ -401,6 +503,17 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
}
}
+ // If it's profitable to commute the instruction, do so.
+ if (TID.isCommutable() && mi->getNumOperands() >= 3) {
+ unsigned regC = mi->getOperand(3-si).getReg();
+ if (isProfitableToCommute(regB, regC, mi, mbbi, Dist, DistanceMap))
+ if (CommuteInstruction(mi, mbbi, regC, Dist, DistanceMap)) {
+ ++NumAggrCommuted;
+ ++NumCommuted;
+ regB = regC;
+ }
+ }
+
InstructionRearranged:
const TargetRegisterClass* rc = MRI->getRegClass(regA);
MachineInstr *DefMI = MRI->getVRegDef(regB);
@@ -418,7 +531,10 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc);
}
- MachineBasicBlock::iterator prevMi = prior(mi);
+ MachineBasicBlock::iterator prevMI = prior(mi);
+ // Update DistanceMap.
+ DistanceMap.insert(std::make_pair(prevMI, Dist));
+ DistanceMap[mi] = ++Dist;
// Update live variables for regB.
if (LV) {
@@ -428,13 +544,13 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
varInfoB.UsedBlocks[mbbi->getNumber()] = true;
if (LV->removeVirtualRegisterKilled(regB, mi))
- LV->addVirtualRegisterKilled(regB, prevMi);
+ LV->addVirtualRegisterKilled(regB, prevMI);
if (LV->removeVirtualRegisterDead(regB, mi))
- LV->addVirtualRegisterDead(regB, prevMi);
+ LV->addVirtualRegisterDead(regB, prevMI);
}
- DOUT << "\t\tprepend:\t"; DEBUG(prevMi->print(*cerr.stream(), &TM));
+ DOUT << "\t\tprepend:\t"; DEBUG(prevMI->print(*cerr.stream(), &TM));
// Replace all occurences of regB with regA.
for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
diff --git a/lib/CodeGen/UnreachableBlockElim.cpp b/lib/CodeGen/UnreachableBlockElim.cpp
index c597e5fd7db0..c3b213cebe95 100644
--- a/lib/CodeGen/UnreachableBlockElim.cpp
+++ b/lib/CodeGen/UnreachableBlockElim.cpp
@@ -105,7 +105,7 @@ const PassInfo *const llvm::UnreachableMachineBlockElimID = &Y;
bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
SmallPtrSet<MachineBasicBlock*, 8> Reachable;
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
// Mark all reachable blocks.
for (df_ext_iterator<MachineFunction*, SmallPtrSet<MachineBasicBlock*, 8> >
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index b35fc2c653a2..9cb580b9f0ab 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -1360,7 +1360,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
MI.getOperand(i).setReg(RReg);
if (VRM.isImplicitlyDefined(VirtReg))
- BuildMI(MBB, &MI, TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
+ BuildMI(MBB, &MI, MI.getDebugLoc(),
+ TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
continue;
}
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index a1fbdd281241..9fea1f5753f8 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -59,7 +59,8 @@ char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) {
}
/// removeModuleProvider - Remove a ModuleProvider from the list of modules.
-/// Release module from ModuleProvider.
+/// Relases the Module from the ModuleProvider, materializing it in the
+/// process, and returns the materialized Module.
Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P,
std::string *ErrInfo) {
for(SmallVector<ModuleProvider *, 1>::iterator I = Modules.begin(),
@@ -74,6 +75,23 @@ Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P,
return NULL;
}
+/// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
+/// and deletes the ModuleProvider and owned Module. Avoids materializing
+/// the underlying module.
+void ExecutionEngine::deleteModuleProvider(ModuleProvider *P,
+ std::string *ErrInfo) {
+ for(SmallVector<ModuleProvider *, 1>::iterator I = Modules.begin(),
+ E = Modules.end(); I != E; ++I) {
+ ModuleProvider *MP = *I;
+ if (MP == P) {
+ Modules.erase(I);
+ clearGlobalMappingsFromModule(MP->getModule());
+ delete MP;
+ return;
+ }
+ }
+}
+
/// FindFunctionNamed - Search all of the active modules to find the one that
/// defines FnName. This is very slow operation and shouldn't be used for
/// general code.
@@ -692,7 +710,7 @@ static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,
assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!");
uint8_t *Src = (uint8_t *)IntVal.getRawData();
- if (sys::littleEndianHost())
+ if (sys::isLittleEndianHost())
// Little-endian host - the source is ordered from LSB to MSB. Order the
// destination from LSB to MSB: Do a straight copy.
memcpy(Dst, Src, StoreBytes);
@@ -751,7 +769,7 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val,
cerr << "Cannot store value of type " << *Ty << "!\n";
}
- if (sys::littleEndianHost() != getTargetData()->isLittleEndian())
+ if (sys::isLittleEndianHost() != getTargetData()->isLittleEndian())
// Host and target are different endian - reverse the stored bytes.
std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr);
}
@@ -762,7 +780,7 @@ static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) {
assert((IntVal.getBitWidth()+7)/8 >= LoadBytes && "Integer too small!");
uint8_t *Dst = (uint8_t *)IntVal.getRawData();
- if (sys::littleEndianHost())
+ if (sys::isLittleEndianHost())
// Little-endian host - the destination must be ordered from LSB to MSB.
// The source is ordered from LSB to MSB: Do a straight copy.
memcpy(Dst, Src, LoadBytes);
@@ -789,7 +807,7 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result,
const Type *Ty) {
const unsigned LoadBytes = getTargetData()->getTypeStoreSize(Ty);
- if (sys::littleEndianHost() != getTargetData()->isLittleEndian()) {
+ if (sys::isLittleEndianHost() != getTargetData()->isLittleEndian()) {
// Host and target are different endian - reverse copy the stored
// bytes into a buffer, and load from that.
uint8_t *Src = (uint8_t*)Ptr;
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index fd69e69c44d5..9595099c3c07 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -65,7 +65,7 @@ namespace llvm {
}
-#if defined (__GNUC__)
+#if defined(__GNUC__) && !defined(__ARM__EABI__)
// libgcc defines the __register_frame function to dynamically register new
// dwarf frames for exception handling. This functionality is not portable
@@ -86,7 +86,7 @@ namespace llvm {
extern "C" void __register_frame(void*);
-#if defined (__APPLE__)
+#if defined(__APPLE__)
namespace {
@@ -225,7 +225,7 @@ JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,
}
// Register routine for informing unwinding runtime about new EH frames
-#if defined(__GNUC__)
+#if defined(__GNUC__) && !defined(__ARM_EABI__)
#if defined(__APPLE__)
struct LibgccObjectInfo* LOI = (struct LibgccObjectInfo*)
_keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST);
@@ -297,6 +297,19 @@ Module *JIT::removeModuleProvider(ModuleProvider *MP, std::string *E) {
return result;
}
+/// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
+/// and deletes the ModuleProvider and owned Module. Avoids materializing
+/// the underlying module.
+void JIT::deleteModuleProvider(ModuleProvider *MP, std::string *E) {
+ ExecutionEngine::deleteModuleProvider(MP, E);
+
+ MutexGuard locked(lock);
+ if (Modules.empty()) {
+ delete jitstate;
+ jitstate = 0;
+ }
+}
+
/// run - Start execution with the specified function and arguments.
///
GenericValue JIT::runFunction(Function *F,
diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h
index b92999960331..7c085e360e20 100644
--- a/lib/ExecutionEngine/JIT/JIT.h
+++ b/lib/ExecutionEngine/JIT/JIT.h
@@ -77,9 +77,18 @@ public:
}
virtual void addModuleProvider(ModuleProvider *MP);
+
+ /// removeModuleProvider - Remove a ModuleProvider from the list of modules.
+ /// Relases the Module from the ModuleProvider, materializing it in the
+ /// process, and returns the materialized Module.
virtual Module *removeModuleProvider(ModuleProvider *MP,
std::string *ErrInfo = 0);
+ /// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
+ /// and deletes the ModuleProvider and owned Module. Avoids materializing
+ /// the underlying module.
+ virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0);
+
/// runFunction - Start execution with the specified function and arguments.
///
virtual GenericValue runFunction(Function *F,
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 367c75be1af6..3d38a0c60666 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -683,7 +683,13 @@ unsigned APInt::countLeadingOnes() const {
return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth);
unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD;
- unsigned shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits);
+ unsigned shift;
+ if (!highWordBits) {
+ highWordBits = APINT_BITS_PER_WORD;
+ shift = 0;
+ } else {
+ shift = APINT_BITS_PER_WORD - highWordBits;
+ }
int i = getNumWords() - 1;
unsigned Count = countLeadingOnes_64(pVal[i], shift);
if (Count == highWordBits) {
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 8cd483a25e5d..2c56e0ffb87e 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -396,7 +396,12 @@ static void ExpandResponseFiles(int argc, char** argv,
// If we could open the file, parse its contents, otherwise
// pass the @file option verbatim.
- // TODO: support recursion.
+
+ // TODO: we should also support recursive loading of response files,
+ // since this is how gcc behaves. (From their man page: "The file may
+ // itself contain additional @file options; any such options will be
+ // processed recursively.")
+
if (respFilePtr != 0) {
ParseCStringVector(newArgv, respFilePtr->getBufferStart());
continue;
@@ -867,6 +872,8 @@ bool parser<bool>::parse(Option &O, const char *ArgName,
return O.error(": '" + Arg +
"' is invalid value for boolean argument! Try 0 or 1");
}
+ if (IsInvertable && strncmp(ArgName+1, "no-", 3) == 0)
+ Value = !Value;
return false;
}
@@ -877,7 +884,8 @@ bool parser<boolOrDefault>::parse(Option &O, const char *ArgName,
if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
Arg == "1") {
Value = BOU_TRUE;
- } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
+ } else if (Arg == "false" || Arg == "FALSE"
+ || Arg == "False" || Arg == "0") {
Value = BOU_FALSE;
} else {
return O.error(": '" + Arg +
diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp
index b7cf3b977abd..10a2c3c64f8d 100644
--- a/lib/Support/Dwarf.cpp
+++ b/lib/Support/Dwarf.cpp
@@ -198,6 +198,8 @@ const char *AttributeString(unsigned Attribute) {
case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
case DW_AT_lo_user: return "DW_AT_lo_user";
case DW_AT_hi_user: return "DW_AT_hi_user";
+ case DW_AT_APPLE_optimized: return "DW_AT_APPLE_optimized";
+ case DW_AT_APPLE_flags: return "DW_AT_APPLE_flags";
}
assert(0 && "Unknown Dwarf Attribute");
return "";
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 96c9a3a263d0..29665dc350c6 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -255,6 +255,12 @@ void raw_fd_ostream::close() {
FD = -1;
}
+uint64_t raw_fd_ostream::seek(uint64_t off) {
+ flush();
+ pos = lseek(FD, off, SEEK_SET);
+ return pos;
+}
+
//===----------------------------------------------------------------------===//
// raw_stdout/err_ostream
//===----------------------------------------------------------------------===//
diff --git a/lib/System/DynamicLibrary.cpp b/lib/System/DynamicLibrary.cpp
index 970266f34387..3bf172c22b3f 100644
--- a/lib/System/DynamicLibrary.cpp
+++ b/lib/System/DynamicLibrary.cpp
@@ -18,11 +18,14 @@
#include <map>
// Collection of symbol name/value pairs to be searched prior to any libraries.
-static std::map<std::string, void *> g_symbols;
+std::map<std::string, void *> &g_symbols() {
+ static std::map<std::string, void *> symbols;
+ return symbols;
+}
void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName,
void *symbolValue) {
- g_symbols[symbolName] = symbolValue;
+ g_symbols()[symbolName] = symbolValue;
}
// It is not possible to use ltdl.c on VC++ builds as the terms of its LGPL
@@ -76,8 +79,8 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
// check_ltdl_initialization();
// First check symbols added via AddSymbol().
- std::map<std::string, void *>::iterator I = g_symbols.find(symbolName);
- if (I != g_symbols.end())
+ std::map<std::string, void *>::iterator I = g_symbols().find(symbolName);
+ if (I != g_symbols().end())
return I->second;
// Now search the libraries.
diff --git a/lib/System/Unix/Host.inc b/lib/System/Unix/Host.inc
index 7bee66fd0d63..205ce2362c79 100644
--- a/lib/System/Unix/Host.inc
+++ b/lib/System/Unix/Host.inc
@@ -23,7 +23,7 @@
using namespace llvm;
-std::string llvm::sys::osName() {
+std::string llvm::sys::getOSName() {
struct utsname info;
if (uname(&info))
@@ -32,7 +32,7 @@ std::string llvm::sys::osName() {
return info.sysname;
}
-std::string llvm::sys::osVersion() {
+std::string llvm::sys::getOSVersion() {
struct utsname info;
if (uname(&info))
diff --git a/lib/System/Win32/DynamicLibrary.inc b/lib/System/Win32/DynamicLibrary.inc
index c76032f62d06..210eb2128d59 100644
--- a/lib/System/Win32/DynamicLibrary.inc
+++ b/lib/System/Win32/DynamicLibrary.inc
@@ -156,8 +156,8 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
// First check symbols added via AddSymbol().
- std::map<std::string, void *>::iterator I = g_symbols.find(symbolName);
- if (I != g_symbols.end())
+ std::map<std::string, void *>::iterator I = g_symbols().find(symbolName);
+ if (I != g_symbols().end())
return I->second;
// Now search the libraries.
diff --git a/lib/System/Win32/Host.inc b/lib/System/Win32/Host.inc
index 7bbf2bd346ed..4fabc78adebf 100644
--- a/lib/System/Win32/Host.inc
+++ b/lib/System/Win32/Host.inc
@@ -17,11 +17,11 @@
using namespace llvm;
-std::string sys::osName() {
+std::string sys::getOSName() {
return "Windows";
}
-std::string sys::osVersion() {
+std::string sys::getOSVersion() {
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(osvi));
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index e544c67d45cb..5ecb28e9ec1f 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -701,6 +701,7 @@ bool ARMConstantIslands::CPEIsInRange(MachineInstr *MI, unsigned UserOffset,
return OffsetIsInRange(UserOffset, CPEOffset, MaxDisp, !isThumb);
}
+#ifndef NDEBUG
/// BBIsJumpedOver - Return true of the specified basic block's only predecessor
/// unconditionally branches to its only successor.
static bool BBIsJumpedOver(MachineBasicBlock *MBB) {
@@ -714,6 +715,7 @@ static bool BBIsJumpedOver(MachineBasicBlock *MBB) {
return PredMI->getOperand(0).getMBB() == Succ;
return false;
}
+#endif // NDEBUG
void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB,
int delta) {
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index eda6ff4266db..9067c2d47847 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -399,9 +399,9 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
MVT RetVT = TheCall->getRetValType(0);
SDValue Chain = TheCall->getChain();
- unsigned CallConv = TheCall->getCallingConv();
- assert((CallConv == CallingConv::C ||
- CallConv == CallingConv::Fast) && "unknown calling convention");
+ assert((TheCall->getCallingConv() == CallingConv::C ||
+ TheCall->getCallingConv() == CallingConv::Fast) &&
+ "unknown calling convention");
SDValue Callee = TheCall->getCallee();
unsigned NumOps = TheCall->getNumArgs();
unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
@@ -740,10 +740,12 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
Entry.Node = Argument;
Entry.Ty = (const Type *) Type::Int32Ty;
Args.push_back(Entry);
+ // FIXME: is there useful debug info available here?
std::pair<SDValue, SDValue> CallResult =
LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false,
CallingConv::C, false,
- DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG);
+ DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG,
+ DebugLoc::getUnknownLoc());
return CallResult.first;
}
diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp
index 3d1e51231923..c160714b5475 100644
--- a/lib/Target/ARM/ARMInstrInfo.cpp
+++ b/lib/Target/ARM/ARMInstrInfo.cpp
@@ -649,7 +649,7 @@ bool ARMInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
return false;
bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
- MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP));
+ MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc());
MBB.insert(MI, PopMI);
for (unsigned i = CSI.size(); i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 12e13466d1b3..83df20cc170b 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -782,9 +782,9 @@ bool ARMAsmPrinter::doInitialization(Module &M) {
bool Result = AsmPrinter::doInitialization(M);
// Emit initial debug information.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
assert(MMI);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "Dwarf Writer is not available");
DW->BeginModule(&M, MMI, O, this, TAI);
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 1c090ff3e2d3..753906ed94fa 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -356,7 +356,8 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg,
bool isInreg, unsigned CallingConv,
bool isTailCall, SDValue Callee,
- ArgListTy &Args, SelectionDAG &DAG) {
+ ArgListTy &Args, SelectionDAG &DAG,
+ DebugLoc dl) {
int NumBytes = 0;
if (Args.size() > 6)
NumBytes = (Args.size() - 6) * 8;
@@ -374,11 +375,13 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
// Promote the integer to 64 bits. If the input type is signed use a
// sign extend, otherwise use a zero extend.
if (Args[i].isSExt)
- Args[i].Node = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].Node);
+ Args[i].Node = DAG.getNode(ISD::SIGN_EXTEND, dl,
+ MVT::i64, Args[i].Node);
else if (Args[i].isZExt)
- Args[i].Node = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].Node);
+ Args[i].Node = DAG.getNode(ISD::ZERO_EXTEND, dl,
+ MVT::i64, Args[i].Node);
else
- Args[i].Node = DAG.getNode(ISD::ANY_EXTEND, MVT::i64, Args[i].Node);
+ Args[i].Node = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i64, Args[i].Node);
break;
case MVT::i64:
case MVT::f64:
@@ -402,7 +405,8 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
Ops.push_back(Chain);
Ops.push_back(Callee);
Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end());
- SDValue TheCall = DAG.getNode(AlphaISD::CALL, RetVals, &Ops[0], Ops.size());
+ SDValue TheCall = DAG.getNode(AlphaISD::CALL, dl,
+ RetVals, &Ops[0], Ops.size());
Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
DAG.getIntPtrConstant(0, true), SDValue());
@@ -416,10 +420,10 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
AssertKind = ISD::AssertZext;
if (AssertKind != ISD::DELETED_NODE)
- RetVal = DAG.getNode(AssertKind, MVT::i64, RetVal,
+ RetVal = DAG.getNode(AssertKind, dl, MVT::i64, RetVal,
DAG.getValueType(RetTyVT));
- RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal);
+ RetVal = DAG.getNode(ISD::TRUNCATE, dl, RetTyVT, RetVal);
}
return std::make_pair(RetVal, Chain);
diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h
index cebd3ac998ae..f165a7fa71f4 100644
--- a/lib/Target/Alpha/AlphaISelLowering.h
+++ b/lib/Target/Alpha/AlphaISelLowering.h
@@ -87,7 +87,8 @@ namespace llvm {
virtual std::pair<SDValue, SDValue>
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
bool isVarArg, bool isInreg, unsigned CC, bool isTailCall,
- SDValue Callee, ArgListTy &Args, SelectionDAG &DAG);
+ SDValue Callee, ArgListTy &Args, SelectionDAG &DAG,
+ DebugLoc dl);
ConstraintType getConstraintType(const std::string &Constraint) const;
diff --git a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
index bc8f6812a2b1..e9b3fc2d26b2 100644
--- a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
@@ -90,13 +90,13 @@ namespace {
printOp(MO);
}
}
-
+
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
-
-
+
+
void
printS7ImmOperand(const MachineInstr *MI, unsigned OpNo)
{
@@ -115,7 +115,7 @@ namespace {
assert(value < (1 << 8) && "Invalid u7 argument");
O << value;
}
-
+
void
printShufAddr(const MachineInstr *MI, unsigned OpNo)
{
@@ -143,7 +143,7 @@ namespace {
{
O << (unsigned)MI->getOperand(OpNo).getImm();
}
-
+
void
printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
// When used as the base register, r0 reads constant zero rather than
@@ -286,7 +286,7 @@ namespace {
/// LinuxAsmPrinter - SPU assembly printer, customized for Linux
struct VISIBILITY_HIDDEN LinuxAsmPrinter : public SPUAsmPrinter {
-
+
DwarfWriter *DW;
MachineModuleInfo *MMI;
@@ -300,12 +300,12 @@ namespace {
virtual const char *getPassName() const {
return "STI CBEA SPU Assembly Printer";
}
-
+
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
//! Dump globals, perform cleanup after function emission
bool doFinalization(Module &M);
-
+
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineModuleInfo>();
@@ -365,7 +365,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
}
}
O << Name;
-
+
if (GV->hasExternalWeakLinkage())
ExtWeakSymbols.insert(GV);
return;
@@ -380,15 +380,15 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant,
+ unsigned AsmVariant,
const char *ExtraCode) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
-
+
switch (ExtraCode[0]) {
default: return true; // Unknown modifier.
- case 'L': // Write second word of DImode reference.
+ case 'L': // Write second word of DImode reference.
// Verify that this operand has two consecutive registers.
if (!MI->getOperand(OpNo).isReg() ||
OpNo+1 == MI->getNumOperands() ||
@@ -398,14 +398,14 @@ bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
break;
}
}
-
+
printOperand(MI, OpNo);
return false;
}
bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo,
- unsigned AsmVariant,
+ unsigned AsmVariant,
const char *ExtraCode) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
@@ -429,7 +429,7 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
{
SetupMachineFunction(MF);
O << "\n\n";
-
+
// Print out constants referenced by the function
EmitConstantPool(MF.getConstantPool());
@@ -478,10 +478,10 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
// Print out jump tables referenced by the function.
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
+
// Emit post-function debug information.
DW->EndFunction(&MF);
-
+
// We didn't modify anything.
return false;
}
@@ -491,9 +491,9 @@ bool LinuxAsmPrinter::doInitialization(Module &M) {
bool Result = AsmPrinter::doInitialization(M);
SwitchToTextSection("\t.text");
// Emit initial debug information.
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "Dwarf Writer is not available");
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
DW->BeginModule(&M, MMI, O, this, TAI);
return Result;
}
@@ -509,7 +509,7 @@ static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
/*!
Emit a global variable according to its section, alignment, etc.
-
+
\note This code was shamelessly copied from the PowerPC's assembly printer,
which sort of screams for some kind of refactorization of common code.
*/
@@ -602,8 +602,6 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
I != E; ++I)
printModuleLevelGV(I);
- // TODO
-
// Emit initial debug information.
DW->EndModule();
diff --git a/lib/Target/CellSPU/SPU64InstrInfo.td b/lib/Target/CellSPU/SPU64InstrInfo.td
index 33298946c521..06eb1496def7 100644
--- a/lib/Target/CellSPU/SPU64InstrInfo.td
+++ b/lib/Target/CellSPU/SPU64InstrInfo.td
@@ -30,8 +30,8 @@
// selb instruction definition for i64. Note that the selection mask is
// a vector, produced by various forms of FSM:
def SELBr64_cond:
- SELBInst<(outs R64C:$rT), (ins R64C:$rA, R64C:$rB, VECREG:$rC),
- [/* no pattern */]>;
+ SELBInst<(outs R64C:$rT), (ins R64C:$rA, R64C:$rB, VECREG:$rC),
+ [/* no pattern */]>;
// The generic i64 select pattern, which assumes that the comparison result
// is in a 32-bit register that contains a select mask pattern (i.e., gather
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
index 0fc7aec9906e..ea767586b060 100644
--- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
+++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
@@ -51,16 +51,6 @@ namespace {
return isS10Constant(CN->getSExtValue());
}
-#if 0
- //! SDNode predicate for sign-extended, 10-bit immediate values
- bool
- isI32IntS10Immediate(SDNode *N)
- {
- return (N->getOpcode() == ISD::Constant
- && isI32IntS10Immediate(cast<ConstantSDNode>(N)));
- }
-#endif
-
//! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
bool
isI32IntU10Immediate(ConstantSDNode *CN)
@@ -79,8 +69,8 @@ namespace {
bool
isI16IntS10Immediate(SDNode *N)
{
- return (N->getOpcode() == ISD::Constant
- && isI16IntS10Immediate(cast<ConstantSDNode>(N)));
+ ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
+ return (CN != 0 && isI16IntS10Immediate(CN));
}
//! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
@@ -230,7 +220,7 @@ public:
SelectionDAGISel(tm),
TM(tm),
SPUtli(*tm.getTargetLowering())
- {}
+ { }
virtual bool runOnFunction(Function &Fn) {
// Make sure we re-emit a set of the global base reg if necessary
@@ -254,26 +244,45 @@ public:
/// getSmallIPtrImm - Return a target constant of pointer type.
inline SDValue getSmallIPtrImm(unsigned Imm) {
return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
- }
+ }
SDNode *emitBuildVector(SDValue build_vec) {
+ MVT vecVT = build_vec.getValueType();
+ SDNode *bvNode = build_vec.getNode();
+
+ // Check to see if this vector can be represented as a CellSPU immediate
+ // constant by invoking all of the instruction selection predicates:
+ if (((vecVT == MVT::v8i16) &&
+ (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
+ ((vecVT == MVT::v4i32) &&
+ ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
+ (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
+ (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
+ (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
+ ((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(build_vec);
+
+ // No, need to emit a constant pool spill:
std::vector<Constant*> CV;
for (size_t i = 0; i < build_vec.getNumOperands(); ++i) {
- ConstantSDNode *V = dyn_cast<ConstantSDNode>(build_vec.getOperand(i));
- CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
+ ConstantSDNode *V = dyn_cast<ConstantSDNode > (build_vec.getOperand(i));
+ CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue()));
}
Constant *CP = ConstantVector::get(CV);
SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy());
- unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
+ unsigned Alignment = 1 << cast<ConstantPoolSDNode > (CPIdx)->getAlignment();
SDValue CGPoolOffset =
SPU::LowerConstantPool(CPIdx, *CurDAG,
SPUtli.getSPUTargetMachine());
return SelectCode(CurDAG->getLoad(build_vec.getValueType(),
- CurDAG->getEntryNode(), CGPoolOffset,
- PseudoSourceValue::getConstantPool(), 0,
- false, Alignment));
+ CurDAG->getEntryNode(), CGPoolOffset,
+ PseudoSourceValue::getConstantPool(), 0,
+ false, Alignment));
}
/// Select - Convert the specified operand from a target-independent to a
@@ -289,6 +298,9 @@ public:
//! Emit the instruction sequence for i64 sra
SDNode *SelectSRAi64(SDValue &Op, MVT OpVT);
+ //! Emit the necessary sequence for loading i64 constants:
+ SDNode *SelectI64Constant(SDValue &Op, MVT OpVT);
+
//! Returns true if the address N is an A-form (local store) address
bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
SDValue &Index);
@@ -378,7 +390,7 @@ SPUDAGToDAGISel::InstructionSelect()
}
/*!
- \arg Op The ISD instructio operand
+ \arg Op The ISD instruction operand
\arg N The address to be tested
\arg Base The base address
\arg Index The base address index
@@ -600,9 +612,9 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
} else {
/* If otherwise unadorned, default to D-form address with 0 offset: */
if (Opc == ISD::CopyFromReg) {
- Index = N.getOperand(1);
+ Index = N.getOperand(1);
} else {
- Index = N;
+ Index = N;
}
Base = CurDAG->getTargetConstant(0, Index.getValueType());
@@ -652,7 +664,9 @@ SPUDAGToDAGISel::Select(SDValue Op) {
if (N->isMachineOpcode()) {
return NULL; // Already selected.
- } else if (Opc == ISD::FrameIndex) {
+ }
+
+ if (Opc == ISD::FrameIndex) {
int FI = cast<FrameIndexSDNode>(N)->getIndex();
SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType());
SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType());
@@ -669,6 +683,11 @@ SPUDAGToDAGISel::Select(SDValue Op) {
TFI, Imm0), 0);
n_ops = 2;
}
+ } else if (Opc == ISD::Constant && OpVT == MVT::i64) {
+ // Catch the i64 constants that end up here. Note: The backend doesn't
+ // attempt to legalize the constant (it's useless because DAGCombiner
+ // will insert 64-bit constants and we can't stop it).
+ return SelectI64Constant(Op, OpVT);
} else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
&& OpVT == MVT::i64) {
SDValue Op0 = Op.getOperand(0);
@@ -745,27 +764,39 @@ SPUDAGToDAGISel::Select(SDValue Op) {
return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, OpVT,
Op.getOperand(0), Op.getOperand(1),
SDValue(CGLoad, 0)));
- } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
- SDNode *CGLoad =
- emitBuildVector(SPU::getCarryGenerateShufMask(*CurDAG));
-
- return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, OpVT,
- Op.getOperand(0), Op.getOperand(1),
- SDValue(CGLoad, 0)));
- } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
- SDNode *CGLoad =
- emitBuildVector(SPU::getBorrowGenerateShufMask(*CurDAG));
-
- return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, OpVT,
- Op.getOperand(0), Op.getOperand(1),
- SDValue(CGLoad, 0)));
- } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
- SDNode *CGLoad =
- emitBuildVector(SPU::getCarryGenerateShufMask(*CurDAG));
-
- return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, OpVT,
- Op.getOperand(0), Op.getOperand(1),
- SDValue(CGLoad, 0)));
+ } else if (Opc == ISD::TRUNCATE) {
+ SDValue Op0 = Op.getOperand(0);
+ if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
+ && OpVT == MVT::i32
+ && Op0.getValueType() == MVT::i64) {
+ // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
+ //
+ // Take advantage of the fact that the upper 32 bits are in the
+ // i32 preferred slot and avoid shuffle gymnastics:
+ ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
+ if (CN != 0) {
+ unsigned shift_amt = unsigned(CN->getZExtValue());
+
+ if (shift_amt >= 32) {
+ SDNode *hi32 =
+ CurDAG->getTargetNode(SPU::ORr32_r64, OpVT, Op0.getOperand(0));
+
+ shift_amt -= 32;
+ if (shift_amt > 0) {
+ // Take care of the additional shift, if present:
+ SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
+ unsigned Opc = SPU::ROTMAIr32_i32;
+
+ if (Op0.getOpcode() == ISD::SRL)
+ Opc = SPU::ROTMr32;
+
+ hi32 = CurDAG->getTargetNode(Opc, OpVT, SDValue(hi32, 0), shift);
+ }
+
+ return hi32;
+ }
+ }
+ }
} else if (Opc == ISD::SHL) {
if (OpVT == MVT::i64) {
return SelectSHLi64(Op, OpVT);
@@ -1046,6 +1077,70 @@ SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, MVT OpVT) {
return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0));
}
+/*!
+ Do the necessary magic necessary to load a i64 constant
+ */
+SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT) {
+ ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
+ MVT OpVecVT = MVT::getVectorVT(OpVT, 2);
+ SDValue i64vec =
+ SPU::LowerSplat_v2i64(OpVecVT, *CurDAG, CN->getZExtValue());
+
+ // Here's where it gets interesting, because we have to parse out the
+ // subtree handed back in i64vec:
+
+ if (i64vec.getOpcode() == ISD::BIT_CONVERT) {
+ // The degenerate case where the upper and lower bits in the splat are
+ // identical:
+ SDValue Op0 = i64vec.getOperand(0);
+
+ ReplaceUses(i64vec, Op0);
+ return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT,
+ SDValue(emitBuildVector(Op0), 0));
+ } else if (i64vec.getOpcode() == SPUISD::SHUFB) {
+ SDValue lhs = i64vec.getOperand(0);
+ SDValue rhs = i64vec.getOperand(1);
+ SDValue shufmask = i64vec.getOperand(2);
+
+ if (lhs.getOpcode() == ISD::BIT_CONVERT) {
+ ReplaceUses(lhs, lhs.getOperand(0));
+ lhs = lhs.getOperand(0);
+ }
+
+ SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
+ ? lhs.getNode()
+ : emitBuildVector(lhs));
+
+ if (rhs.getOpcode() == ISD::BIT_CONVERT) {
+ ReplaceUses(rhs, rhs.getOperand(0));
+ rhs = rhs.getOperand(0);
+ }
+
+ SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
+ ? rhs.getNode()
+ : emitBuildVector(rhs));
+
+ if (shufmask.getOpcode() == ISD::BIT_CONVERT) {
+ ReplaceUses(shufmask, shufmask.getOperand(0));
+ shufmask = shufmask.getOperand(0);
+ }
+
+ SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
+ ? shufmask.getNode()
+ : emitBuildVector(shufmask));
+
+ SDNode *shufNode =
+ Select(CurDAG->getNode(SPUISD::SHUFB, OpVecVT,
+ SDValue(lhsNode, 0), SDValue(rhsNode, 0),
+ SDValue(shufMaskNode, 0)));
+
+ return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(shufNode, 0));
+ } else {
+ cerr << "SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec condition\n";
+ abort();
+ }
+}
+
/// createSPUISelDag - This pass converts a legalized DAG into a
/// SPU-specific DAG, ready for instruction scheduling.
///
diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp
index 124f1a7536b6..0718330d422d 100644
--- a/lib/Target/CellSPU/SPUISelLowering.cpp
+++ b/lib/Target/CellSPU/SPUISelLowering.cpp
@@ -17,6 +17,7 @@
#include "SPUFrameInfo.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/VectorExtras.h"
+#include "llvm/CallingConv.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -79,6 +80,44 @@ namespace {
return retval;
}
+ //! Expand a library call into an actual call DAG node
+ /*!
+ \note
+ This code is taken from SelectionDAGLegalize, since it is not exposed as
+ part of the LLVM SelectionDAG API.
+ */
+
+ SDValue
+ ExpandLibCall(RTLIB::Libcall LC, SDValue Op, SelectionDAG &DAG,
+ bool isSigned, SDValue &Hi, SPUTargetLowering &TLI) {
+ // The input chain to this libcall is the entry node of the function.
+ // Legalizing the call will automatically add the previous call to the
+ // dependence.
+ SDValue InChain = DAG.getEntryNode();
+
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
+ MVT ArgVT = Op.getOperand(i).getValueType();
+ const Type *ArgTy = ArgVT.getTypeForMVT();
+ Entry.Node = Op.getOperand(i);
+ Entry.Ty = ArgTy;
+ Entry.isSExt = isSigned;
+ Entry.isZExt = !isSigned;
+ Args.push_back(Entry);
+ }
+ SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
+ TLI.getPointerTy());
+
+ // Splice the libcall in wherever FindInputOutputChains tells us to.
+ const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT();
+ std::pair<SDValue, SDValue> CallInfo =
+ TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
+ CallingConv::C, false, Callee, Args, DAG,
+ Op.getNode()->getDebugLoc());
+
+ return CallInfo.first;
+ }
}
SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
@@ -113,7 +152,6 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
// SPU constant load actions are custom lowered:
- setOperationAction(ISD::Constant, MVT::i64, Custom);
setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
@@ -128,10 +166,6 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
- // SMUL_LOHI, UMUL_LOHI are not legal for Cell:
- setOperationAction(ISD::SMUL_LOHI, VT, Expand);
- setOperationAction(ISD::UMUL_LOHI, VT, Expand);
-
for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
MVT StoreVT = (MVT::SimpleValueType) stype;
setTruncStoreAction(VT, StoreVT, Expand);
@@ -179,16 +213,14 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
setOperationAction(ISD::FCOS , MVT::f32, Expand);
setOperationAction(ISD::FREM , MVT::f32, Expand);
- // If we're enabling GP optimizations, use hardware square root
+ // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
+ // for f32!)
setOperationAction(ISD::FSQRT, MVT::f64, Expand);
setOperationAction(ISD::FSQRT, MVT::f32, Expand);
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
- // Make sure that DAGCombine doesn't insert illegal 64-bit constants
- setOperationAction(ISD::FABS, MVT::f64, Custom);
-
// SPU can do rotate right and left, so legalize it... but customize for i8
// because instructions don't exist.
@@ -254,22 +286,21 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
// Custom lower i128 -> i64 truncates
setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
- // SPU has a legal FP -> signed INT instruction
- setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
- setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
- setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
- setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
+ // SPU has a legal FP -> signed INT instruction for f32, but for f64, need
+ // to expand to a libcall, hence the custom lowering:
+ setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
// FDIV on SPU requires custom lowering
- setOperationAction(ISD::FDIV, MVT::f64, Expand); // libcall
+ setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
- // SPU has [U|S]INT_TO_FP
- setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
+ // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
+ setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
- setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
- setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
+ setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
- setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
@@ -338,24 +369,23 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
MVT VT = (MVT::SimpleValueType)i;
// add/sub are legal for all supported vector VT's.
- setOperationAction(ISD::ADD , VT, Legal);
- setOperationAction(ISD::SUB , VT, Legal);
+ setOperationAction(ISD::ADD, VT, Legal);
+ setOperationAction(ISD::SUB, VT, Legal);
// mul has to be custom lowered.
- // TODO: v2i64 vector multiply
- setOperationAction(ISD::MUL , VT, Legal);
+ setOperationAction(ISD::MUL, VT, Legal);
- setOperationAction(ISD::AND , VT, Legal);
- setOperationAction(ISD::OR , VT, Legal);
- setOperationAction(ISD::XOR , VT, Legal);
- setOperationAction(ISD::LOAD , VT, Legal);
- setOperationAction(ISD::SELECT, VT, Legal);
- setOperationAction(ISD::STORE, VT, Legal);
+ setOperationAction(ISD::AND, VT, Legal);
+ setOperationAction(ISD::OR, VT, Legal);
+ setOperationAction(ISD::XOR, VT, Legal);
+ setOperationAction(ISD::LOAD, VT, Legal);
+ setOperationAction(ISD::SELECT, VT, Legal);
+ setOperationAction(ISD::STORE, VT, Legal);
// These operations need to be expanded:
- setOperationAction(ISD::SDIV, VT, Expand);
- setOperationAction(ISD::SREM, VT, Expand);
- setOperationAction(ISD::UDIV, VT, Expand);
- setOperationAction(ISD::UREM, VT, Expand);
+ setOperationAction(ISD::SDIV, VT, Expand);
+ setOperationAction(ISD::SREM, VT, Expand);
+ setOperationAction(ISD::UDIV, VT, Expand);
+ setOperationAction(ISD::UREM, VT, Expand);
// Custom lower build_vector, constant pool spills, insert and
// extract vector elements:
@@ -579,7 +609,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
// specified by the operand:
MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT,
- DAG.getNode(ISD::BIT_CONVERT, vecVT, result));
+ DAG.getNode(ISD::BIT_CONVERT, vecVT, result));
// Handle extending loads by extending the scalar result:
if (ExtType == ISD::SEXTLOAD) {
@@ -590,7 +620,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
unsigned NewOpc = ISD::ANY_EXTEND;
if (OutVT.isFloatingPoint())
- NewOpc = ISD::FP_EXTEND;
+ NewOpc = ISD::FP_EXTEND;
result = DAG.getNode(NewOpc, OutVT, result);
}
@@ -746,8 +776,8 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
result = DAG.getNode(SPUISD::SHUFB, vecVT,
- vectorizeOp, alignLoadVec,
- DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp));
+ vectorizeOp, alignLoadVec,
+ DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp));
result = DAG.getStore(the_chain, result, basePtr,
LN->getSrcValue(), LN->getSrcValueOffset(),
@@ -866,31 +896,6 @@ LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
return SDValue();
}
-//! Custom lower i64 integer constants
-/*!
- This code inserts all of the necessary juggling that needs to occur to load
- a 64-bit constant into a register.
- */
-static SDValue
-LowerConstant(SDValue Op, SelectionDAG &DAG) {
- MVT VT = Op.getValueType();
-
- if (VT == MVT::i64) {
- ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
- SDValue T = DAG.getConstant(CN->getZExtValue(), VT);
- return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
- DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
- } else {
- cerr << "LowerConstant: unhandled constant type "
- << VT.getMVTString()
- << "\n";
- abort();
- /*NOTREACHED*/
- }
-
- return SDValue();
-}
-
//! Custom lower double precision floating point constants
static SDValue
LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
@@ -1564,7 +1569,7 @@ static bool isConstantSplat(const uint64_t Bits128[2],
//! Lower a BUILD_VECTOR instruction creatively:
SDValue
-SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
+LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
MVT VT = Op.getValueType();
// If this is a vector of constants or undefs, get the bits. A bit in
// UndefBits is set if the corresponding element of the vector is an
@@ -1588,7 +1593,7 @@ SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
abort();
/*NOTREACHED*/
case MVT::v4f32: {
- uint32_t Value32 = SplatBits;
+ uint32_t Value32 = uint32_t(SplatBits);
assert(SplatSize == 4
&& "LowerBUILD_VECTOR: Unexpected floating point vector element.");
// NOTE: pretend the constant is an integer. LLVM won't load FP constants
@@ -1598,7 +1603,7 @@ SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
break;
}
case MVT::v2f64: {
- uint64_t f64val = SplatBits;
+ uint64_t f64val = uint64_t(SplatBits);
assert(SplatSize == 8
&& "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
// NOTE: pretend the constant is an integer. LLVM won't load FP constants
@@ -1638,93 +1643,99 @@ SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
}
case MVT::v2i64: {
- uint64_t val = SplatBits;
- uint32_t upper = uint32_t(val >> 32);
- uint32_t lower = uint32_t(val);
-
- if (upper == lower) {
- // Magic constant that can be matched by IL, ILA, et. al.
- SDValue Val = DAG.getTargetConstant(val, MVT::i64);
- return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
- } else {
- SDValue LO32;
- SDValue HI32;
- SmallVector<SDValue, 16> ShufBytes;
- SDValue Result;
- bool upper_special, lower_special;
-
- // NOTE: This code creates common-case shuffle masks that can be easily
- // detected as common expressions. It is not attempting to create highly
- // specialized masks to replace any and all 0's, 0xff's and 0x80's.
-
- // Detect if the upper or lower half is a special shuffle mask pattern:
- upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000);
- lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000);
-
- // Create lower vector if not a special pattern
- if (!lower_special) {
- SDValue LO32C = DAG.getConstant(lower, MVT::i32);
- LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
- DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
- LO32C, LO32C, LO32C, LO32C));
- }
+ return SPU::LowerSplat_v2i64(VT, DAG, SplatBits);
+ }
+ }
- // Create upper vector if not a special pattern
- if (!upper_special) {
- SDValue HI32C = DAG.getConstant(upper, MVT::i32);
- HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
- DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
- HI32C, HI32C, HI32C, HI32C));
- }
+ return SDValue();
+}
- // If either upper or lower are special, then the two input operands are
- // the same (basically, one of them is a "don't care")
- if (lower_special)
- LO32 = HI32;
- if (upper_special)
- HI32 = LO32;
- if (lower_special && upper_special) {
- // Unhappy situation... both upper and lower are special, so punt with
- // a target constant:
- SDValue Zero = DAG.getConstant(0, MVT::i32);
- HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
- Zero, Zero);
- }
+SDValue
+SPU::LowerSplat_v2i64(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal) {
+ uint32_t upper = uint32_t(SplatVal >> 32);
+ uint32_t lower = uint32_t(SplatVal);
+
+ if (upper == lower) {
+ // Magic constant that can be matched by IL, ILA, et. al.
+ SDValue Val = DAG.getTargetConstant(upper, MVT::i32);
+ return DAG.getNode(ISD::BIT_CONVERT, OpVT,
+ DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
+ Val, Val, Val, Val));
+ } else {
+ SDValue LO32;
+ SDValue HI32;
+ SmallVector<SDValue, 16> ShufBytes;
+ SDValue Result;
+ bool upper_special, lower_special;
+
+ // NOTE: This code creates common-case shuffle masks that can be easily
+ // detected as common expressions. It is not attempting to create highly
+ // specialized masks to replace any and all 0's, 0xff's and 0x80's.
+
+ // Detect if the upper or lower half is a special shuffle mask pattern:
+ upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
+ lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
+
+ // Create lower vector if not a special pattern
+ if (!lower_special) {
+ SDValue LO32C = DAG.getConstant(lower, MVT::i32);
+ LO32 = DAG.getNode(ISD::BIT_CONVERT, OpVT,
+ DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
+ LO32C, LO32C, LO32C, LO32C));
+ }
- for (int i = 0; i < 4; ++i) {
- uint64_t val = 0;
- for (int j = 0; j < 4; ++j) {
- SDValue V;
- bool process_upper, process_lower;
- val <<= 8;
- process_upper = (upper_special && (i & 1) == 0);
- process_lower = (lower_special && (i & 1) == 1);
-
- if (process_upper || process_lower) {
- if ((process_upper && upper == 0)
- || (process_lower && lower == 0))
- val |= 0x80;
- else if ((process_upper && upper == 0xffffffff)
- || (process_lower && lower == 0xffffffff))
- val |= 0xc0;
- else if ((process_upper && upper == 0x80000000)
- || (process_lower && lower == 0x80000000))
- val |= (j == 0 ? 0xe0 : 0x80);
- } else
- val |= i * 4 + j + ((i & 1) * 16);
- }
+ // Create upper vector if not a special pattern
+ if (!upper_special) {
+ SDValue HI32C = DAG.getConstant(upper, MVT::i32);
+ HI32 = DAG.getNode(ISD::BIT_CONVERT, OpVT,
+ DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
+ HI32C, HI32C, HI32C, HI32C));
+ }
- ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
+ // If either upper or lower are special, then the two input operands are
+ // the same (basically, one of them is a "don't care")
+ if (lower_special)
+ LO32 = HI32;
+ if (upper_special)
+ HI32 = LO32;
+ if (lower_special && upper_special) {
+ // Unhappy situation... both upper and lower are special, so punt with
+ // a target constant:
+ SDValue Zero = DAG.getConstant(0, MVT::i32);
+ HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
+ Zero, Zero);
+ }
+
+ for (int i = 0; i < 4; ++i) {
+ uint64_t val = 0;
+ for (int j = 0; j < 4; ++j) {
+ SDValue V;
+ bool process_upper, process_lower;
+ val <<= 8;
+ process_upper = (upper_special && (i & 1) == 0);
+ process_lower = (lower_special && (i & 1) == 1);
+
+ if (process_upper || process_lower) {
+ if ((process_upper && upper == 0)
+ || (process_lower && lower == 0))
+ val |= 0x80;
+ else if ((process_upper && upper == 0xffffffff)
+ || (process_lower && lower == 0xffffffff))
+ val |= 0xc0;
+ else if ((process_upper && upper == 0x80000000)
+ || (process_lower && lower == 0x80000000))
+ val |= (j == 0 ? 0xe0 : 0x80);
+ } else
+ val |= i * 4 + j + ((i & 1) * 16);
}
- return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
- DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
- &ShufBytes[0], ShufBytes.size()));
+ ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
}
- }
- }
- return SDValue();
+ return DAG.getNode(SPUISD::SHUFB, OpVT, HI32, LO32,
+ DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
+ &ShufBytes[0], ShufBytes.size()));
+ }
}
/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
@@ -2084,7 +2095,7 @@ static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
DAG.getNode(SPUISD::SHUFB, VT,
DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
VecOp,
- DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
+ DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
return result;
}
@@ -2271,6 +2282,7 @@ LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
}
}
+
// These operations (AND, OR, XOR) are legal, they just couldn't be custom
// lowered. Return the operation, rather than a null SDValue.
return Op;
@@ -2384,81 +2396,180 @@ static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
return SDValue();
}
-//! Lower ISD::FABS
+//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
/*!
- DAGCombine does the same basic reduction: convert the double to i64 and mask
- off the sign bit. Unfortunately, DAGCombine inserts the i64 constant, which
- CellSPU has to legalize. Hence, the custom lowering.
+ f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall.
+ All conversions to i64 are expanded to a libcall.
*/
-
-static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG) {
+static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
+ SPUTargetLowering &TLI) {
MVT OpVT = Op.getValueType();
- MVT IntVT(MVT::i64);
SDValue Op0 = Op.getOperand(0);
+ MVT Op0VT = Op0.getValueType();
- assert(OpVT == MVT::f64 && "LowerFABS: expecting MVT::f64!\n");
+ if ((OpVT == MVT::i32 && Op0VT == MVT::f64)
+ || OpVT == MVT::i64) {
+ // Convert f32 / f64 to i32 / i64 via libcall.
+ RTLIB::Libcall LC =
+ (Op.getOpcode() == ISD::FP_TO_SINT)
+ ? RTLIB::getFPTOSINT(Op0VT, OpVT)
+ : RTLIB::getFPTOUINT(Op0VT, OpVT);
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!");
+ SDValue Dummy;
+ return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
+ }
+
+ return Op; // return unmolested, legalized op
+}
- SDValue iABS =
- DAG.getNode(ISD::AND, IntVT,
- DAG.getNode(ISD::BIT_CONVERT, IntVT, Op0),
- DAG.getConstant(~IntVT.getIntegerVTSignBit(), IntVT));
+//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32
+/*!
+ i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall.
+ All conversions from i64 are expanded to a libcall.
+ */
+static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG,
+ SPUTargetLowering &TLI) {
+ MVT OpVT = Op.getValueType();
+ SDValue Op0 = Op.getOperand(0);
+ MVT Op0VT = Op0.getValueType();
- return DAG.getNode(ISD::BIT_CONVERT, MVT::f64, iABS);
+ if ((OpVT == MVT::f64 && Op0VT == MVT::i32)
+ || Op0VT == MVT::i64) {
+ // Convert i32, i64 to f64 via libcall:
+ RTLIB::Libcall LC =
+ (Op.getOpcode() == ISD::SINT_TO_FP)
+ ? RTLIB::getSINTTOFP(Op0VT, OpVT)
+ : RTLIB::getUINTTOFP(Op0VT, OpVT);
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!");
+ SDValue Dummy;
+ return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
+ }
+
+ return Op; // return unmolested, legalized
}
//! Lower ISD::SETCC
/*!
This handles MVT::f64 (double floating point) condition lowering
*/
-
static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
const TargetLowering &TLI) {
+ CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
+ assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
+
SDValue lhs = Op.getOperand(0);
SDValue rhs = Op.getOperand(1);
- CondCodeSDNode *CC = dyn_cast<CondCodeSDNode > (Op.getOperand(2));
MVT lhsVT = lhs.getValueType();
- SDValue posNaN = DAG.getConstant(0x7ff0000000000001ULL, MVT::i64);
-
- assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
- switch (CC->get()) {
- case ISD::SETOEQ:
- case ISD::SETOGT:
- case ISD::SETOGE:
- case ISD::SETOLT:
- case ISD::SETOLE:
- case ISD::SETONE:
- cerr << "CellSPU ISel Select: unimplemented f64 condition\n";
- abort();
- break;
- case ISD::SETO: {
- SDValue lhsfabs = DAG.getNode(ISD::FABS, MVT::f64, lhs);
- SDValue i64lhs =
- DAG.getNode(ISD::BIT_CONVERT, MVT::i64, lhsfabs);
+ MVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType());
+ APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
+ MVT IntVT(MVT::i64);
- return DAG.getSetCC(MVT::i32, i64lhs, posNaN, ISD::SETLT);
- }
- case ISD::SETUO: {
- SDValue lhsfabs = DAG.getNode(ISD::FABS, MVT::f64, lhs);
- SDValue i64lhs =
- DAG.getNode(ISD::BIT_CONVERT, MVT::i64, lhsfabs);
+ // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently
+ // selected to a NOP:
+ SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, IntVT, lhs);
+ SDValue lhsHi32 =
+ DAG.getNode(ISD::TRUNCATE, MVT::i32,
+ DAG.getNode(ISD::SRL, IntVT,
+ i64lhs, DAG.getConstant(32, MVT::i32)));
+ SDValue lhsHi32abs =
+ DAG.getNode(ISD::AND, MVT::i32,
+ lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
+ SDValue lhsLo32 =
+ DAG.getNode(ISD::TRUNCATE, MVT::i32, i64lhs);
+
+ // SETO and SETUO only use the lhs operand:
+ if (CC->get() == ISD::SETO) {
+ // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of
+ // SETUO
+ APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
+ return DAG.getNode(ISD::XOR, ccResultVT,
+ DAG.getSetCC(ccResultVT,
+ lhs, DAG.getConstantFP(0.0, lhsVT),
+ ISD::SETUO),
+ DAG.getConstant(ccResultAllOnes, ccResultVT));
+ } else if (CC->get() == ISD::SETUO) {
+ // Evaluates to true if Op0 is [SQ]NaN
+ return DAG.getNode(ISD::AND, ccResultVT,
+ DAG.getSetCC(ccResultVT,
+ lhsHi32abs,
+ DAG.getConstant(0x7ff00000, MVT::i32),
+ ISD::SETGE),
+ DAG.getSetCC(ccResultVT,
+ lhsLo32,
+ DAG.getConstant(0, MVT::i32),
+ ISD::SETGT));
+ }
+
+ SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, IntVT, rhs);
+ SDValue rhsHi32 =
+ DAG.getNode(ISD::TRUNCATE, MVT::i32,
+ DAG.getNode(ISD::SRL, IntVT,
+ i64rhs, DAG.getConstant(32, MVT::i32)));
+
+ // If a value is negative, subtract from the sign magnitude constant:
+ SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT);
+
+ // Convert the sign-magnitude representation into 2's complement:
+ SDValue lhsSelectMask = DAG.getNode(ISD::SRA, ccResultVT,
+ lhsHi32, DAG.getConstant(31, MVT::i32));
+ SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, IntVT, signMag2TC, i64lhs);
+ SDValue lhsSelect =
+ DAG.getNode(ISD::SELECT, IntVT,
+ lhsSelectMask, lhsSignMag2TC, i64lhs);
+
+ SDValue rhsSelectMask = DAG.getNode(ISD::SRA, ccResultVT,
+ rhsHi32, DAG.getConstant(31, MVT::i32));
+ SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, IntVT, signMag2TC, i64rhs);
+ SDValue rhsSelect =
+ DAG.getNode(ISD::SELECT, IntVT,
+ rhsSelectMask, rhsSignMag2TC, i64rhs);
+
+ unsigned compareOp;
- return DAG.getSetCC(MVT::i32, i64lhs, posNaN, ISD::SETGE);
- }
+ switch (CC->get()) {
+ case ISD::SETOEQ:
case ISD::SETUEQ:
+ compareOp = ISD::SETEQ; break;
+ case ISD::SETOGT:
case ISD::SETUGT:
+ compareOp = ISD::SETGT; break;
+ case ISD::SETOGE:
case ISD::SETUGE:
+ compareOp = ISD::SETGE; break;
+ case ISD::SETOLT:
case ISD::SETULT:
+ compareOp = ISD::SETLT; break;
+ case ISD::SETOLE:
case ISD::SETULE:
+ compareOp = ISD::SETLE; break;
case ISD::SETUNE:
+ case ISD::SETONE:
+ compareOp = ISD::SETNE; break;
default:
cerr << "CellSPU ISel Select: unimplemented f64 condition\n";
abort();
break;
}
- return SDValue();
+ SDValue result =
+ DAG.getSetCC(ccResultVT, lhsSelect, rhsSelect, (ISD::CondCode) compareOp);
+
+ if ((CC->get() & 0x8) == 0) {
+ // Ordered comparison:
+ SDValue lhsNaN = DAG.getSetCC(ccResultVT,
+ lhs, DAG.getConstantFP(0.0, MVT::f64),
+ ISD::SETO);
+ SDValue rhsNaN = DAG.getSetCC(ccResultVT,
+ rhs, DAG.getConstantFP(0.0, MVT::f64),
+ ISD::SETO);
+ SDValue ordered = DAG.getNode(ISD::AND, ccResultVT, lhsNaN, rhsNaN);
+
+ result = DAG.getNode(ISD::AND, ccResultVT, ordered, result);
+ }
+
+ return result;
}
//! Lower ISD::SELECT_CC
@@ -2566,8 +2677,6 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
case ISD::JumpTable:
return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
- case ISD::Constant:
- return LowerConstant(Op, DAG);
case ISD::ConstantFP:
return LowerConstantFP(Op, DAG);
case ISD::FORMAL_ARGUMENTS:
@@ -2590,12 +2699,17 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
break;
}
- case ISD::FABS:
- return LowerFABS(Op, DAG);
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT:
+ return LowerFP_TO_INT(Op, DAG, *this);
+
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP:
+ return LowerINT_TO_FP(Op, DAG, *this);
// Vector-related lowering.
case ISD::BUILD_VECTOR:
- return SPU::LowerBUILD_VECTOR(Op, DAG);
+ return LowerBUILD_VECTOR(Op, DAG);
case ISD::SCALAR_TO_VECTOR:
return LowerSCALAR_TO_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE:
diff --git a/lib/Target/CellSPU/SPUISelLowering.h b/lib/Target/CellSPU/SPUISelLowering.h
index 079f3ba69efa..24c2803fe65f 100644
--- a/lib/Target/CellSPU/SPUISelLowering.h
+++ b/lib/Target/CellSPU/SPUISelLowering.h
@@ -61,7 +61,7 @@ namespace llvm {
};
}
- //! Utility functions specific to CellSPU-only:
+ //! Utility functions specific to CellSPU:
namespace SPU {
SDValue get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
MVT ValueType);
@@ -78,7 +78,7 @@ namespace llvm {
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG,
const SPUTargetMachine &TM);
- SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerSplat_v2i64(MVT OpVT, SelectionDAG &DAG, uint64_t splat);
SDValue getBorrowGenerateShufMask(SelectionDAG &DAG);
SDValue getCarryGenerateShufMask(SelectionDAG &DAG);
diff --git a/lib/Target/CellSPU/SPUInstrFormats.td b/lib/Target/CellSPU/SPUInstrFormats.td
index 710196467bc1..21bc275209c6 100644
--- a/lib/Target/CellSPU/SPUInstrFormats.td
+++ b/lib/Target/CellSPU/SPUInstrFormats.td
@@ -290,6 +290,9 @@ class RR_Int_v4i32<bits<11> opcode, string opc, InstrItinClass itin,
class Pseudo<dag OOL, dag IOL, string asmstr, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, NoItinerary> {
+ let OutOperandList = OOL;
+ let InOperandList = IOL;
+ let AsmString = asmstr;
let Pattern = pattern;
let Inst{31-0} = 0;
}
diff --git a/lib/Target/CellSPU/SPUInstrInfo.cpp b/lib/Target/CellSPU/SPUInstrInfo.cpp
index 91d52facada8..46e63893ee27 100644
--- a/lib/Target/CellSPU/SPUInstrInfo.cpp
+++ b/lib/Target/CellSPU/SPUInstrInfo.cpp
@@ -28,8 +28,8 @@ namespace {
unsigned opc = I->getOpcode();
return (opc == SPU::BR
- || opc == SPU::BRA
- || opc == SPU::BI);
+ || opc == SPU::BRA
+ || opc == SPU::BI);
}
//! Predicate for a conditional branch instruction
@@ -38,12 +38,12 @@ namespace {
return (opc == SPU::BRNZr32
|| opc == SPU::BRNZv4i32
- || opc == SPU::BRZr32
- || opc == SPU::BRZv4i32
- || opc == SPU::BRHNZr16
- || opc == SPU::BRHNZv8i16
- || opc == SPU::BRHZr16
- || opc == SPU::BRHZv8i16);
+ || opc == SPU::BRZr32
+ || opc == SPU::BRZv4i32
+ || opc == SPU::BRHNZr16
+ || opc == SPU::BRHNZv8i16
+ || opc == SPU::BRHZr16
+ || opc == SPU::BRHZv8i16);
}
}
@@ -155,13 +155,13 @@ SPUInstrInfo::isMoveInstr(const MachineInstr& MI,
case SPU::ORr8_r32:
case SPU::ORr32_r16:
case SPU::ORr32_r8:
- case SPU::ORr32_r64:
case SPU::ORr16_r64:
case SPU::ORr8_r64:
- case SPU::ORr64_r32:
case SPU::ORr64_r16:
case SPU::ORr64_r8:
*/
+ case SPU::ORr64_r32:
+ case SPU::ORr32_r64:
case SPU::ORf32_r32:
case SPU::ORr32_f32:
case SPU::ORf64_r64:
@@ -531,8 +531,8 @@ SPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
*/
bool
SPUInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
- MachineBasicBlock *&FBB,
- SmallVectorImpl<MachineOperand> &Cond) const {
+ MachineBasicBlock *&FBB,
+ SmallVectorImpl<MachineOperand> &Cond) const {
// If the block has no terminators, it just falls into the block after it.
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
@@ -621,8 +621,8 @@ SPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
unsigned
SPUInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
- MachineBasicBlock *FBB,
- const SmallVectorImpl<MachineOperand> &Cond) const {
+ MachineBasicBlock *FBB,
+ const SmallVectorImpl<MachineOperand> &Cond) const {
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 2 || Cond.size() == 0) &&
diff --git a/lib/Target/CellSPU/SPUInstrInfo.h b/lib/Target/CellSPU/SPUInstrInfo.h
index 7bbdfada12c7..0ec3b5ffa13b 100644
--- a/lib/Target/CellSPU/SPUInstrInfo.h
+++ b/lib/Target/CellSPU/SPUInstrInfo.h
@@ -103,14 +103,14 @@ namespace llvm {
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
- MachineBasicBlock *&FBB,
- SmallVectorImpl<MachineOperand> &Cond) const;
+ MachineBasicBlock *&FBB,
+ SmallVectorImpl<MachineOperand> &Cond) const;
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
- MachineBasicBlock *FBB,
- const SmallVectorImpl<MachineOperand> &Cond) const;
+ MachineBasicBlock *FBB,
+ const SmallVectorImpl<MachineOperand> &Cond) const;
};
}
diff --git a/lib/Target/CellSPU/SPUInstrInfo.td b/lib/Target/CellSPU/SPUInstrInfo.td
index 2834a1eb8d9c..250a57dd128d 100644
--- a/lib/Target/CellSPU/SPUInstrInfo.td
+++ b/lib/Target/CellSPU/SPUInstrInfo.td
@@ -34,10 +34,9 @@ let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in {
// DWARF debugging Pseudo Instructions
//===----------------------------------------------------------------------===//
-def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
- "${:comment} .loc $file, $line, $col",
- [(dwarf_loc (i32 imm:$line), (i32 imm:$col),
- (i32 imm:$file))]>;
+def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
+ ".loc $file, $line, $col",
+ [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
//===----------------------------------------------------------------------===//
// Loads:
@@ -624,25 +623,25 @@ defm A : AddInstruction;
class AIInst<dag OOL, dag IOL, list<dag> pattern>:
RI10Form<0b00111000, OOL, IOL,
- "ai\t$rT, $rA, $val", IntegerOp,
- pattern>;
+ "ai\t$rT, $rA, $val", IntegerOp,
+ pattern>;
class AIVecInst<ValueType vectype, PatLeaf immpred>:
AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
- [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), immpred:$val))]>;
+ [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), immpred:$val))]>;
class AIFPVecInst<ValueType vectype, PatLeaf immpred>:
AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
- [/* no pattern */]>;
+ [/* no pattern */]>;
class AIRegInst<RegisterClass rclass, PatLeaf immpred>:
AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val),
- [(set rclass:$rT, (add rclass:$rA, immpred:$val))]>;
+ [(set rclass:$rT, (add rclass:$rA, immpred:$val))]>;
// This is used to add epsilons to floating point numbers in the f32 fdiv code:
class AIFPInst<RegisterClass rclass, PatLeaf immpred>:
AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val),
- [/* no pattern */]>;
+ [/* no pattern */]>;
multiclass AddImmediate {
def v4i32: AIVecInst<v4i32, v4i32SExt10Imm>;
@@ -1259,6 +1258,9 @@ multiclass BitwiseAnd
def fabs32: ANDInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB),
[/* Intentionally does not match a pattern */]>;
+ def fabs64: ANDInst<(outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB),
+ [/* Intentionally does not match a pattern */]>;
+
// Could use v4i32, but won't for clarity
def fabsvec: ANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
[/* Intentionally does not match a pattern */]>;
@@ -1525,17 +1527,17 @@ multiclass BitwiseOr
// Conversion from R32C to register
def r32_r16: ORCvtFormR32Reg<R16C>;
def r32_r8: ORCvtFormR32Reg<R8C>;
+*/
- // Conversion from register to R64C:
+ // Conversion to register from R64C:
def r32_r64: ORCvtFormR64Reg<R32C>;
- def r16_r64: ORCvtFormR64Reg<R16C>;
- def r8_r64: ORCvtFormR64Reg<R8C>;
+ // def r16_r64: ORCvtFormR64Reg<R16C>;
+ // def r8_r64: ORCvtFormR64Reg<R8C>;
- // Conversion from R64C to register
+ // Conversion to R64C from register
def r64_r32: ORCvtFormRegR64<R32C>;
- def r64_r16: ORCvtFormRegR64<R16C>;
- def r64_r8: ORCvtFormRegR64<R8C>;
-*/
+ // def r64_r16: ORCvtFormRegR64<R16C>;
+ // def r64_r8: ORCvtFormRegR64<R8C>;
// bitconvert patterns:
def r32_f32: ORCvtFormR32Reg<R32FP,
@@ -1910,11 +1912,11 @@ class SELBInst<dag OOL, dag IOL, list<dag> pattern>:
RRRForm<0b1000, OOL, IOL, "selb\t$rT, $rA, $rB, $rC",
IntegerOp, pattern>;
-class SELBVecInst<ValueType vectype>:
+class SELBVecInst<ValueType vectype, PatFrag vnot_frag = vnot>:
SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
[(set (vectype VECREG:$rT),
(or (and (vectype VECREG:$rC), (vectype VECREG:$rB)),
- (and (vnot (vectype VECREG:$rC)),
+ (and (vnot_frag (vectype VECREG:$rC)),
(vectype VECREG:$rA))))]>;
class SELBVecVCondInst<ValueType vectype>:
@@ -1947,7 +1949,7 @@ multiclass SelectBits
def v16i8: SELBVecInst<v16i8>;
def v8i16: SELBVecInst<v8i16>;
def v4i32: SELBVecInst<v4i32>;
- def v2i64: SELBVecInst<v2i64>;
+ def v2i64: SELBVecInst<v2i64, vnot_conv>;
def r128: SELBRegInst<GPRC>;
def r64: SELBRegInst<R64C>;
@@ -1966,11 +1968,11 @@ multiclass SelectBits
def v2i64_vcond: SELBVecCondInst<v2i64>;
def v4f32_cond:
- SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
- [(set (v4f32 VECREG:$rT),
- (select (v4i32 VECREG:$rC),
- (v4f32 VECREG:$rB),
- (v4f32 VECREG:$rA)))]>;
+ SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
+ [(set (v4f32 VECREG:$rT),
+ (select (v4i32 VECREG:$rC),
+ (v4f32 VECREG:$rB),
+ (v4f32 VECREG:$rA)))]>;
// SELBr64_cond is defined in SPU64InstrInfo.td
def r32_cond: SELBRegCondInst<R32C, R32C>;
@@ -3257,7 +3259,7 @@ multiclass CmpGtrWordImm
(v4i32 v4i32SExt16Imm:$val)))]>;
def f32: CGTIInst<(outs R32C:$rT), (ins R32FP:$rA, s10imm_i32:$val),
- [/* no pattern */]>;
+ [/* no pattern */]>;
}
class CLGTBInst<dag OOL, dag IOL, list<dag> pattern> :
@@ -4321,6 +4323,13 @@ def : Pat<(fabs (v4f32 VECREG:$rA)),
(ANDfabsvec (v4f32 VECREG:$rA),
(v4f32 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
+def : Pat<(fabs R64FP:$rA),
+ (ANDfabs64 R64FP:$rA, (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f))>;
+
+def : Pat<(fabs (v2f64 VECREG:$rA)),
+ (ANDfabsvec (v2f64 VECREG:$rA),
+ (v2f64 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
+
//===----------------------------------------------------------------------===//
// Hint for branch instructions:
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/CellSPU/SPUMathInstr.td b/lib/Target/CellSPU/SPUMathInstr.td
index 64548fd8c087..80ebde3ef259 100644
--- a/lib/Target/CellSPU/SPUMathInstr.td
+++ b/lib/Target/CellSPU/SPUMathInstr.td
@@ -66,15 +66,15 @@ def Interpf32: CodeFrag<(FIf32 R32FP:$rB, (FRESTf32 R32FP:$rB))>;
def DivEstf32: CodeFrag<(FMf32 R32FP:$rA, Interpf32.Fragment)>;
// Newton-Raphson iteration
def NRaphf32: CodeFrag<(FMAf32 (FNMSf32 DivEstf32.Fragment, R32FP:$rB, R32FP:$rA),
- Interpf32.Fragment,
- DivEstf32.Fragment)>;
+ Interpf32.Fragment,
+ DivEstf32.Fragment)>;
// Epsilon addition
def Epsilonf32: CodeFrag<(AIf32 NRaphf32.Fragment, 1)>;
def : Pat<(fdiv R32FP:$rA, R32FP:$rB),
- (SELBf32_cond NRaphf32.Fragment,
- Epsilonf32.Fragment,
- (CGTIf32 (FNMSf32 R32FP:$rB, Epsilonf32.Fragment, R32FP:$rA), -1))>;
+ (SELBf32_cond NRaphf32.Fragment,
+ Epsilonf32.Fragment,
+ (CGTIf32 (FNMSf32 R32FP:$rB, Epsilonf32.Fragment, R32FP:$rA), -1))>;
// Reciprocal estimate and interpolation
def Interpv4f32: CodeFrag<(FIv4f32 (v4f32 VECREG:$rB), (FRESTv4f32 (v4f32 VECREG:$rB)))>;
@@ -82,16 +82,16 @@ def Interpv4f32: CodeFrag<(FIv4f32 (v4f32 VECREG:$rB), (FRESTv4f32 (v4f32 VECREG
def DivEstv4f32: CodeFrag<(FMv4f32 (v4f32 VECREG:$rA), Interpv4f32.Fragment)>;
// Newton-Raphson iteration
def NRaphv4f32: CodeFrag<(FMAv4f32 (FNMSv4f32 DivEstv4f32.Fragment,
- (v4f32 VECREG:$rB),
- (v4f32 VECREG:$rA)),
- Interpv4f32.Fragment,
- DivEstv4f32.Fragment)>;
+ (v4f32 VECREG:$rB),
+ (v4f32 VECREG:$rA)),
+ Interpv4f32.Fragment,
+ DivEstv4f32.Fragment)>;
// Epsilon addition
def Epsilonv4f32: CodeFrag<(AIv4f32 NRaphv4f32.Fragment, 1)>;
def : Pat<(fdiv (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)),
- (SELBv4f32_cond NRaphv4f32.Fragment,
- Epsilonv4f32.Fragment,
- (CGTIv4f32 (FNMSv4f32 (v4f32 VECREG:$rB),
- Epsilonv4f32.Fragment,
- (v4f32 VECREG:$rA)), -1))>;
+ (SELBv4f32_cond NRaphv4f32.Fragment,
+ Epsilonv4f32.Fragment,
+ (CGTIv4f32 (FNMSv4f32 (v4f32 VECREG:$rB),
+ Epsilonv4f32.Fragment,
+ (v4f32 VECREG:$rA)), -1))>;
diff --git a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
index 72752555e499..ff88ed810716 100644
--- a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
+++ b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
@@ -15,8 +15,10 @@
#include "SPUTargetMachine.h"
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Dwarf.h"
using namespace llvm;
+using namespace llvm::dwarf;
SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
SPUTargetAsmInfo<ELFTargetAsmInfo>(TM) {
@@ -27,12 +29,34 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
// This corresponds to what the gcc SPU compiler emits, for consistency.
CStringSection = ".rodata.str";
+ // Has leb128, .loc and .file
+ HasLEB128 = true;
+ HasDotLocAndDotFile = true;
+
// BSS section needs to be emitted as ".section"
BSSSection = "\t.section\t.bss";
BSSSection_ = getUnnamedSection("\t.section\t.bss",
SectionFlags::Writeable | SectionFlags::BSS,
true);
+ SupportsDebugInformation = true;
+ NeedsSet = true;
+ SupportsMacInfoSection = false;
+ DwarfAbbrevSection = "\t.section .debug_abbrev,\"\",@progbits";
+ DwarfInfoSection = "\t.section .debug_info,\"\",@progbits";
+ DwarfLineSection = "\t.section .debug_line,\"\",@progbits";
+ DwarfFrameSection = "\t.section .debug_frame,\"\",@progbits";
+ DwarfPubNamesSection = "\t.section .debug_pubnames,\"\",@progbits";
+ DwarfPubTypesSection = "\t.section .debug_pubtypes,\"\",progbits";
+ DwarfStrSection = "\t.section .debug_str,\"MS\",@progbits,1";
+ DwarfLocSection = "\t.section .debug_loc,\"\",@progbits";
+ DwarfARangesSection = "\t.section .debug_aranges,\"\",@progbits";
+ DwarfRangesSection = "\t.section .debug_ranges,\"\",@progbits";
+ DwarfMacInfoSection = "\t.section .debug_macinfo,\"\",progbits";
+
+ // Exception handling is not supported on CellSPU (think about it: you only
+ // have 256K for code+data. Would you support exception handling?)
+ SupportsExceptionHandling = false;
}
/// PreferredEHDataFormat - This hook allows the target to select data
diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp
index 57e70148f481..cc05c09c5170 100644
--- a/lib/Target/DarwinTargetAsmInfo.cpp
+++ b/lib/Target/DarwinTargetAsmInfo.cpp
@@ -115,9 +115,9 @@ const Section*
DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
const TargetData *TD = TM.getTargetData();
Constant *C = cast<GlobalVariable>(GV)->getInitializer();
- const Type *Type = cast<ConstantArray>(C)->getType()->getElementType();
+ const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
- unsigned Size = TD->getTypePaddedSize(Type);
+ unsigned Size = TD->getTypePaddedSize(Ty);
if (Size) {
unsigned Align = TD->getPreferredAlignment(GV);
if (Align <= 32)
diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp
index 5a3b93a52f37..624b95c7b6c1 100644
--- a/lib/Target/ELFTargetAsmInfo.cpp
+++ b/lib/Target/ELFTargetAsmInfo.cpp
@@ -126,8 +126,7 @@ const Section*
ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
const TargetData *TD = TM.getTargetData();
Constant *C = cast<GlobalVariable>(GV)->getInitializer();
- const ConstantArray *CVA = cast<ConstantArray>(C);
- const Type *Ty = CVA->getType()->getElementType();
+ const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
unsigned Size = TD->getTypePaddedSize(Ty);
if (Size <= 16) {
diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp
index c40f89d7f0de..ff7ad9018779 100644
--- a/lib/Target/IA64/IA64ISelLowering.cpp
+++ b/lib/Target/IA64/IA64ISelLowering.cpp
@@ -145,7 +145,8 @@ MVT IA64TargetLowering::getSetCCResultType(MVT VT) const {
}
void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &ArgValues) {
+ SmallVectorImpl<SDValue> &ArgValues,
+ DebugLoc dl) {
//
// add beautiful description of IA64 stack frame format
// here (from intel 24535803.pdf most likely)
@@ -199,7 +200,7 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), argVreg[count],
MVT::f64);
if (I->getType() == Type::FloatTy)
- argt = DAG.getNode(ISD::FP_ROUND, MVT::f32, argt,
+ argt = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, argt,
DAG.getIntPtrConstant(0));
break;
case MVT::i1: // NOTE: as far as C abi stuff goes,
@@ -218,7 +219,7 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
argt = newroot =
DAG.getCopyFromReg(DAG.getRoot(), argVreg[count], MVT::i64);
if ( getValueType(I->getType()) != MVT::i64)
- argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()),
+ argt = DAG.getNode(ISD::TRUNCATE, dl, getValueType(I->getType()),
newroot);
break;
}
@@ -230,7 +231,7 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
// Create the SelectionDAG nodes corresponding to a load
//from this parameter
SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
- argt = newroot = DAG.getLoad(getValueType(I->getType()),
+ argt = newroot = DAG.getLoad(getValueType(I->getType()), dl,
DAG.getEntryNode(), FIN, NULL, 0);
}
++count;
@@ -307,7 +308,8 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg,
bool isInreg, unsigned CallingConv,
bool isTailCall, SDValue Callee,
- ArgListTy &Args, SelectionDAG &DAG) {
+ ArgListTy &Args, SelectionDAG &DAG,
+ DebugLoc dl) {
MachineFunction &MF = DAG.getMachineFunction();
@@ -360,7 +362,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
ExtendKind = ISD::SIGN_EXTEND;
else if (Args[i].isZExt)
ExtendKind = ISD::ZERO_EXTEND;
- Val = DAG.getNode(ExtendKind, MVT::i64, Val);
+ Val = DAG.getNode(ExtendKind, dl, MVT::i64, Val);
// XXX: fall through
}
case MVT::i64:
@@ -373,7 +375,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
break;
case MVT::f32:
//promote to 64-bits
- Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val);
+ Val = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Val);
// XXX: fall through
case MVT::f64:
if(RegValuesToPass.size() >= 8) {
@@ -392,19 +394,21 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
StackPtr = DAG.getRegister(IA64::r12, MVT::i64);
}
SDValue PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
- PtrOff = DAG.getNode(ISD::ADD, MVT::i64, StackPtr, PtrOff);
- Stores.push_back(DAG.getStore(Chain, ValToStore, PtrOff, NULL, 0));
+ PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i64, StackPtr, PtrOff);
+ Stores.push_back(DAG.getStore(Chain, dl, ValToStore, PtrOff, NULL, 0));
ArgOffset += ObjSize;
}
if(ValToConvert.getNode()) {
- Converts.push_back(DAG.getNode(IA64ISD::GETFD, MVT::i64, ValToConvert));
+ Converts.push_back(DAG.getNode(IA64ISD::GETFD, dl,
+ MVT::i64, ValToConvert));
}
}
// Emit all stores, make sure they occur before any copies into physregs.
if (!Stores.empty())
- Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],Stores.size());
+ Chain = DAG.getNode(ISD::TokenFactor, dl,
+ MVT::Other, &Stores[0],Stores.size());
static const unsigned IntArgRegs[] = {
IA64::out0, IA64::out1, IA64::out2, IA64::out3,
@@ -477,7 +481,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
assert(0 && "this should never happen!\n");
// to make way for a hack:
- Chain = DAG.getNode(IA64ISD::BRCALL, NodeTys,
+ Chain = DAG.getNode(IA64ISD::BRCALL, dl, NodeTys,
&CallOperands[0], CallOperands.size());
InFlag = Chain.getValue(1);
@@ -508,7 +512,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
InFlag = zeroReg.getValue(2);
Chain = zeroReg.getValue(1);
- RetVal = DAG.getSetCC(MVT::i1, boolInR8, zeroReg, ISD::SETNE);
+ RetVal = DAG.getSetCC(dl, MVT::i1, boolInR8, zeroReg, ISD::SETNE);
break;
}
case MVT::i8:
@@ -520,9 +524,9 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
// keep track of whether it is sign or zero extended (todo: bools?)
/* XXX
RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext :ISD::AssertZext,
- MVT::i64, RetVal, DAG.getValueType(RetTyVT));
+ dl, MVT::i64, RetVal, DAG.getValueType(RetTyVT));
*/
- RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal);
+ RetVal = DAG.getNode(ISD::TRUNCATE, dl, RetTyVT, RetVal);
break;
case MVT::i64:
RetVal = DAG.getCopyFromReg(Chain, IA64::r8, MVT::i64, InFlag);
@@ -532,7 +536,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
case MVT::f32:
RetVal = DAG.getCopyFromReg(Chain, IA64::F8, MVT::f64, InFlag);
Chain = RetVal.getValue(1);
- RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal,
+ RetVal = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, RetVal,
DAG.getIntPtrConstant(0));
break;
case MVT::f64:
diff --git a/lib/Target/IA64/IA64ISelLowering.h b/lib/Target/IA64/IA64ISelLowering.h
index 9b0854fb8931..edf7eb895ad2 100644
--- a/lib/Target/IA64/IA64ISelLowering.h
+++ b/lib/Target/IA64/IA64ISelLowering.h
@@ -54,7 +54,8 @@ namespace llvm {
/// LowerArguments - This hook must be implemented to indicate how we should
/// lower the arguments for the specified function, into the specified DAG.
virtual void LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &ArgValues);
+ SmallVectorImpl<SDValue> &ArgValues,
+ DebugLoc dl);
/// LowerCallTo - This hook lowers an abstract call to a function into an
/// actual call.
@@ -62,7 +63,8 @@ namespace llvm {
LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg,
unsigned CC, bool isTailCall,
- SDValue Callee, ArgListTy &Args, SelectionDAG &DAG);
+ SDValue Callee, ArgListTy &Args, SelectionDAG &DAG,
+ DebugLoc dl);
/// LowerOperation - for custom lowering specific ops
/// (currently, only "ret void")
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index f2786dc12027..5af38bf4ab47 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -573,9 +573,8 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG)
// CALL Calling Convention Implementation
//===----------------------------------------------------------------------===//
-/// LowerCCCCallTo - functions arguments are copied from virtual
-/// regs to (physical regs)/(stack frame), CALLSEQ_START and
-/// CALLSEQ_END are emitted.
+/// LowerCALL - functions arguments are copied from virtual regs to
+/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
/// TODO: isVarArg, isTailCall.
SDValue MipsTargetLowering::
LowerCALL(SDValue Op, SelectionDAG &DAG)
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp
index dc91128d5a38..63ad6e4f4488 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp
@@ -242,48 +242,11 @@ void PIC16AsmPrinter::EmitInitData (Module &M) {
continue;
O << name;
- EmitGlobalConstant(C);
+ EmitGlobalConstant(C, AddrSpace);
}
}
}
-void PIC16AsmPrinter::EmitConstantValueOnly(const Constant* CV) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- unsigned BitWidth = CI->getBitWidth();
- int Val = CI->getZExtValue();
- if (BitWidth == 8) {
- // Expecting db directive here. In case of romdata we need to pad the
- // word with zeros.
- if (IsRomData)
- O << 0 <<", ";
- O << Val;
- }
- else if (BitWidth == 16) {
- unsigned Element1, Element2;
- Element1 = 0x00ff & Val;
- Element2 = 0x00ff & (Val >> 8);
- if (IsRomData)
- O << 0 <<", "<<Element1 <<", "<< 0 <<", "<< Element2;
- else
- O << Element1 <<", "<< Element2;
- }
- else if (BitWidth == 32) {
- unsigned Element1, Element2, Element3, Element4;
- Element1 = 0x00ff & Val;
- Element2 = 0x00ff & (Val >> 8);
- Element3 = 0x00ff & (Val >> 16);
- Element4 = 0x00ff & (Val >> 24);
- if (IsRomData)
- O << 0 <<", "<< Element1 <<", "<< 0 <<", "<< Element2 <<", "<< 0
- <<", "<< Element3 <<", "<< 0 <<", "<< Element4;
- else
- O << Element1 <<", "<< Element2 <<", "<< Element3 <<", "<< Element4;
- }
- return;
- }
- AsmPrinter::EmitConstantValueOnly(CV);
-}
-
void PIC16AsmPrinter::EmitRomData (Module &M)
{
SwitchToSection(TAI->getReadOnlySection());
@@ -308,7 +271,7 @@ void PIC16AsmPrinter::EmitRomData (Module &M)
continue;
O << name;
- EmitGlobalConstant(C);
+ EmitGlobalConstant(C, AddrSpace);
O << "\n";
}
}
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.h b/lib/Target/PIC16/PIC16AsmPrinter.h
index 876e4be7439a..ce79afd6079e 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/PIC16AsmPrinter.h
@@ -43,7 +43,6 @@ namespace llvm {
void EmitInitData (Module &M);
void EmitUnInitData (Module &M);
void EmitRomData (Module &M);
- virtual void EmitConstantValueOnly(const Constant *CV);
void emitFunctionData(MachineFunction &MF);
void emitFunctionTempData(MachineFunction &MF, unsigned &FrameSize);
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index ae031bc64693..4e7e1e44fcb8 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -172,7 +172,7 @@ SDValue
PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call,
MVT RetVT, const SDValue *Ops,
unsigned NumOps, bool isSigned,
- SelectionDAG &DAG) {
+ SelectionDAG &DAG, DebugLoc dl) {
TargetLowering::ArgListTy Args;
Args.reserve(NumOps);
@@ -190,7 +190,7 @@ PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call,
const Type *RetTy = RetVT.getTypeForMVT();
std::pair<SDValue,SDValue> CallInfo =
LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
- false, CallingConv::C, false, Callee, Args, DAG);
+ false, CallingConv::C, false, Callee, Args, DAG, dl);
return CallInfo.first;
}
@@ -758,7 +758,8 @@ SDValue PIC16TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) {
SmallVector<SDValue, 2> Ops(2);
Ops[0] = Value;
Ops[1] = Amt;
- SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2, true, DAG);
+ SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2,
+ true, DAG, N->getDebugLoc());
return Call;
}
@@ -1288,23 +1289,25 @@ SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS,
}
PIC16CC = DAG.getConstant(CondCode, MVT::i8);
- SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
// These are signed comparisons.
SDValue Mask = DAG.getConstant(128, MVT::i8);
if (isSignedComparison(CondCode)) {
- LHS = DAG.getNode (ISD::XOR, MVT::i8, LHS, Mask);
+ LHS = DAG.getNode (ISD::XOR, MVT::i8, LHS, Mask);
RHS = DAG.getNode (ISD::XOR, MVT::i8, RHS, Mask);
}
+
+ SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
// We can use a subtract operation to set the condition codes. But
// we need to put one operand in memory if required.
- // Nothing to do if the first operand is already a direct load and it has
- // only one use.
- if (! (isDirectLoad(LHS) && LHS.hasOneUse()))
- // Put first operand on stack.
- LHS = ConvertToMemOperand (LHS, DAG);
-
- SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
+ // Nothing to do if the first operand is already a valid type (direct load
+ // for subwf and literal for sublw) and it is used by this operation only.
+ if ((LHS.getOpcode() == ISD::Constant || isDirectLoad(LHS))
+ && LHS.hasOneUse())
+ return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
+
+ // else convert the first operand to mem.
+ LHS = ConvertToMemOperand (LHS, DAG);
return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
}
diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h
index 78571f46fbbb..011d91e4383b 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.h
+++ b/lib/Target/PIC16/PIC16ISelLowering.h
@@ -168,7 +168,7 @@ namespace llvm {
// Make PIC16 Libcall
SDValue MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT,
const SDValue *Ops, unsigned NumOps, bool isSigned,
- SelectionDAG &DAG);
+ SelectionDAG &DAG, DebugLoc dl);
// Check if operation has a direct load operand.
inline bool isDirectLoad(const SDValue Op);
diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td
index 077b50838e8b..31ceba37996c 100644
--- a/lib/Target/PIC16/PIC16InstrInfo.td
+++ b/lib/Target/PIC16/PIC16InstrInfo.td
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file describes the ARM instructions in TableGen format.
+// This file describes the PIC16 instructions in TableGen format.
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
index 8e2392e6f71a..d40f2065b828 100644
--- a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
+++ b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
@@ -22,8 +22,11 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
: TargetAsmInfo(TM) {
CommentString = ";";
Data8bitsDirective = " db ";
- Data16bitsDirective = " db ";
- Data32bitsDirective = " db ";
+ Data16bitsDirective = " dw ";
+ Data32bitsDirective = " dl ";
+ RomData8bitsDirective = " dw ";
+ RomData16bitsDirective = " rom_di ";
+ RomData32bitsDirective = " rom_dl ";
ZeroDirective = NULL;
AsciiDirective = " dt ";
AscizDirective = NULL;
@@ -33,3 +36,25 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable);
SwitchToSectionDirective = "";
}
+
+const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const
+{
+ if (size == 8)
+ return RomData8bitsDirective;
+ else if (size == 16)
+ return RomData16bitsDirective;
+ else if (size == 32)
+ return RomData32bitsDirective;
+ else
+ return NULL;
+}
+
+
+const char *PIC16TargetAsmInfo::getASDirective(unsigned size,
+ unsigned AS) const {
+ if (AS == PIC16ISD::ROM_SPACE)
+ return getRomDirective(size);
+ else
+ return NULL;
+}
+
diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.h b/lib/Target/PIC16/PIC16TargetAsmInfo.h
index 88de79f357eb..305e74d5a301 100644
--- a/lib/Target/PIC16/PIC16TargetAsmInfo.h
+++ b/lib/Target/PIC16/PIC16TargetAsmInfo.h
@@ -23,7 +23,12 @@ namespace llvm {
struct PIC16TargetAsmInfo : public TargetAsmInfo {
PIC16TargetAsmInfo(const PIC16TargetMachine &TM);
- public :
+ private:
+ const char *RomData8bitsDirective;
+ const char *RomData16bitsDirective;
+ const char *RomData32bitsDirective;
+ const char *getRomDirective(unsigned size) const;
+ virtual const char *getASDirective(unsigned size, unsigned AS) const;
};
} // namespace llvm
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index 362e8d19da6c..5f3ba931faf4 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -641,9 +641,9 @@ bool PPCLinuxAsmPrinter::doInitialization(Module &M) {
bool Result = AsmPrinter::doInitialization(M);
// Emit initial debug information.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
assert(MMI);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "DwarfWriter is not available");
DW->BeginModule(&M, MMI, O, this, TAI);
@@ -776,6 +776,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
+ case Function::PrivateLinkage:
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
@@ -858,9 +859,9 @@ bool PPCDarwinAsmPrinter::doInitialization(Module &M) {
// Emit initial debug information.
// We need this for Personality functions.
// AsmPrinter::doInitialization should have done this analysis.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
assert(MMI);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "DwarfWriter is not available");
DW->BeginModule(&M, MMI, O, this, TAI);
@@ -959,6 +960,7 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
O << "\t.globl " << name << '\n';
// FALL THROUGH
case GlobalValue::InternalLinkage:
+ case GlobalValue::PrivateLinkage:
break;
default:
cerr << "Unknown linkage type!";
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 67c253654677..1a192a101700 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1229,6 +1229,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) {
SDValue Trmp = Op.getOperand(1); // trampoline
SDValue FPtr = Op.getOperand(2); // nested function
SDValue Nest = Op.getOperand(3); // 'nest' parameter value
+ DebugLoc dl = Op.getNode()->getDebugLoc();
MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
bool isPPC64 = (PtrVT == MVT::i64);
@@ -1254,7 +1255,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) {
LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false,
false, false, CallingConv::C, false,
DAG.getExternalSymbol("__trampoline_setup", PtrVT),
- Args, DAG);
+ Args, DAG, dl);
SDValue Ops[] =
{ CallResult.first, CallResult.second };
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index b7e3ac282404..c5c9defd9dac 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -893,7 +893,8 @@ void PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const {
// If we are a leaf function, and use up to 224 bytes of stack space,
// don't have a frame pointer, calls, or dynamic alloca then we do not need
// to adjust the stack pointer (we fit in the Red Zone).
- if (FrameSize <= 224 && // Fits in red zone.
+ if (!DisableRedZone &&
+ FrameSize <= 224 && // Fits in red zone.
!MFI->hasVarSizedObjects() && // No dynamic alloca.
!MFI->hasCalls() && // No calls.
(!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment.
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index 756f38a64913..78dcb12581c6 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -1673,3 +1673,19 @@ while it could get this:
sarl $5, %eax
//===---------------------------------------------------------------------===//
+
+GCC PR31029:
+
+int test(int x) { return 1-x == x; } // --> return false
+int test2(int x) { return 2-x == x; } // --> return x == 1 ?
+
+Always foldable for odd constants, what is the rule for even?
+
+//===---------------------------------------------------------------------===//
+
+PR 3381: GEP to field of size 0 inside a struct could be turned into GEP
+for next field in struct (which is at same address).
+
+For example: store of float into { {{}}, float } could be turned into a store to
+the float directly.
+
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index b1031b46be6b..af5d6e526e27 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -77,7 +77,8 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) {
/// in FP registers for fastcc functions.
void
SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &ArgValues) {
+ SmallVectorImpl<SDValue> &ArgValues,
+ DebugLoc dl) {
MachineFunction &MF = DAG.getMachineFunction();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
diff --git a/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h
index a0e3c653441f..acd1b50dc894 100644
--- a/lib/Target/Sparc/SparcISelLowering.h
+++ b/lib/Target/Sparc/SparcISelLowering.h
@@ -58,7 +58,8 @@ namespace llvm {
unsigned Depth = 0) const;
virtual void LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &ArgValues);
+ SmallVectorImpl<SDValue> &ArgValues,
+ DebugLoc dl);
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB);
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp
index 532b8b9a5bbf..d687e2f44cfd 100644
--- a/lib/Target/TargetAsmInfo.cpp
+++ b/lib/Target/TargetAsmInfo.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
@@ -99,6 +100,7 @@ void TargetAsmInfo::fillDefaultValues() {
SupportsDebugInformation = false;
SupportsExceptionHandling = false;
DwarfRequiresFrameSection = true;
+ SupportsMacInfoSection = true;
NonLocalEHFrameLabel = false;
GlobalEHDirective = 0;
SupportsWeakOmittedEHFrame = true;
@@ -169,6 +171,25 @@ static bool isSuitableForBSS(const GlobalVariable *GV) {
return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
}
+static bool isConstantString(const Constant *C) {
+ // First check: is we have constant array of i8 terminated with zero
+ const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
+ // Check, if initializer is a null-terminated string
+ if (CVA && CVA->isCString())
+ return true;
+
+ // Another possibility: [1 x i8] zeroinitializer
+ if (isa<ConstantAggregateZero>(C)) {
+ if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType())) {
+ return (Ty->getElementType() == Type::Int8Ty &&
+ Ty->getNumElements() == 1);
+ }
+ }
+
+ return false;
+}
+
+
SectionKind::Kind
TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
// Early exit - functions should be always in text sections.
@@ -190,9 +211,8 @@ TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
if (C->ContainsRelocations())
return SectionKind::ROData;
else {
- const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
// Check, if initializer is a null-terminated string
- if (CVA && CVA->isCString())
+ if (isConstantString(C))
return SectionKind::RODataMergeStr;
else
return SectionKind::RODataMergeConst;
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp
index a1d6fa7eb975..49f1e4dfaae6 100644
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -40,6 +40,7 @@ namespace llvm {
bool VerboseAsm;
bool DisableJumpTables;
bool StrongPHIElim;
+ bool DisableRedZone;
}
static cl::opt<bool, true> PrintCode("print-machineinstrs",
@@ -164,6 +165,12 @@ EnableStrongPHIElim(cl::Hidden, "strong-phi-elim",
cl::location(StrongPHIElim),
cl::init(false));
+static cl::opt<bool, true>
+DisableRedZoneOption("disable-red-zone",
+ cl::desc("Do not emit code that uses the red zone."),
+ cl::location(DisableRedZone),
+ cl::init(false));
+
//---------------------------------------------------------------------------
// TargetMachine Class
//
diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
index df0b107f9d84..9e0afc8d6f23 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
@@ -709,6 +709,9 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
case 'q': // Print SImode register
// These only apply to registers, ignore on mem.
break;
+ case 'P': // Don't print @PLT, but do print as memory.
+ printOperand(MI, OpNo, "mem");
+ return false;
}
}
printMemReference(MI, OpNo);
@@ -734,8 +737,8 @@ bool X86ATTAsmPrinter::doInitialization(Module &M) {
// Let PassManager know we need debug information and relay
// the MachineModuleInfo address on to DwarfWriter.
// AsmPrinter::doInitialization did this analysis.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
- DW = getAnalysisToUpdate<DwarfWriter>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
DW->BeginModule(&M, MMI, O, this, TAI);
}
@@ -972,7 +975,7 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
}
// Emit final debug information.
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
DW->EndModule();
// Funny Darwin hack: This flag tells the linker that no global symbols
@@ -992,11 +995,11 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
}
// Emit final debug information.
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
DW->EndModule();
} else if (Subtarget->isTargetELF()) {
// Emit final debug information.
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
DW->EndModule();
}
diff --git a/lib/Target/X86/README-SSE.txt b/lib/Target/X86/README-SSE.txt
index 7110b3148715..bc51b5348243 100644
--- a/lib/Target/X86/README-SSE.txt
+++ b/lib/Target/X86/README-SSE.txt
@@ -907,3 +907,8 @@ We should be able to use:
cvtsi2ss 8($esp), %xmm0
since we know the stack slot is already zext'd.
+//===---------------------------------------------------------------------===//
+
+Consider using movlps instead of movsd to implement (scalar_to_vector (loadf64))
+when code size is critical. movlps is slower than movsd on core2 but it's one
+byte shorter.
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index 7a2f2570b34c..0e2c98097ed4 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -45,9 +45,11 @@ def Feature3DNow : SubtargetFeature<"3dnow", "X863DNowLevel", "ThreeDNow",
def Feature3DNowA : SubtargetFeature<"3dnowa", "X863DNowLevel", "ThreeDNowA",
"Enable 3DNow! Athlon instructions",
[Feature3DNow]>;
+// All x86-64 hardware has SSE2, but we don't mark SSE2 as an implied
+// feature, because SSE2 can be disabled (e.g. for compiling OS kernels)
+// without disabling 64-bit mode.
def Feature64Bit : SubtargetFeature<"64bit", "HasX86_64", "true",
- "Support 64-bit instructions",
- [FeatureSSE2]>;
+ "Support 64-bit instructions">;
def FeatureSlowBTMem : SubtargetFeature<"slow-bt-mem", "IsBTMemSlow", "true",
"Bit testing of memory is slow">;
@@ -70,7 +72,7 @@ def : Proc<"pentium2", [FeatureMMX]>;
def : Proc<"pentium3", [FeatureSSE1]>;
def : Proc<"pentium-m", [FeatureSSE2, FeatureSlowBTMem]>;
def : Proc<"pentium4", [FeatureSSE2]>;
-def : Proc<"x86-64", [Feature64Bit, FeatureSlowBTMem]>;
+def : Proc<"x86-64", [FeatureSSE2, Feature64Bit, FeatureSlowBTMem]>;
def : Proc<"yonah", [FeatureSSE3, FeatureSlowBTMem]>;
def : Proc<"prescott", [FeatureSSE3, FeatureSlowBTMem]>;
def : Proc<"nocona", [FeatureSSE3, Feature64Bit, FeatureSlowBTMem]>;
@@ -87,10 +89,14 @@ def : Proc<"athlon-tbird", [FeatureMMX, Feature3DNowA, FeatureSlowBTMem]>;
def : Proc<"athlon-4", [FeatureSSE1, Feature3DNowA, FeatureSlowBTMem]>;
def : Proc<"athlon-xp", [FeatureSSE1, Feature3DNowA, FeatureSlowBTMem]>;
def : Proc<"athlon-mp", [FeatureSSE1, Feature3DNowA, FeatureSlowBTMem]>;
-def : Proc<"k8", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>;
-def : Proc<"opteron", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>;
-def : Proc<"athlon64", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>;
-def : Proc<"athlon-fx", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>;
+def : Proc<"k8", [FeatureSSE2, Feature3DNowA, Feature64Bit,
+ FeatureSlowBTMem]>;
+def : Proc<"opteron", [FeatureSSE2, Feature3DNowA, Feature64Bit,
+ FeatureSlowBTMem]>;
+def : Proc<"athlon64", [FeatureSSE2, Feature3DNowA, Feature64Bit,
+ FeatureSlowBTMem]>;
+def : Proc<"athlon-fx", [FeatureSSE2, Feature3DNowA, Feature64Bit,
+ FeatureSlowBTMem]>;
def : Proc<"winchip-c6", [FeatureMMX]>;
def : Proc<"winchip2", [FeatureMMX, Feature3DNow]>;
diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td
index db92a0cdc02d..6742a90058a2 100644
--- a/lib/Target/X86/X86CallingConv.td
+++ b/lib/Target/X86/X86CallingConv.td
@@ -49,7 +49,7 @@ def RetCC_X86_32_C : CallingConv<[
// weirdly; this is really the sse-regparm calling convention) in which
// case they use XMM0, otherwise it is the same as the common X86 calling
// conv.
- CCIfInReg<CCIfSubtarget<"hasSSE2()",
+ CCIfInReg<CCIfSubtarget<"hasSSE2()",
CCIfType<[f32, f64], CCAssignToReg<[XMM0,XMM1,XMM2]>>>>,
CCIfType<[f32,f64], CCAssignToReg<[ST0, ST1]>>,
CCDelegateTo<RetCC_X86Common>
@@ -134,7 +134,8 @@ def CC_X86_64_C : CallingConv<[
// The first 8 FP/Vector arguments are passed in XMM registers.
CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
- CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>,
+ CCIfSubtarget<"hasSSE1()",
+ CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>,
// The first 8 MMX (except for v1i64) vector arguments are passed in XMM
// registers on Darwin.
@@ -223,7 +224,8 @@ def CC_X86_64_TailCall : CallingConv<[
// The first 8 FP/Vector arguments are passed in XMM registers.
CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
- CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>,
+ CCIfSubtarget<"hasSSE1()",
+ CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>,
// The first 8 MMX (except for v1i64) vector arguments are passed in XMM
// registers on Darwin.
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index f657d37d6adb..d85d2fbea3fc 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -1011,7 +1011,8 @@ bool X86FastISel::X86SelectTrunc(Instruction *I) {
BuildMI(MBB, TII.get(CopyOpc), CopyReg).addReg(InputReg);
// Then issue an extract_subreg.
- unsigned ResultReg = FastEmitInst_extractsubreg(CopyReg, X86::SUBREG_8BIT);
+ unsigned ResultReg = FastEmitInst_extractsubreg(DstVT.getSimpleVT(),
+ CopyReg, X86::SUBREG_8BIT);
if (!ResultReg)
return false;
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index c1d886c32f56..54b04ecabc69 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -242,40 +242,37 @@ namespace {
static SDNode *findFlagUse(SDNode *N) {
unsigned FlagResNo = N->getNumValues()-1;
for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
- SDNode *User = *I;
- for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
- SDValue Op = User->getOperand(i);
- if (Op.getNode() == N && Op.getResNo() == FlagResNo)
- return User;
- }
+ SDUse &Use = I.getUse();
+ if (Use.getResNo() == FlagResNo)
+ return Use.getUser();
}
return NULL;
}
-/// findNonImmUse - Return true by reference in "found" if "Use" is an
-/// non-immediate use of "Def". This function recursively traversing
-/// up the operand chain ignoring certain nodes.
-static void findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
- SDNode *Root, bool &found,
+/// findNonImmUse - Return true if "Use" is a non-immediate use of "Def".
+/// 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 (found ||
- Use->getNodeId() < Def->getNodeId() ||
+ if (Use->getNodeId() < Def->getNodeId() ||
!Visited.insert(Use))
- return;
-
- for (unsigned i = 0, e = Use->getNumOperands(); !found && i != e; ++i) {
+ return false;
+
+ for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {
SDNode *N = Use->getOperand(i).getNode();
if (N == Def) {
if (Use == ImmedUse || Use == Root)
continue; // We are not looking for immediate use.
assert(N != Root);
- found = true;
- break;
+ return true;
}
// Traverse up the operand chain.
- findNonImmUse(N, Def, ImmedUse, Root, found, Visited);
+ if (findNonImmUse(N, Def, ImmedUse, Root, Visited))
+ return true;
}
+ return false;
}
/// isNonImmUse - Start searching from Root up the DAG to check is Def can
@@ -290,9 +287,7 @@ static void findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
/// its chain operand.
static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) {
SmallPtrSet<SDNode*, 16> Visited;
- bool found = false;
- findNonImmUse(Root, Def, ImmedUse, Root, found, Visited);
- return found;
+ return findNonImmUse(Root, Def, ImmedUse, Root, Visited);
}
@@ -432,14 +427,27 @@ static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
/// MoveBelowCallSeqStart - Replace CALLSEQ_START operand with load's chain
/// operand and move load below the call's chain operand.
static void MoveBelowCallSeqStart(SelectionDAG *CurDAG, SDValue Load,
- SDValue Call, SDValue Chain) {
+ SDValue Call, SDValue CallSeqStart) {
SmallVector<SDValue, 8> Ops;
- for (unsigned i = 0, e = Chain.getNode()->getNumOperands(); i != e; ++i)
- if (Load.getNode() == Chain.getOperand(i).getNode())
- Ops.push_back(Load.getOperand(0));
- else
- Ops.push_back(Chain.getOperand(i));
- CurDAG->UpdateNodeOperands(Chain, &Ops[0], Ops.size());
+ SDValue Chain = CallSeqStart.getOperand(0);
+ if (Chain.getNode() == Load.getNode())
+ Ops.push_back(Load.getOperand(0));
+ else {
+ assert(Chain.getOpcode() == ISD::TokenFactor &&
+ "Unexpected CallSeqStart chain operand");
+ for (unsigned i = 0, e = Chain.getNumOperands(); i != e; ++i)
+ if (Chain.getOperand(i).getNode() == Load.getNode())
+ Ops.push_back(Load.getOperand(0));
+ else
+ Ops.push_back(Chain.getOperand(i));
+ SDValue NewChain =
+ CurDAG->getNode(ISD::TokenFactor, MVT::Other, &Ops[0], Ops.size());
+ Ops.clear();
+ Ops.push_back(NewChain);
+ }
+ for (unsigned i = 1, e = CallSeqStart.getNumOperands(); i != e; ++i)
+ Ops.push_back(CallSeqStart.getOperand(i));
+ CurDAG->UpdateNodeOperands(CallSeqStart, &Ops[0], Ops.size());
CurDAG->UpdateNodeOperands(Load, Call.getOperand(0),
Load.getOperand(1), Load.getOperand(2));
Ops.clear();
@@ -468,7 +476,13 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain) {
return false;
Chain = Chain.getOperand(0);
}
- return Chain.getOperand(0).getNode() == Callee.getNode();
+
+ if (Chain.getOperand(0).getNode() == Callee.getNode())
+ return true;
+ if (Chain.getOperand(0).getOpcode() == ISD::TokenFactor &&
+ Callee.getValue(1).isOperandOf(Chain.getOperand(0).getNode()))
+ return true;
+ return false;
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index c59e9cd77237..7a4d34d10a4d 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -806,6 +806,9 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setTargetDAGCombine(ISD::VECTOR_SHUFFLE);
setTargetDAGCombine(ISD::BUILD_VECTOR);
setTargetDAGCombine(ISD::SELECT);
+ setTargetDAGCombine(ISD::SHL);
+ setTargetDAGCombine(ISD::SRA);
+ setTargetDAGCombine(ISD::SRL);
setTargetDAGCombine(ISD::STORE);
computeRegisterProperties();
@@ -1028,6 +1031,7 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall,
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
bool isVarArg = TheCall->isVarArg();
+ bool Is64Bit = Subtarget->is64Bit();
CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs);
CCInfo.AnalyzeCallResult(TheCall, RetCC_X86);
@@ -1036,7 +1040,14 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall,
// Copy all of the result registers out of their specified physreg.
for (unsigned i = 0; i != RVLocs.size(); ++i) {
MVT CopyVT = RVLocs[i].getValVT();
-
+
+ // If this is x86-64, and we disabled SSE, we can't return FP values
+ if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
+ ((Is64Bit || TheCall->isInreg()) && !Subtarget->hasSSE1())) {
+ cerr << "SSE register return with SSE disabled\n";
+ exit(1);
+ }
+
// If this is a call to a function that returns an fp value on the floating
// point stack, but where we prefer to use the value in xmm registers, copy
// it out as F80 and use a truncate to move it from fp stack reg to xmm reg.
@@ -1379,6 +1390,13 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs,
TotalNumXMMRegs);
+ assert((Subtarget->hasSSE1() || !NumXMMRegs) &&
+ "SSE register cannot be used when SSE is disabled!");
+ if (!Subtarget->hasSSE1()) {
+ // Kernel mode asks for SSE to be disabled, so don't push them
+ // on the stack.
+ TotalNumXMMRegs = 0;
+ }
// For X86-64, if there are vararg parameters that are passed via
// registers, then we must store them to their spots on the stack so they
// may be loaded by deferencing the result of va_next.
@@ -1672,6 +1690,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
};
unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8);
+ assert((Subtarget->hasSSE1() || !NumXMMRegs)
+ && "SSE registers cannot be used when SSE is disabled");
Chain = DAG.getCopyToReg(Chain, X86::AL,
DAG.getConstant(NumXMMRegs, MVT::i8), InFlag);
@@ -2157,7 +2177,8 @@ bool X86::isPSHUFLWMask(SDNode *N) {
/// isSHUFPMask - Return true if the specified VECTOR_SHUFFLE operand
/// specifies a shuffle of elements that is suitable for input to SHUFP*.
-static bool isSHUFPMask(SDOperandPtr Elems, unsigned NumElems) {
+template<class SDOperand>
+static bool isSHUFPMask(SDOperand *Elems, unsigned NumElems) {
if (NumElems != 2 && NumElems != 4) return false;
unsigned Half = NumElems / 2;
@@ -2180,7 +2201,8 @@ bool X86::isSHUFPMask(SDNode *N) {
/// the reverse of what x86 shuffles want. x86 shuffles requires the lower
/// half elements to come from vector 1 (which would equal the dest.) and
/// the upper half to come from vector 2.
-static bool isCommutedSHUFP(SDOperandPtr Ops, unsigned NumOps) {
+template<class SDOperand>
+static bool isCommutedSHUFP(SDOperand *Ops, unsigned NumOps) {
if (NumOps != 2 && NumOps != 4) return false;
unsigned Half = NumOps / 2;
@@ -2274,7 +2296,8 @@ bool X86::isMOVHPMask(SDNode *N) {
/// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand
/// specifies a shuffle of elements that is suitable for input to UNPCKL.
-bool static isUNPCKLMask(SDOperandPtr Elts, unsigned NumElts,
+template<class SDOperand>
+bool static isUNPCKLMask(SDOperand *Elts, unsigned NumElts,
bool V2IsSplat = false) {
if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16)
return false;
@@ -2303,7 +2326,8 @@ bool X86::isUNPCKLMask(SDNode *N, bool V2IsSplat) {
/// isUNPCKHMask - Return true if the specified VECTOR_SHUFFLE operand
/// specifies a shuffle of elements that is suitable for input to UNPCKH.
-bool static isUNPCKHMask(SDOperandPtr Elts, unsigned NumElts,
+template<class SDOperand>
+bool static isUNPCKHMask(SDOperand *Elts, unsigned NumElts,
bool V2IsSplat = false) {
if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16)
return false;
@@ -2379,7 +2403,8 @@ bool X86::isUNPCKH_v_undef_Mask(SDNode *N) {
/// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand
/// specifies a shuffle of elements that is suitable for input to MOVSS,
/// MOVSD, and MOVD, i.e. setting the lowest element.
-static bool isMOVLMask(SDOperandPtr Elts, unsigned NumElts) {
+template<class SDOperand>
+static bool isMOVLMask(SDOperand *Elts, unsigned NumElts) {
if (NumElts != 2 && NumElts != 4)
return false;
@@ -2402,7 +2427,8 @@ bool X86::isMOVLMask(SDNode *N) {
/// isCommutedMOVL - Returns true if the shuffle mask is except the reverse
/// of what x86 movss want. X86 movs requires the lowest element to be lowest
/// element of vector 2 and the other elements to come from vector 1 in order.
-static bool isCommutedMOVL(SDOperandPtr Ops, unsigned NumOps,
+template<class SDOperand>
+static bool isCommutedMOVL(SDOperand *Ops, unsigned NumOps,
bool V2IsSplat = false,
bool V2IsUndef = false) {
if (NumOps != 2 && NumOps != 4 && NumOps != 8 && NumOps != 16)
@@ -3668,7 +3694,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
++V2InOrder;
} else if (EltIdx < 8) {
V1Elts.push_back(Elt);
- V2Elts.push_back(DAG.getConstant(i+8, MaskEVT));
+ V2Elts.push_back(DAG.getConstant(EltIdx+8, MaskEVT));
++V1FromV1;
} else {
V1Elts.push_back(Elt);
@@ -5105,22 +5131,39 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
SDValue Op1 = Op.getOperand(1);
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
- // Lower (X & (1 << N)) == 0 to BT.
- // Lower ((X >>u N) & 1) != 0 to BT.
- // Lower ((X >>s N) & 1) != 0 to BT.
+ // Lower (X & (1 << N)) == 0 to BT(X, N).
+ // Lower ((X >>u N) & 1) != 0 to BT(X, N).
+ // Lower ((X >>s N) & 1) != 0 to BT(X, N).
if (Op0.getOpcode() == ISD::AND &&
Op0.hasOneUse() &&
Op1.getOpcode() == ISD::Constant &&
- Op0.getOperand(1).getOpcode() == ISD::Constant &&
+ cast<ConstantSDNode>(Op1)->getZExtValue() == 0 &&
(CC == ISD::SETEQ || CC == ISD::SETNE)) {
- ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
- ConstantSDNode *CmpRHS = cast<ConstantSDNode>(Op1);
- SDValue AndLHS = Op0.getOperand(0);
- if (CmpRHS->getZExtValue() == 0 && AndRHS->getZExtValue() == 1 &&
- AndLHS.getOpcode() == ISD::SRL) {
- SDValue LHS = AndLHS.getOperand(0);
- SDValue RHS = AndLHS.getOperand(1);
+ 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);
+ }
+ } 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.getOperand(1).getOpcode() == ISD::Constant) {
+ ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
+ SDValue AndLHS = Op0.getOperand(0);
+ if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
+ LHS = AndLHS.getOperand(0);
+ RHS = AndLHS.getOperand(1);
+ }
+ }
+ if (LHS.getNode()) {
// If LHS is i8, promote it to i16 with any_extend. There is no i8 BT
// instruction. Since the shift amount is in-range-or-undefined, we know
// that doing a bittest on the i16 value is ok. We extend to i32 because
@@ -5132,10 +5175,10 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
// BT ignores high bits (like shifts) we can use anyextend.
if (LHS.getValueType() != RHS.getValueType())
RHS = DAG.getNode(ISD::ANY_EXTEND, LHS.getValueType(), RHS);
-
+
SDValue BT = DAG.getNode(X86ISD::BT, MVT::i32, LHS, RHS);
unsigned Cond = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B;
- return DAG.getNode(X86ISD::SETCC, MVT::i8,
+ return DAG.getNode(X86ISD::SETCC, MVT::i8,
DAG.getConstant(Cond, MVT::i8), BT);
}
}
@@ -5242,7 +5285,8 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) {
// bits of the inputs before performing those operations.
if (FlipSigns) {
MVT EltVT = VT.getVectorElementType();
- SDValue SignBit = DAG.getConstant(EltVT.getIntegerVTSignBit(), EltVT);
+ SDValue SignBit = DAG.getConstant(APInt::getSignBit(EltVT.getSizeInBits()),
+ EltVT);
std::vector<SDValue> SignBits(VT.getVectorNumElements(), SignBit);
SDValue SignVec = DAG.getNode(ISD::BUILD_VECTOR, VT, &SignBits[0],
SignBits.size());
@@ -5253,14 +5297,9 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) {
SDValue Result = DAG.getNode(Opc, VT, Op0, Op1);
// If the logical-not of the result is required, perform that now.
- if (Invert) {
- MVT EltVT = VT.getVectorElementType();
- SDValue NegOne = DAG.getConstant(EltVT.getIntegerVTBitMask(), EltVT);
- std::vector<SDValue> NegOnes(VT.getVectorNumElements(), NegOne);
- SDValue NegOneV = DAG.getNode(ISD::BUILD_VECTOR, VT, &NegOnes[0],
- NegOnes.size());
- Result = DAG.getNode(ISD::XOR, VT, Result, NegOneV);
- }
+ if (Invert)
+ Result = DAG.getNOT(Op.getDebugLoc(), Result, VT);
+
return Result;
}
@@ -5291,7 +5330,7 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
!isScalarFPTypeInSSEReg(VT)) // FPStack?
IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSExtValue());
- if (isX86LogicalCmp(Opc) && !IllegalFPCMov) {
+ if ((isX86LogicalCmp(Opc) && !IllegalFPCMov) || Opc == X86ISD::BT) { // FIXME
Cond = Cmp;
addTest = false;
}
@@ -5327,6 +5366,19 @@ static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc) {
Op.getOperand(1).hasOneUse());
}
+// isXor1OfSetCC - Return true if node is an ISD::XOR of a X86ISD::SETCC and
+// 1 and that the SETCC node has a single use.
+static bool isXor1OfSetCC(SDValue Op) {
+ if (Op.getOpcode() != ISD::XOR)
+ return false;
+ ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+ if (N1C && N1C->getAPIntValue() == 1) {
+ return Op.getOperand(0).getOpcode() == X86ISD::SETCC &&
+ Op.getOperand(0).hasOneUse();
+ }
+ return false;
+}
+
SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
bool addTest = true;
SDValue Chain = Op.getOperand(0);
@@ -5421,6 +5473,16 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
}
}
}
+ } else if (Cond.hasOneUse() && isXor1OfSetCC(Cond)) {
+ // Recognize for xorb (setcc), 1 patterns. The xor inverts the condition.
+ // It should be transformed during dag combiner except when the condition
+ // is set by a arithmetics with overflow node.
+ X86::CondCode CCode =
+ (X86::CondCode)Cond.getOperand(0).getConstantOperandVal(0);
+ CCode = X86::GetOppositeBranchCondition(CCode);
+ CC = DAG.getConstant(CCode, MVT::i8);
+ Cond = Cond.getOperand(0).getOperand(1);
+ addTest = false;
}
}
@@ -5511,10 +5573,12 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
Args.push_back(Entry);
Entry.Node = Size;
Args.push_back(Entry);
+ // FIXME provide DebugLoc info
std::pair<SDValue,SDValue> CallResult =
LowerCallTo(Chain, Type::VoidTy, false, false, false, false,
CallingConv::C, false,
- DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG);
+ DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG,
+ DebugLoc::getUnknownLoc());
return CallResult.second;
}
@@ -7451,6 +7515,14 @@ void X86TargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); // Don't know anything.
switch (Opc) {
default: break;
+ case X86ISD::ADD:
+ case X86ISD::SUB:
+ case X86ISD::SMUL:
+ case X86ISD::UMUL:
+ // These nodes' second result is a boolean.
+ if (Op.getResNo() == 0)
+ break;
+ // Fallthrough
case X86ISD::SETCC:
KnownZero |= APInt::getHighBitsSet(Mask.getBitWidth(),
Mask.getBitWidth() - 1);
@@ -7543,6 +7615,7 @@ static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
/// PerformBuildVectorCombine - build_vector 0,(load i64 / f64) -> movq / movsd.
static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget *Subtarget,
const TargetLowering &TLI) {
unsigned NumOps = N->getNumOperands();
@@ -7579,11 +7652,17 @@ static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
// Load must not be an extload.
if (LD->getExtensionType() != ISD::NON_EXTLOAD)
return SDValue();
-
+
+ // Load type should legal type so we don't have to legalize it.
+ if (!TLI.isTypeLegal(VT))
+ return SDValue();
+
SDVTList Tys = DAG.getVTList(VT, MVT::Other);
SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
SDValue ResNode = DAG.getNode(X86ISD::VZEXT_LOAD, Tys, Ops, 2);
- DAG.ReplaceAllUsesOfValueWith(SDValue(Base, 1), ResNode.getValue(1));
+ TargetLowering::TargetLoweringOpt TLO(DAG);
+ TLO.CombineTo(SDValue(Base, 1), ResNode.getValue(1));
+ DCI.CommitTargetLoweringOpt(TLO);
return ResNode;
}
@@ -7659,6 +7738,100 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+/// PerformShiftCombine - Transforms vector shift nodes to use vector shifts
+/// when possible.
+static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG,
+ const X86Subtarget *Subtarget) {
+ // On X86 with SSE2 support, we can transform this to a vector shift if
+ // all elements are shifted by the same amount. We can't do this in legalize
+ // because the a constant vector is typically transformed to a constant pool
+ // so we have no knowledge of the shift amount.
+ if (!Subtarget->hasSSE2())
+ return SDValue();
+
+ MVT VT = N->getValueType(0);
+ if (VT != MVT::v2i64 && VT != MVT::v4i32 && VT != MVT::v8i16)
+ return SDValue();
+
+ SDValue ShAmtOp = N->getOperand(1);
+ MVT EltVT = VT.getVectorElementType();
+ SDValue BaseShAmt;
+ if (ShAmtOp.getOpcode() == ISD::BUILD_VECTOR) {
+ unsigned NumElts = VT.getVectorNumElements();
+ unsigned i = 0;
+ for (; i != NumElts; ++i) {
+ SDValue Arg = ShAmtOp.getOperand(i);
+ if (Arg.getOpcode() == ISD::UNDEF) continue;
+ BaseShAmt = Arg;
+ break;
+ }
+ for (; i != NumElts; ++i) {
+ SDValue Arg = ShAmtOp.getOperand(i);
+ if (Arg.getOpcode() == ISD::UNDEF) continue;
+ if (Arg != BaseShAmt) {
+ return SDValue();
+ }
+ }
+ } else if (ShAmtOp.getOpcode() == ISD::VECTOR_SHUFFLE &&
+ isSplatMask(ShAmtOp.getOperand(2).getNode())) {
+ BaseShAmt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, ShAmtOp,
+ DAG.getIntPtrConstant(0));
+ } else
+ return SDValue();
+
+ if (EltVT.bitsGT(MVT::i32))
+ BaseShAmt = DAG.getNode(ISD::TRUNCATE, MVT::i32, BaseShAmt);
+ else if (EltVT.bitsLT(MVT::i32))
+ BaseShAmt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, BaseShAmt);
+
+ // The shift amount is identical so we can do a vector shift.
+ SDValue ValOp = N->getOperand(0);
+ switch (N->getOpcode()) {
+ default:
+ assert(0 && "Unknown shift opcode!");
+ break;
+ case ISD::SHL:
+ if (VT == MVT::v2i64)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_pslli_q, MVT::i32),
+ ValOp, BaseShAmt);
+ if (VT == MVT::v4i32)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_pslli_d, MVT::i32),
+ ValOp, BaseShAmt);
+ if (VT == MVT::v8i16)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_pslli_w, MVT::i32),
+ ValOp, BaseShAmt);
+ break;
+ case ISD::SRA:
+ if (VT == MVT::v4i32)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_psrai_d, MVT::i32),
+ ValOp, BaseShAmt);
+ if (VT == MVT::v8i16)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_psrai_w, MVT::i32),
+ ValOp, BaseShAmt);
+ break;
+ case ISD::SRL:
+ if (VT == MVT::v2i64)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_psrli_q, MVT::i32),
+ ValOp, BaseShAmt);
+ if (VT == MVT::v4i32)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_psrli_d, MVT::i32),
+ ValOp, BaseShAmt);
+ if (VT == MVT::v8i16)
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+ DAG.getConstant(Intrinsic::x86_sse2_psrli_w, MVT::i32),
+ ValOp, BaseShAmt);
+ break;
+ }
+ return SDValue();
+}
+
/// PerformSTORECombine - Do target-specific dag combines on STORE nodes.
static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
const X86Subtarget *Subtarget) {
@@ -7777,6 +7950,23 @@ static SDValue PerformFANDCombine(SDNode *N, SelectionDAG &DAG) {
return SDValue();
}
+static SDValue PerformBTCombine(SDNode *N,
+ SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ // BT ignores high bits in the bit index operand.
+ SDValue Op1 = N->getOperand(1);
+ if (Op1.hasOneUse()) {
+ unsigned BitWidth = Op1.getValueSizeInBits();
+ APInt DemandedMask = APInt::getLowBitsSet(BitWidth, Log2_32(BitWidth));
+ APInt KnownZero, KnownOne;
+ TargetLowering::TargetLoweringOpt TLO(DAG);
+ TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (TLO.ShrinkDemandedConstant(Op1, DemandedMask) ||
+ TLI.SimplifyDemandedBits(Op1, DemandedMask, KnownZero, KnownOne, TLO))
+ DCI.CommitTargetLoweringOpt(TLO);
+ }
+ return SDValue();
+}
SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
@@ -7785,12 +7975,16 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
default: break;
case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, *this);
case ISD::BUILD_VECTOR:
- return PerformBuildVectorCombine(N, DAG, Subtarget, *this);
+ return PerformBuildVectorCombine(N, DAG, DCI, Subtarget, *this);
case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget);
+ case ISD::SHL:
+ case ISD::SRA:
+ case ISD::SRL: return PerformShiftCombine(N, DAG, Subtarget);
case ISD::STORE: return PerformSTORECombine(N, DAG, Subtarget);
case X86ISD::FXOR:
case X86ISD::FOR: return PerformFORCombine(N, DAG);
case X86ISD::FAND: return PerformFANDCombine(N, DAG);
+ case X86ISD::BT: return PerformBTCombine(N, DAG, DCI);
}
return SDValue();
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 558b119954be..c8dc30a4f9cb 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -185,7 +185,7 @@ namespace llvm {
/// in order to obtain suitable precision.
FRSQRT, FRCP,
- // TLSADDR, THREAThread - Thread Local Storage.
+ // TLSADDR, THREAD_POINTER - Thread Local Storage.
TLSADDR, THREAD_POINTER,
// EH_RETURN - Exception Handling helpers.
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 123062c6d059..774da61ba941 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -1242,6 +1242,11 @@ def TLS_addr64 : I<0, Pseudo, (outs GR64:$dst), (ins i64imm:$sym),
".byte\t0x66; leaq\t${sym:mem}(%rip), $dst; .word\t0x6666; rex64",
[(set GR64:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
+let AddedComplexity = 5 in
+def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
+ "movq\t%gs:$src, $dst",
+ [(set GR64:$dst, (gsload addr:$src))]>, SegGS;
+
//===----------------------------------------------------------------------===//
// Atomic Instructions
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 188d40208762..21a11e3808b7 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -1938,9 +1938,11 @@ bool X86InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
static MachineInstr *FuseTwoAddrInst(MachineFunction &MF, unsigned Opcode,
const SmallVectorImpl<MachineOperand> &MOs,
- MachineInstr *MI, const TargetInstrInfo &TII) {
+ MachineInstr *MI,
+ const TargetInstrInfo &TII) {
// Create the base instruction with the memory operand as the first part.
- MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), true);
+ MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode),
+ MI->getDebugLoc(), true);
MachineInstrBuilder MIB(NewMI);
unsigned NumAddrOps = MOs.size();
for (unsigned i = 0; i != NumAddrOps; ++i)
@@ -1965,7 +1967,8 @@ static MachineInstr *FuseInst(MachineFunction &MF,
unsigned Opcode, unsigned OpNo,
const SmallVectorImpl<MachineOperand> &MOs,
MachineInstr *MI, const TargetInstrInfo &TII) {
- MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), true);
+ MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode),
+ MI->getDebugLoc(), true);
MachineInstrBuilder MIB(NewMI);
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
@@ -2298,7 +2301,7 @@ bool X86InstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
}
// Emit the data processing instruction.
- MachineInstr *DataMI = MF.CreateMachineInstr(TID, true);
+ MachineInstr *DataMI = MF.CreateMachineInstr(TID, MI->getDebugLoc(), true);
MachineInstrBuilder MIB(DataMI);
if (FoldedStore)
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index fbe03299e07a..f4a57be007e1 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -308,6 +308,16 @@ def nvloadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
return false;
}]>;
+def gsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+ LoadSDNode *LD = cast<LoadSDNode>(N);
+ const Value *Src = LD->getSrcValue();
+ if (!Src)
+ return false;
+ if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
+ return PT->getAddressSpace() == 256;
+ return false;
+}]>;
+
def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
@@ -2852,6 +2862,11 @@ def TLS_tp : I<0x8B, Pseudo, (outs GR32:$dst), (ins),
"movl\t%gs:0, $dst",
[(set GR32:$dst, X86TLStp)]>, SegGS;
+let AddedComplexity = 5 in
+def GS_MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
+ "movl\t%gs:$src, $dst",
+ [(set GR32:$dst, (gsload addr:$src))]>, SegGS;
+
//===----------------------------------------------------------------------===//
// DWARF Pseudo Instructions
//
@@ -3597,6 +3612,17 @@ def : Pat<(parallel (X86smul_ovf (load addr:$src1), i32immSExt8:$src2),
(implicit EFLAGS)),
(IMUL32rmi8 addr:$src1, i32immSExt8:$src2)>;
+// Optimize multiple with overflow by 2.
+let AddedComplexity = 2 in {
+def : Pat<(parallel (X86smul_ovf GR16:$src1, 2),
+ (implicit EFLAGS)),
+ (ADD16rr GR16:$src1, GR16:$src1)>;
+
+def : Pat<(parallel (X86smul_ovf GR32:$src1, 2),
+ (implicit EFLAGS)),
+ (ADD32rr GR32:$src1, GR32:$src1)>;
+}
+
//===----------------------------------------------------------------------===//
// Floating Point Stack Support
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index b7a959a78332..4fc1044cba96 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -3019,62 +3019,60 @@ def : Pat<(v4i32 (vector_shuffle VR128:$src1, (undef),
let AddedComplexity = 20 in {
// vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
// vector_shuffle v1, (load v2) <0, 1, 4, 5> using MOVHPS
-def : Pat<(v4f32 (vector_shuffle VR128:$src1, (memop addr:$src2),
+def : Pat<(v4f32 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVLP_shuffle_mask)),
(MOVLPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE1]>;
-def : Pat<(v2f64 (vector_shuffle VR128:$src1, (memop addr:$src2),
+def : Pat<(v2f64 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVLP_shuffle_mask)),
(MOVLPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
-def : Pat<(v4f32 (vector_shuffle VR128:$src1, (memop addr:$src2),
+def : Pat<(v4f32 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVHP_shuffle_mask)),
(MOVHPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE1]>;
-def : Pat<(v2f64 (vector_shuffle VR128:$src1, (memop addr:$src2),
+def : Pat<(v2f64 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVHP_shuffle_mask)),
(MOVHPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
-def : Pat<(v4i32 (vector_shuffle VR128:$src1,
- (bc_v4i32 (memopv2i64 addr:$src2)),
+def : Pat<(v4i32 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVLP_shuffle_mask)),
(MOVLPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
-def : Pat<(v2i64 (vector_shuffle VR128:$src1, (memop addr:$src2),
+def : Pat<(v2i64 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVLP_shuffle_mask)),
(MOVLPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
-def : Pat<(v4i32 (vector_shuffle VR128:$src1,
- (bc_v4i32 (memopv2i64 addr:$src2)),
+def : Pat<(v4i32 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVHP_shuffle_mask)),
(MOVHPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE1]>;
-def : Pat<(v2i64 (vector_shuffle VR128:$src1, (memop addr:$src2),
+def : Pat<(v2i64 (vector_shuffle VR128:$src1, (load addr:$src2),
MOVHP_shuffle_mask)),
(MOVHPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
}
// (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
// (store (vector_shuffle (load addr), v2, <0, 1, 4, 5>), addr) using MOVHPS
-def : Pat<(store (v4f32 (vector_shuffle (memop addr:$src1), VR128:$src2,
+def : Pat<(store (v4f32 (vector_shuffle (load addr:$src1), VR128:$src2,
MOVLP_shuffle_mask)), addr:$src1),
(MOVLPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
-def : Pat<(store (v2f64 (vector_shuffle (memop addr:$src1), VR128:$src2,
+def : Pat<(store (v2f64 (vector_shuffle (load addr:$src1), VR128:$src2,
MOVLP_shuffle_mask)), addr:$src1),
(MOVLPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
-def : Pat<(store (v4f32 (vector_shuffle (memop addr:$src1), VR128:$src2,
+def : Pat<(store (v4f32 (vector_shuffle (load addr:$src1), VR128:$src2,
MOVHP_shuffle_mask)), addr:$src1),
(MOVHPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
-def : Pat<(store (v2f64 (vector_shuffle (memop addr:$src1), VR128:$src2,
+def : Pat<(store (v2f64 (vector_shuffle (load addr:$src1), VR128:$src2,
MOVHP_shuffle_mask)), addr:$src1),
(MOVHPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
def : Pat<(store (v4i32 (vector_shuffle
- (bc_v4i32 (memopv2i64 addr:$src1)), VR128:$src2,
+ (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2,
MOVLP_shuffle_mask)), addr:$src1),
(MOVLPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
-def : Pat<(store (v2i64 (vector_shuffle (memop addr:$src1), VR128:$src2,
+def : Pat<(store (v2i64 (vector_shuffle (load addr:$src1), VR128:$src2,
MOVLP_shuffle_mask)), addr:$src1),
(MOVLPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
def : Pat<(store (v4i32 (vector_shuffle
- (bc_v4i32 (memopv2i64 addr:$src1)), VR128:$src2,
+ (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2,
MOVHP_shuffle_mask)), addr:$src1),
(MOVHPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
-def : Pat<(store (v2i64 (vector_shuffle (memop addr:$src1), VR128:$src2,
+def : Pat<(store (v2i64 (vector_shuffle (load addr:$src1), VR128:$src2,
MOVHP_shuffle_mask)), addr:$src1),
(MOVHPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index a0d8b58b789c..73cab622b668 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -727,6 +727,21 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
X86FI->setCalleeSavedFrameSize(
X86FI->getCalleeSavedFrameSize() +(-TailCallReturnAddrDelta));
+ // If this is x86-64 and the Red Zone is not disabled, if we are a leaf
+ // function, and use up to 128 bytes of stack space, don't have a frame
+ // pointer, calls, or dynamic alloca then we do not need to adjust the
+ // stack pointer (we fit in the Red Zone).
+ if (Is64Bit && !DisableRedZone &&
+ !needsStackRealignment(MF) &&
+ !MFI->hasVarSizedObjects() && // No dynamic alloca.
+ !MFI->hasCalls()) { // No calls.
+ uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
+ if (hasFP(MF)) MinSize += SlotSize;
+ StackSize = std::max(MinSize,
+ StackSize > 128 ? StackSize - 128 : 0);
+ MFI->setStackSize(StackSize);
+ }
+
// Insert stack pointer adjustment for later moving of return addr. Only
// applies to tail call optimized functions where the callee argument stack
// size is bigger than the callers.
diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td
index b67b1bb2f3fa..7303e8a40d4e 100644
--- a/lib/Target/X86/X86RegisterInfo.td
+++ b/lib/Target/X86/X86RegisterInfo.td
@@ -237,20 +237,23 @@ def GR8 : RegisterClass<"X86", [i8], 8,
iterator allocation_order_end(const MachineFunction &MF) const;
}];
let MethodBodies = [{
- // Does the function dedicate RBP / EBP to being a frame ptr?
- // If so, don't allocate SPL or BPL.
- static const unsigned X86_GR8_AO_64_fp[] =
- {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL,
- X86::R8B, X86::R9B, X86::R10B, X86::R11B,
- X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B};
- // If not, just don't allocate SPL.
- static const unsigned X86_GR8_AO_64[] =
- {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL,
- X86::R8B, X86::R9B, X86::R10B, X86::R11B,
- X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B, X86::BPL};
- // In 32-mode, none of the 8-bit registers aliases EBP or ESP.
- static const unsigned X86_GR8_AO_32[] =
- {X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, X86::BL, X86::BH};
+ // Does the function dedicate RBP / EBP to being a frame ptr?
+ // If so, don't allocate SPL or BPL.
+ static const unsigned X86_GR8_AO_64_fp[] = {
+ X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL,
+ X86::R8B, X86::R9B, X86::R10B, X86::R11B,
+ X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B
+ };
+ // If not, just don't allocate SPL.
+ static const unsigned X86_GR8_AO_64[] = {
+ X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL,
+ X86::R8B, X86::R9B, X86::R10B, X86::R11B,
+ X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B, X86::BPL
+ };
+ // In 32-mode, none of the 8-bit registers aliases EBP or ESP.
+ static const unsigned X86_GR8_AO_32[] = {
+ X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, X86::BL, X86::BH
+ };
GR8Class::iterator
GR8Class::allocation_order_begin(const MachineFunction &MF) const {
@@ -290,21 +293,25 @@ def GR16 : RegisterClass<"X86", [i16], 16,
iterator allocation_order_end(const MachineFunction &MF) const;
}];
let MethodBodies = [{
- // Does the function dedicate RBP / EBP to being a frame ptr?
- // If so, don't allocate SP or BP.
- static const unsigned X86_GR16_AO_64_fp[] =
- {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI,
- X86::R8W, X86::R9W, X86::R10W, X86::R11W,
- X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W};
- static const unsigned X86_GR16_AO_32_fp[] =
- {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX};
- // If not, just don't allocate SPL.
- static const unsigned X86_GR16_AO_64[] =
- {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI,
- X86::R8W, X86::R9W, X86::R10W, X86::R11W,
- X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W, X86::BP};
- static const unsigned X86_GR16_AO_32[] =
- {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, X86::BP};
+ // Does the function dedicate RBP / EBP to being a frame ptr?
+ // If so, don't allocate SP or BP.
+ static const unsigned X86_GR16_AO_64_fp[] = {
+ X86::AX, X86::CX, X86::DX, X86::SI, X86::DI,
+ X86::R8W, X86::R9W, X86::R10W, X86::R11W,
+ X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W
+ };
+ static const unsigned X86_GR16_AO_32_fp[] = {
+ X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX
+ };
+ // If not, just don't allocate SPL.
+ static const unsigned X86_GR16_AO_64[] = {
+ X86::AX, X86::CX, X86::DX, X86::SI, X86::DI,
+ X86::R8W, X86::R9W, X86::R10W, X86::R11W,
+ X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W, X86::BP
+ };
+ static const unsigned X86_GR16_AO_32[] = {
+ X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, X86::BP
+ };
GR16Class::iterator
GR16Class::allocation_order_begin(const MachineFunction &MF) const {
@@ -354,21 +361,25 @@ def GR32 : RegisterClass<"X86", [i32], 32,
iterator allocation_order_end(const MachineFunction &MF) const;
}];
let MethodBodies = [{
- // Does the function dedicate RBP / EBP to being a frame ptr?
- // If so, don't allocate ESP or EBP.
- static const unsigned X86_GR32_AO_64_fp[] =
- {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI,
- X86::R8D, X86::R9D, X86::R10D, X86::R11D,
- X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D};
- static const unsigned X86_GR32_AO_32_fp[] =
- {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX};
- // If not, just don't allocate SPL.
- static const unsigned X86_GR32_AO_64[] =
- {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI,
- X86::R8D, X86::R9D, X86::R10D, X86::R11D,
- X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, X86::EBP};
- static const unsigned X86_GR32_AO_32[] =
- {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP};
+ // Does the function dedicate RBP / EBP to being a frame ptr?
+ // If so, don't allocate ESP or EBP.
+ static const unsigned X86_GR32_AO_64_fp[] = {
+ X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI,
+ X86::R8D, X86::R9D, X86::R10D, X86::R11D,
+ X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D
+ };
+ static const unsigned X86_GR32_AO_32_fp[] = {
+ X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX
+ };
+ // If not, just don't allocate SPL.
+ static const unsigned X86_GR32_AO_64[] = {
+ X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI,
+ X86::R8D, X86::R9D, X86::R10D, X86::R11D,
+ X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, X86::EBP
+ };
+ static const unsigned X86_GR32_AO_32[] = {
+ X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP
+ };
GR32Class::iterator
GR32Class::allocation_order_begin(const MachineFunction &MF) const {
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index 5dc5103727d5..5ceafa4c593d 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -322,21 +322,25 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit)
// If feature string is not empty, parse features string.
std::string CPU = GetCurrentX86CPU();
ParseSubtargetFeatures(FS, CPU);
+ // All X86-64 CPUs also have SSE2, however user might request no SSE via
+ // -mattr, so don't force SSELevel here.
} else {
// Otherwise, use CPUID to auto-detect feature set.
AutoDetectSubtargetFeatures();
- }
-
- // If requesting codegen for X86-64, make sure that 64-bit and SSE2 features
- // are enabled. These are available on all x86-64 CPUs.
- if (Is64Bit) {
- HasX86_64 = true;
- if (X86SSELevel < SSE2)
+ // If requesting codegen for X86-64, make sure that 64-bit features
+ // are enabled.
+ if (Is64Bit)
+ HasX86_64 = true;
+ // Make sure SSE2 is enabled; it is available on all X86-64 CPUs.
+ if (Is64Bit && X86SSELevel < SSE2)
X86SSELevel = SSE2;
}
+
DOUT << "Subtarget features: SSELevel " << X86SSELevel
<< ", 3DNowLevel " << X863DNowLevel
<< ", 64bit " << HasX86_64 << "\n";
+ assert((!Is64Bit || HasX86_64) &&
+ "64-bit code requested on a subtarget that doesn't support it!");
// Set the boolean corresponding to the current target triple, or the default
// if one cannot be determined, to true.
diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp
index f966d8564d27..9e6e19fe44fd 100644
--- a/lib/Target/XCore/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/XCoreAsmPrinter.cpp
@@ -441,9 +441,9 @@ bool XCoreAsmPrinter::doInitialization(Module &M) {
}
// Emit initial debug information.
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "Dwarf Writer is not available");
- DW->BeginModule(&M, getAnalysisToUpdate<MachineModuleInfo>(),
+ DW->BeginModule(&M, getAnalysisIfAvailable<MachineModuleInfo>(),
O, this, TAI);
return Result;
}
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
index 69e427e8ad1b..183e1a1e0a4c 100644
--- a/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -135,7 +135,7 @@ bool ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
// Ensure that this call site is CALLING the function, not passing it as
// an argument.
- if (UI.getOperandNo() != 0)
+ if (!CS.isCallee(UI))
return false;
}
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 9d7980c0b2b9..dd5fce69fe15 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -182,7 +182,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
if (!TheCall) return false; // Not a direct call site?
// The addr of this function is passed to the call.
- if (I.getOperandNo() != 0) return false;
+ if (!CS.isCallee(I)) return false;
}
// Okay, we know we can transform this function if safe. Scan its body
@@ -438,13 +438,13 @@ void DAE::SurveyFunction(Function &F) {
for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) {
// If the function is PASSED IN as an argument, its address has been
// taken.
- if (I.getOperandNo() != 0) {
+ CallSite CS = CallSite::get(*I);
+ if (!CS.getInstruction() || !CS.isCallee(I)) {
MarkLive(F);
return;
}
// If this use is anything other than a call site, the function is alive.
- CallSite CS = CallSite::get(*I);
Instruction *TheCall = CS.getInstruction();
if (!TheCall) { // Not a direct call site?
MarkLive(F);
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index 99fc7317b1fa..7f636c927015 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -988,8 +988,7 @@ static void ReplaceUsesOfMallocWithGlobal(Instruction *Alloc,
} else if (PHINode *PN = dyn_cast<PHINode>(U)) {
// Insert the load in the corresponding predecessor, not right before the
// PHI.
- unsigned PredNo = Alloc->use_begin().getOperandNo()/2;
- InsertPt = PN->getIncomingBlock(PredNo)->getTerminator();
+ InsertPt = PN->getIncomingBlock(Alloc->use_begin())->getTerminator();
} else if (isa<BitCastInst>(U)) {
// Must be bitcast between the malloc and store to initialize the global.
ReplaceUsesOfMallocWithGlobal(U, GV);
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp
index 6ae8276d5247..2dc855824691 100644
--- a/lib/Transforms/IPO/IPConstantPropagation.cpp
+++ b/lib/Transforms/IPO/IPConstantPropagation.cpp
@@ -88,11 +88,12 @@ bool IPCP::PropagateConstantsIntoArguments(Function &F) {
for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) {
// Used by a non-instruction, or not the callee of a function, do not
// transform.
- if (UI.getOperandNo() != 0 ||
- (!isa<CallInst>(*UI) && !isa<InvokeInst>(*UI)))
+ if (!isa<CallInst>(*UI) && !isa<InvokeInst>(*UI))
return false;
CallSite CS = CallSite::get(cast<Instruction>(*UI));
+ if (!CS.isCallee(UI))
+ return false;
// Check out all of the potentially constant arguments. Note that we don't
// inspect varargs here.
@@ -219,7 +220,7 @@ bool IPCP::PropagateConstantReturn(Function &F) {
// Not a call instruction or a call instruction that's not calling F
// directly?
- if (!Call || UI.getOperandNo() != 0)
+ if (!Call || !CS.isCallee(UI))
continue;
// Call result not used?
diff --git a/lib/Transforms/IPO/IndMemRemoval.cpp b/lib/Transforms/IPO/IndMemRemoval.cpp
index b251ab4b09c1..6b1f969e440e 100644
--- a/lib/Transforms/IPO/IndMemRemoval.cpp
+++ b/lib/Transforms/IPO/IndMemRemoval.cpp
@@ -44,11 +44,11 @@ static RegisterPass<IndMemRemPass>
X("indmemrem","Indirect Malloc and Free Removal");
bool IndMemRemPass::runOnModule(Module &M) {
- //in Theory, all direct calls of malloc and free should be promoted
- //to intrinsics. Therefor, this goes through and finds where the
- //address of free or malloc are taken and replaces those with bounce
- //functions, ensuring that all malloc and free that might happen
- //happen through intrinsics.
+ // In theory, all direct calls of malloc and free should be promoted
+ // to intrinsics. Therefore, this goes through and finds where the
+ // address of free or malloc are taken and replaces those with bounce
+ // functions, ensuring that all malloc and free that might happen
+ // happen through intrinsics.
bool changed = false;
if (Function* F = M.getFunction("free")) {
if (F->isDeclaration() && F->arg_size() == 1 && !F->use_empty()) {
@@ -69,6 +69,7 @@ bool IndMemRemPass::runOnModule(Module &M) {
Function* FN = Function::Create(F->getFunctionType(),
GlobalValue::LinkOnceLinkage,
"malloc_llvm_bounce", &M);
+ FN->setDoesNotAlias(0);
BasicBlock* bb = BasicBlock::Create("entry",FN);
Instruction* c = CastInst::CreateIntegerCast(
FN->arg_begin(), Type::Int32Ty, false, "c", bb);
diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp
index b226d1959a01..5093ae90b5ba 100644
--- a/lib/Transforms/IPO/Internalize.cpp
+++ b/lib/Transforms/IPO/Internalize.cpp
@@ -99,7 +99,7 @@ void InternalizePass::LoadFile(const char *Filename) {
}
bool InternalizePass::runOnModule(Module &M) {
- CallGraph *CG = getAnalysisToUpdate<CallGraph>();
+ CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
if (ExternalNames.empty()) {
diff --git a/lib/Transforms/IPO/StructRetPromotion.cpp b/lib/Transforms/IPO/StructRetPromotion.cpp
index 00556f963352..9f54388aa45e 100644
--- a/lib/Transforms/IPO/StructRetPromotion.cpp
+++ b/lib/Transforms/IPO/StructRetPromotion.cpp
@@ -149,14 +149,11 @@ bool SRETPromotion::isSafeToUpdateAllCallers(Function *F) {
FnUseI != FnUseE; ++FnUseI) {
// The function is passed in as an argument to (possibly) another function,
// we can't change it!
- if (FnUseI.getOperandNo() != 0)
- return false;
-
CallSite CS = CallSite::get(*FnUseI);
Instruction *Call = CS.getInstruction();
// The function is used by something else than a call or invoke instruction,
// we can't change it!
- if (!Call)
+ if (!Call || !CS.isCallee(FnUseI))
return false;
CallSite::arg_iterator AI = CS.arg_begin();
Value *FirstArg = *AI;
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp
index 59c6586532c0..0a1c641e2bf4 100644
--- a/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -459,8 +459,7 @@ static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI){
// appropriate predecessor block.
BasicBlock *UserBB = User->getParent();
if (PHINode *PN = dyn_cast<PHINode>(User)) {
- unsigned OpVal = UI.getOperandNo()/2;
- UserBB = PN->getIncomingBlock(OpVal);
+ UserBB = PN->getIncomingBlock(UI);
}
// Preincrement use iterator so we don't invalidate it.
diff --git a/lib/Transforms/Scalar/CondPropagate.cpp b/lib/Transforms/Scalar/CondPropagate.cpp
index 2e899432909e..f68fb292e4a9 100644
--- a/lib/Transforms/Scalar/CondPropagate.cpp
+++ b/lib/Transforms/Scalar/CondPropagate.cpp
@@ -126,6 +126,14 @@ void CondProp::SimplifyPredecessors(BranchInst *BI) {
// one use (the branch), and is the only instruction besides the branch in the
// block.
PHINode *PN = cast<PHINode>(BI->getCondition());
+
+ if (PN->getNumIncomingValues() == 1) {
+ // Eliminate single-entry PHI nodes.
+ FoldSingleEntryPHINodes(PN->getParent());
+ return;
+ }
+
+
if (!PN->hasOneUse()) return;
BasicBlock *BB = BI->getParent();
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 8b20453a0e4b..77a7d93d4103 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -303,23 +303,6 @@ namespace {
}
}
- // UpdateValueUsesWith - This method is to be used when an value is
- // found to be replacable with another preexisting expression or was
- // updated. Here we add all uses of I to the worklist, replace all uses of
- // I with the new value (unless the instruction was just updated), then
- // return true, so that the inst combiner will know that I was modified.
- //
- bool UpdateValueUsesWith(Value *Old, Value *New) {
- AddUsersToWorkList(*Old); // Add all modified instrs to worklist
- if (Old != New)
- Old->replaceAllUsesWith(New);
- if (Instruction *I = dyn_cast<Instruction>(Old))
- AddToWorkList(I);
- if (Instruction *I = dyn_cast<Instruction>(New))
- AddToWorkList(I);
- return true;
- }
-
// EraseInstFromFunction - When dealing with an instruction that has side
// effects or produces a void value, we can't rely on DCE to delete the
// instruction. Instead, visit methods should return the value returned by
@@ -355,12 +338,20 @@ namespace {
/// most-complex to least-complex order.
bool SimplifyCompare(CmpInst &I);
- /// SimplifyDemandedBits - Attempts to replace V with a simpler value based
- /// on the demanded bits.
- bool SimplifyDemandedBits(Value *V, APInt DemandedMask,
+ /// SimplifyDemandedUseBits - Attempts to replace V with a simpler value
+ /// based on the demanded bits.
+ Value *SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
+ APInt& KnownZero, APInt& KnownOne,
+ unsigned Depth);
+ bool SimplifyDemandedBits(Use &U, APInt DemandedMask,
APInt& KnownZero, APInt& KnownOne,
- unsigned Depth = 0);
-
+ unsigned Depth=0);
+
+ /// SimplifyDemandedInstructionBits - Inst is an integer instruction that
+ /// SimplifyDemandedBits knows about. See if the instruction has any
+ /// properties that allow us to simplify its operands.
+ bool SimplifyDemandedInstructionBits(Instruction &Inst);
+
Value *SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts,
uint64_t &UndefElts, unsigned Depth = 0);
@@ -750,14 +741,44 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const Type *Ty,
Max = KnownOne|UnknownBits;
}
-/// SimplifyDemandedBits - This function attempts to replace V with a simpler
-/// value based on the demanded bits. When this function is called, it is known
+/// SimplifyDemandedInstructionBits - Inst is an integer instruction that
+/// SimplifyDemandedBits knows about. See if the instruction has any
+/// properties that allow us to simplify its operands.
+bool InstCombiner::SimplifyDemandedInstructionBits(Instruction &Inst) {
+ unsigned BitWidth = cast<IntegerType>(Inst.getType())->getBitWidth();
+ APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
+ APInt DemandedMask(APInt::getAllOnesValue(BitWidth));
+
+ Value *V = SimplifyDemandedUseBits(&Inst, DemandedMask,
+ KnownZero, KnownOne, 0);
+ if (V == 0) return false;
+ if (V == &Inst) return true;
+ ReplaceInstUsesWith(Inst, V);
+ return true;
+}
+
+/// SimplifyDemandedBits - This form of SimplifyDemandedBits simplifies the
+/// specified instruction operand if possible, updating it in place. It returns
+/// true if it made any change and false otherwise.
+bool InstCombiner::SimplifyDemandedBits(Use &U, APInt DemandedMask,
+ APInt &KnownZero, APInt &KnownOne,
+ unsigned Depth) {
+ Value *NewVal = SimplifyDemandedUseBits(U.get(), DemandedMask,
+ KnownZero, KnownOne, Depth);
+ if (NewVal == 0) return false;
+ U.set(NewVal);
+ return true;
+}
+
+
+/// SimplifyDemandedUseBits - This function attempts to replace V with a simpler
+/// value based on the demanded bits. When this function is called, it is known
/// that only the bits set in DemandedMask of the result of V are ever used
/// downstream. Consequently, depending on the mask and V, it may be possible
/// to replace V with a constant or one of its operands. In such cases, this
/// function does the replacement and returns true. In all other cases, it
/// returns false after analyzing the expression and setting KnownOne and known
-/// to be one in the expression. KnownZero contains all the bits that are known
+/// to be one in the expression. KnownZero contains all the bits that are known
/// to be zero in the expression. These are provided to potentially allow the
/// caller (which might recursively be SimplifyDemandedBits itself) to simplify
/// the expression. KnownOne and KnownZero always follow the invariant that
@@ -765,9 +786,15 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const Type *Ty,
/// the bits in KnownOne and KnownZero may only be accurate for those bits set
/// in DemandedMask. Note also that the bitwidth of V, DemandedMask, KnownZero
/// and KnownOne must all be the same.
-bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
- APInt& KnownZero, APInt& KnownOne,
- unsigned Depth) {
+///
+/// This returns null if it did not change anything and it permits no
+/// simplification. This returns V itself if it did some simplification of V's
+/// operands based on the information about what bits are demanded. This returns
+/// some other non-null value if it found out that V is equal to another value
+/// in the context where the specified bits are demanded, but not for all users.
+Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
+ APInt &KnownZero, APInt &KnownOne,
+ unsigned Depth) {
assert(V != 0 && "Null pointer of Value???");
assert(Depth <= 6 && "Limit Search Depth");
uint32_t BitWidth = DemandedMask.getBitWidth();
@@ -781,69 +808,127 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// We know all of the bits for a constant!
KnownOne = CI->getValue() & DemandedMask;
KnownZero = ~KnownOne & DemandedMask;
- return false;
+ return 0;
}
- KnownZero.clear();
+ KnownZero.clear();
KnownOne.clear();
- if (!V->hasOneUse()) { // Other users may use these bits.
- if (Depth != 0) { // Not at the root.
- // Just compute the KnownZero/KnownOne bits to simplify things downstream.
- ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth);
- return false;
- }
- // If this is the root being simplified, allow it to have multiple uses,
- // just set the DemandedMask to all bits.
- DemandedMask = APInt::getAllOnesValue(BitWidth);
- } else if (DemandedMask == 0) { // Not demanding any bits from V.
- if (V != UndefValue::get(VTy))
- return UpdateValueUsesWith(V, UndefValue::get(VTy));
- return false;
- } else if (Depth == 6) { // Limit search depth.
- return false;
+ if (DemandedMask == 0) { // Not demanding any bits from V.
+ if (isa<UndefValue>(V))
+ return 0;
+ return UndefValue::get(VTy);
}
+ if (Depth == 6) // Limit search depth.
+ return 0;
+
Instruction *I = dyn_cast<Instruction>(V);
- if (!I) return false; // Only analyze instructions.
-
+ if (!I) return 0; // Only analyze instructions.
+
APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne;
+
+ // If there are multiple uses of this value and we aren't at the root, then
+ // we can't do any simplifications of the operands, because DemandedMask
+ // only reflects the bits demanded by *one* of the users.
+ if (Depth != 0 && !I->hasOneUse()) {
+ // Despite the fact that we can't simplify this instruction in all User's
+ // context, we can at least compute the knownzero/knownone bits, and we can
+ // do simplifications that apply to *just* the one user if we know that
+ // this instruction has a simpler value in that context.
+ if (I->getOpcode() == Instruction::And) {
+ // If either the LHS or the RHS are Zero, the result is zero.
+ ComputeMaskedBits(I->getOperand(1), DemandedMask,
+ RHSKnownZero, RHSKnownOne, Depth+1);
+ ComputeMaskedBits(I->getOperand(0), DemandedMask & ~RHSKnownZero,
+ LHSKnownZero, LHSKnownOne, Depth+1);
+
+ // If all of the demanded bits are known 1 on one side, return the other.
+ // These bits cannot contribute to the result of the 'and' in this
+ // context.
+ if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) ==
+ (DemandedMask & ~LHSKnownZero))
+ return I->getOperand(0);
+ if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) ==
+ (DemandedMask & ~RHSKnownZero))
+ return I->getOperand(1);
+
+ // If all of the demanded bits in the inputs are known zeros, return zero.
+ if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask)
+ return Constant::getNullValue(VTy);
+
+ } else if (I->getOpcode() == Instruction::Or) {
+ // We can simplify (X|Y) -> X or Y in the user's context if we know that
+ // only bits from X or Y are demanded.
+
+ // If either the LHS or the RHS are One, the result is One.
+ ComputeMaskedBits(I->getOperand(1), DemandedMask,
+ RHSKnownZero, RHSKnownOne, Depth+1);
+ ComputeMaskedBits(I->getOperand(0), DemandedMask & ~RHSKnownOne,
+ LHSKnownZero, LHSKnownOne, Depth+1);
+
+ // If all of the demanded bits are known zero on one side, return the
+ // other. These bits cannot contribute to the result of the 'or' in this
+ // context.
+ if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) ==
+ (DemandedMask & ~LHSKnownOne))
+ return I->getOperand(0);
+ if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) ==
+ (DemandedMask & ~RHSKnownOne))
+ return I->getOperand(1);
+
+ // If all of the potentially set bits on one side are known to be set on
+ // the other side, just use the 'other' side.
+ if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) ==
+ (DemandedMask & (~RHSKnownZero)))
+ return I->getOperand(0);
+ if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) ==
+ (DemandedMask & (~LHSKnownZero)))
+ return I->getOperand(1);
+ }
+
+ // Compute the KnownZero/KnownOne bits to simplify things downstream.
+ ComputeMaskedBits(I, DemandedMask, KnownZero, KnownOne, Depth);
+ return 0;
+ }
+
+ // If this is the root being simplified, allow it to have multiple uses,
+ // just set the DemandedMask to all bits so that we can try to simplify the
+ // operands. This allows visitTruncInst (for example) to simplify the
+ // operand of a trunc without duplicating all the logic below.
+ if (Depth == 0 && !V->hasOneUse())
+ DemandedMask = APInt::getAllOnesValue(BitWidth);
+
switch (I->getOpcode()) {
default:
- ComputeMaskedBits(V, DemandedMask, RHSKnownZero, RHSKnownOne, Depth);
+ ComputeMaskedBits(I, DemandedMask, RHSKnownZero, RHSKnownOne, Depth);
break;
case Instruction::And:
// If either the LHS or the RHS are Zero, the result is zero.
- if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
- RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
-
- // If something is known zero on the RHS, the bits aren't demanded on the
- // LHS.
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownZero,
+ if (SimplifyDemandedBits(I->getOperandUse(1), DemandedMask,
+ RHSKnownZero, RHSKnownOne, Depth+1) ||
+ SimplifyDemandedBits(I->getOperandUse(0), DemandedMask & ~RHSKnownZero,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
- assert((LHSKnownZero & LHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?");
// If all of the demanded bits are known 1 on one side, return the other.
// These bits cannot contribute to the result of the 'and'.
if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) ==
(DemandedMask & ~LHSKnownZero))
- return UpdateValueUsesWith(I, I->getOperand(0));
+ return I->getOperand(0);
if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) ==
(DemandedMask & ~RHSKnownZero))
- return UpdateValueUsesWith(I, I->getOperand(1));
+ return I->getOperand(1);
// If all of the demanded bits in the inputs are known zeros, return zero.
if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask)
- return UpdateValueUsesWith(I, Constant::getNullValue(VTy));
+ return Constant::getNullValue(VTy);
// If the RHS is a constant, see if we can simplify it.
if (ShrinkDemandedConstant(I, 1, DemandedMask & ~LHSKnownZero))
- return UpdateValueUsesWith(I, I);
+ return I;
// Output known-1 bits are only known if set in both the LHS & RHS.
RHSKnownOne &= LHSKnownOne;
@@ -852,40 +937,35 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
break;
case Instruction::Or:
// If either the LHS or the RHS are One, the result is One.
- if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
- RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
- // If something is known one on the RHS, the bits aren't demanded on the
- // LHS.
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownOne,
+ if (SimplifyDemandedBits(I->getOperandUse(1), DemandedMask,
+ RHSKnownZero, RHSKnownOne, Depth+1) ||
+ SimplifyDemandedBits(I->getOperandUse(0), DemandedMask & ~RHSKnownOne,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
- assert((LHSKnownZero & LHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?");
// If all of the demanded bits are known zero on one side, return the other.
// These bits cannot contribute to the result of the 'or'.
if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) ==
(DemandedMask & ~LHSKnownOne))
- return UpdateValueUsesWith(I, I->getOperand(0));
+ return I->getOperand(0);
if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) ==
(DemandedMask & ~RHSKnownOne))
- return UpdateValueUsesWith(I, I->getOperand(1));
+ return I->getOperand(1);
// If all of the potentially set bits on one side are known to be set on
// the other side, just use the 'other' side.
if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) ==
(DemandedMask & (~RHSKnownZero)))
- return UpdateValueUsesWith(I, I->getOperand(0));
+ return I->getOperand(0);
if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) ==
(DemandedMask & (~LHSKnownZero)))
- return UpdateValueUsesWith(I, I->getOperand(1));
+ return I->getOperand(1);
// If the RHS is a constant, see if we can simplify it.
if (ShrinkDemandedConstant(I, 1, DemandedMask))
- return UpdateValueUsesWith(I, I);
+ return I;
// Output known-0 bits are only known if clear in both the LHS & RHS.
RHSKnownZero &= LHSKnownZero;
@@ -893,23 +973,20 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
RHSKnownOne |= LHSKnownOne;
break;
case Instruction::Xor: {
- if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
- RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+ if (SimplifyDemandedBits(I->getOperandUse(1), DemandedMask,
+ RHSKnownZero, RHSKnownOne, Depth+1) ||
+ SimplifyDemandedBits(I->getOperandUse(0), DemandedMask,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
- assert((LHSKnownZero & LHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?");
// If all of the demanded bits are known zero on one side, return the other.
// These bits cannot contribute to the result of the 'xor'.
if ((DemandedMask & RHSKnownZero) == DemandedMask)
- return UpdateValueUsesWith(I, I->getOperand(0));
+ return I->getOperand(0);
if ((DemandedMask & LHSKnownZero) == DemandedMask)
- return UpdateValueUsesWith(I, I->getOperand(1));
+ return I->getOperand(1);
// Output known-0 bits are known if clear or set in both the LHS & RHS.
APInt KnownZeroOut = (RHSKnownZero & LHSKnownZero) |
@@ -925,8 +1002,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
Instruction *Or =
BinaryOperator::CreateOr(I->getOperand(0), I->getOperand(1),
I->getName());
- InsertNewInstBefore(Or, *I);
- return UpdateValueUsesWith(I, Or);
+ return InsertNewInstBefore(Or, *I);
}
// If all of the demanded bits on one side are known, and all of the set
@@ -939,92 +1015,80 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
Constant *AndC = ConstantInt::get(~RHSKnownOne & DemandedMask);
Instruction *And =
BinaryOperator::CreateAnd(I->getOperand(0), AndC, "tmp");
- InsertNewInstBefore(And, *I);
- return UpdateValueUsesWith(I, And);
+ return InsertNewInstBefore(And, *I);
}
}
// If the RHS is a constant, see if we can simplify it.
// FIXME: for XOR, we prefer to force bits to 1 if they will make a -1.
if (ShrinkDemandedConstant(I, 1, DemandedMask))
- return UpdateValueUsesWith(I, I);
+ return I;
RHSKnownZero = KnownZeroOut;
RHSKnownOne = KnownOneOut;
break;
}
case Instruction::Select:
- if (SimplifyDemandedBits(I->getOperand(2), DemandedMask,
- RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
+ if (SimplifyDemandedBits(I->getOperandUse(2), DemandedMask,
+ RHSKnownZero, RHSKnownOne, Depth+1) ||
+ SimplifyDemandedBits(I->getOperandUse(1), DemandedMask,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
- assert((LHSKnownZero & LHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?");
// If the operands are constants, see if we can simplify them.
- if (ShrinkDemandedConstant(I, 1, DemandedMask))
- return UpdateValueUsesWith(I, I);
- if (ShrinkDemandedConstant(I, 2, DemandedMask))
- return UpdateValueUsesWith(I, I);
+ if (ShrinkDemandedConstant(I, 1, DemandedMask) ||
+ ShrinkDemandedConstant(I, 2, DemandedMask))
+ return I;
// Only known if known in both the LHS and RHS.
RHSKnownOne &= LHSKnownOne;
RHSKnownZero &= LHSKnownZero;
break;
case Instruction::Trunc: {
- uint32_t truncBf =
- cast<IntegerType>(I->getOperand(0)->getType())->getBitWidth();
+ unsigned truncBf = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
DemandedMask.zext(truncBf);
RHSKnownZero.zext(truncBf);
RHSKnownOne.zext(truncBf);
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask,
RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
+ return I;
DemandedMask.trunc(BitWidth);
RHSKnownZero.trunc(BitWidth);
RHSKnownOne.trunc(BitWidth);
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
break;
}
case Instruction::BitCast:
if (!I->getOperand(0)->getType()->isInteger())
- return false;
-
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+ return false; // vector->int or fp->int?
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask,
RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
break;
case Instruction::ZExt: {
// Compute the bits in the result that are not present in the input.
- const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
- uint32_t SrcBitWidth = SrcTy->getBitWidth();
+ unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits();
DemandedMask.trunc(SrcBitWidth);
RHSKnownZero.trunc(SrcBitWidth);
RHSKnownOne.trunc(SrcBitWidth);
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask,
RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
+ return I;
DemandedMask.zext(BitWidth);
RHSKnownZero.zext(BitWidth);
RHSKnownOne.zext(BitWidth);
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
// The top bits are known to be zero.
RHSKnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
break;
}
case Instruction::SExt: {
// Compute the bits in the result that are not present in the input.
- const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
- uint32_t SrcBitWidth = SrcTy->getBitWidth();
+ unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits();
APInt InputDemandedBits = DemandedMask &
APInt::getLowBitsSet(BitWidth, SrcBitWidth);
@@ -1038,25 +1102,23 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
InputDemandedBits.trunc(SrcBitWidth);
RHSKnownZero.trunc(SrcBitWidth);
RHSKnownOne.trunc(SrcBitWidth);
- if (SimplifyDemandedBits(I->getOperand(0), InputDemandedBits,
+ if (SimplifyDemandedBits(I->getOperandUse(0), InputDemandedBits,
RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
+ return I;
InputDemandedBits.zext(BitWidth);
RHSKnownZero.zext(BitWidth);
RHSKnownOne.zext(BitWidth);
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
// If the sign bit of the input is known set or clear, then we know the
// top bits of the result.
// If the input sign bit is known zero, or if the NewBits are not demanded
// convert this into a zero extension.
- if (RHSKnownZero[SrcBitWidth-1] || (NewBits & ~DemandedMask) == NewBits)
- {
+ if (RHSKnownZero[SrcBitWidth-1] || (NewBits & ~DemandedMask) == NewBits) {
// Convert to ZExt cast
- CastInst *NewCast = new ZExtInst(I->getOperand(0), VTy, I->getName(), I);
- return UpdateValueUsesWith(I, NewCast);
+ CastInst *NewCast = new ZExtInst(I->getOperand(0), VTy, I->getName());
+ return InsertNewInstBefore(NewCast, *I);
} else if (RHSKnownOne[SrcBitWidth-1]) { // Input sign bit known set
RHSKnownOne |= NewBits;
}
@@ -1066,7 +1128,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// Figure out what the input bits are. If the top bits of the and result
// are not demanded, then the add doesn't demand them from its input
// either.
- uint32_t NLZ = DemandedMask.countLeadingZeros();
+ unsigned NLZ = DemandedMask.countLeadingZeros();
// If there is a constant on the RHS, there are a variety of xformations
// we can do.
@@ -1081,14 +1143,14 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
APInt InDemandedBits(APInt::getLowBitsSet(BitWidth, BitWidth - NLZ));
// Find information about known zero/one bits in the input.
- if (SimplifyDemandedBits(I->getOperand(0), InDemandedBits,
+ if (SimplifyDemandedBits(I->getOperandUse(0), InDemandedBits,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
+ return I;
// If the RHS of the add has bits set that can't affect the input, reduce
// the constant.
if (ShrinkDemandedConstant(I, 1, InDemandedBits))
- return UpdateValueUsesWith(I, I);
+ return I;
// Avoid excess work.
if (LHSKnownZero == 0 && LHSKnownOne == 0)
@@ -1099,8 +1161,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
Instruction *Or =
BinaryOperator::CreateOr(I->getOperand(0), I->getOperand(1),
I->getName());
- InsertNewInstBefore(Or, *I);
- return UpdateValueUsesWith(I, Or);
+ return InsertNewInstBefore(Or, *I);
}
// We can say something about the output known-zero and known-one bits,
@@ -1112,7 +1173,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// To compute this, we first compute the potential carry bits. These are
// the bits which may be modified. I'm not aware of a better way to do
// this scan.
- const APInt& RHSVal = RHS->getValue();
+ const APInt &RHSVal = RHS->getValue();
APInt CarryBits((~LHSKnownZero + RHSVal) ^ (~LHSKnownZero ^ RHSVal));
// Now that we know which bits have carries, compute the known-1/0 sets.
@@ -1132,12 +1193,11 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// Right fill the mask of bits for this ADD to demand the most
// significant bit and all those below it.
APInt DemandedFromOps(APInt::getLowBitsSet(BitWidth, BitWidth-NLZ));
- if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps,
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedFromOps,
+ LHSKnownZero, LHSKnownOne, Depth+1) ||
+ SimplifyDemandedBits(I->getOperandUse(1), DemandedFromOps,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
- if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps,
- LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
+ return I;
}
}
break;
@@ -1150,12 +1210,11 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// significant bit and all those below it.
uint32_t NLZ = DemandedMask.countLeadingZeros();
APInt DemandedFromOps(APInt::getLowBitsSet(BitWidth, BitWidth-NLZ));
- if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps,
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedFromOps,
+ LHSKnownZero, LHSKnownOne, Depth+1) ||
+ SimplifyDemandedBits(I->getOperandUse(1), DemandedFromOps,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
- if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps,
- LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
+ return I;
}
// Otherwise just hand the sub off to ComputeMaskedBits to fill in
// the known zeros and ones.
@@ -1165,11 +1224,10 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth);
APInt DemandedMaskIn(DemandedMask.lshr(ShiftAmt));
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMaskIn,
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn,
RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
RHSKnownZero <<= ShiftAmt;
RHSKnownOne <<= ShiftAmt;
// low bits known zero.
@@ -1184,11 +1242,10 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// Unsigned shift right.
APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt));
- if (SimplifyDemandedBits(I->getOperand(0), DemandedMaskIn,
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn,
RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt);
RHSKnownOne = APIntOps::lshr(RHSKnownOne, ShiftAmt);
if (ShiftAmt) {
@@ -1205,16 +1262,15 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// the shift amount is >= the size of the datatype, which is undefined.
if (DemandedMask == 1) {
// Perform the logical shift right.
- Value *NewVal = BinaryOperator::CreateLShr(
+ Instruction *NewVal = BinaryOperator::CreateLShr(
I->getOperand(0), I->getOperand(1), I->getName());
- InsertNewInstBefore(cast<Instruction>(NewVal), *I);
- return UpdateValueUsesWith(I, NewVal);
+ return InsertNewInstBefore(NewVal, *I);
}
// If the sign bit is the only bit demanded by this ashr, then there is no
// need to do it, the shift doesn't change the high bit.
if (DemandedMask.isSignBit())
- return UpdateValueUsesWith(I, I->getOperand(0));
+ return I->getOperand(0);
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint32_t ShiftAmt = SA->getLimitedValue(BitWidth);
@@ -1225,12 +1281,10 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// demanded.
if (DemandedMask.countLeadingZeros() <= ShiftAmt)
DemandedMaskIn.set(BitWidth-1);
- if (SimplifyDemandedBits(I->getOperand(0),
- DemandedMaskIn,
+ if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn,
RHSKnownZero, RHSKnownOne, Depth+1))
- return true;
- assert((RHSKnownZero & RHSKnownOne) == 0 &&
- "Bits known to be one AND zero?");
+ return I;
+ assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
// Compute the new bits that are at the top now.
APInt HighBits(APInt::getHighBitsSet(BitWidth, ShiftAmt));
RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt);
@@ -1246,10 +1300,9 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
if (BitWidth <= ShiftAmt || RHSKnownZero[BitWidth-ShiftAmt-1] ||
(HighBits & ~DemandedMask) == HighBits) {
// Perform the logical shift right.
- Value *NewVal = BinaryOperator::CreateLShr(
+ Instruction *NewVal = BinaryOperator::CreateLShr(
I->getOperand(0), SA, I->getName());
- InsertNewInstBefore(cast<Instruction>(NewVal), *I);
- return UpdateValueUsesWith(I, NewVal);
+ return InsertNewInstBefore(NewVal, *I);
} else if ((RHSKnownOne & SignBit) != 0) { // New bits are known one.
RHSKnownOne |= HighBits;
}
@@ -1260,35 +1313,33 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
APInt RA = Rem->getValue().abs();
if (RA.isPowerOf2()) {
if (DemandedMask.ule(RA)) // srem won't affect demanded bits
- return UpdateValueUsesWith(I, I->getOperand(0));
+ return I->getOperand(0);
APInt LowBits = RA - 1;
APInt Mask2 = LowBits | APInt::getSignBit(BitWidth);
- if (SimplifyDemandedBits(I->getOperand(0), Mask2,
+ if (SimplifyDemandedBits(I->getOperandUse(0), Mask2,
LHSKnownZero, LHSKnownOne, Depth+1))
- return true;
+ return I;
if (LHSKnownZero[BitWidth-1] || ((LHSKnownZero & LowBits) == LowBits))
LHSKnownZero |= ~LowBits;
KnownZero |= LHSKnownZero & DemandedMask;
- assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
}
}
break;
case Instruction::URem: {
APInt KnownZero2(BitWidth, 0), KnownOne2(BitWidth, 0);
APInt AllOnes = APInt::getAllOnesValue(BitWidth);
- if (SimplifyDemandedBits(I->getOperand(0), AllOnes,
+ if (SimplifyDemandedBits(I->getOperandUse(0), AllOnes,
+ KnownZero2, KnownOne2, Depth+1) ||
+ SimplifyDemandedBits(I->getOperandUse(1), AllOnes,
KnownZero2, KnownOne2, Depth+1))
- return true;
+ return I;
unsigned Leaders = KnownZero2.countLeadingOnes();
- if (SimplifyDemandedBits(I->getOperand(1), AllOnes,
- KnownZero2, KnownOne2, Depth+1))
- return true;
-
Leaders = std::max(Leaders,
KnownZero2.countLeadingOnes());
KnownZero = APInt::getHighBitsSet(BitWidth, Leaders) & DemandedMask;
@@ -1324,8 +1375,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
NewVal = BinaryOperator::CreateShl(I->getOperand(1),
ConstantInt::get(I->getType(), ResultBit-InputBit));
NewVal->takeName(I);
- InsertNewInstBefore(NewVal, *I);
- return UpdateValueUsesWith(I, NewVal);
+ return InsertNewInstBefore(NewVal, *I);
}
// TODO: Could compute known zero/one bits based on the input.
@@ -1340,7 +1390,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
// If the client is only demanding bits that we know, return the known
// constant.
if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask)
- return UpdateValueUsesWith(I, ConstantInt::get(RHSKnownOne));
+ return ConstantInt::get(RHSKnownOne);
return false;
}
@@ -1993,12 +2043,8 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
// See if SimplifyDemandedBits can simplify this. This handles stuff like
// (X & 254)+1 -> (X&254)|1
- if (!isa<VectorType>(I.getType())) {
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth),
- KnownZero, KnownOne))
- return &I;
- }
+ if (!isa<VectorType>(I.getType()) && SimplifyDemandedInstructionBits(I))
+ return &I;
// zext(i1) - 1 -> select i1, 0, -1
if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS))
@@ -3002,10 +3048,7 @@ Instruction *InstCombiner::commonIRemTransforms(BinaryOperator &I) {
}
// See if we can fold away this rem instruction.
- uint32_t BitWidth = cast<IntegerType>(I.getType())->getBitWidth();
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth),
- KnownZero, KnownOne))
+ if (SimplifyDemandedInstructionBits(I))
return &I;
}
}
@@ -3786,10 +3829,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
if (!isa<VectorType>(I.getType())) {
- uint32_t BitWidth = cast<IntegerType>(I.getType())->getBitWidth();
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth),
- KnownZero, KnownOne))
+ if (SimplifyDemandedInstructionBits(I))
return &I;
} else {
if (ConstantVector *CP = dyn_cast<ConstantVector>(Op1)) {
@@ -4496,10 +4536,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
if (!isa<VectorType>(I.getType())) {
- uint32_t BitWidth = cast<IntegerType>(I.getType())->getBitWidth();
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth),
- KnownZero, KnownOne))
+ if (SimplifyDemandedInstructionBits(I))
return &I;
} else if (isa<ConstantAggregateZero>(Op1)) {
return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X
@@ -4837,10 +4874,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
if (!isa<VectorType>(I.getType())) {
- uint32_t BitWidth = cast<IntegerType>(I.getType())->getBitWidth();
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth),
- KnownZero, KnownOne))
+ if (SimplifyDemandedInstructionBits(I))
return &I;
} else if (isa<ConstantAggregateZero>(Op1)) {
return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X
@@ -5826,7 +5860,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
bool UnusedBit;
bool isSignBit = isSignBitCheck(I.getPredicate(), CI, UnusedBit);
- if (SimplifyDemandedBits(Op0,
+ if (SimplifyDemandedBits(I.getOperandUse(0),
isSignBit ? APInt::getSignBit(BitWidth)
: APInt::getAllOnesValue(BitWidth),
KnownZero, KnownOne, 0))
@@ -6061,18 +6095,39 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1)) {
if (Op0I->getOpcode() == Op1I->getOpcode() && Op0I->hasOneUse() &&
- Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1) &&
- I.isEquality()) {
+ Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1)) {
switch (Op0I->getOpcode()) {
default: break;
case Instruction::Add:
case Instruction::Sub:
case Instruction::Xor:
- // a+x icmp eq/ne b+x --> a icmp b
- return new ICmpInst(I.getPredicate(), Op0I->getOperand(0),
- Op1I->getOperand(0));
+ if (I.isEquality()) // a+x icmp eq/ne b+x --> a icmp b
+ return new ICmpInst(I.getPredicate(), Op0I->getOperand(0),
+ Op1I->getOperand(0));
+ // icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u a, b
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
+ if (CI->getValue().isSignBit()) {
+ ICmpInst::Predicate Pred = I.isSignedPredicate()
+ ? I.getUnsignedPredicate()
+ : I.getSignedPredicate();
+ return new ICmpInst(Pred, Op0I->getOperand(0),
+ Op1I->getOperand(0));
+ }
+
+ if (CI->getValue().isMaxSignedValue()) {
+ ICmpInst::Predicate Pred = I.isSignedPredicate()
+ ? I.getUnsignedPredicate()
+ : I.getSignedPredicate();
+ Pred = I.getSwappedPredicate(Pred);
+ return new ICmpInst(Pred, Op0I->getOperand(0),
+ Op1I->getOperand(0));
+ }
+ }
break;
case Instruction::Mul:
+ if (!I.isEquality())
+ break;
+
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
// a * Cst icmp eq/ne b * Cst --> a & Mask icmp b & Mask
// Mask = -1 >> count-trailing-zeros(Cst).
@@ -6391,6 +6446,29 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
else
return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS));
}
+
+ if (LHSI->hasOneUse()) {
+ // (icmp u/s (xor A SignBit), C) -> (icmp s/u A, (xor C SignBit))
+ if (!ICI.isEquality() && XorCST->getValue().isSignBit()) {
+ const APInt &SignBit = XorCST->getValue();
+ ICmpInst::Predicate Pred = ICI.isSignedPredicate()
+ ? ICI.getUnsignedPredicate()
+ : ICI.getSignedPredicate();
+ return new ICmpInst(Pred, LHSI->getOperand(0),
+ ConstantInt::get(RHSV ^ SignBit));
+ }
+
+ // (icmp u/s (xor A ~SignBit), C) -> (icmp s/u (xor C ~SignBit), A)
+ if (!ICI.isEquality() && XorCST->getValue().isMaxSignedValue()) {
+ const APInt &NotSignBit = XorCST->getValue();
+ ICmpInst::Predicate Pred = ICI.isSignedPredicate()
+ ? ICI.getUnsignedPredicate()
+ : ICI.getSignedPredicate();
+ Pred = ICI.getSwappedPredicate(Pred);
+ return new ICmpInst(Pred, LHSI->getOperand(0),
+ ConstantInt::get(RHSV ^ NotSignBit));
+ }
+ }
}
break;
case Instruction::And: // (icmp pred (and X, AndCST), RHS)
@@ -6990,14 +7068,12 @@ Instruction *InstCombiner::commonShiftTransforms(BinaryOperator &I) {
Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
BinaryOperator &I) {
- bool isLeftShift = I.getOpcode() == Instruction::Shl;
+ bool isLeftShift = I.getOpcode() == Instruction::Shl;
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
uint32_t TypeBits = Op0->getType()->getPrimitiveSizeInBits();
- APInt KnownZero(TypeBits, 0), KnownOne(TypeBits, 0);
- if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(TypeBits),
- KnownZero, KnownOne))
+ if (SimplifyDemandedInstructionBits(I))
return &I;
// shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
@@ -7700,12 +7776,12 @@ Instruction *InstCombiner::commonCastTransforms(CastInst &CI) {
/// FindElementAtOffset - Given a type and a constant offset, determine whether
/// or not there is a sequence of GEP indices into the type that will land us at
-/// the specified offset. If so, fill them into NewIndices and return true,
-/// otherwise return false.
-static bool FindElementAtOffset(const Type *Ty, int64_t Offset,
- SmallVectorImpl<Value*> &NewIndices,
- const TargetData *TD) {
- if (!Ty->isSized()) return false;
+/// the specified offset. If so, fill them into NewIndices and return the
+/// resultant element type, otherwise return null.
+static const Type *FindElementAtOffset(const Type *Ty, int64_t Offset,
+ SmallVectorImpl<Value*> &NewIndices,
+ const TargetData *TD) {
+ if (!Ty->isSized()) return 0;
// Start with the index over the outer type. Note that the type size
// might be zero (even if the offset isn't zero) if the indexed type
@@ -7731,7 +7807,7 @@ static bool FindElementAtOffset(const Type *Ty, int64_t Offset,
while (Offset) {
// Indexing into tail padding between struct/array elements.
if (uint64_t(Offset*8) >= TD->getTypeSizeInBits(Ty))
- return false;
+ return 0;
if (const StructType *STy = dyn_cast<StructType>(Ty)) {
const StructLayout *SL = TD->getStructLayout(STy);
@@ -7751,11 +7827,11 @@ static bool FindElementAtOffset(const Type *Ty, int64_t Offset,
Ty = AT->getElementType();
} else {
// Otherwise, we can't index into the middle of this atomic type, bail.
- return false;
+ return 0;
}
}
- return true;
+ return Ty;
}
/// @brief Implement the transforms for cast of pointer (bitcast/ptrtoint)
@@ -7828,9 +7904,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
// See if we can simplify any instructions used by the LHS whose sole
// purpose is to compute bits we don't care about.
- APInt KnownZero(DestBitSize, 0), KnownOne(DestBitSize, 0);
- if (SimplifyDemandedBits(&CI, APInt::getAllOnesValue(DestBitSize),
- KnownZero, KnownOne))
+ if (SimplifyDemandedInstructionBits(CI))
return &CI;
// If the source isn't an instruction or has more than one use then we
@@ -7862,15 +7936,15 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
break;
case Instruction::ZExt: {
DoXForm = NumCastsRemoved >= 1;
- if (!DoXForm) {
+ if (!DoXForm && 0) {
// If it's unnecessary to issue an AND to clear the high bits, it's
// always profitable to do this xform.
- Value *TryRes = EvaluateInDifferentType(SrcI, DestTy,
- CI.getOpcode() == Instruction::SExt);
+ Value *TryRes = EvaluateInDifferentType(SrcI, DestTy, false);
APInt Mask(APInt::getBitsSet(DestBitSize, SrcBitSize, DestBitSize));
if (MaskedValueIsZero(TryRes, Mask))
return ReplaceInstUsesWith(CI, TryRes);
- else if (Instruction *TryI = dyn_cast<Instruction>(TryRes))
+
+ if (Instruction *TryI = dyn_cast<Instruction>(TryRes))
if (TryI->use_empty())
EraseInstFromFunction(*TryI);
}
@@ -7878,7 +7952,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
}
case Instruction::SExt: {
DoXForm = NumCastsRemoved >= 2;
- if (!DoXForm && !isa<TruncInst>(SrcI)) {
+ if (!DoXForm && !isa<TruncInst>(SrcI) && 0) {
// If we do not have to emit the truncate + sext pair, then it's always
// profitable to do this xform.
//
@@ -7888,12 +7962,12 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
// t3 = sext i16 t2 to i32
// !=
// i32 t1
- Value *TryRes = EvaluateInDifferentType(SrcI, DestTy,
- CI.getOpcode() == Instruction::SExt);
+ Value *TryRes = EvaluateInDifferentType(SrcI, DestTy, true);
unsigned NumSignBits = ComputeNumSignBits(TryRes);
if (NumSignBits > (DestBitSize - SrcBitSize))
return ReplaceInstUsesWith(CI, TryRes);
- else if (Instruction *TryI = dyn_cast<Instruction>(TryRes))
+
+ if (Instruction *TryI = dyn_cast<Instruction>(TryRes))
if (TryI->use_empty())
EraseInstFromFunction(*TryI);
}
@@ -7902,11 +7976,13 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
}
if (DoXForm) {
+ DOUT << "ICE: EvaluateInDifferentType converting expression type to avoid"
+ << " cast: " << CI;
Value *Res = EvaluateInDifferentType(SrcI, DestTy,
CI.getOpcode() == Instruction::SExt);
if (JustReplace)
- // Just replace this cast with the result.
- return ReplaceInstUsesWith(CI, Res);
+ // Just replace this cast with the result.
+ return ReplaceInstUsesWith(CI, Res);
assert(Res->getType() == DestTy);
switch (CI.getOpcode()) {
@@ -11139,7 +11215,8 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
}
/// InstCombineStoreToCast - Fold store V, (cast P) -> store (cast V), P
-/// when possible.
+/// when possible. This makes it generally easy to do alias analysis and/or
+/// SROA/mem2reg of the memory object.
static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
User *CI = cast<User>(SI.getOperand(1));
Value *CastOp = CI->getOperand(0);
@@ -11153,18 +11230,36 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
if (!DestPTy->isInteger() && !isa<PointerType>(DestPTy))
return 0;
+ /// NewGEPIndices - If SrcPTy is an aggregate type, we can emit a "noop gep"
+ /// to its first element. This allows us to handle things like:
+ /// store i32 xxx, (bitcast {foo*, float}* %P to i32*)
+ /// on 32-bit hosts.
+ SmallVector<Value*, 4> NewGEPIndices;
+
// 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 (const ArrayType *ASrcTy = dyn_cast<ArrayType>(SrcPTy))
- if (Constant *CSrc = dyn_cast<Constant>(CastOp))
- if (ASrcTy->getNumElements() != 0) {
- Value* Idxs[2];
- Idxs[0] = Idxs[1] = Constant::getNullValue(Type::Int32Ty);
- CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs, 2);
- SrcTy = cast<PointerType>(CastOp->getType());
- SrcPTy = SrcTy->getElementType();
+ if (isa<ArrayType>(SrcPTy) || isa<StructType>(SrcPTy)) {
+ // Index through pointer.
+ Constant *Zero = Constant::getNullValue(Type::Int32Ty);
+ NewGEPIndices.push_back(Zero);
+
+ while (1) {
+ if (const StructType *STy = dyn_cast<StructType>(SrcPTy)) {
+ if (!STy->getNumElements()) /* Struct can be empty {} */
+ break;
+ NewGEPIndices.push_back(Zero);
+ SrcPTy = STy->getElementType(0);
+ } else if (const ArrayType *ATy = dyn_cast<ArrayType>(SrcPTy)) {
+ NewGEPIndices.push_back(Zero);
+ SrcPTy = ATy->getElementType();
+ } else {
+ break;
}
+ }
+
+ SrcTy = PointerType::get(SrcPTy, SrcTy->getAddressSpace());
+ }
if (!SrcPTy->isInteger() && !isa<PointerType>(SrcPTy))
return 0;
@@ -11192,6 +11287,19 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
if (isa<PointerType>(SIOp0->getType()))
opcode = Instruction::PtrToInt;
}
+
+ // SIOp0 is a pointer to aggregate and this is a store to the first field,
+ // emit a GEP to index into its first field.
+ if (!NewGEPIndices.empty()) {
+ if (Constant *C = dyn_cast<Constant>(CastOp))
+ CastOp = ConstantExpr::getGetElementPtr(C, &NewGEPIndices[0],
+ NewGEPIndices.size());
+ else
+ CastOp = IC.InsertNewInstBefore(
+ GetElementPtrInst::Create(CastOp, NewGEPIndices.begin(),
+ NewGEPIndices.end()), SI);
+ }
+
if (Constant *C = dyn_cast<Constant>(SIOp0))
NewCast = ConstantExpr::getCast(opcode, C, CastDstTy);
else
@@ -12147,9 +12255,11 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
// If the result mask is equal to the src shuffle or this shuffle mask, do
// the replacement.
if (NewMask == LHSMask || NewMask == Mask) {
+ unsigned LHSInNElts =
+ cast<VectorType>(LHSSVI->getOperand(0)->getType())->getNumElements();
std::vector<Constant*> Elts;
for (unsigned i = 0, e = NewMask.size(); i != e; ++i) {
- if (NewMask[i] >= e*2) {
+ if (NewMask[i] >= LHSInNElts*2) {
Elts.push_back(UndefValue::get(Type::Int32Ty));
} else {
Elts.push_back(ConstantInt::get(Type::Int32Ty, NewMask[i]));
@@ -12322,6 +12432,7 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
if (!I->use_empty())
I->replaceAllUsesWith(UndefValue::get(I->getType()));
I->eraseFromParent();
+ Changed = true;
}
}
}
@@ -12341,6 +12452,7 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
I->eraseFromParent();
RemoveFromWorkList(I);
+ Changed = true;
continue;
}
@@ -12355,17 +12467,19 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
++NumConstProp;
I->eraseFromParent();
RemoveFromWorkList(I);
+ Changed = true;
continue;
}
if (TD && I->getType()->getTypeID() == Type::VoidTyID) {
// See if we can constant fold its operands.
- for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) {
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(i)) {
+ for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i)
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(i))
if (Constant *NewC = ConstantFoldConstantExpression(CE, TD))
- i->set(NewC);
- }
- }
+ if (NewC != CE) {
+ i->set(NewC);
+ Changed = true;
+ }
}
// See if we can trivially sink this instruction to a successor basic block.
diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp
index e8df49b6e4e5..65b74b4e7ff5 100644
--- a/lib/Transforms/Scalar/LoopRotation.cpp
+++ b/lib/Transforms/Scalar/LoopRotation.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "loop-rotate"
-
#include "llvm/Transforms/Scalar.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
@@ -26,7 +25,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SmallVector.h"
-
using namespace llvm;
#define MAX_HEADER_SIZE 16
@@ -128,7 +126,6 @@ bool LoopRotate::runOnLoop(Loop *Lp, LPPassManager &LPM) {
/// Rotate loop LP. Return true if the loop is rotated.
bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
-
L = Lp;
OrigHeader = L->getHeader();
@@ -139,8 +136,8 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
if (L->getBlocks().size() == 1)
return false;
- assert (OrigHeader && OrigLatch && OrigPreHeader &&
- "Loop is not in canonical form");
+ assert(OrigHeader && OrigLatch && OrigPreHeader &&
+ "Loop is not in canonical form");
// If loop header is not one of the loop exit block then
// either this loop is already rotated or it is not
@@ -151,7 +148,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
BranchInst *BI = dyn_cast<BranchInst>(OrigHeader->getTerminator());
if (!BI)
return false;
- assert (BI->isConditional() && "Branch Instruction is not conditional");
+ assert(BI->isConditional() && "Branch Instruction is not conditional");
// Updating PHInodes in loops with multiple exits adds complexity.
// Keep it simple, and restrict loop rotation to loops with one exit only.
@@ -170,15 +167,21 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
// Now, this loop is suitable for rotation.
// Find new Loop header. NewHeader is a Header's one and only successor
- // that is inside loop. Header's other successor is out side the
- // loop. Otherwise loop is not suitable for rotation.
+ // that is inside loop. Header's other successor is outside the
+ // loop. Otherwise loop is not suitable for rotation.
Exit = BI->getSuccessor(0);
NewHeader = BI->getSuccessor(1);
if (L->contains(Exit))
std::swap(Exit, NewHeader);
- assert (NewHeader && "Unable to determine new loop header");
+ assert(NewHeader && "Unable to determine new loop header");
assert(L->contains(NewHeader) && !L->contains(Exit) &&
"Unable to determine loop header and exit blocks");
+
+ // This code assumes that new header has exactly one predecessor. Remove any
+ // single entry PHI nodes in it.
+ assert(NewHeader->getSinglePredecessor() &&
+ "New header doesn't have one pred!");
+ FoldSingleEntryPHINodes(NewHeader);
// Copy PHI nodes and other instructions from original header
// into original pre-header. Unlike original header, original pre-header is
@@ -197,31 +200,29 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
// receive a clone of original header terminator as a new terminator.
OrigPreHeader->getInstList().pop_back();
BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end();
- PHINode *PN = NULL;
+ PHINode *PN = 0;
for (; (PN = dyn_cast<PHINode>(I)); ++I) {
- Instruction *In = I;
-
// PHI nodes are not copied into original pre-header. Instead their values
// are directly propagated.
- Value * NPV = PN->getIncomingValueForBlock(OrigPreHeader);
+ Value *NPV = PN->getIncomingValueForBlock(OrigPreHeader);
// Create new PHI node with two incoming values for NewHeader.
// One incoming value is from OrigLatch (through OrigHeader) and
// second incoming value is from original pre-header.
- PHINode *NH = PHINode::Create(In->getType(), In->getName(),
+ PHINode *NH = PHINode::Create(PN->getType(), PN->getName(),
NewHeader->begin());
NH->addIncoming(PN->getIncomingValueForBlock(OrigLatch), OrigHeader);
NH->addIncoming(NPV, OrigPreHeader);
// "In" can be replaced by NH at various places.
- LoopHeaderInfo.push_back(RenameData(In, NPV, NH));
+ LoopHeaderInfo.push_back(RenameData(PN, NPV, NH));
}
// Now, handle non-phi instructions.
for (; I != E; ++I) {
Instruction *In = I;
-
- assert (!isa<PHINode>(In) && "PHINode is not expected here");
+ assert(!isa<PHINode>(In) && "PHINode is not expected here");
+
// This is not a PHI instruction. Insert its clone into original pre-header.
// If this instruction is using a value from same basic block then
// update it to use value from cloned instruction.
@@ -230,21 +231,12 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
OrigPreHeader->getInstList().push_back(C);
for (unsigned opi = 0, e = In->getNumOperands(); opi != e; ++opi) {
- if (Instruction *OpPhi = dyn_cast<PHINode>(In->getOperand(opi))) {
- if (const RenameData *D = findReplacementData(OpPhi)) {
- // This is using values from original header PHI node.
- // Here, directly used incoming value from original pre-header.
- C->setOperand(opi, D->PreHeader);
- }
- }
- else if (Instruction *OpInsn =
- dyn_cast<Instruction>(In->getOperand(opi))) {
- if (const RenameData *D = findReplacementData(OpInsn))
- C->setOperand(opi, D->PreHeader);
- }
+ Instruction *OpInsn = dyn_cast<Instruction>(In->getOperand(opi));
+ if (!OpInsn) continue; // Ignore non-instruction values.
+ if (const RenameData *D = findReplacementData(OpInsn))
+ C->setOperand(opi, D->PreHeader);
}
-
// If this instruction is used outside this basic block then
// create new PHINode for this instruction.
Instruction *NewHeaderReplacement = NULL;
@@ -276,7 +268,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
// 2) Inside loop but not in original header
//
// Replace this use to reflect definition from new header.
- for(unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) {
+ for (unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) {
const RenameData &ILoopHeaderInfo = LoopHeaderInfo[LHI];
if (!ILoopHeaderInfo.Header)
@@ -289,10 +281,8 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
// not invalidated.
SmallVector<Instruction *, 16> AllUses;
for (Value::use_iterator UI = OldPhi->use_begin(), UE = OldPhi->use_end();
- UI != UE; ++UI) {
- Instruction *U = cast<Instruction>(UI);
- AllUses.push_back(U);
- }
+ UI != UE; ++UI)
+ AllUses.push_back(cast<Instruction>(UI));
for (SmallVector<Instruction *, 16>::iterator UI = AllUses.begin(),
UE = AllUses.end(); UI != UE; ++UI) {
@@ -325,7 +315,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
// Used inside Exit Block. Since we are in LCSSA form, U must be PHINode.
if (U->getParent() == Exit) {
- assert (isa<PHINode>(U) && "Use in Exit Block that is not PHINode");
+ assert(isa<PHINode>(U) && "Use in Exit Block that is not PHINode");
PHINode *UPhi = cast<PHINode>(U);
// UPhi already has one incoming argument from original header.
@@ -351,14 +341,9 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
// Removing incoming branch from loop preheader to original header.
// Now original header is inside the loop.
for (BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end();
- I != E; ++I) {
- Instruction *In = I;
- PHINode *PN = dyn_cast<PHINode>(In);
- if (!PN)
- break;
-
- PN->removeIncomingValue(OrigPreHeader);
- }
+ I != E; ++I)
+ if (PHINode *PN = dyn_cast<PHINode>(I))
+ PN->removeIncomingValue(OrigPreHeader);
// Make NewHeader as the new header for the loop.
L->moveToHeader(NewHeader);
@@ -411,14 +396,11 @@ void LoopRotate::initialize() {
/// Return true if this instruction is used by any instructions in the loop that
/// aren't in original header.
bool LoopRotate::usedOutsideOriginalHeader(Instruction *In) {
-
for (Value::use_iterator UI = In->use_begin(), UE = In->use_end();
UI != UE; ++UI) {
- Instruction *U = cast<Instruction>(UI);
- if (U->getParent() != OrigHeader) {
- if (L->contains(U->getParent()))
- return true;
- }
+ BasicBlock *UserBB = cast<Instruction>(UI)->getParent();
+ if (UserBB != OrigHeader && L->contains(UserBB))
+ return true;
}
return false;
@@ -429,7 +411,7 @@ bool LoopRotate::usedOutsideOriginalHeader(Instruction *In) {
const RenameData *LoopRotate::findReplacementData(Instruction *In) {
// Since LoopHeaderInfo is small, linear walk is OK.
- for(unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) {
+ for (unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) {
const RenameData &ILoopHeaderInfo = LoopHeaderInfo[LHI];
if (ILoopHeaderInfo.Original == In)
return &ILoopHeaderInfo;
@@ -457,26 +439,25 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
if (OrigPH_BI->getSuccessor(0) == NewHeader)
OrigPH_BI->setSuccessor(0, NewPreHeader);
else {
- assert (OrigPH_BI->getSuccessor(1) == NewHeader &&
- "Unexpected original pre-header terminator");
+ assert(OrigPH_BI->getSuccessor(1) == NewHeader &&
+ "Unexpected original pre-header terminator");
OrigPH_BI->setSuccessor(1, NewPreHeader);
}
for (BasicBlock::iterator I = NewHeader->begin(), E = NewHeader->end();
I != E; ++I) {
- Instruction *In = I;
- PHINode *PN = dyn_cast<PHINode>(In);
+ PHINode *PN = dyn_cast<PHINode>(I);
if (!PN)
break;
int index = PN->getBasicBlockIndex(OrigPreHeader);
- assert (index != -1 && "Expected incoming value from Original PreHeader");
+ assert(index != -1 && "Expected incoming value from Original PreHeader");
PN->setIncomingBlock(index, NewPreHeader);
- assert (PN->getBasicBlockIndex(OrigPreHeader) == -1 &&
- "Expected only one incoming value from Original PreHeader");
+ assert(PN->getBasicBlockIndex(OrigPreHeader) == -1 &&
+ "Expected only one incoming value from Original PreHeader");
}
- if (DominatorTree *DT = getAnalysisToUpdate<DominatorTree>()) {
+ if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>()) {
DT->addNewBlock(NewPreHeader, OrigPreHeader);
DT->changeImmediateDominator(L->getHeader(), NewPreHeader);
DT->changeImmediateDominator(Exit, OrigPreHeader);
@@ -492,8 +473,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
DT->changeImmediateDominator(OrigHeader, OrigLatch);
}
- if(DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>()) {
-
+ if (DominanceFrontier *DF = getAnalysisIfAvailable<DominanceFrontier>()) {
// New Preheader's dominance frontier is Exit block.
DominanceFrontier::DomSetType NewPHSet;
NewPHSet.insert(Exit);
@@ -529,7 +509,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
// If a loop block dominates new loop latch then its frontier is
// new header and Exit.
BasicBlock *NewLatch = L->getLoopLatch();
- DominatorTree *DT = getAnalysisToUpdate<DominatorTree>();
+ DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
for (Loop::block_iterator BI = L->block_begin(), BE = L->block_end();
BI != BE; ++BI) {
BasicBlock *B = *BI;
@@ -571,11 +551,10 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
}
}
- assert (NewHeader && L->getHeader() == NewHeader
- && "Invalid loop header after loop rotation");
- assert (NewPreHeader && L->getLoopPreheader() == NewPreHeader
- && "Invalid loop preheader after loop rotation");
- assert (L->getLoopLatch()
- && "Invalid loop latch after loop rotation");
-
+ assert(NewHeader && L->getHeader() == NewHeader &&
+ "Invalid loop header after loop rotation");
+ assert(NewPreHeader && L->getLoopPreheader() == NewPreHeader &&
+ "Invalid loop preheader after loop rotation");
+ assert(L->getLoopLatch() &&
+ "Invalid loop latch after loop rotation");
}
diff --git a/lib/Transforms/Scalar/LoopUnroll.cpp b/lib/Transforms/Scalar/LoopUnroll.cpp
index 6d685d58f96b..2025fb682885 100644
--- a/lib/Transforms/Scalar/LoopUnroll.cpp
+++ b/lib/Transforms/Scalar/LoopUnroll.cpp
@@ -170,10 +170,10 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
return false;
// FIXME: Reconstruct dom info, because it is not preserved properly.
- DominatorTree *DT = getAnalysisToUpdate<DominatorTree>();
+ DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
if (DT) {
DT->runOnFunction(*F);
- DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>();
+ DominanceFrontier *DF = getAnalysisIfAvailable<DominanceFrontier>();
if (DF)
DF->runOnFunction(*F);
}
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index 97aa475a67fe..a563c7a9ee92 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -188,8 +188,8 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) {
bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
LI = &getAnalysis<LoopInfo>();
LPM = &LPM_Ref;
- DF = getAnalysisToUpdate<DominanceFrontier>();
- DT = getAnalysisToUpdate<DominatorTree>();
+ DF = getAnalysisIfAvailable<DominanceFrontier>();
+ DT = getAnalysisIfAvailable<DominatorTree>();
currentLoop = L;
Function *F = currentLoop->getHeader()->getParent();
bool Changed = false;
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 18716b7e445b..83572d65dae3 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -123,15 +123,15 @@ namespace {
void RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocationInst *AI,
SmallVector<AllocaInst*, 32> &NewElts);
void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocationInst *AI,
- SmallVector<AllocaInst*, 32> &NewElts);
+ SmallVector<AllocaInst*, 32> &NewElts);
- const Type *CanConvertToScalar(Value *V, bool &IsNotTrivial);
- void ConvertToScalar(AllocationInst *AI, const Type *Ty);
- void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset);
+ bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
+ uint64_t Offset, unsigned AllocaSize);
+ void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset);
Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
- unsigned Offset);
- Value *ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI,
- unsigned Offset);
+ uint64_t Offset);
+ Value *ConvertUsesOfStoreToScalar(Value *StoredVal, AllocaInst *NewAI,
+ uint64_t Offset, Instruction *InsertPt);
static Instruction *isOnlyCopiedFromConstantGlobal(AllocationInst *AI);
};
}
@@ -223,27 +223,38 @@ bool SROA::performScalarRepl(Function &F) {
AI->eraseFromParent();
continue;
}
-
- // If we can turn this aggregate value (potentially with casts) into a
- // simple scalar value that can be mem2reg'd into a register value.
- bool IsNotTrivial = false;
- if (const Type *ActualType = CanConvertToScalar(AI, IsNotTrivial))
- if (IsNotTrivial && ActualType != Type::VoidTy) {
- ConvertToScalar(AI, ActualType);
- Changed = true;
- continue;
- }
+ // If this alloca is impossible for us to promote, reject it early.
+ if (AI->isArrayAllocation() || !AI->getAllocatedType()->isSized())
+ continue;
+
+ // Check to see if this allocation is only modified by a memcpy/memmove from
+ // a constant global. If this is the case, we can change all users to use
+ // the constant global instead. This is commonly produced by the CFE by
+ // constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A'
+ // is only subsequently read.
+ if (Instruction *TheCopy = isOnlyCopiedFromConstantGlobal(AI)) {
+ DOUT << "Found alloca equal to global: " << *AI;
+ DOUT << " memcpy = " << *TheCopy;
+ Constant *TheSrc = cast<Constant>(TheCopy->getOperand(2));
+ AI->replaceAllUsesWith(ConstantExpr::getBitCast(TheSrc, AI->getType()));
+ TheCopy->eraseFromParent(); // Don't mutate the global.
+ AI->eraseFromParent();
+ ++NumGlobals;
+ Changed = true;
+ continue;
+ }
+
// Check to see if we can perform the core SROA transformation. We cannot
// transform the allocation instruction if it is an array allocation
// (allocations OF arrays are ok though), and an allocation of a scalar
// value cannot be decomposed at all.
- if (!AI->isArrayAllocation() &&
- (isa<StructType>(AI->getAllocatedType()) ||
+ uint64_t AllocaSize = TD->getTypePaddedSize(AI->getAllocatedType());
+
+ if ((isa<StructType>(AI->getAllocatedType()) ||
isa<ArrayType>(AI->getAllocatedType())) &&
- AI->getAllocatedType()->isSized() &&
- // Do not promote any struct whose size is larger than "128" bytes.
- TD->getTypePaddedSize(AI->getAllocatedType()) < SRThreshold &&
+ // Do not promote any struct whose size is too big.
+ AllocaSize < SRThreshold &&
// Do not promote any struct into more than "32" separate vars.
getNumSAElements(AI->getAllocatedType()) < SRThreshold/4) {
// Check that all of the users of the allocation are capable of being
@@ -261,25 +272,40 @@ bool SROA::performScalarRepl(Function &F) {
continue;
}
}
-
- // Check to see if this allocation is only modified by a memcpy/memmove from
- // a constant global. If this is the case, we can change all users to use
- // the constant global instead. This is commonly produced by the CFE by
- // constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A'
- // is only subsequently read.
- if (Instruction *TheCopy = isOnlyCopiedFromConstantGlobal(AI)) {
- DOUT << "Found alloca equal to global: " << *AI;
- DOUT << " memcpy = " << *TheCopy;
- Constant *TheSrc = cast<Constant>(TheCopy->getOperand(2));
- AI->replaceAllUsesWith(ConstantExpr::getBitCast(TheSrc, AI->getType()));
- TheCopy->eraseFromParent(); // Don't mutate the global.
+
+ // If we can turn this aggregate value (potentially with casts) into a
+ // simple scalar value that can be mem2reg'd into a register value.
+ // IsNotTrivial tracks whether this is something that mem2reg could have
+ // promoted itself. If so, we don't want to transform it needlessly. Note
+ // that we can't just check based on the type: the alloca may be of an i32
+ // but that has pointer arithmetic to set byte 3 of it or something.
+ bool IsNotTrivial = false;
+ const Type *VectorTy = 0;
+ if (CanConvertToScalar(AI, IsNotTrivial, VectorTy,
+ 0, unsigned(AllocaSize)) && IsNotTrivial) {
+ AllocaInst *NewAI;
+ if (VectorTy && isa<VectorType>(VectorTy)) {
+ DOUT << "CONVERT TO VECTOR: " << *AI << " TYPE = " << *VectorTy <<"\n";
+
+ // Create and insert the vector alloca.
+ NewAI = new AllocaInst(VectorTy, 0, "", AI->getParent()->begin());
+ ConvertUsesToScalar(AI, NewAI, 0);
+ } else {
+ DOUT << "CONVERT TO SCALAR INTEGER: " << *AI << "\n";
+
+ // Create and insert the integer alloca.
+ const Type *NewTy = IntegerType::get(AllocaSize*8);
+ NewAI = new AllocaInst(NewTy, 0, "", AI->getParent()->begin());
+ ConvertUsesToScalar(AI, NewAI, 0);
+ }
+ NewAI->takeName(AI);
AI->eraseFromParent();
- ++NumGlobals;
+ ++NumConverted;
Changed = true;
continue;
}
-
- // Otherwise, couldn't process this.
+
+ // Otherwise, couldn't process this alloca.
}
return Changed;
@@ -476,11 +502,13 @@ void SROA::isSafeUseOfAllocation(Instruction *User, AllocationInst *AI,
if (BitCastInst *C = dyn_cast<BitCastInst>(User))
return isSafeUseOfBitCastedAllocation(C, AI, Info);
- if (isa<LoadInst>(User))
- return; // Loads (returning a first class aggregrate) are always rewritable
+ if (LoadInst *LI = dyn_cast<LoadInst>(User))
+ if (!LI->isVolatile())
+ return;// Loads (returning a first class aggregrate) are always rewritable
- if (isa<StoreInst>(User) && User->getOperand(0) != AI)
- return; // Store is ok if storing INTO the pointer, not storing the pointer
+ if (StoreInst *SI = dyn_cast<StoreInst>(User))
+ if (!SI->isVolatile() && SI->getOperand(0) != AI)
+ return;// Store is ok if storing INTO the pointer, not storing the pointer
GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User);
if (GEPI == 0)
@@ -590,6 +618,9 @@ void SROA::isSafeUseOfBitCastedAllocation(BitCastInst *BC, AllocationInst *AI,
} else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(UI)) {
isSafeMemIntrinsicOnAllocation(MI, AI, UI.getOperandNo(), Info);
} else if (StoreInst *SI = dyn_cast<StoreInst>(UI)) {
+ if (SI->isVolatile())
+ return MarkUnsafe(Info);
+
// If storing the entire alloca in one chunk through a bitcasted pointer
// to integer, we can transform it. This happens (for example) when you
// cast a {i32,i32}* to i64* and store through it. This is similar to the
@@ -602,6 +633,9 @@ void SROA::isSafeUseOfBitCastedAllocation(BitCastInst *BC, AllocationInst *AI,
}
return MarkUnsafe(Info);
} else if (LoadInst *LI = dyn_cast<LoadInst>(UI)) {
+ if (LI->isVolatile())
+ return MarkUnsafe(Info);
+
// If loading the entire alloca in one chunk through a bitcasted pointer
// to integer, we can transform it. This happens (for example) when you
// cast a {i32,i32}* to i64* and load through it. This is similar to the
@@ -1137,226 +1171,126 @@ void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) {
}
}
-/// MergeInType - Add the 'In' type to the accumulated type so far. If the
-/// types are incompatible, return true, otherwise update Accum and return
-/// false.
+/// MergeInType - Add the 'In' type to the accumulated type (Accum) so far at
+/// the offset specified by Offset (which is specified in bytes).
///
-/// There are three cases we handle here:
-/// 1) An effectively-integer union, where the pieces are stored into as
-/// smaller integers (common with byte swap and other idioms).
-/// 2) A union of vector types of the same size and potentially its elements.
+/// There are two cases we handle here:
+/// 1) A union of vector types of the same size and potentially its elements.
/// Here we turn element accesses into insert/extract element operations.
-/// 3) A union of scalar types, such as int/float or int/pointer. Here we
-/// merge together into integers, allowing the xform to work with #1 as
-/// well.
-static bool MergeInType(const Type *In, const Type *&Accum,
- const TargetData &TD) {
- // If this is our first type, just use it.
- const VectorType *PTy;
- if (Accum == Type::VoidTy || In == Accum) {
- Accum = In;
- } else if (In == Type::VoidTy) {
- // Noop.
- } else if (In->isInteger() && Accum->isInteger()) { // integer union.
- // Otherwise pick whichever type is larger.
- if (cast<IntegerType>(In)->getBitWidth() >
- cast<IntegerType>(Accum)->getBitWidth())
- Accum = In;
- } else if (isa<PointerType>(In) && isa<PointerType>(Accum)) {
- // Pointer unions just stay as one of the pointers.
- } else if (isa<VectorType>(In) || isa<VectorType>(Accum)) {
- if ((PTy = dyn_cast<VectorType>(Accum)) &&
- PTy->getElementType() == In) {
- // Accum is a vector, and we are accessing an element: ok.
- } else if ((PTy = dyn_cast<VectorType>(In)) &&
- PTy->getElementType() == Accum) {
- // In is a vector, and accum is an element: ok, remember In.
- Accum = In;
- } else if ((PTy = dyn_cast<VectorType>(In)) && isa<VectorType>(Accum) &&
- PTy->getBitWidth() == cast<VectorType>(Accum)->getBitWidth()) {
- // Two vectors of the same size: keep Accum.
- } else {
- // Cannot insert an short into a <4 x int> or handle
- // <2 x int> -> <4 x int>
- return true;
- }
- } else {
- // Pointer/FP/Integer unions merge together as integers.
- switch (Accum->getTypeID()) {
- case Type::PointerTyID: Accum = TD.getIntPtrType(); break;
- case Type::FloatTyID: Accum = Type::Int32Ty; break;
- case Type::DoubleTyID: Accum = Type::Int64Ty; break;
- case Type::X86_FP80TyID: return true;
- case Type::FP128TyID: return true;
- case Type::PPC_FP128TyID: return true;
- default:
- assert(Accum->isInteger() && "Unknown FP type!");
- break;
- }
-
- switch (In->getTypeID()) {
- case Type::PointerTyID: In = TD.getIntPtrType(); break;
- case Type::FloatTyID: In = Type::Int32Ty; break;
- case Type::DoubleTyID: In = Type::Int64Ty; break;
- case Type::X86_FP80TyID: return true;
- case Type::FP128TyID: return true;
- case Type::PPC_FP128TyID: return true;
- default:
- assert(In->isInteger() && "Unknown FP type!");
- break;
+/// This promotes a <4 x float> with a store of float to the third element
+/// into a <4 x float> that uses insert element.
+/// 2) A fully general blob of memory, which we turn into some (potentially
+/// large) integer type with extract and insert operations where the loads
+/// and stores would mutate the memory.
+static void MergeInType(const Type *In, uint64_t Offset, const Type *&VecTy,
+ unsigned AllocaSize, const TargetData &TD) {
+ // If this could be contributing to a vector, analyze it.
+ if (VecTy != Type::VoidTy) { // either null or a vector type.
+
+ // If the In type is a vector that is the same size as the alloca, see if it
+ // matches the existing VecTy.
+ if (const VectorType *VInTy = dyn_cast<VectorType>(In)) {
+ if (VInTy->getBitWidth()/8 == AllocaSize && Offset == 0) {
+ // If we're storing/loading a vector of the right size, allow it as a
+ // vector. If this the first vector we see, remember the type so that
+ // we know the element size.
+ if (VecTy == 0)
+ VecTy = VInTy;
+ return;
+ }
+ } else if (In == Type::FloatTy || In == Type::DoubleTy ||
+ (isa<IntegerType>(In) && 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
+ // compatible with it.
+ unsigned EltSize = In->getPrimitiveSizeInBits()/8;
+ if (Offset % EltSize == 0 &&
+ AllocaSize % EltSize == 0 &&
+ (VecTy == 0 ||
+ cast<VectorType>(VecTy)->getElementType()
+ ->getPrimitiveSizeInBits()/8 == EltSize)) {
+ if (VecTy == 0)
+ VecTy = VectorType::get(In, AllocaSize/EltSize);
+ return;
+ }
}
- return MergeInType(In, Accum, TD);
}
- return false;
-}
-
-/// getIntAtLeastAsBigAs - Return an integer type that is at least as big as the
-/// specified type. If there is no suitable type, this returns null.
-const Type *getIntAtLeastAsBigAs(unsigned NumBits) {
- if (NumBits > 64) return 0;
- if (NumBits > 32) return Type::Int64Ty;
- if (NumBits > 16) return Type::Int32Ty;
- if (NumBits > 8) return Type::Int16Ty;
- return Type::Int8Ty;
+
+ // Otherwise, we have a case that we can't handle with an optimized vector
+ // form. We can still turn this into a large integer.
+ VecTy = Type::VoidTy;
}
-/// CanConvertToScalar - V is a pointer. If we can convert the pointee to a
-/// single scalar integer type, return that type. Further, if the use is not
-/// a completely trivial use that mem2reg could promote, set IsNotTrivial. If
-/// there are no uses of this pointer, return Type::VoidTy to differentiate from
-/// failure.
+/// CanConvertToScalar - V is a pointer. If we can convert the pointee and all
+/// its accesses to use a to single vector type, return true, and set VecTy to
+/// the new type. If we could convert the alloca into a single promotable
+/// integer, return true but set VecTy to VoidTy. Further, if the use is not a
+/// completely trivial use that mem2reg could promote, set IsNotTrivial. Offset
+/// is the current offset from the base of the alloca being analyzed.
///
-const Type *SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial) {
- const Type *UsedType = Type::VoidTy; // No uses, no forced type.
- const PointerType *PTy = cast<PointerType>(V->getType());
-
+bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial,
+ const Type *&VecTy, uint64_t Offset,
+ unsigned AllocaSize) {
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) {
Instruction *User = cast<Instruction>(*UI);
if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
- // FIXME: Loads of a first class aggregrate value could be converted to a
- // series of loads and insertvalues
- if (!LI->getType()->isSingleValueType())
- return 0;
-
- if (MergeInType(LI->getType(), UsedType, *TD))
- return 0;
+ // Don't break volatile loads.
+ if (LI->isVolatile())
+ return false;
+ MergeInType(LI->getType(), Offset, VecTy, AllocaSize, *TD);
continue;
}
if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
// Storing the pointer, not into the value?
- if (SI->getOperand(0) == V) return 0;
-
- // FIXME: Stores of a first class aggregrate value could be converted to a
- // series of extractvalues and stores
- if (!SI->getOperand(0)->getType()->isSingleValueType())
- return 0;
-
- // NOTE: We could handle storing of FP imms into integers here!
-
- if (MergeInType(SI->getOperand(0)->getType(), UsedType, *TD))
- return 0;
+ if (SI->getOperand(0) == V || SI->isVolatile()) return 0;
+ MergeInType(SI->getOperand(0)->getType(), Offset, VecTy, AllocaSize, *TD);
continue;
}
- if (BitCastInst *CI = dyn_cast<BitCastInst>(User)) {
+
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
+ if (!CanConvertToScalar(BCI, IsNotTrivial, VecTy, Offset, AllocaSize))
+ return false;
IsNotTrivial = true;
- const Type *SubTy = CanConvertToScalar(CI, IsNotTrivial);
- if (!SubTy || MergeInType(SubTy, UsedType, *TD)) return 0;
continue;
}
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(User)) {
- // Check to see if this is stepping over an element: GEP Ptr, int C
- if (GEP->getNumOperands() == 2 && isa<ConstantInt>(GEP->getOperand(1))) {
- unsigned Idx = cast<ConstantInt>(GEP->getOperand(1))->getZExtValue();
- unsigned ElSize = TD->getTypePaddedSize(PTy->getElementType());
- unsigned BitOffset = Idx*ElSize*8;
- if (BitOffset > 64 || !isPowerOf2_32(ElSize)) return 0;
-
- IsNotTrivial = true;
- const Type *SubElt = CanConvertToScalar(GEP, IsNotTrivial);
- if (SubElt == 0) return 0;
- if (SubElt != Type::VoidTy && SubElt->isInteger()) {
- const Type *NewTy =
- getIntAtLeastAsBigAs(TD->getTypePaddedSizeInBits(SubElt)+BitOffset);
- if (NewTy == 0 || MergeInType(NewTy, UsedType, *TD)) return 0;
- continue;
- }
- // Cannot handle this!
- return 0;
- }
+ // If this is a GEP with a variable indices, we can't handle it.
+ if (!GEP->hasAllConstantIndices())
+ return false;
- if (GEP->getNumOperands() == 3 &&
- isa<ConstantInt>(GEP->getOperand(1)) &&
- isa<ConstantInt>(GEP->getOperand(2)) &&
- cast<ConstantInt>(GEP->getOperand(1))->isZero()) {
- // We are stepping into an element, e.g. a structure or an array:
- // GEP Ptr, i32 0, i32 Cst
- const Type *AggTy = PTy->getElementType();
- unsigned Idx = cast<ConstantInt>(GEP->getOperand(2))->getZExtValue();
-
- if (const ArrayType *ATy = dyn_cast<ArrayType>(AggTy)) {
- if (Idx >= ATy->getNumElements()) return 0; // Out of range.
- } else if (const VectorType *VectorTy = dyn_cast<VectorType>(AggTy)) {
- // Getting an element of the vector.
- if (Idx >= VectorTy->getNumElements()) return 0; // Out of range.
-
- // Merge in the vector type.
- if (MergeInType(VectorTy, UsedType, *TD)) return 0;
-
- const Type *SubTy = CanConvertToScalar(GEP, IsNotTrivial);
- if (SubTy == 0) return 0;
-
- if (SubTy != Type::VoidTy && MergeInType(SubTy, UsedType, *TD))
- return 0;
-
- // We'll need to change this to an insert/extract element operation.
- IsNotTrivial = true;
- continue; // Everything looks ok
-
- } else if (isa<StructType>(AggTy)) {
- // Structs are always ok.
- } else {
- return 0;
- }
- const Type *NTy =
- getIntAtLeastAsBigAs(TD->getTypePaddedSizeInBits(AggTy));
- if (NTy == 0 || MergeInType(NTy, UsedType, *TD)) return 0;
- const Type *SubTy = CanConvertToScalar(GEP, IsNotTrivial);
- if (SubTy == 0) return 0;
- if (SubTy != Type::VoidTy && MergeInType(SubTy, UsedType, *TD))
- return 0;
- continue; // Everything looks ok
- }
- return 0;
+ // Compute the offset that this GEP adds to the pointer.
+ SmallVector<Value*, 8> Indices(GEP->op_begin()+1, GEP->op_end());
+ uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(),
+ &Indices[0], Indices.size());
+ // See if all uses can be converted.
+ if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, Offset+GEPOffset,
+ AllocaSize))
+ return false;
+ IsNotTrivial = true;
+ continue;
}
- // Cannot handle this!
- return 0;
+ // If this is a constant sized memset of a constant value (e.g. 0) we can
+ // handle it.
+ if (isa<MemSetInst>(User) &&
+ // Store of constant value.
+ isa<ConstantInt>(User->getOperand(2)) &&
+ // Store with constant size.
+ isa<ConstantInt>(User->getOperand(3))) {
+ VecTy = Type::VoidTy;
+ IsNotTrivial = true;
+ continue;
+ }
+
+ // Otherwise, we cannot handle this!
+ return false;
}
- return UsedType;
-}
-
-/// ConvertToScalar - The specified alloca passes the CanConvertToScalar
-/// predicate and is non-trivial. Convert it to something that can be trivially
-/// promoted into a register by mem2reg.
-void SROA::ConvertToScalar(AllocationInst *AI, const Type *ActualTy) {
- DOUT << "CONVERT TO SCALAR: " << *AI << " TYPE = "
- << *ActualTy << "\n";
- ++NumConverted;
-
- BasicBlock *EntryBlock = AI->getParent();
- assert(EntryBlock == &EntryBlock->getParent()->getEntryBlock() &&
- "Not in the entry block!");
- EntryBlock->getInstList().remove(AI); // Take the alloca out of the program.
-
- // Create and insert the alloca.
- AllocaInst *NewAI = new AllocaInst(ActualTy, 0, AI->getName(),
- EntryBlock->begin());
- ConvertUsesToScalar(AI, NewAI, 0);
- delete AI;
+ return true;
}
@@ -1367,105 +1301,87 @@ void SROA::ConvertToScalar(AllocationInst *AI, const Type *ActualTy) {
///
/// Offset is an offset from the original alloca, in bits that need to be
/// shifted to the right. By the end of this, there should be no uses of Ptr.
-void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) {
+void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
while (!Ptr->use_empty()) {
Instruction *User = cast<Instruction>(Ptr->use_back());
-
+
if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
- Value *NV = ConvertUsesOfLoadToScalar(LI, NewAI, Offset);
- LI->replaceAllUsesWith(NV);
+ LI->replaceAllUsesWith(ConvertUsesOfLoadToScalar(LI, NewAI, Offset));
LI->eraseFromParent();
continue;
}
-
+
if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
assert(SI->getOperand(0) != Ptr && "Consistency error!");
-
- Value *SV = ConvertUsesOfStoreToScalar(SI, NewAI, Offset);
- new StoreInst(SV, NewAI, SI);
+ new StoreInst(ConvertUsesOfStoreToScalar(SI->getOperand(0), NewAI,
+ Offset, SI), NewAI, SI);
SI->eraseFromParent();
continue;
}
-
+
if (BitCastInst *CI = dyn_cast<BitCastInst>(User)) {
ConvertUsesToScalar(CI, NewAI, Offset);
CI->eraseFromParent();
continue;
}
-
+
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(User)) {
- const PointerType *AggPtrTy =
- cast<PointerType>(GEP->getOperand(0)->getType());
- unsigned AggSizeInBits =
- TD->getTypePaddedSizeInBits(AggPtrTy->getElementType());
-
- // Check to see if this is stepping over an element: GEP Ptr, int C
- unsigned NewOffset = Offset;
- if (GEP->getNumOperands() == 2) {
- unsigned Idx = cast<ConstantInt>(GEP->getOperand(1))->getZExtValue();
- unsigned BitOffset = Idx*AggSizeInBits;
-
- NewOffset += BitOffset;
- ConvertUsesToScalar(GEP, NewAI, NewOffset);
- GEP->eraseFromParent();
- continue;
- }
+ // Compute the offset that this GEP adds to the pointer.
+ SmallVector<Value*, 8> Indices(GEP->op_begin()+1, GEP->op_end());
+ uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(),
+ &Indices[0], Indices.size());
+ ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8);
+ GEP->eraseFromParent();
+ continue;
+ }
+
+ // If this is a constant sized memset of a constant value (e.g. 0) we can
+ // transform it into a store of the expanded constant value.
+ if (MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
+ assert(MSI->getRawDest() == Ptr && "Consistency error!");
+ unsigned NumBytes = cast<ConstantInt>(MSI->getLength())->getZExtValue();
+ unsigned Val = cast<ConstantInt>(MSI->getValue())->getZExtValue();
- assert(GEP->getNumOperands() == 3 && "Unsupported operation");
+ // Compute the value replicated the right number of times.
+ APInt APVal(NumBytes*8, Val);
+
+ // Splat the value if non-zero.
+ if (Val)
+ for (unsigned i = 1; i != NumBytes; ++i)
+ APVal |= APVal << 8;
- // We know that operand #2 is zero.
- unsigned Idx = cast<ConstantInt>(GEP->getOperand(2))->getZExtValue();
- const Type *AggTy = AggPtrTy->getElementType();
- if (const SequentialType *SeqTy = dyn_cast<SequentialType>(AggTy)) {
- unsigned ElSizeBits =
- TD->getTypePaddedSizeInBits(SeqTy->getElementType());
-
- NewOffset += ElSizeBits*Idx;
- } else {
- const StructType *STy = cast<StructType>(AggTy);
- unsigned EltBitOffset =
- TD->getStructLayout(STy)->getElementOffsetInBits(Idx);
-
- NewOffset += EltBitOffset;
- }
- ConvertUsesToScalar(GEP, NewAI, NewOffset);
- GEP->eraseFromParent();
+ new StoreInst(ConvertUsesOfStoreToScalar(ConstantInt::get(APVal), NewAI,
+ Offset, MSI), NewAI, MSI);
+ MSI->eraseFromParent();
continue;
}
+
assert(0 && "Unsupported operation!");
abort();
}
}
-/// ConvertUsesOfLoadToScalar - Convert all of the users the specified load to
-/// use the new alloca directly, returning the value that should replace the
-/// load. This happens when we are converting an "integer union" to a
-/// single integer scalar, or when we are converting a "vector union" to a
-/// vector with insert/extractelement instructions.
+/// ConvertUsesOfLoadToScalar - Convert all of the users of the specified load
+/// to use the new alloca directly, returning the value that should replace the
+/// load. This happens when we are converting an "integer union" to a single
+/// integer scalar, or when we are converting a "vector union" to a vector with
+/// insert/extractelement instructions.
///
/// Offset is an offset from the original alloca, in bits that need to be
/// shifted to the right. By the end of this, there should be no uses of Ptr.
-Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
- unsigned Offset) {
+Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
+ uint64_t Offset) {
// The load is a bit extract from NewAI shifted right by Offset bits.
Value *NV = new LoadInst(NewAI, LI->getName(), LI);
-
- if (NV->getType() == LI->getType() && Offset == 0) {
- // We win, no conversion needed.
+
+ // If the load is of the whole new alloca, no conversion is needed.
+ if (NV->getType() == LI->getType() && Offset == 0)
return NV;
- }
- // If the result type of the 'union' is a pointer, then this must be ptr->ptr
- // cast. Anything else would result in NV being an integer.
- if (isa<PointerType>(NV->getType())) {
- assert(isa<PointerType>(LI->getType()));
- return new BitCastInst(NV, LI->getType(), LI->getName(), LI);
- }
-
+ // 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>(NV->getType())) {
- // If the result alloca is a vector type, this is either an element
- // access or a bitcast to another vector type.
if (isa<VectorType>(LI->getType()))
return new BitCastInst(NV, LI->getType(), LI->getName(), LI);
@@ -1474,18 +1390,19 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
if (Offset) {
unsigned EltSize = TD->getTypePaddedSizeInBits(VTy->getElementType());
Elt = Offset/EltSize;
- Offset -= EltSize*Elt;
+ assert(EltSize*Elt == Offset && "Invalid modulus in validity checking");
}
- NV = new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt),
- "tmp", LI);
-
- // If we're done, return this element.
- if (NV->getType() == LI->getType() && Offset == 0)
- return NV;
+ // Return the element extracted out of it.
+ Value *V = new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt),
+ "tmp", LI);
+ if (V->getType() != LI->getType())
+ V = new BitCastInst(V, LI->getType(), "tmp", LI);
+ return V;
}
-
+
+ // Otherwise, this must be a union that was converted to an integer value.
const IntegerType *NTy = cast<IntegerType>(NV->getType());
-
+
// If this is a big-endian system and the load is narrower than the
// full alloca type, we need to do a shift to get the right bits.
int ShAmt = 0;
@@ -1498,29 +1415,30 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
} else {
ShAmt = Offset;
}
-
+
// Note: we support negative bitwidths (with shl) which are not defined.
// We do this to support (f.e.) loads off the end of a structure where
// only some bits are used.
if (ShAmt > 0 && (unsigned)ShAmt < NTy->getBitWidth())
- NV = BinaryOperator::CreateLShr(NV,
- ConstantInt::get(NV->getType(),ShAmt),
+ NV = BinaryOperator::CreateLShr(NV,
+ ConstantInt::get(NV->getType(), ShAmt),
LI->getName(), LI);
else if (ShAmt < 0 && (unsigned)-ShAmt < NTy->getBitWidth())
- NV = BinaryOperator::CreateShl(NV,
- ConstantInt::get(NV->getType(),-ShAmt),
+ NV = BinaryOperator::CreateShl(NV,
+ ConstantInt::get(NV->getType(), -ShAmt),
LI->getName(), LI);
-
+
// Finally, unconditionally truncate the integer to the right width.
unsigned LIBitWidth = TD->getTypeSizeInBits(LI->getType());
if (LIBitWidth < NTy->getBitWidth())
NV = new TruncInst(NV, IntegerType::get(LIBitWidth),
LI->getName(), LI);
-
+
// If the result is an integer, this is a trunc or bitcast.
if (isa<IntegerType>(LI->getType())) {
// Should be done.
- } else if (LI->getType()->isFloatingPoint()) {
+ } else if (LI->getType()->isFloatingPoint() ||
+ isa<VectorType>(LI->getType())) {
// Just do a bitcast, we know the sizes match up.
NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
} else {
@@ -1540,91 +1458,101 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
///
/// Offset is an offset from the original alloca, in bits that need to be
/// shifted to the right. By the end of this, there should be no uses of Ptr.
-Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI,
- unsigned Offset) {
-
+Value *SROA::ConvertUsesOfStoreToScalar(Value *SV, AllocaInst *NewAI,
+ uint64_t Offset, Instruction *IP) {
+
// Convert the stored type to the actual type, shift it left to insert
// then 'or' into place.
- Value *SV = SI->getOperand(0);
const Type *AllocaType = NewAI->getType()->getElementType();
- if (SV->getType() == AllocaType && Offset == 0) {
- // All is well.
- } else if (const VectorType *PTy = dyn_cast<VectorType>(AllocaType)) {
- Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI);
-
+ if (SV->getType() == AllocaType && Offset == 0)
+ return SV;
+
+ if (const VectorType *VTy = dyn_cast<VectorType>(AllocaType)) {
+ Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", IP);
+
// If the result alloca is a vector type, this is either an element
// access or a bitcast to another vector type.
if (isa<VectorType>(SV->getType())) {
- SV = new BitCastInst(SV, AllocaType, SV->getName(), SI);
+ SV = new BitCastInst(SV, AllocaType, SV->getName(), IP);
} else {
// Must be an element insertion.
- unsigned Elt = Offset/TD->getTypePaddedSizeInBits(PTy->getElementType());
+ unsigned Elt = Offset/TD->getTypePaddedSizeInBits(VTy->getElementType());
+
+ if (SV->getType() != VTy->getElementType())
+ SV = new BitCastInst(SV, VTy->getElementType(), "tmp", IP);
+
SV = InsertElementInst::Create(Old, SV,
ConstantInt::get(Type::Int32Ty, Elt),
- "tmp", SI);
- }
- } else if (isa<PointerType>(AllocaType)) {
- // If the alloca type is a pointer, then all the elements must be
- // pointers.
- if (SV->getType() != AllocaType)
- SV = new BitCastInst(SV, AllocaType, SV->getName(), SI);
- } else {
- Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI);
-
- // If SV is a float, convert it to the appropriate integer type.
- // If it is a pointer, do the same, and also handle ptr->ptr casts
- // here.
- unsigned SrcWidth = TD->getTypeSizeInBits(SV->getType());
- unsigned DestWidth = TD->getTypeSizeInBits(AllocaType);
- unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType());
- unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType);
- if (SV->getType()->isFloatingPoint())
- SV = new BitCastInst(SV, IntegerType::get(SrcWidth),
- SV->getName(), SI);
- else if (isa<PointerType>(SV->getType()))
- SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), SI);
-
- // Always zero extend the value if needed.
- if (SV->getType() != AllocaType)
- SV = new ZExtInst(SV, AllocaType, SV->getName(), SI);
-
- // If this is a big-endian system and the store is narrower than the
- // full alloca type, we need to do a shift to get the right bits.
- int ShAmt = 0;
- if (TD->isBigEndian()) {
- // On big-endian machines, the lowest bit is stored at the bit offset
- // from the pointer given by getTypeStoreSizeInBits. This matters for
- // integers with a bitwidth that is not a multiple of 8.
- ShAmt = DestStoreWidth - SrcStoreWidth - Offset;
- } else {
- ShAmt = Offset;
- }
-
- // Note: we support negative bitwidths (with shr) which are not defined.
- // We do this to support (f.e.) stores off the end of a structure where
- // only some bits in the structure are set.
- APInt Mask(APInt::getLowBitsSet(DestWidth, SrcWidth));
- if (ShAmt > 0 && (unsigned)ShAmt < DestWidth) {
- SV = BinaryOperator::CreateShl(SV,
- ConstantInt::get(SV->getType(), ShAmt),
- SV->getName(), SI);
- Mask <<= ShAmt;
- } else if (ShAmt < 0 && (unsigned)-ShAmt < DestWidth) {
- SV = BinaryOperator::CreateLShr(SV,
- ConstantInt::get(SV->getType(),-ShAmt),
- SV->getName(), SI);
- Mask = Mask.lshr(ShAmt);
+ "tmp", IP);
}
-
- // Mask out the bits we are about to insert from the old value, and or
- // in the new bits.
- if (SrcWidth != DestWidth) {
- assert(DestWidth > SrcWidth);
- Old = BinaryOperator::CreateAnd(Old, ConstantInt::get(~Mask),
- Old->getName()+".mask", SI);
- SV = BinaryOperator::CreateOr(Old, SV, SV->getName()+".ins", SI);
+ return SV;
+ }
+
+
+ Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", IP);
+
+ // If SV is a float, convert it to the appropriate integer type.
+ // If it is a pointer, do the same, and also handle ptr->ptr casts
+ // here.
+ unsigned SrcWidth = TD->getTypeSizeInBits(SV->getType());
+ unsigned DestWidth = TD->getTypeSizeInBits(AllocaType);
+ unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType());
+ unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType);
+ if (SV->getType()->isFloatingPoint() || isa<VectorType>(SV->getType()))
+ SV = new BitCastInst(SV, IntegerType::get(SrcWidth), SV->getName(), IP);
+ else if (isa<PointerType>(SV->getType()))
+ SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), IP);
+
+ // Zero extend or truncate the value if needed.
+ if (SV->getType() != AllocaType) {
+ if (SV->getType()->getPrimitiveSizeInBits() <
+ AllocaType->getPrimitiveSizeInBits())
+ SV = new ZExtInst(SV, AllocaType, SV->getName(), IP);
+ else {
+ // Truncation may be needed if storing more than the alloca can hold
+ // (undefined behavior).
+ SV = new TruncInst(SV, AllocaType, SV->getName(), IP);
+ SrcWidth = DestWidth;
+ SrcStoreWidth = DestStoreWidth;
}
}
+
+ // If this is a big-endian system and the store is narrower than the
+ // full alloca type, we need to do a shift to get the right bits.
+ int ShAmt = 0;
+ if (TD->isBigEndian()) {
+ // On big-endian machines, the lowest bit is stored at the bit offset
+ // from the pointer given by getTypeStoreSizeInBits. This matters for
+ // integers with a bitwidth that is not a multiple of 8.
+ ShAmt = DestStoreWidth - SrcStoreWidth - Offset;
+ } else {
+ ShAmt = Offset;
+ }
+
+ // Note: we support negative bitwidths (with shr) which are not defined.
+ // We do this to support (f.e.) stores off the end of a structure where
+ // only some bits in the structure are set.
+ APInt Mask(APInt::getLowBitsSet(DestWidth, SrcWidth));
+ if (ShAmt > 0 && (unsigned)ShAmt < DestWidth) {
+ SV = BinaryOperator::CreateShl(SV,
+ ConstantInt::get(SV->getType(), ShAmt),
+ SV->getName(), IP);
+ Mask <<= ShAmt;
+ } else if (ShAmt < 0 && (unsigned)-ShAmt < DestWidth) {
+ SV = BinaryOperator::CreateLShr(SV,
+ ConstantInt::get(SV->getType(), -ShAmt),
+ SV->getName(), IP);
+ Mask = Mask.lshr(-ShAmt);
+ }
+
+ // Mask out the bits we are about to insert from the old value, and or
+ // in the new bits.
+ if (SrcWidth != DestWidth) {
+ assert(DestWidth > SrcWidth);
+ Old = BinaryOperator::CreateAnd(Old, ConstantInt::get(~Mask),
+ Old->getName()+".mask", IP);
+ SV = BinaryOperator::CreateOr(Old, SV, SV->getName()+".ins", IP);
+ }
return SV;
}
@@ -1653,10 +1581,11 @@ static bool PointsToConstantGlobal(Value *V) {
static bool isOnlyCopiedFromConstantGlobal(Value *V, Instruction *&TheCopy,
bool isOffset) {
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) {
- if (isa<LoadInst>(*UI)) {
- // Ignore loads, they are always ok.
- continue;
- }
+ if (LoadInst *LI = dyn_cast<LoadInst>(*UI))
+ // Ignore non-volatile loads, they are always ok.
+ if (!LI->isVolatile())
+ continue;
+
if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI)) {
// If uses of the bitcast are ok, we are ok.
if (!isOnlyCopiedFromConstantGlobal(BCI, TheCopy, isOffset))
diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp
index 431424ee9f39..7b633b20077d 100644
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -136,7 +136,7 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
// Finally, erase the old block and update dominator info.
if (P) {
- if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) {
+ if (DominatorTree* DT = P->getAnalysisIfAvailable<DominatorTree>()) {
DomTreeNode* DTN = DT->getNode(BB);
DomTreeNode* PredDTN = DT->getNode(PredBB);
@@ -299,11 +299,11 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P) {
BasicBlock *New = Old->splitBasicBlock(SplitIt, Old->getName()+".split");
// The new block lives in whichever loop the old one did.
- if (LoopInfo* LI = P->getAnalysisToUpdate<LoopInfo>())
+ if (LoopInfo* LI = P->getAnalysisIfAvailable<LoopInfo>())
if (Loop *L = LI->getLoopFor(Old))
L->addBasicBlockToLoop(New, LI->getBase());
- if (DominatorTree *DT = P->getAnalysisToUpdate<DominatorTree>())
+ if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>())
{
// Old dominates New. New node domiantes all other nodes dominated by Old.
DomTreeNode *OldNode = DT->getNode(Old);
@@ -319,7 +319,7 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P) {
DT->changeImmediateDominator(*I, NewNode);
}
- if (DominanceFrontier *DF = P->getAnalysisToUpdate<DominanceFrontier>())
+ if (DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>())
DF->splitBlock(Old);
return New;
@@ -350,12 +350,12 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB);
// Update dominator tree and dominator frontier if available.
- DominatorTree *DT = P ? P->getAnalysisToUpdate<DominatorTree>() : 0;
+ DominatorTree *DT = P ? P->getAnalysisIfAvailable<DominatorTree>() : 0;
if (DT)
DT->splitBlock(NewBB);
- if (DominanceFrontier *DF = P ? P->getAnalysisToUpdate<DominanceFrontier>():0)
+ if (DominanceFrontier *DF = P ? P->getAnalysisIfAvailable<DominanceFrontier>():0)
DF->splitBlock(NewBB);
- AliasAnalysis *AA = P ? P->getAnalysisToUpdate<AliasAnalysis>() : 0;
+ AliasAnalysis *AA = P ? P->getAnalysisIfAvailable<AliasAnalysis>() : 0;
// Insert a new PHI node into NewBB for every PHI node in BB and that new PHI
diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp
index a32c01671282..c4fd1eae43cd 100644
--- a/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -187,7 +187,7 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
bool NewBBDominatesDestBB = true;
// Should we update DominatorTree information?
- if (DominatorTree *DT = P->getAnalysisToUpdate<DominatorTree>()) {
+ if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>()) {
DomTreeNode *TINode = DT->getNode(TIBB);
// The new block is not the immediate dominator for any other nodes, but
@@ -218,7 +218,7 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
}
// Should we update DominanceFrontier information?
- if (DominanceFrontier *DF = P->getAnalysisToUpdate<DominanceFrontier>()) {
+ if (DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>()) {
// If NewBBDominatesDestBB hasn't been computed yet, do so with DF.
if (!OtherPreds.empty()) {
// FIXME: IMPLEMENT THIS!
@@ -252,7 +252,7 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
}
// Update LoopInfo if it is around.
- if (LoopInfo *LI = P->getAnalysisToUpdate<LoopInfo>()) {
+ if (LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>()) {
// 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.
if (Loop *TIL = LI->getLoopFor(TIBB))
diff --git a/lib/Transforms/Utils/CloneLoop.cpp b/lib/Transforms/Utils/CloneLoop.cpp
index d52d79598f05..a0306ffa5272 100644
--- a/lib/Transforms/Utils/CloneLoop.cpp
+++ b/lib/Transforms/Utils/CloneLoop.cpp
@@ -79,8 +79,8 @@ Loop *llvm::CloneLoop(Loop *OrigL, LPPassManager *LPM, LoopInfo *LI,
DominatorTree *DT = NULL;
DominanceFrontier *DF = NULL;
if (P) {
- DT = P->getAnalysisToUpdate<DominatorTree>();
- DF = P->getAnalysisToUpdate<DominanceFrontier>();
+ DT = P->getAnalysisIfAvailable<DominatorTree>();
+ DF = P->getAnalysisIfAvailable<DominanceFrontier>();
}
SmallVector<BasicBlock *, 16> NewBlocks;
diff --git a/lib/Transforms/Utils/InlineCost.cpp b/lib/Transforms/Utils/InlineCost.cpp
index 80516723d0ca..69cd9343f8c7 100644
--- a/lib/Transforms/Utils/InlineCost.cpp
+++ b/lib/Transforms/Utils/InlineCost.cpp
@@ -119,7 +119,7 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
NeverInline = true;
return;
}
-
+
// Calls often compile into many machine instructions. Bump up their
// cost to reflect this.
if (!isa<IntrinsicInst>(II))
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index cee224aae524..eb136b503497 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -37,11 +37,12 @@ bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD) {
/// in the body of the inlined function into invokes and turn unwind
/// instructions into branches to the invoke unwind dest.
///
-/// II is the invoke instruction begin inlined. FirstNewBlock is the first
+/// II is the invoke instruction being inlined. FirstNewBlock is the first
/// block of the inlined code (the last block is the end of the function),
/// and InlineCodeInfo is information about the code that got inlined.
static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
- ClonedCodeInfo &InlinedCodeInfo) {
+ ClonedCodeInfo &InlinedCodeInfo,
+ CallGraph *CG) {
BasicBlock *InvokeDest = II->getUnwindDest();
std::vector<Value*> InvokeDestPHIValues;
@@ -93,6 +94,10 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
// Make sure that anything using the call now uses the invoke!
CI->replaceAllUsesWith(II);
+ // Update the callgraph.
+ if (CG)
+ (*CG)[Caller]->replaceCallSite(CI, II);
+
// Delete the unconditional branch inserted by splitBasicBlock
BB->getInstList().pop_back();
Split->getInstList().pop_front(); // Delete the original call
@@ -433,7 +438,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
// any inlined 'unwind' instructions into branches to the invoke exception
// destination, and call instructions into invoke instructions.
if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall))
- HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo);
+ HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo, CG);
// If we cloned in _exactly one_ basic block, and if that block ends in a
// return instruction, we splice the body of the inlined callee directly into
diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp
index 385588861154..9cd7e69557ad 100644
--- a/lib/Transforms/Utils/LCSSA.cpp
+++ b/lib/Transforms/Utils/LCSSA.cpp
@@ -175,8 +175,7 @@ void LCSSA::ProcessInstruction(Instruction *Instr,
UI != E;) {
BasicBlock *UserBB = cast<Instruction>(*UI)->getParent();
if (PHINode *P = dyn_cast<PHINode>(*UI)) {
- unsigned OperandNo = UI.getOperandNo();
- UserBB = P->getIncomingBlock(OperandNo/2);
+ UserBB = P->getIncomingBlock(UI);
}
// If the user is in the loop, don't rewrite it!
@@ -212,8 +211,7 @@ void LCSSA::getLoopValuesUsedOutsideLoop(Loop *L,
++UI) {
BasicBlock *UserBB = cast<Instruction>(*UI)->getParent();
if (PHINode* p = dyn_cast<PHINode>(*UI)) {
- unsigned OperandNo = UI.getOperandNo();
- UserBB = p->getIncomingBlock(OperandNo/2);
+ UserBB = p->getIncomingBlock(UI);
}
if (*BB != UserBB && !inLoop(UserBB)) {
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index b8077aefb132..c22485342e09 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -38,8 +38,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
// Branch - See if we are conditional jumping on constant
if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
if (BI->isUnconditional()) return false; // Can't optimize uncond branch
- BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
- BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));
+ BasicBlock *Dest1 = BI->getSuccessor(0);
+ BasicBlock *Dest2 = BI->getSuccessor(1);
if (ConstantInt *Cond = dyn_cast<ConstantInt>(BI->getCondition())) {
// Are we branching on constant?
diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp
index af41036252b2..03d273d25d79 100644
--- a/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/lib/Transforms/Utils/LoopSimplify.cpp
@@ -112,7 +112,7 @@ FunctionPass *llvm::createLoopSimplifyPass() { return new LoopSimplify(); }
bool LoopSimplify::runOnFunction(Function &F) {
bool Changed = false;
LI = &getAnalysis<LoopInfo>();
- AA = getAnalysisToUpdate<AliasAnalysis>();
+ AA = getAnalysisIfAvailable<AliasAnalysis>();
DT = &getAnalysis<DominatorTree>();
// Check to see that no blocks (other than the header) in loops have
@@ -595,6 +595,6 @@ void LoopSimplify::InsertUniqueBackedgeBlock(Loop *L) {
// Update dominator information
DT->splitBlock(BEBlock);
- if (DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>())
+ if (DominanceFrontier *DF = getAnalysisIfAvailable<DominanceFrontier>())
DF->splitBlock(BEBlock);
}
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp
index b09ab93aa11d..f33c1a23f238 100644
--- a/lib/VMCore/Instruction.cpp
+++ b/lib/VMCore/Instruction.cpp
@@ -278,8 +278,7 @@ bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const {
continue;
}
- unsigned UseOperand = UI.getOperandNo();
- if (PN->getIncomingBlock(UseOperand/2) != BB)
+ if (PN->getIncomingBlock(UI) != BB)
return true;
}
return false;
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
index 35cbe906b701..6db5d7e24c5e 100644
--- a/lib/VMCore/Pass.cpp
+++ b/lib/VMCore/Pass.cpp
@@ -37,7 +37,7 @@ Pass::~Pass() {
ModulePass::~ModulePass() { }
bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const {
- return Resolver->getAnalysisToUpdate(AnalysisID, true) != 0;
+ return Resolver->getAnalysisIfAvailable(AnalysisID, true) != 0;
}
// dumpPassStructure - Implement the -debug-passes=Structure option
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index 690c485fe20d..f2bfaefe0f78 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -679,7 +679,7 @@ void PMDataManager::verifyDomInfo(Pass &P, Function &F) {
if (!VerifyDomInfo || !P.getResolver())
return;
- DominatorTree *DT = P.getAnalysisToUpdate<DominatorTree>();
+ DominatorTree *DT = P.getAnalysisIfAvailable<DominatorTree>();
if (!DT)
return;
@@ -695,7 +695,7 @@ void PMDataManager::verifyDomInfo(Pass &P, Function &F) {
assert (0 && "Invalid dominator info");
}
- DominanceFrontier *DF = P.getAnalysisToUpdate<DominanceFrontier>();
+ DominanceFrontier *DF = P.getAnalysisIfAvailable<DominanceFrontier>();
if (!DF)
return;
@@ -1088,8 +1088,8 @@ PMDataManager::~PMDataManager() {
//===----------------------------------------------------------------------===//
// NOTE: Is this the right place to define this method ?
-// getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
-Pass *AnalysisResolver::getAnalysisToUpdate(AnalysisID ID, bool dir) const {
+// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
+Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
return PM.findAnalysisPass(ID, dir);
}
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 384aa3ec4bce..62d2930ae072 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -715,6 +715,8 @@ void Verifier::visitTruncInst(TruncInst &I) {
Assert1(SrcTy->isIntOrIntVector(), "Trunc only operates on integer", &I);
Assert1(DestTy->isIntOrIntVector(), "Trunc only produces integer", &I);
+ Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
+ "trunc source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for Trunc", &I);
visitInstruction(I);
@@ -728,6 +730,8 @@ void Verifier::visitZExtInst(ZExtInst &I) {
// 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),
+ "zext source and destination must both be a vector or neither", &I);
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
@@ -747,6 +751,8 @@ void Verifier::visitSExtInst(SExtInst &I) {
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),
+ "sext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"Type too small for SExt", &I);
visitInstruction(I);
@@ -762,6 +768,8 @@ void Verifier::visitFPTruncInst(FPTruncInst &I) {
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),
+ "fptrunc source and destination must both be a vector or neither",&I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for FPTrunc", &I);
visitInstruction(I);
@@ -778,6 +786,8 @@ void Verifier::visitFPExtInst(FPExtInst &I) {
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),
+ "fpext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"DestTy too small for FPExt", &I);
visitInstruction(I);
diff --git a/test/Assembler/2009-02-01-UnnamedForwardRef.ll b/test/Assembler/2009-02-01-UnnamedForwardRef.ll
new file mode 100644
index 000000000000..9c6e20d7335e
--- /dev/null
+++ b/test/Assembler/2009-02-01-UnnamedForwardRef.ll
@@ -0,0 +1,6 @@
+; RUN: llvm-as < %s | llvm-dis
+; PR3372
+
+@X = global i32* @0
+global i32 4
+
diff --git a/test/Assembler/vector-cmp.ll b/test/Assembler/vector-cmp.ll
new file mode 100644
index 000000000000..383c0faf6206
--- /dev/null
+++ b/test/Assembler/vector-cmp.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep {global.*vicmp slt}
+; PR2317
+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-darwin9.2.2"
+
+define <4 x i32> @foo(<4 x float> %a, <4 x float> %b) nounwind {
+entry:
+ %cmp = vfcmp olt <4 x float> %a, %b ; <4 x i32> [#uses=1]
+ ret <4 x i32> %cmp
+}
+
+global <4 x i32> vicmp slt ( <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> <i32 1, i32 2, i32 1, i32 2> ) ;
+
+@B = external global i32;
+
+global <4 x i32> vicmp slt ( <4 x i32> <i32 ptrtoint (i32 * @B to i32), i32 1, i32 1, i32 1>, <4 x i32> <i32 1, i32 2, i32 1, i32 2> ) ;
diff --git a/test/Bitcode/extractelement.ll b/test/Bitcode/extractelement.ll
new file mode 100644
index 000000000000..04cb131f6e7f
--- /dev/null
+++ b/test/Bitcode/extractelement.ll
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -constprop | llvm-dis
+; PR3465
+
+define double @test() {
+ %tmp24 = extractelement <2 x double> bitcast (<1 x i128> < i128 85070591730234615870450834276742070272 > to <2 x double>), i32 0
+ ret double %tmp24
+}
+
diff --git a/test/CodeGen/CellSPU/fcmp.ll b/test/CodeGen/CellSPU/fcmp32.ll
index aad77175d163..27a659e82930 100644
--- a/test/CodeGen/CellSPU/fcmp.ll
+++ b/test/CodeGen/CellSPU/fcmp32.ll
@@ -1,22 +1,23 @@
; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
; RUN: grep fceq %t1.s | count 1
; RUN: grep fcmeq %t1.s | count 1
-;
-; This file includes standard floating point arithmetic instructions
+
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
+; Exercise the floating point comparison operators for f32:
+
declare double @fabs(double)
declare float @fabsf(float)
define i1 @fcmp_eq(float %arg1, float %arg2) {
- %A = fcmp oeq float %arg1, %arg2 ; <float> [#uses=1]
+ %A = fcmp oeq float %arg1, %arg2
ret i1 %A
}
define i1 @fcmp_mag_eq(float %arg1, float %arg2) {
- %A = call float @fabsf(float %arg1) ; <float> [#uses=1]
- %B = call float @fabsf(float %arg2) ; <float> [#uses=1]
- %C = fcmp oeq float %A, %B ; <float> [#uses=1]
- ret i1 %C
+ %1 = call float @fabsf(float %arg1)
+ %2 = call float @fabsf(float %arg2)
+ %3 = fcmp oeq float %1, %2
+ ret i1 %3
}
diff --git a/test/CodeGen/CellSPU/fcmp64.ll b/test/CodeGen/CellSPU/fcmp64.ll
new file mode 100644
index 000000000000..1906bfe7ddaa
--- /dev/null
+++ b/test/CodeGen/CellSPU/fcmp64.ll
@@ -0,0 +1,7 @@
+; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
+
+define i1 @fcmp_eq_setcc_f64(double %arg1, double %arg2) nounwind {
+entry:
+ %A = fcmp oeq double %arg1, %arg2
+ ret i1 %A
+}
diff --git a/test/CodeGen/CellSPU/fneg-fabs.ll b/test/CodeGen/CellSPU/fneg-fabs.ll
index 70220a563d94..b6eca10803ec 100644
--- a/test/CodeGen/CellSPU/fneg-fabs.ll
+++ b/test/CodeGen/CellSPU/fneg-fabs.ll
@@ -1,9 +1,10 @@
; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
-; RUN: grep fsmbi %t1.s | count 2
+; RUN: grep fsmbi %t1.s | count 3
; RUN: grep 32768 %t1.s | count 2
; RUN: grep xor %t1.s | count 4
-; RUN: grep and %t1.s | count 4
-; RUN: grep andbi %t1.s | count 2
+; RUN: grep and %t1.s | count 5
+; RUN: grep andbi %t1.s | count 3
+
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
@@ -33,11 +34,11 @@ declare double @fabs(double)
declare float @fabsf(float)
define double @fabs_dp(double %X) {
- %Y = call double @fabs( double %X ) ; <double> [#uses=1]
+ %Y = call double @fabs( double %X )
ret double %Y
}
define float @fabs_sp(float %X) {
- %Y = call float @fabsf( float %X ) ; <float> [#uses=1]
+ %Y = call float @fabsf( float %X )
ret float %Y
}
diff --git a/test/CodeGen/CellSPU/select_bits.ll b/test/CodeGen/CellSPU/select_bits.ll
index 3a7334d808cf..e83e47606c28 100644
--- a/test/CodeGen/CellSPU/select_bits.ll
+++ b/test/CodeGen/CellSPU/select_bits.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
-; RUN: grep selb %t1.s | count 280
+; RUN: grep selb %t1.s | count 56
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
@@ -9,7 +9,7 @@ target triple = "spu"
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
-define <2 x i64> @selb_v2i64_01(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_01(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rC, %rB
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
@@ -18,7 +18,7 @@ define <2 x i64> @selb_v2i64_01(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
}
; (or (and rB, rC), (and (not rC), rA))
-define <2 x i64> @selb_v2i64_02(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_02(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rB, %rC
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
@@ -27,7 +27,7 @@ define <2 x i64> @selb_v2i64_02(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
}
; (or (and (not rC), rA), (and rB, rC))
-define <2 x i64> @selb_v2i64_03(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_03(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
%C = and <2 x i64> %rB, %rC
@@ -36,7 +36,7 @@ define <2 x i64> @selb_v2i64_03(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
}
; (or (and (not rC), rA), (and rC, rB))
-define <2 x i64> @selb_v2i64_04(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_04(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
%C = and <2 x i64> %rC, %rB
@@ -45,7 +45,7 @@ define <2 x i64> @selb_v2i64_04(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
}
; (or (and rC, rB), (and rA, (not rC)))
-define <2 x i64> @selb_v2i64_05(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_05(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rC, %rB
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
@@ -54,7 +54,7 @@ define <2 x i64> @selb_v2i64_05(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
}
; (or (and rB, rC), (and rA, (not rC)))
-define <2 x i64> @selb_v2i64_06(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_06(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rB, %rC
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
@@ -63,7 +63,7 @@ define <2 x i64> @selb_v2i64_06(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
}
; (or (and rA, (not rC)), (and rB, rC))
-define <2 x i64> @selb_v2i64_07(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_07(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
%C = and <2 x i64> %rB, %rC
@@ -72,7 +72,7 @@ define <2 x i64> @selb_v2i64_07(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
}
; (or (and rA, (not rC)), (and rC, rB))
-define <2 x i64> @selb_v2i64_08(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
+define <2 x i64> @selectbits_v2i64_08(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
%C = and <2 x i64> %rC, %rB
@@ -85,7 +85,7 @@ define <2 x i64> @selb_v2i64_08(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
-define <4 x i32> @selb_v4i32_01(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_01(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rC, %rB
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %A, %rA
@@ -94,7 +94,7 @@ define <4 x i32> @selb_v4i32_01(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
}
; (or (and rB, rC), (and (not rC), rA))
-define <4 x i32> @selb_v4i32_02(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_02(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rB, %rC
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %A, %rA
@@ -103,7 +103,7 @@ define <4 x i32> @selb_v4i32_02(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
}
; (or (and (not rC), rA), (and rB, rC))
-define <4 x i32> @selb_v4i32_03(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_03(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %A, %rA
%C = and <4 x i32> %rB, %rC
@@ -112,7 +112,7 @@ define <4 x i32> @selb_v4i32_03(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
}
; (or (and (not rC), rA), (and rC, rB))
-define <4 x i32> @selb_v4i32_04(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_04(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %A, %rA
%C = and <4 x i32> %rC, %rB
@@ -121,7 +121,7 @@ define <4 x i32> @selb_v4i32_04(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
}
; (or (and rC, rB), (and rA, (not rC)))
-define <4 x i32> @selb_v4i32_05(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_05(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rC, %rB
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
@@ -130,7 +130,7 @@ define <4 x i32> @selb_v4i32_05(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
}
; (or (and rB, rC), (and rA, (not rC)))
-define <4 x i32> @selb_v4i32_06(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_06(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rB, %rC
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
@@ -139,7 +139,7 @@ define <4 x i32> @selb_v4i32_06(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
}
; (or (and rA, (not rC)), (and rB, rC))
-define <4 x i32> @selb_v4i32_07(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_07(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
%C = and <4 x i32> %rB, %rC
@@ -148,7 +148,7 @@ define <4 x i32> @selb_v4i32_07(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
}
; (or (and rA, (not rC)), (and rC, rB))
-define <4 x i32> @selb_v4i32_08(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
+define <4 x i32> @selectbits_v4i32_08(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
%C = and <4 x i32> %rC, %rB
@@ -161,7 +161,7 @@ define <4 x i32> @selb_v4i32_08(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
-define <8 x i16> @selb_v8i16_01(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_01(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rC, %rB
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
@@ -171,7 +171,7 @@ define <8 x i16> @selb_v8i16_01(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
}
; (or (and rB, rC), (and (not rC), rA))
-define <8 x i16> @selb_v8i16_02(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_02(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rB, %rC
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
@@ -181,7 +181,7 @@ define <8 x i16> @selb_v8i16_02(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
}
; (or (and (not rC), rA), (and rB, rC))
-define <8 x i16> @selb_v8i16_03(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_03(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %A, %rA
@@ -191,7 +191,7 @@ define <8 x i16> @selb_v8i16_03(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
}
; (or (and (not rC), rA), (and rC, rB))
-define <8 x i16> @selb_v8i16_04(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_04(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %A, %rA
@@ -201,7 +201,7 @@ define <8 x i16> @selb_v8i16_04(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
}
; (or (and rC, rB), (and rA, (not rC)))
-define <8 x i16> @selb_v8i16_05(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_05(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rC, %rB
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
@@ -211,7 +211,7 @@ define <8 x i16> @selb_v8i16_05(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
}
; (or (and rB, rC), (and rA, (not rC)))
-define <8 x i16> @selb_v8i16_06(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_06(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rB, %rC
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
@@ -221,7 +221,7 @@ define <8 x i16> @selb_v8i16_06(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
}
; (or (and rA, (not rC)), (and rB, rC))
-define <8 x i16> @selb_v8i16_07(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_07(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %rA, %A
@@ -231,7 +231,7 @@ define <8 x i16> @selb_v8i16_07(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
}
; (or (and rA, (not rC)), (and rC, rB))
-define <8 x i16> @selb_v8i16_08(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
+define <8 x i16> @selectbits_v8i16_08(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %rA, %A
@@ -245,7 +245,7 @@ define <8 x i16> @selb_v8i16_08(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
-define <16 x i8> @selb_v16i8_01(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_01(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rC, %rB
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -257,7 +257,7 @@ define <16 x i8> @selb_v16i8_01(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
}
; (or (and rB, rC), (and (not rC), rA))
-define <16 x i8> @selb_v16i8_02(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_02(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rB, %rC
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -269,7 +269,7 @@ define <16 x i8> @selb_v16i8_02(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
}
; (or (and (not rC), rA), (and rB, rC))
-define <16 x i8> @selb_v16i8_03(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_03(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -281,7 +281,7 @@ define <16 x i8> @selb_v16i8_03(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
}
; (or (and (not rC), rA), (and rC, rB))
-define <16 x i8> @selb_v16i8_04(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_04(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -293,7 +293,7 @@ define <16 x i8> @selb_v16i8_04(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
}
; (or (and rC, rB), (and rA, (not rC)))
-define <16 x i8> @selb_v16i8_05(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_05(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rC, %rB
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -305,7 +305,7 @@ define <16 x i8> @selb_v16i8_05(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
}
; (or (and rB, rC), (and rA, (not rC)))
-define <16 x i8> @selb_v16i8_06(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_06(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rB, %rC
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -317,7 +317,7 @@ define <16 x i8> @selb_v16i8_06(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
}
; (or (and rA, (not rC)), (and rB, rC))
-define <16 x i8> @selb_v16i8_07(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_07(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -329,7 +329,7 @@ define <16 x i8> @selb_v16i8_07(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
}
; (or (and rA, (not rC)), (and rC, rB))
-define <16 x i8> @selb_v16i8_08(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
+define <16 x i8> @selectbits_v16i8_08(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
@@ -345,7 +345,7 @@ define <16 x i8> @selb_v16i8_08(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
-define i32 @selb_i32_01(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_01(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rC, %rB
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
@@ -354,7 +354,7 @@ define i32 @selb_i32_01(i32 %rA, i32 %rB, i32 %rC) {
}
; (or (and rB, rC), (and (not rC), rA))
-define i32 @selb_i32_02(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_02(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rB, %rC
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
@@ -363,7 +363,7 @@ define i32 @selb_i32_02(i32 %rA, i32 %rB, i32 %rC) {
}
; (or (and (not rC), rA), (and rB, rC))
-define i32 @selb_i32_03(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_03(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
%C = and i32 %rB, %rC
@@ -372,7 +372,7 @@ define i32 @selb_i32_03(i32 %rA, i32 %rB, i32 %rC) {
}
; (or (and (not rC), rA), (and rC, rB))
-define i32 @selb_i32_04(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_04(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
%C = and i32 %rC, %rB
@@ -381,7 +381,7 @@ define i32 @selb_i32_04(i32 %rA, i32 %rB, i32 %rC) {
}
; (or (and rC, rB), (and rA, (not rC)))
-define i32 @selb_i32_05(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_05(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rC, %rB
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
@@ -390,7 +390,7 @@ define i32 @selb_i32_05(i32 %rA, i32 %rB, i32 %rC) {
}
; (or (and rB, rC), (and rA, (not rC)))
-define i32 @selb_i32_06(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_06(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rB, %rC
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
@@ -399,7 +399,7 @@ define i32 @selb_i32_06(i32 %rA, i32 %rB, i32 %rC) {
}
; (or (and rA, (not rC)), (and rB, rC))
-define i32 @selb_i32_07(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_07(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
%C = and i32 %rB, %rC
@@ -408,7 +408,7 @@ define i32 @selb_i32_07(i32 %rA, i32 %rB, i32 %rC) {
}
; (or (and rA, (not rC)), (and rC, rB))
-define i32 @selb_i32_08(i32 %rA, i32 %rB, i32 %rC) {
+define i32 @selectbits_i32_08(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
%C = and i32 %rC, %rB
@@ -421,7 +421,7 @@ define i32 @selb_i32_08(i32 %rA, i32 %rB, i32 %rC) {
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
-define i16 @selb_i16_01(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_01(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rC, %rB
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
@@ -430,7 +430,7 @@ define i16 @selb_i16_01(i16 %rA, i16 %rB, i16 %rC) {
}
; (or (and rB, rC), (and (not rC), rA))
-define i16 @selb_i16_02(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_02(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rB, %rC
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
@@ -439,7 +439,7 @@ define i16 @selb_i16_02(i16 %rA, i16 %rB, i16 %rC) {
}
; (or (and (not rC), rA), (and rB, rC))
-define i16 @selb_i16_03(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_03(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
%C = and i16 %rB, %rC
@@ -448,7 +448,7 @@ define i16 @selb_i16_03(i16 %rA, i16 %rB, i16 %rC) {
}
; (or (and (not rC), rA), (and rC, rB))
-define i16 @selb_i16_04(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_04(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
%C = and i16 %rC, %rB
@@ -457,7 +457,7 @@ define i16 @selb_i16_04(i16 %rA, i16 %rB, i16 %rC) {
}
; (or (and rC, rB), (and rA, (not rC)))
-define i16 @selb_i16_05(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_05(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rC, %rB
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
@@ -466,7 +466,7 @@ define i16 @selb_i16_05(i16 %rA, i16 %rB, i16 %rC) {
}
; (or (and rB, rC), (and rA, (not rC)))
-define i16 @selb_i16_06(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_06(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rB, %rC
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
@@ -475,7 +475,7 @@ define i16 @selb_i16_06(i16 %rA, i16 %rB, i16 %rC) {
}
; (or (and rA, (not rC)), (and rB, rC))
-define i16 @selb_i16_07(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_07(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
%C = and i16 %rB, %rC
@@ -484,7 +484,7 @@ define i16 @selb_i16_07(i16 %rA, i16 %rB, i16 %rC) {
}
; (or (and rA, (not rC)), (and rC, rB))
-define i16 @selb_i16_08(i16 %rA, i16 %rB, i16 %rC) {
+define i16 @selectbits_i16_08(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
%C = and i16 %rC, %rB
@@ -497,7 +497,7 @@ define i16 @selb_i16_08(i16 %rA, i16 %rB, i16 %rC) {
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
-define i8 @selb_i8_01(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_01(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rC, %rB
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
@@ -506,7 +506,7 @@ define i8 @selb_i8_01(i8 %rA, i8 %rB, i8 %rC) {
}
; (or (and rB, rC), (and (not rC), rA))
-define i8 @selb_i8_02(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_02(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rB, %rC
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
@@ -515,7 +515,7 @@ define i8 @selb_i8_02(i8 %rA, i8 %rB, i8 %rC) {
}
; (or (and (not rC), rA), (and rB, rC))
-define i8 @selb_i8_03(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_03(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
%C = and i8 %rB, %rC
@@ -524,7 +524,7 @@ define i8 @selb_i8_03(i8 %rA, i8 %rB, i8 %rC) {
}
; (or (and (not rC), rA), (and rC, rB))
-define i8 @selb_i8_04(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_04(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
%C = and i8 %rC, %rB
@@ -533,7 +533,7 @@ define i8 @selb_i8_04(i8 %rA, i8 %rB, i8 %rC) {
}
; (or (and rC, rB), (and rA, (not rC)))
-define i8 @selb_i8_05(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_05(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rC, %rB
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
@@ -542,7 +542,7 @@ define i8 @selb_i8_05(i8 %rA, i8 %rB, i8 %rC) {
}
; (or (and rB, rC), (and rA, (not rC)))
-define i8 @selb_i8_06(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_06(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rB, %rC
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
@@ -551,7 +551,7 @@ define i8 @selb_i8_06(i8 %rA, i8 %rB, i8 %rC) {
}
; (or (and rA, (not rC)), (and rB, rC))
-define i8 @selb_i8_07(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_07(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
%C = and i8 %rB, %rC
@@ -560,7 +560,7 @@ define i8 @selb_i8_07(i8 %rA, i8 %rB, i8 %rC) {
}
; (or (and rA, (not rC)), (and rC, rB))
-define i8 @selb_i8_08(i8 %rA, i8 %rB, i8 %rC) {
+define i8 @selectbits_i8_08(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
%C = and i8 %rC, %rB
diff --git a/test/CodeGen/CellSPU/shift_ops.ll b/test/CodeGen/CellSPU/shift_ops.ll
index 2df2f96435d3..3c26baa7c7ab 100644
--- a/test/CodeGen/CellSPU/shift_ops.ll
+++ b/test/CodeGen/CellSPU/shift_ops.ll
@@ -275,3 +275,9 @@ define i64 @ashr_i64_3(i64 %arg1, i32 %shift) {
%2 = ashr i64 %arg1, %1
ret i64 %2
}
+
+define i32 @hi32_i64(i64 %arg) {
+ %1 = lshr i64 %arg, 32
+ %2 = trunc i64 %1 to i32
+ ret i32 %2
+}
diff --git a/test/CodeGen/CellSPU/sp_farith.ll b/test/CodeGen/CellSPU/sp_farith.ll
index 949e69a5a3d4..df3baef85c9d 100644
--- a/test/CodeGen/CellSPU/sp_farith.ll
+++ b/test/CodeGen/CellSPU/sp_farith.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
+; RUN: llvm-as -o - %s | llc -march=cellspu -enable-unsafe-fp-math > %t1.s
; RUN: grep fa %t1.s | count 2
; RUN: grep fs %t1.s | count 2
; RUN: grep fm %t1.s | count 6
diff --git a/test/CodeGen/PowerPC/private.ll b/test/CodeGen/PowerPC/private.ll
index e25d2936b71e..0f0d13492a08 100644
--- a/test/CodeGen/PowerPC/private.ll
+++ b/test/CodeGen/PowerPC/private.ll
@@ -5,6 +5,11 @@
; RUN: grep bl.*\.Lfoo %t
; RUN: grep .Lbaz: %t
; RUN: grep lis.*\.Lbaz %t
+; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin > %t
+; RUN: grep L_foo: %t
+; RUN: grep bl.*\L_foo %t
+; RUN: grep L_baz: %t
+; RUN: grep lis.*\L_baz %t
declare void @foo()
diff --git a/test/CodeGen/X86/2006-07-19-ATTAsm.ll b/test/CodeGen/X86/2006-07-19-ATTAsm.ll
index f426e529f016..78167f631e1b 100644
--- a/test/CodeGen/X86/2006-07-19-ATTAsm.ll
+++ b/test/CodeGen/X86/2006-07-19-ATTAsm.ll
@@ -10,7 +10,7 @@ target triple = "i386-unknown-freebsd6.1"
%llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8 *, i8*, { }*, i32, { }*, i1, i1, { }* }
@x = global i32 0 ; <i32*> [#uses=1]
@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type {
- i32 458804,
+ i32 327732,
{ }* 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]* @str, i64 0, i64 0),
diff --git a/test/CodeGen/X86/2008-02-22-ReMatBug.ll b/test/CodeGen/X86/2008-02-22-ReMatBug.ll
index f78d52651ded..539fc15fcba5 100644
--- a/test/CodeGen/X86/2008-02-22-ReMatBug.ll
+++ b/test/CodeGen/X86/2008-02-22-ReMatBug.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of re-materialization} | grep 3
+; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of re-materialization} | grep 4
; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of dead spill slots removed}
; rdar://5761454
diff --git a/test/CodeGen/X86/2008-07-19-movups-spills.ll b/test/CodeGen/X86/2008-07-19-movups-spills.ll
index ef5c7c50f66e..880035715f83 100644
--- a/test/CodeGen/X86/2008-07-19-movups-spills.ll
+++ b/test/CodeGen/X86/2008-07-19-movups-spills.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux -realign-stack=1 -mattr=sse2 | grep movaps | count 76
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux -realign-stack=1 -mattr=sse2 | grep movaps | count 75
; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux -realign-stack=0 -mattr=sse2 | grep movaps | count 1
; PR2539
diff --git a/test/CodeGen/X86/2008-07-23-VSetCC.ll b/test/CodeGen/X86/2008-07-23-VSetCC.ll
new file mode 100644
index 000000000000..735c610bc7a9
--- /dev/null
+++ b/test/CodeGen/X86/2008-07-23-VSetCC.ll
@@ -0,0 +1,30 @@
+; RUN: llvm-as < %s | llc -march=x86 -mcpu=pentium
+; PR2575
+
+define void @entry(i32 %m_task_id, i32 %start_x, i32 %end_x) nounwind {
+ br i1 false, label %bb.nph, label %._crit_edge
+
+bb.nph: ; preds = %bb.nph, %0
+ vicmp sgt <4 x i32> zeroinitializer, < i32 -128, i32 -128, i32 -128, i32 -128 > ; <<4 x i32>>:1 [#uses=1]
+ extractelement <4 x i32> %1, i32 3 ; <i32>:2 [#uses=1]
+ lshr i32 %2, 31 ; <i32>:3 [#uses=1]
+ trunc i32 %3 to i1 ; <i1>:4 [#uses=1]
+ select i1 %4, i32 -1, i32 0 ; <i32>:5 [#uses=1]
+ insertelement <4 x i32> zeroinitializer, i32 %5, i32 3 ; <<4 x i32>>:6 [#uses=1]
+ and <4 x i32> zeroinitializer, %6 ; <<4 x i32>>:7 [#uses=1]
+ bitcast <4 x i32> %7 to <4 x float> ; <<4 x float>>:8 [#uses=1]
+ mul <4 x float> zeroinitializer, %8 ; <<4 x float>>:9 [#uses=1]
+ bitcast <4 x float> %9 to <4 x i32> ; <<4 x i32>>:10 [#uses=1]
+ or <4 x i32> %10, zeroinitializer ; <<4 x i32>>:11 [#uses=1]
+ bitcast <4 x i32> %11 to <4 x float> ; <<4 x float>>:12 [#uses=1]
+ mul <4 x float> %12, < float 1.000000e+02, float 1.000000e+02, float 1.000000e+02, float 1.000000e+02 > ; <<4 x float>>:13 [#uses=1]
+ sub <4 x float> %13, < float 1.000000e+02, float 1.000000e+02, float 1.000000e+02, float 1.000000e+02 > ; <<4 x float>>:14 [#uses=1]
+ extractelement <4 x float> %14, i32 3 ; <float>:15 [#uses=1]
+ call float @fmaxf( float 0.000000e+00, float %15 ) ; <float>:16 [#uses=0]
+ br label %bb.nph
+
+._crit_edge: ; preds = %0
+ ret void
+}
+
+declare float @fmaxf(float, float)
diff --git a/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll b/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll
index 61240979ac3b..f793b524e61f 100644
--- a/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll
+++ b/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll
@@ -1,5 +1,5 @@
-; RUN: llvm-as < %s | llc -mcpu=yonah | grep pxor | count 2
-; RUN: llvm-as < %s | llc -mcpu=yonah | not grep movapd
+; RUN: llvm-as < %s | llc -mcpu=core2 | grep pxor | count 2
+; RUN: llvm-as < %s | llc -mcpu=core2 | not grep movapd
; PR2715
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"
diff --git a/test/CodeGen/X86/2009-01-25-NoSSE.ll b/test/CodeGen/X86/2009-01-25-NoSSE.ll
new file mode 100644
index 000000000000..b12e4137dbd5
--- /dev/null
+++ b/test/CodeGen/X86/2009-01-25-NoSSE.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llc -march=x86-64 -mattr=-sse,-sse2 | not grep xmm
+; PR3402
+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.ktermios = type { i32, i32, i32, i32, i8, [19 x i8], i32, i32 }
+
+define void @foo() nounwind {
+entry:
+ %termios = alloca %struct.ktermios, align 8
+ %termios1 = bitcast %struct.ktermios* %termios to i8*
+ call void @llvm.memset.i64(i8* %termios1, i8 0, i64 44, i32 8)
+ call void @bar(%struct.ktermios* %termios) nounwind
+ ret void
+}
+
+declare void @llvm.memset.i64(i8* nocapture, i8, i64, i32) nounwind
+
+declare void @bar(%struct.ktermios*)
+
diff --git a/test/CodeGen/X86/2009-01-26-WrongCheck.ll b/test/CodeGen/X86/2009-01-26-WrongCheck.ll
new file mode 100644
index 000000000000..db9dbb67def4
--- /dev/null
+++ b/test/CodeGen/X86/2009-01-26-WrongCheck.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | llc -march=x86 -enable-legalize-types-checking
+; PR3393
+
+define void @foo(i32 inreg %x) {
+ %t709 = select i1 false, i32 0, i32 %x ; <i32> [#uses=1]
+ %t711 = add i32 %t709, 1 ; <i32> [#uses=4]
+ %t801 = icmp slt i32 %t711, 0 ; <i1> [#uses=1]
+ %t712 = zext i32 %t711 to i64 ; <i64> [#uses=1]
+ %t804 = select i1 %t801, i64 0, i64 %t712 ; <i64> [#uses=1]
+ store i64 %t804, i64* null
+ %t815 = icmp slt i32 %t711, 0 ; <i1> [#uses=1]
+ %t814 = sext i32 %t711 to i64 ; <i64> [#uses=1]
+ %t816 = select i1 %t815, i64 0, i64 %t814 ; <i64> [#uses=1]
+ store i64 %t816, i64* null
+ unreachable
+}
diff --git a/test/CodeGen/X86/2009-01-27-NullStrings.ll b/test/CodeGen/X86/2009-01-27-NullStrings.ll
new file mode 100644
index 000000000000..b0c27d8903e7
--- /dev/null
+++ b/test/CodeGen/X86/2009-01-27-NullStrings.ll
@@ -0,0 +1,38 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin | grep {\\.cstring} | count 1
+ %struct.A = type { }
+ %struct.NSString = type opaque
+ %struct.__builtin_CFString = type { i32*, i32, i8*, i32 }
+ %struct._objc_module = type { i32, i32, i8*, %struct._objc_symtab* }
+ %struct._objc_symtab = type { i32, %struct.objc_selector**, i16, i16 }
+ %struct.objc_object = type opaque
+ %struct.objc_selector = type opaque
+@"\01L_unnamed_cfstring_0" = internal constant %struct.__builtin_CFString { i32* getelementptr ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr ([1 x i8]* @"\01LC", i32 0, i32 0), i32 0 }, section "__DATA, __cfstring" ; <%struct.__builtin_CFString*> [#uses=1]
+@__CFConstantStringClassReference = external global [0 x i32] ; <[0 x i32]*> [#uses=1]
+@"\01LC" = internal constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1]
+@"\01L_OBJC_SELECTOR_REFERENCES_0" = internal global %struct.objc_selector* bitcast ([6 x i8]* @"\01L_OBJC_METH_VAR_NAME_0" to %struct.objc_selector*), section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4 ; <%struct.objc_selector**> [#uses=2]
+@"\01L_OBJC_SYMBOLS" = internal global %struct._objc_symtab zeroinitializer, section "__OBJC,__symbols,regular,no_dead_strip", align 4 ; <%struct._objc_symtab*> [#uses=2]
+@"\01L_OBJC_METH_VAR_NAME_0" = internal global [6 x i8] c"bork:\00", section "__TEXT,__cstring,cstring_literals", align 1 ; <[6 x i8]*> [#uses=2]
+@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] zeroinitializer, section "__OBJC, __image_info,regular" ; <[2 x i32]*> [#uses=1]
+@"\01L_OBJC_CLASS_NAME_0" = internal global [1 x i8] zeroinitializer, section "__TEXT,__cstring,cstring_literals", align 1 ; <[1 x i8]*> [#uses=1]
+@"\01L_OBJC_MODULES" = internal global %struct._objc_module { i32 7, i32 16, i8* getelementptr ([1 x i8]* @"\01L_OBJC_CLASS_NAME_0", i32 0, i32 0), %struct._objc_symtab* @"\01L_OBJC_SYMBOLS" }, section "__OBJC,__module_info,regular,no_dead_strip", align 4 ; <%struct._objc_module*> [#uses=1]
+@llvm.used = appending global [6 x i8*] [ i8* bitcast (%struct.objc_selector** @"\01L_OBJC_SELECTOR_REFERENCES_0" to i8*), i8* bitcast (%struct._objc_symtab* @"\01L_OBJC_SYMBOLS" to i8*), i8* getelementptr ([6 x i8]* @"\01L_OBJC_METH_VAR_NAME_0", i32 0, i32 0), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*), i8* getelementptr ([1 x i8]* @"\01L_OBJC_CLASS_NAME_0", i32 0, i32 0), i8* bitcast (%struct._objc_module* @"\01L_OBJC_MODULES" to i8*) ], section "llvm.metadata" ; <[6 x i8*]*> [#uses=0]
+
+define void @func(%struct.A* %a) nounwind {
+entry:
+ %a_addr = alloca %struct.A* ; <%struct.A**> [#uses=2]
+ %a.0 = alloca %struct.objc_object* ; <%struct.objc_object**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %struct.A* %a, %struct.A** %a_addr
+ %0 = load %struct.A** %a_addr, align 4 ; <%struct.A*> [#uses=1]
+ %1 = bitcast %struct.A* %0 to %struct.objc_object* ; <%struct.objc_object*> [#uses=1]
+ store %struct.objc_object* %1, %struct.objc_object** %a.0, align 4
+ %2 = load %struct.objc_selector** @"\01L_OBJC_SELECTOR_REFERENCES_0", align 4 ; <%struct.objc_selector*> [#uses=1]
+ %3 = load %struct.objc_object** %a.0, align 4 ; <%struct.objc_object*> [#uses=1]
+ call void bitcast (%struct.objc_object* (%struct.objc_object*, %struct.objc_selector*, ...)* @objc_msgSend to void (%struct.objc_object*, %struct.objc_selector*, %struct.NSString*)*)(%struct.objc_object* %3, %struct.objc_selector* %2, %struct.NSString* bitcast (%struct.__builtin_CFString* @"\01L_unnamed_cfstring_0" to %struct.NSString*)) nounwind
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+declare %struct.objc_object* @objc_msgSend(%struct.objc_object*, %struct.objc_selector*, ...)
diff --git a/test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll b/test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll
new file mode 100644
index 000000000000..b7f37c9d3102
--- /dev/null
+++ b/test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll
@@ -0,0 +1,38 @@
+; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9.6 -regalloc=local -disable-fp-elim
+; rdar://6538384
+
+ %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.Lit = type { i32 }
+ %struct.StreamBuffer = type { %struct.FILE*, [1048576 x i8], i32, i32 }
+ %struct.__sFILEX = type opaque
+ %struct.__sbuf = type { i8*, i32 }
+
+declare fastcc i32 @_Z8parseIntI12StreamBufferEiRT_(%struct.StreamBuffer*)
+
+declare i8* @llvm.eh.exception() nounwind
+
+define i32 @main(i32 %argc, i8** nocapture %argv) noreturn {
+entry:
+ %0 = invoke fastcc i32 @_Z8parseIntI12StreamBufferEiRT_(%struct.StreamBuffer* null)
+ to label %bb1.i16.i.i unwind label %lpad.i.i ; <i32> [#uses=0]
+
+bb1.i16.i.i: ; preds = %entry
+ br i1 false, label %bb.i.i.i.i, label %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i
+
+bb.i.i.i.i: ; preds = %bb1.i16.i.i
+ br label %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i
+
+_ZN3vecI3LitE4pushERKS0_.exit.i.i.i: ; preds = %bb.i.i.i.i, %bb1.i16.i.i
+ %lits.i.i.0.0 = phi %struct.Lit* [ null, %bb1.i16.i.i ], [ null, %bb.i.i.i.i ] ; <%struct.Lit*> [#uses=1]
+ %1 = invoke fastcc i32 @_Z8parseIntI12StreamBufferEiRT_(%struct.StreamBuffer* null)
+ to label %.noexc21.i.i unwind label %lpad.i.i ; <i32> [#uses=0]
+
+.noexc21.i.i: ; preds = %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i
+ unreachable
+
+lpad.i.i: ; preds = %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i, %entry
+ %lits.i.i.0.3 = phi %struct.Lit* [ %lits.i.i.0.0, %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i ], [ null, %entry ] ; <%struct.Lit*> [#uses=1]
+ %eh_ptr.i.i = call i8* @llvm.eh.exception() ; <i8*> [#uses=0]
+ free %struct.Lit* %lits.i.i.0.3
+ unreachable
+}
diff --git a/test/CodeGen/X86/2009-01-31-BigShift.ll b/test/CodeGen/X86/2009-01-31-BigShift.ll
new file mode 100644
index 000000000000..360b4f0e46bf
--- /dev/null
+++ b/test/CodeGen/X86/2009-01-31-BigShift.ll
@@ -0,0 +1,9 @@
+; RUN: llvm-as < %s | llc -march=x86 | not grep and
+; PR3401
+
+define void @x(i288 %i) nounwind {
+ call void @add(i288 %i)
+ ret void
+}
+
+declare void @add(i288)
diff --git a/test/CodeGen/X86/2009-01-31-BigShift2.ll b/test/CodeGen/X86/2009-01-31-BigShift2.ll
new file mode 100644
index 000000000000..2b5b18957830
--- /dev/null
+++ b/test/CodeGen/X86/2009-01-31-BigShift2.ll
@@ -0,0 +1,11 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep {mov.*56}
+; PR3449
+
+define void @test(<8 x double>* %P, i64* %Q) nounwind {
+ %A = load <8 x double>* %P ; <<8 x double>> [#uses=1]
+ %B = bitcast <8 x double> %A to i512 ; <i512> [#uses=1]
+ %C = lshr i512 %B, 448 ; <i512> [#uses=1]
+ %D = trunc i512 %C to i64 ; <i64> [#uses=1]
+ volatile store i64 %D, i64* %Q
+ ret void
+}
diff --git a/test/CodeGen/X86/2009-01-31-BigShift3.ll b/test/CodeGen/X86/2009-01-31-BigShift3.ll
new file mode 100644
index 000000000000..c92c86a092a1
--- /dev/null
+++ b/test/CodeGen/X86/2009-01-31-BigShift3.ll
@@ -0,0 +1,31 @@
+; RUN: llvm-as < %s | llc -march=x86
+; PR3450
+
+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-darwin7"
+ %struct.BitMap = type { i8* }
+ %struct.BitMapListStruct = type { %struct.BitMap, %struct.BitMapListStruct*, %struct.BitMapListStruct* }
+ %struct.Material = type { float, float, float, %struct.Material*, %struct.Material* }
+ %struct.ObjPoint = type { double, double, double, double, double, double }
+ %struct.ObjectStruct = type { [57 x i8], %struct.PointListStruct*, %struct.Poly3Struct*, %struct.Poly4Struct*, %struct.Texture*, %struct.Material*, %struct.Point, i32, i32, %struct.Point, %struct.Point, %struct.Point, %struct.ObjectStruct*, %struct.ObjectStruct*, i32, i32, i32, i32, i32, i32, i32, %struct.ObjectStruct*, %struct.ObjectStruct* }
+ %struct.Point = type { double, double, double }
+ %struct.PointListStruct = type { %struct.ObjPoint*, %struct.PointListStruct*, %struct.PointListStruct* }
+ %struct.Poly3Struct = type { [3 x %struct.ObjPoint*], %struct.Material*, %struct.Texture*, %struct.Poly3Struct*, %struct.Poly3Struct* }
+ %struct.Poly4Struct = type { [4 x %struct.ObjPoint*], %struct.Material*, %struct.Texture*, %struct.Poly4Struct*, %struct.Poly4Struct* }
+ %struct.Texture = type { %struct.Point, %struct.BitMapListStruct*, %struct.Point, %struct.Point, %struct.Point, %struct.Texture*, %struct.Texture* }
+
+define fastcc void @ScaleObjectAdd(%struct.ObjectStruct* %o, double %sx, double %sy, double %sz) nounwind {
+entry:
+ %sz101112.ins = or i960 0, 0 ; <i960> [#uses=1]
+ br i1 false, label %return, label %bb1.preheader
+
+bb1.preheader: ; preds = %entry
+ %0 = lshr i960 %sz101112.ins, 640 ; <i960> [#uses=0]
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.preheader
+ br label %bb1
+
+return: ; preds = %entry
+ ret void
+}
diff --git a/test/CodeGen/X86/2009-02-01-LargeMask.ll b/test/CodeGen/X86/2009-02-01-LargeMask.ll
new file mode 100644
index 000000000000..f2a964f208ce
--- /dev/null
+++ b/test/CodeGen/X86/2009-02-01-LargeMask.ll
@@ -0,0 +1,32 @@
+; RUN: llvm-as < %s | llc -march=x86
+; PR3453
+
+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"
+ %struct.cl_engine = type { i32, i16, i32, i8**, i8**, i8*, i8*, i8*, i8*, i8*, i8*, i8* }
+ %struct.cl_limits = type { i32, i32, i32, i32, i16, i32 }
+ %struct.cli_ac_alt = type { i8, i8*, i16, i16, %struct.cli_ac_alt* }
+ %struct.cli_ac_node = type { i8, i8, %struct.cli_ac_patt*, %struct.cli_ac_node**, %struct.cli_ac_node* }
+ %struct.cli_ac_patt = type { i16*, i16*, i16, i16, i8, i32, i32, i8*, i8*, i32, i16, i16, i16, i16, %struct.cli_ac_alt**, i8, i16, %struct.cli_ac_patt*, %struct.cli_ac_patt* }
+ %struct.cli_bm_patt = type { i8*, i8*, i16, i16, i8*, i8*, i8, %struct.cli_bm_patt*, i16 }
+ %struct.cli_ctx = type { i8**, i32*, %struct.cli_matcher*, %struct.cl_engine*, %struct.cl_limits*, i32, i32, i32, i32, %struct.cli_dconf* }
+ %struct.cli_dconf = type { i32, i32, i32, i32, i32, i32, i32 }
+ %struct.cli_matcher = type { i16, i8, i8*, %struct.cli_bm_patt**, i32*, i32, i8, i8, %struct.cli_ac_node*, %struct.cli_ac_node**, %struct.cli_ac_patt**, i32, i32, i32 }
+
+define fastcc i32 @cli_scanautoit(i32 %desc, %struct.cli_ctx* %ctx, i32 %offset) nounwind {
+entry:
+ br i1 false, label %bb.i49.i72, label %bb14
+
+bb.i49.i72: ; preds = %bb.i49.i72, %entry
+ %UNP.i1482.0 = phi i288 [ %.ins659, %bb.i49.i72 ], [ undef, %entry ] ; <i288> [#uses=1]
+ %0 = load i32* null, align 4 ; <i32> [#uses=1]
+ %1 = xor i32 %0, 17834 ; <i32> [#uses=1]
+ %2 = zext i32 %1 to i288 ; <i288> [#uses=1]
+ %3 = shl i288 %2, 160 ; <i288> [#uses=1]
+ %UNP.i1482.in658.mask = and i288 %UNP.i1482.0, -6277101733925179126504886505003981583386072424808101969921 ; <i288> [#uses=1]
+ %.ins659 = or i288 %3, %UNP.i1482.in658.mask ; <i288> [#uses=1]
+ br label %bb.i49.i72
+
+bb14: ; preds = %entry
+ ret i32 -123
+}
diff --git a/test/CodeGen/X86/bt.ll b/test/CodeGen/X86/bt.ll
index 86254d3295b0..a76242c977ce 100644
--- a/test/CodeGen/X86/bt.ll
+++ b/test/CodeGen/X86/bt.ll
@@ -1,14 +1,23 @@
-; RUN: llvm-as < %s | llc | grep btl
-; RUN: llvm-as < %s | llc -mcpu=pentium4 | grep btl | not grep esp
-; RUN: llvm-as < %s | llc -mcpu=penryn | grep btl | not grep esp
+; RUN: llvm-as < %s | llc -march=x86 | grep btl | count 28
+; RUN: llvm-as < %s | llc -march=x86 -mcpu=pentium4 | grep btl | not grep esp
+; RUN: llvm-as < %s | llc -march=x86 -mcpu=penryn | grep btl | not grep esp
; PR3253
; The register+memory form of the BT instruction should be usable on
; pentium4, however it is currently disabled due to the register+memory
; form having different semantics than the register+register form.
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin8"
+; Test these patterns:
+; (X & (1 << N)) != 0 --> BT(X, N).
+; ((X >>u N) & 1) != 0 --> BT(X, N).
+; as well as several variations:
+; - The second form can use an arithmetic shift.
+; - Either form can use == instead of !=.
+; - Either form can compare with an operand of the &
+; instead of with 0.
+; - The comparison can be commuted (only cases where neither
+; operand is constant are included).
+; - The and can be commuted.
define void @test2(i32 %x, i32 %n) nounwind {
entry:
@@ -25,4 +34,409 @@ UnifiedReturnBlock: ; preds = %entry
ret void
}
+define void @test2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @atest2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @atest2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @test3(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1]
+ %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @test3b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %x, %tmp29
+ %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @testne2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @testne2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @atestne2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @atestne2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @testne3(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @testne3b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %x, %tmp29
+ %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @query2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @query2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @aquery2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @aquery2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @query3(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1]
+ %tmp4 = icmp eq i32 %tmp3, %tmp29 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @query3b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %x, %tmp29
+ %tmp4 = icmp eq i32 %tmp3, %tmp29 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @query3x(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1]
+ %tmp4 = icmp eq i32 %tmp29, %tmp3 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @query3bx(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %x, %tmp29
+ %tmp4 = icmp eq i32 %tmp29, %tmp3 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @queryne2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @queryne2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @aqueryne2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @aqueryne2b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 1, %tmp29
+ %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @queryne3(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp3, %tmp29 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @queryne3b(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %x, %tmp29
+ %tmp4 = icmp ne i32 %tmp3, %tmp29 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @queryne3x(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp29, %tmp3 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+define void @queryne3bx(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = shl i32 1, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %x, %tmp29
+ %tmp4 = icmp ne i32 %tmp29, %tmp3 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
declare void @foo()
diff --git a/test/CodeGen/X86/commute-cmov.ll b/test/CodeGen/X86/commute-cmov.ll
index 24398dc12570..ac0e4ef3e577 100644
--- a/test/CodeGen/X86/commute-cmov.ll
+++ b/test/CodeGen/X86/commute-cmov.ll
@@ -1,5 +1,20 @@
-; RUN: llvm-as < %s | llc -march=x86 | grep {cmove 16(%esp)}
+; RUN: llvm-as < %s | llc -march=x86 > %t
+; RUN: grep btl %t | count 2
+; RUN: grep cmov %t | count 2
+; RUN: not grep test %t
+; RUN: not grep set %t
+; RUN: not grep j %t
+; RUN: not grep cmovne %t
+; RUN: not grep cmove %t
+define i32 @foo(i32 %x, i32 %n, i32 %w, i32 %v) nounwind readnone {
+entry:
+ %0 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %1 = and i32 %0, 1 ; <i32> [#uses=1]
+ %toBool = icmp eq i32 %1, 0 ; <i1> [#uses=1]
+ %.0 = select i1 %toBool, i32 %v, i32 12 ; <i32> [#uses=1]
+ ret i32 %.0
+}
define i32 @bar(i32 %x, i32 %n, i32 %w, i32 %v) nounwind readnone {
entry:
%0 = lshr i32 %x, %n ; <i32> [#uses=1]
diff --git a/test/CodeGen/X86/pr3018.ll b/test/CodeGen/X86/dag-rauw-cse.ll
index 7d335ee2f6de..ba84711c03eb 100644
--- a/test/CodeGen/X86/pr3018.ll
+++ b/test/CodeGen/X86/dag-rauw-cse.ll
@@ -1,4 +1,5 @@
; RUN: llvm-as < %s | llc -march=x86 | grep {orl \$1}
+; PR3018
define i32 @test(i32 %A) nounwind {
%B = or i32 %A, 1
diff --git a/test/CodeGen/X86/extractelement-load.ll b/test/CodeGen/X86/extractelement-load.ll
index 4850eba60928..601690ef7cab 100644
--- a/test/CodeGen/X86/extractelement-load.ll
+++ b/test/CodeGen/X86/extractelement-load.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o - | llc -march=x86 -mattr=+sse2 -mcpu=yonah | not grep movd
-; RUN: llvm-as %s -o - | llc -march=x86-64 -mattr=+sse2 -mcpu=yonah | not grep movd
+; RUN: llvm-as %s -o - | llc -march=x86-64 -mattr=+sse2 -mcpu=core2 | not grep movd
define i32 @t(<2 x i64>* %val) nounwind {
%tmp2 = load <2 x i64>* %val, align 16 ; <<2 x i64>> [#uses=1]
diff --git a/test/CodeGen/X86/fold-call-3.ll b/test/CodeGen/X86/fold-call-3.ll
new file mode 100644
index 000000000000..824ae003da25
--- /dev/null
+++ b/test/CodeGen/X86/fold-call-3.ll
@@ -0,0 +1,45 @@
+; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep call | grep 560
+; rdar://6522427
+
+ %"struct.clang::Action" = type { %"struct.clang::ActionBase" }
+ %"struct.clang::ActionBase" = type { i32 (...)** }
+ %"struct.clang::ActionBase::ActionResult<0u>" = type { i8*, i8 }
+@NumTrials = internal global i32 10000000 ; <i32*> [#uses=2]
+@llvm.used = appending global [1 x i8*] [ i8* bitcast (void (i8*, %"struct.clang::Action"*)* @_Z25RawPointerPerformanceTestPvRN5clang6ActionE to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]
+
+define void @_Z25RawPointerPerformanceTestPvRN5clang6ActionE(i8* %Val, %"struct.clang::Action"* %Actions) nounwind {
+entry:
+ %0 = alloca %"struct.clang::ActionBase::ActionResult<0u>", align 8 ; <%"struct.clang::ActionBase::ActionResult<0u>"*> [#uses=3]
+ %1 = load i32* @NumTrials, align 4 ; <i32> [#uses=1]
+ %2 = icmp eq i32 %1, 0 ; <i1> [#uses=1]
+ br i1 %2, label %return, label %bb.nph
+
+bb.nph: ; preds = %entry
+ %3 = getelementptr %"struct.clang::Action"* %Actions, i64 0, i32 0, i32 0 ; <i32 (...)***> [#uses=1]
+ %mrv_gep = bitcast %"struct.clang::ActionBase::ActionResult<0u>"* %0 to i64* ; <i64*> [#uses=1]
+ %mrv_gep1 = getelementptr %"struct.clang::ActionBase::ActionResult<0u>"* %0, i64 0, i32 1 ; <i8*> [#uses=1]
+ %4 = bitcast i8* %mrv_gep1 to i64* ; <i64*> [#uses=1]
+ %5 = getelementptr %"struct.clang::ActionBase::ActionResult<0u>"* %0, i64 0, i32 0 ; <i8**> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph
+ %Trial.01 = phi i32 [ 0, %bb.nph ], [ %12, %bb ] ; <i32> [#uses=1]
+ %Val_addr.02 = phi i8* [ %Val, %bb.nph ], [ %11, %bb ] ; <i8*> [#uses=1]
+ %6 = load i32 (...)*** %3, align 8 ; <i32 (...)**> [#uses=1]
+ %7 = getelementptr i32 (...)** %6, i64 70 ; <i32 (...)**> [#uses=1]
+ %8 = load i32 (...)** %7, align 8 ; <i32 (...)*> [#uses=1]
+ %9 = bitcast i32 (...)* %8 to { i64, i64 } (%"struct.clang::Action"*, i8*)* ; <{ i64, i64 } (%"struct.clang::Action"*, i8*)*> [#uses=1]
+ %10 = call { i64, i64 } %9(%"struct.clang::Action"* %Actions, i8* %Val_addr.02) nounwind ; <{ i64, i64 }> [#uses=2]
+ %mrv_gr = extractvalue { i64, i64 } %10, 0 ; <i64> [#uses=1]
+ store i64 %mrv_gr, i64* %mrv_gep
+ %mrv_gr2 = extractvalue { i64, i64 } %10, 1 ; <i64> [#uses=1]
+ store i64 %mrv_gr2, i64* %4
+ %11 = load i8** %5, align 8 ; <i8*> [#uses=1]
+ %12 = add i32 %Trial.01, 1 ; <i32> [#uses=2]
+ %13 = load i32* @NumTrials, align 4 ; <i32> [#uses=1]
+ %14 = icmp ult i32 %12, %13 ; <i1> [#uses=1]
+ br i1 %14, label %bb, label %return
+
+return: ; preds = %bb, %entry
+ ret void
+}
diff --git a/test/CodeGen/X86/illegal-asm.ll b/test/CodeGen/X86/illegal-asm.ll
new file mode 100644
index 000000000000..0e7dc59eb52a
--- /dev/null
+++ b/test/CodeGen/X86/illegal-asm.ll
@@ -0,0 +1,32 @@
+; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -disable-fp-elim
+; XFAIL: *
+; Expected to run out of registers during allocation.
+; rdar://6251720
+
+ %struct.CABACContext = type { i32, i32, i8* }
+ %struct.H264Context = type { %struct.CABACContext, [460 x i8] }
+@coeff_abs_level_m1_offset = common global [6 x i32] zeroinitializer ; <[6 x i32]*> [#uses=1]
+@coeff_abs_level1_ctx = common global [8 x i8] zeroinitializer ; <[8 x i8]*> [#uses=1]
+
+define i32 @decode_cabac_residual(%struct.H264Context* %h, i32 %cat) nounwind {
+entry:
+ %0 = getelementptr [6 x i32]* @coeff_abs_level_m1_offset, i32 0, i32 %cat ; <i32*> [#uses=1]
+ %1 = load i32* %0, align 4 ; <i32> [#uses=1]
+ %2 = load i8* getelementptr ([8 x i8]* @coeff_abs_level1_ctx, i32 0, i32 0), align 1 ; <i8> [#uses=1]
+ %3 = zext i8 %2 to i32 ; <i32> [#uses=1]
+ %.sum = add i32 %3, %1 ; <i32> [#uses=1]
+ %4 = getelementptr %struct.H264Context* %h, i32 0, i32 1, i32 %.sum ; <i8*> [#uses=2]
+ %5 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 0 ; <i32*> [#uses=2]
+ %6 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 1 ; <i32*> [#uses=2]
+ %7 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 2 ; <i8**> [#uses=2]
+ %8 = load i32* %5, align 4 ; <i32> [#uses=1]
+ %9 = load i32* %6, align 4 ; <i32> [#uses=1]
+ %10 = load i8* %4, align 4 ; <i8> [#uses=1]
+ %asmtmp = tail call { i32, i32, i32, i32 } asm sideeffect "#$0 $1 $2 $3 $4 $5", "=&{di},=r,=r,=*m,=&q,=*imr,1,2,*m,5,~{dirflag},~{fpsr},~{flags},~{cx}"(i8** %7, i8* %4, i32 %8, i32 %9, i8** %7, i8 %10) nounwind ; <{ i32, i32, i32, i32 }> [#uses=3]
+ %asmresult = extractvalue { i32, i32, i32, i32 } %asmtmp, 0 ; <i32> [#uses=1]
+ %asmresult1 = extractvalue { i32, i32, i32, i32 } %asmtmp, 1 ; <i32> [#uses=1]
+ store i32 %asmresult1, i32* %5
+ %asmresult2 = extractvalue { i32, i32, i32, i32 } %asmtmp, 2 ; <i32> [#uses=1]
+ store i32 %asmresult2, i32* %6
+ ret i32 %asmresult
+}
diff --git a/test/CodeGen/X86/movgs.ll b/test/CodeGen/X86/movgs.ll
new file mode 100644
index 000000000000..f621849e5b06
--- /dev/null
+++ b/test/CodeGen/X86/movgs.ll
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep gs
+
+define i32 @foo() nounwind readonly {
+entry:
+ %tmp = load i32* addrspace(256)* getelementptr (i32* addrspace(256)* inttoptr (i32 72 to i32* addrspace(256)*), i32 31) ; <i32*> [#uses=1]
+ %tmp1 = load i32* %tmp ; <i32> [#uses=1]
+ ret i32 %tmp1
+}
diff --git a/test/CodeGen/X86/neg_fp.ll b/test/CodeGen/X86/neg_fp.ll
new file mode 100644
index 000000000000..55c76549ffe2
--- /dev/null
+++ b/test/CodeGen/X86/neg_fp.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse41 -o %t -f
+; RUN: grep xorps %t | count 1
+
+; Test that when we don't -enable-unsafe-fp-math, we don't do the optimization
+; -0 - (A - B) to (B - A) because A==B, -0 != 0
+
+define float @negfp(float %a, float %b) {
+entry:
+ %sub = sub float %a, %b ; <float> [#uses=1]
+ %neg = sub float -0.000000e+00, %sub ; <float> [#uses=1]
+ ret float %neg
+} \ No newline at end of file
diff --git a/test/CodeGen/X86/nosse-error1.ll b/test/CodeGen/X86/nosse-error1.ll
new file mode 100644
index 000000000000..16cbb732af0e
--- /dev/null
+++ b/test/CodeGen/X86/nosse-error1.ll
@@ -0,0 +1,33 @@
+; RUN: llvm-as < %s > %t1
+; RUN: not llc -march=x86-64 -mattr=-sse < %t1 2> %t2
+; RUN: grep "SSE register return with SSE disabled" %t2
+; RUN: llc -march=x86-64 < %t1 | grep xmm
+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"
+@f = external global float ; <float*> [#uses=4]
+@d = external global double ; <double*> [#uses=4]
+
+define void @test() nounwind {
+entry:
+ %0 = load float* @f, align 4 ; <float> [#uses=1]
+ %1 = tail call float @foo1(float %0) nounwind ; <float> [#uses=1]
+ store float %1, float* @f, align 4
+ %2 = load double* @d, align 8 ; <double> [#uses=1]
+ %3 = tail call double @foo2(double %2) nounwind ; <double> [#uses=1]
+ store double %3, double* @d, align 8
+ %4 = load float* @f, align 4 ; <float> [#uses=1]
+ %5 = tail call float @foo3(float %4) nounwind ; <float> [#uses=1]
+ store float %5, float* @f, align 4
+ %6 = load double* @d, align 8 ; <double> [#uses=1]
+ %7 = tail call double @foo4(double %6) nounwind ; <double> [#uses=1]
+ store double %7, double* @d, align 8
+ ret void
+}
+
+declare float @foo1(float)
+
+declare double @foo2(double)
+
+declare float @foo3(float)
+
+declare double @foo4(double)
diff --git a/test/CodeGen/X86/nosse-error2.ll b/test/CodeGen/X86/nosse-error2.ll
new file mode 100644
index 000000000000..45a5eaf3a415
--- /dev/null
+++ b/test/CodeGen/X86/nosse-error2.ll
@@ -0,0 +1,33 @@
+; RUN: llvm-as < %s > %t1
+; RUN: not llc -march=x86 -mcpu=i686 -mattr=-sse < %t1 2> %t2
+; RUN: grep "SSE register return with SSE disabled" %t2
+; RUN: llc -march=x86 -mcpu=i686 -mattr=+sse < %t1 | grep xmm
+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-unknown-linux-gnu"
+@f = external global float ; <float*> [#uses=4]
+@d = external global double ; <double*> [#uses=4]
+
+define void @test() nounwind {
+entry:
+ %0 = load float* @f, align 4 ; <float> [#uses=1]
+ %1 = tail call inreg float @foo1(float inreg %0) nounwind ; <float> [#uses=1]
+ store float %1, float* @f, align 4
+ %2 = load double* @d, align 8 ; <double> [#uses=1]
+ %3 = tail call inreg double @foo2(double inreg %2) nounwind ; <double> [#uses=1]
+ store double %3, double* @d, align 8
+ %4 = load float* @f, align 4 ; <float> [#uses=1]
+ %5 = tail call inreg float @foo3(float inreg %4) nounwind ; <float> [#uses=1]
+ store float %5, float* @f, align 4
+ %6 = load double* @d, align 8 ; <double> [#uses=1]
+ %7 = tail call inreg double @foo4(double inreg %6) nounwind ; <double> [#uses=1]
+ store double %7, double* @d, align 8
+ ret void
+}
+
+declare inreg float @foo1(float inreg)
+
+declare inreg double @foo2(double inreg)
+
+declare inreg float @foo3(float inreg)
+
+declare inreg double @foo4(double inreg)
diff --git a/test/CodeGen/X86/nosse-varargs.ll b/test/CodeGen/X86/nosse-varargs.ll
new file mode 100644
index 000000000000..e6da0ab5e371
--- /dev/null
+++ b/test/CodeGen/X86/nosse-varargs.ll
@@ -0,0 +1,46 @@
+; RUN: llvm-as < %s > %t
+; RUN: llc -march=x86-64 -mattr=-sse < %t | not grep xmm
+; RUN: llc -march=x86-64 < %t | grep xmm
+; PR3403
+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.__va_list_tag = type { i32, i32, i8*, i8* }
+
+define i32 @foo(float %a, i8* nocapture %fmt, ...) nounwind {
+entry:
+ %ap = alloca [1 x %struct.__va_list_tag], align 8 ; <[1 x %struct.__va_list_tag]*> [#uses=4]
+ %ap12 = bitcast [1 x %struct.__va_list_tag]* %ap to i8* ; <i8*> [#uses=2]
+ call void @llvm.va_start(i8* %ap12)
+ %0 = getelementptr [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 0 ; <i32*> [#uses=2]
+ %1 = load i32* %0, align 8 ; <i32> [#uses=3]
+ %2 = icmp ult i32 %1, 48 ; <i1> [#uses=1]
+ br i1 %2, label %bb, label %bb3
+
+bb: ; preds = %entry
+ %3 = getelementptr [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 3 ; <i8**> [#uses=1]
+ %4 = load i8** %3, align 8 ; <i8*> [#uses=1]
+ %5 = inttoptr i32 %1 to i8* ; <i8*> [#uses=1]
+ %6 = ptrtoint i8* %5 to i64 ; <i64> [#uses=1]
+ %ctg2 = getelementptr i8* %4, i64 %6 ; <i8*> [#uses=1]
+ %7 = add i32 %1, 8 ; <i32> [#uses=1]
+ store i32 %7, i32* %0, align 8
+ br label %bb4
+
+bb3: ; preds = %entry
+ %8 = getelementptr [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 2 ; <i8**> [#uses=2]
+ %9 = load i8** %8, align 8 ; <i8*> [#uses=2]
+ %10 = getelementptr i8* %9, i64 8 ; <i8*> [#uses=1]
+ store i8* %10, i8** %8, align 8
+ br label %bb4
+
+bb4: ; preds = %bb3, %bb
+ %addr.0.0 = phi i8* [ %ctg2, %bb ], [ %9, %bb3 ] ; <i8*> [#uses=1]
+ %11 = bitcast i8* %addr.0.0 to i32* ; <i32*> [#uses=1]
+ %12 = load i32* %11, align 4 ; <i32> [#uses=1]
+ call void @llvm.va_end(i8* %ap12)
+ ret i32 %12
+}
+
+declare void @llvm.va_start(i8*) nounwind
+
+declare void @llvm.va_end(i8*) nounwind
diff --git a/test/CodeGen/X86/pmul.ll b/test/CodeGen/X86/pmul.ll
index 5ee09326dd1f..b619411eaff2 100644
--- a/test/CodeGen/X86/pmul.ll
+++ b/test/CodeGen/X86/pmul.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as < %s | llc -march=x86 -mattr=sse41 -stack-alignment=16 > %t
; RUN: grep pmul %t | count 12
-; RUN: grep mov %t | count 19
+; RUN: grep mov %t | count 15
define <4 x i32> @a(<4 x i32> %i) nounwind {
%A = mul <4 x i32> %i, < i32 117, i32 117, i32 117, i32 117 >
diff --git a/test/CodeGen/X86/pre-split1.ll b/test/CodeGen/X86/pre-split1.ll
index f99ac8981dd7..99a46b6e5fd2 100644
--- a/test/CodeGen/X86/pre-split1.ll
+++ b/test/CodeGen/X86/pre-split1.ll
@@ -1,5 +1,6 @@
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -pre-alloc-split -stats |& \
; RUN: grep {pre-alloc-split} | grep {Number of intervals split} | grep 1
+; XFAIL: *
define void @test(double* %P, i32 %cond) nounwind {
entry:
diff --git a/test/CodeGen/X86/red-zone.ll b/test/CodeGen/X86/red-zone.ll
new file mode 100644
index 000000000000..60e16b05ca75
--- /dev/null
+++ b/test/CodeGen/X86/red-zone.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -march=x86-64 > %t
+; RUN: not grep subq %t
+; RUN: not grep addq %t
+; RUN: grep {\\-4(%%rsp)} %t | count 2
+; RUN: llvm-as < %s | llc -march=x86-64 -disable-red-zone > %t
+; RUN: grep subq %t | count 1
+; RUN: grep addq %t | count 1
+
+define x86_fp80 @f0(float %f) nounwind readnone {
+entry:
+ %0 = fpext float %f to x86_fp80 ; <x86_fp80> [#uses=1]
+ ret x86_fp80 %0
+}
diff --git a/test/CodeGen/X86/smul-with-overflow-2.ll b/test/CodeGen/X86/smul-with-overflow-2.ll
new file mode 100644
index 000000000000..c3dbfd796f20
--- /dev/null
+++ b/test/CodeGen/X86/smul-with-overflow-2.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep mul | count 1
+; RUN: llvm-as < %s | llc -march=x86 | grep add | count 3
+
+define i32 @t1(i32 %a, i32 %b) nounwind readnone {
+entry:
+ %tmp0 = add i32 %b, %a
+ %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 2)
+ %tmp2 = extractvalue { i32, i1 } %tmp1, 0
+ ret i32 %tmp2
+}
+
+define i32 @t2(i32 %a, i32 %b) nounwind readnone {
+entry:
+ %tmp0 = add i32 %b, %a
+ %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 4)
+ %tmp2 = extractvalue { i32, i1 } %tmp1, 0
+ ret i32 %tmp2
+}
+
+declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind
diff --git a/test/CodeGen/X86/smul-with-overflow-3.ll b/test/CodeGen/X86/smul-with-overflow-3.ll
new file mode 100644
index 000000000000..aa5e67a02998
--- /dev/null
+++ b/test/CodeGen/X86/smul-with-overflow-3.ll
@@ -0,0 +1,23 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep {jno} | count 1
+
+@ok = internal constant [4 x i8] c"%d\0A\00"
+@no = internal constant [4 x i8] c"no\0A\00"
+
+define i1 @func1(i32 %v1, i32 %v2) nounwind {
+entry:
+ %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %overflow, label %normal
+
+overflow:
+ %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind
+ ret i1 false
+
+normal:
+ %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
+ ret i1 true
+}
+
+declare i32 @printf(i8*, ...) nounwind
+declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
diff --git a/test/CodeGen/X86/subclass-coalesce.ll b/test/CodeGen/X86/subclass-coalesce.ll
index 26e6256ea0f5..a010f1b29f1d 100644
--- a/test/CodeGen/X86/subclass-coalesce.ll
+++ b/test/CodeGen/X86/subclass-coalesce.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=x86 -join-subclass-copies -stats |& grep {Number of subclass joins performed}
+; RUN: llvm-as < %s | llc -march=x86 -join-cross-class-copies -stats |& grep {Number of cross class joins performed}
@mem.6 = external global i64 ; <i64*> [#uses=1]
diff --git a/test/CodeGen/X86/swizzle.ll b/test/CodeGen/X86/swizzle.ll
new file mode 100644
index 000000000000..d00bb9a0fadb
--- /dev/null
+++ b/test/CodeGen/X86/swizzle.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movlps
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movsd
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | not grep movups
+; rdar://6523650
+
+ %struct.vector4_t = type { <4 x float> }
+
+define void @swizzle(i8* nocapture %a, %struct.vector4_t* nocapture %b, %struct.vector4_t* nocapture %c) nounwind {
+entry:
+ %0 = getelementptr %struct.vector4_t* %b, i32 0, i32 0 ; <<4 x float>*> [#uses=2]
+ %1 = load <4 x float>* %0, align 4 ; <<4 x float>> [#uses=1]
+ %tmp.i = bitcast i8* %a to double* ; <double*> [#uses=1]
+ %tmp1.i = load double* %tmp.i ; <double> [#uses=1]
+ %2 = insertelement <2 x double> undef, double %tmp1.i, i32 0 ; <<2 x double>> [#uses=1]
+ %tmp2.i = bitcast <2 x double> %2 to <4 x float> ; <<4 x float>> [#uses=1]
+ %3 = shufflevector <4 x float> %1, <4 x float> %tmp2.i, <4 x i32> < i32 4, i32 5, i32 2, i32 3 > ; <<4 x float>> [#uses=1]
+ store <4 x float> %3, <4 x float>* %0, align 4
+ ret void
+}
diff --git a/test/CodeGen/X86/twoaddr-coalesce.ll b/test/CodeGen/X86/twoaddr-coalesce.ll
new file mode 100644
index 000000000000..c369d91f56ae
--- /dev/null
+++ b/test/CodeGen/X86/twoaddr-coalesce.ll
@@ -0,0 +1,25 @@
+; RUN: llvm-as < %s | llc -march=x86 -join-cross-class-copies -stats |& \
+; RUN: grep {twoaddrinstr} | grep {Number of instructions aggressively commuted}
+; rdar://6523745
+
+@"\01LC" = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1]
+
+define i32 @main() nounwind {
+bb1.thread:
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ] ; <i32> [#uses=2]
+ %0 = trunc i32 %i.0.reg2mem.0 to i8 ; <i8> [#uses=1]
+ %1 = sdiv i8 %0, 2 ; <i8> [#uses=1]
+ %2 = sext i8 %1 to i32 ; <i32> [#uses=1]
+ %3 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @"\01LC", i32 0, i32 0), i32 %2) nounwind ; <i32> [#uses=0]
+ %indvar.next = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, 258 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 0
+}
+
+declare i32 @printf(i8*, ...) nounwind
diff --git a/test/CodeGen/X86/vec_ins_extract-1.ll b/test/CodeGen/X86/vec_ins_extract-1.ll
new file mode 100644
index 000000000000..44ae03938480
--- /dev/null
+++ b/test/CodeGen/X86/vec_ins_extract-1.ll
@@ -0,0 +1,25 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep {(%esp,%eax,4)} | count 4
+
+; Inserts and extracts with variable indices must be lowered
+; to memory accesses.
+
+define i32 @t0(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
+ %t13 = insertelement <4 x i32> %t8, i32 76, i32 %t7
+ %t9 = extractelement <4 x i32> %t13, i32 0
+ ret i32 %t9
+}
+define i32 @t1(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
+ %t13 = insertelement <4 x i32> %t8, i32 76, i32 0
+ %t9 = extractelement <4 x i32> %t13, i32 %t7
+ ret i32 %t9
+}
+define <4 x i32> @t2(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
+ %t9 = extractelement <4 x i32> %t8, i32 %t7
+ %t13 = insertelement <4 x i32> %t8, i32 %t9, i32 0
+ ret <4 x i32> %t13
+}
+define <4 x i32> @t3(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
+ %t9 = extractelement <4 x i32> %t8, i32 0
+ %t13 = insertelement <4 x i32> %t8, i32 %t9, i32 %t7
+ ret <4 x i32> %t13
+}
diff --git a/test/CodeGen/X86/vec_shuffle-29.ll b/test/CodeGen/X86/vec_shuffle-29.ll
new file mode 100644
index 000000000000..aac63c3bbec6
--- /dev/null
+++ b/test/CodeGen/X86/vec_shuffle-29.ll
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=sse41 -disable-mmx -o %t -f
+; RUN: not grep pextrw %t
+; RUN: grep pinsrw %t
+
+; Test for v8xi16 lowering where we extract the first element of the vector and
+; placed it in the second element of the result.
+
+define void @test_cl(<8 x i16> addrspace(1)* %dest, <8 x i16> addrspace(1)* %old) nounwind {
+entry:
+ %tmp3 = load <8 x i16> addrspace(1)* %old ; <<8 x i16>> [#uses=1]
+ %tmp6 = shufflevector <8 x i16> %tmp3, <8 x i16> < i16 0, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef >, <8 x i32> < i32 8, i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef > ; <<8 x i16>> [#uses=1]
+ store <8 x i16> %tmp6, <8 x i16> addrspace(1)* %dest
+ ret void
+} \ No newline at end of file
diff --git a/test/CodeGen/X86/vfcmp.ll b/test/CodeGen/X86/vfcmp.ll
new file mode 100644
index 000000000000..85b82a0ac8e8
--- /dev/null
+++ b/test/CodeGen/X86/vfcmp.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2
+; PR2620
+
+define void @t(i32 %m_task_id, i32 %start_x, i32 %end_x) nounwind {
+ vfcmp olt <2 x double> zeroinitializer, zeroinitializer ; <<2 x i64>>:1 [#uses=1]
+ extractelement <2 x i64> %1, i32 1 ; <i64>:2 [#uses=1]
+ lshr i64 %2, 63 ; <i64>:3 [#uses=1]
+ trunc i64 %3 to i1 ; <i1>:4 [#uses=1]
+ zext i1 %4 to i8 ; <i8>:5 [#uses=1]
+ insertelement <2 x i8> zeroinitializer, i8 %5, i32 1 ; <<2 x i8>>:6 [#uses=1]
+ store <2 x i8> %6, <2 x i8>* null
+ ret void
+}
diff --git a/test/CodeGen/X86/vshift-1.ll b/test/CodeGen/X86/vshift-1.ll
new file mode 100644
index 000000000000..d7a20e46c18e
--- /dev/null
+++ b/test/CodeGen/X86/vshift-1.ll
@@ -0,0 +1,65 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
+; RUN: grep psllq %t | count 2
+; RUN: grep pslld %t | count 2
+; RUN: grep psllw %t | count 2
+
+; test vector shifts converted to proper SSE2 vector shifts when the shift
+; amounts are the same.
+
+define void @shift1a(<2 x i64> %val, <2 x i64>* %dst) nounwind {
+entry:
+ %shl = shl <2 x i64> %val, < i64 32, i64 32 >
+ store <2 x i64> %shl, <2 x i64>* %dst
+ ret void
+}
+
+define void @shift1b(<2 x i64> %val, <2 x i64>* %dst, i64 %amt) nounwind {
+entry:
+ %0 = insertelement <2 x i64> undef, i64 %amt, i32 0
+ %1 = insertelement <2 x i64> %0, i64 %amt, i32 1
+ %shl = shl <2 x i64> %val, %1
+ store <2 x i64> %shl, <2 x i64>* %dst
+ ret void
+}
+
+
+define void @shift2a(<4 x i32> %val, <4 x i32>* %dst) nounwind {
+entry:
+ %shl = shl <4 x i32> %val, < i32 5, i32 5, i32 5, i32 5 >
+ store <4 x i32> %shl, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, i32 %amt) nounwind {
+entry:
+ %0 = insertelement <4 x i32> undef, i32 %amt, i32 0
+ %1 = insertelement <4 x i32> %0, i32 %amt, i32 1
+ %2 = insertelement <4 x i32> %1, i32 %amt, i32 2
+ %3 = insertelement <4 x i32> %2, i32 %amt, i32 3
+ %shl = shl <4 x i32> %val, %3
+ store <4 x i32> %shl, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift3a(<8 x i16> %val, <8 x i16>* %dst) nounwind {
+entry:
+ %shl = shl <8 x i16> %val, < i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5 >
+ store <8 x i16> %shl, <8 x i16>* %dst
+ ret void
+}
+
+define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
+entry:
+ %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
+ %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
+ %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
+ %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
+ %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
+ %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
+ %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
+ %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
+ %shl = shl <8 x i16> %val, %7
+ store <8 x i16> %shl, <8 x i16>* %dst
+ ret void
+}
+
diff --git a/test/CodeGen/X86/vshift-2.ll b/test/CodeGen/X86/vshift-2.ll
new file mode 100644
index 000000000000..0807174420e8
--- /dev/null
+++ b/test/CodeGen/X86/vshift-2.ll
@@ -0,0 +1,64 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
+; RUN: grep psrlq %t | count 2
+; RUN: grep psrld %t | count 2
+; RUN: grep psrlw %t | count 2
+
+; test vector shifts converted to proper SSE2 vector shifts when the shift
+; amounts are the same.
+
+define void @shift1a(<2 x i64> %val, <2 x i64>* %dst) nounwind {
+entry:
+ %lshr = lshr <2 x i64> %val, < i64 32, i64 32 >
+ store <2 x i64> %lshr, <2 x i64>* %dst
+ ret void
+}
+
+define void @shift1b(<2 x i64> %val, <2 x i64>* %dst, i64 %amt) nounwind {
+entry:
+ %0 = insertelement <2 x i64> undef, i64 %amt, i32 0
+ %1 = insertelement <2 x i64> %0, i64 %amt, i32 1
+ %lshr = lshr <2 x i64> %val, %1
+ store <2 x i64> %lshr, <2 x i64>* %dst
+ ret void
+}
+
+define void @shift2a(<4 x i32> %val, <4 x i32>* %dst) nounwind {
+entry:
+ %lshr = lshr <4 x i32> %val, < i32 17, i32 17, i32 17, i32 17 >
+ store <4 x i32> %lshr, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, i32 %amt) nounwind {
+entry:
+ %0 = insertelement <4 x i32> undef, i32 %amt, i32 0
+ %1 = insertelement <4 x i32> %0, i32 %amt, i32 1
+ %2 = insertelement <4 x i32> %1, i32 %amt, i32 2
+ %3 = insertelement <4 x i32> %2, i32 %amt, i32 3
+ %lshr = lshr <4 x i32> %val, %3
+ store <4 x i32> %lshr, <4 x i32>* %dst
+ ret void
+}
+
+
+define void @shift3a(<8 x i16> %val, <8 x i16>* %dst) nounwind {
+entry:
+ %lshr = lshr <8 x i16> %val, < i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5 >
+ store <8 x i16> %lshr, <8 x i16>* %dst
+ ret void
+}
+
+define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
+entry:
+ %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
+ %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
+ %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
+ %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
+ %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
+ %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
+ %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
+ %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
+ %lshr = lshr <8 x i16> %val, %7
+ store <8 x i16> %lshr, <8 x i16>* %dst
+ ret void
+} \ No newline at end of file
diff --git a/test/CodeGen/X86/vshift-3.ll b/test/CodeGen/X86/vshift-3.ll
new file mode 100644
index 000000000000..eea8ad1c798e
--- /dev/null
+++ b/test/CodeGen/X86/vshift-3.ll
@@ -0,0 +1,54 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
+; RUN: grep psrad %t | count 2
+; RUN: grep psraw %t | count 2
+
+; test vector shifts converted to proper SSE2 vector shifts when the shift
+; amounts are the same.
+
+; Note that x86 does have ashr
+define void @shift1a(<2 x i64> %val, <2 x i64>* %dst) nounwind {
+entry:
+ %ashr = ashr <2 x i64> %val, < i64 32, i64 32 >
+ store <2 x i64> %ashr, <2 x i64>* %dst
+ ret void
+}
+
+define void @shift2a(<4 x i32> %val, <4 x i32>* %dst) nounwind {
+entry:
+ %ashr = ashr <4 x i32> %val, < i32 5, i32 5, i32 5, i32 5 >
+ store <4 x i32> %ashr, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, i32 %amt) nounwind {
+entry:
+ %0 = insertelement <4 x i32> undef, i32 %amt, i32 0
+ %1 = insertelement <4 x i32> %0, i32 %amt, i32 1
+ %2 = insertelement <4 x i32> %1, i32 %amt, i32 2
+ %3 = insertelement <4 x i32> %2, i32 %amt, i32 3
+ %ashr = ashr <4 x i32> %val, %3
+ store <4 x i32> %ashr, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift3a(<8 x i16> %val, <8 x i16>* %dst) nounwind {
+entry:
+ %ashr = ashr <8 x i16> %val, < i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5 >
+ store <8 x i16> %ashr, <8 x i16>* %dst
+ ret void
+}
+
+define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
+entry:
+ %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
+ %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
+ %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
+ %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
+ %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
+ %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
+ %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
+ %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
+ %ashr = ashr <8 x i16> %val, %7
+ store <8 x i16> %ashr, <8 x i16>* %dst
+ ret void
+} \ No newline at end of file
diff --git a/test/CodeGen/X86/vshift-4.ll b/test/CodeGen/X86/vshift-4.ll
new file mode 100644
index 000000000000..03ab95c0e105
--- /dev/null
+++ b/test/CodeGen/X86/vshift-4.ll
@@ -0,0 +1,71 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
+; RUN: grep psllq %t | count 1
+; RUN: grep pslld %t | count 3
+; RUN: grep psllw %t | count 2
+
+; test vector shifts converted to proper SSE2 vector shifts when the shift
+; amounts are the same when using a shuffle splat.
+
+define void @shift1a(<2 x i64> %val, <2 x i64>* %dst, <2 x i64> %sh) nounwind {
+entry:
+ %shamt = shufflevector <2 x i64> %sh, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
+ %shl = shl <2 x i64> %val, %shamt
+ store <2 x i64> %shl, <2 x i64>* %dst
+ ret void
+}
+
+define void @shift1b(<2 x i64> %val, <2 x i64>* %dst, <2 x i64> %sh) nounwind {
+entry:
+ %shamt = shufflevector <2 x i64> %sh, <2 x i64> undef, <2 x i32> <i32 0, i32 1>
+ %shl = shl <2 x i64> %val, %shamt
+ store <2 x i64> %shl, <2 x i64>* %dst
+ ret void
+}
+
+define void @shift2a(<4 x i32> %val, <4 x i32>* %dst, <2 x i32> %amt) nounwind {
+entry:
+ %shamt = shufflevector <2 x i32> %amt, <2 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ %shl = shl <4 x i32> %val, %shamt
+ store <4 x i32> %shl, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, <2 x i32> %amt) nounwind {
+entry:
+ %shamt = shufflevector <2 x i32> %amt, <2 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 1, i32 1>
+ %shl = shl <4 x i32> %val, %shamt
+ store <4 x i32> %shl, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift2c(<4 x i32> %val, <4 x i32>* %dst, <2 x i32> %amt) nounwind {
+entry:
+ %shamt = shufflevector <2 x i32> %amt, <2 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ %shl = shl <4 x i32> %val, %shamt
+ store <4 x i32> %shl, <4 x i32>* %dst
+ ret void
+}
+
+define void @shift3a(<8 x i16> %val, <8 x i16>* %dst, <8 x i16> %amt) nounwind {
+entry:
+ %shamt = shufflevector <8 x i16> %amt, <8 x i16> undef, <8 x i32> <i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6>
+ %shl = shl <8 x i16> %val, %shamt
+ store <8 x i16> %shl, <8 x i16>* %dst
+ ret void
+}
+
+define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
+entry:
+ %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
+ %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
+ %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
+ %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
+ %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
+ %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
+ %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
+ %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
+ %shl = shl <8 x i16> %val, %7
+ store <8 x i16> %shl, <8 x i16>* %dst
+ ret void
+}
+
diff --git a/test/DebugInfo/2009-01-15-RecordVariableCrash.ll b/test/DebugInfo/2009-01-15-RecordVariableCrash.ll
index e9b4eeb1b6f6..0fa216700dc9 100644
--- a/test/DebugInfo/2009-01-15-RecordVariableCrash.ll
+++ b/test/DebugInfo/2009-01-15-RecordVariableCrash.ll
@@ -22,29 +22,27 @@
@.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 459008, { }* 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 22, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
@.str6 = internal constant [8 x i8] c"islower\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str7 = internal constant [8 x i8] c"ctype.h\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@.str8 = internal constant [13 x i8] c"/usr/include\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@llvm.dbg.subprogram9 = 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 ([8 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 267, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@llvm.dbg.subprogram9 = 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 ([8 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 267, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
@.str10 = internal constant [3 x i8] c"_c\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1]
-@llvm.dbg.variable11 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram9 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 266, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+@llvm.dbg.variable11 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram9 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 266, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
@.str12 = internal constant [9 x i8] c"__istype\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
-@llvm.dbg.subprogram13 = 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 ([9 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 171, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@llvm.dbg.subprogram13 = 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 ([9 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 171, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
@.str14 = internal constant [19 x i8] c"__darwin_ct_rune_t\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1]
@.str15 = internal constant [9 x i8] c"_types.h\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1]
@.str16 = internal constant [18 x i8] c"/usr/include/i386\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458774, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([19 x i8]* @.str14, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 70, i64 0, i64 0, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([9 x i8]* @.str15, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str16, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.variable17 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+@llvm.dbg.variable17 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
@.str18 = internal constant [18 x i8] c"long unsigned int\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1]
@llvm.dbg.basictype19 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str18, 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, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
@.str20 = internal constant [3 x i8] c"_f\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1]
-@llvm.dbg.variable21 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str20, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+@llvm.dbg.variable21 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str20, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
@_DefaultRuneLocale = external global %struct._RuneLocale ; <%struct._RuneLocale*> [#uses=1]
@.str22 = internal constant [8 x i8] c"isascii\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.subprogram23 = 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 ([8 x i8]* @.str22, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 153, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable24 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram23 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 152, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+@llvm.dbg.subprogram23 = 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 ([8 x i8]* @.str22, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 153, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@llvm.dbg.variable24 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram23 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 152, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
@.str25 = internal constant [8 x i8] c"toupper\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
-@llvm.dbg.subprogram26 = 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 ([8 x i8]* @.str25, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 316, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.variable27 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram26 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 315, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+@llvm.dbg.subprogram26 = 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 ([8 x i8]* @.str25, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 316, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@llvm.dbg.variable27 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram26 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 315, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
define i32 @main() nounwind {
entry:
diff --git a/test/DebugInfo/2009-01-15-member.ll b/test/DebugInfo/2009-01-15-member.ll
index ae598d6a6e35..7eb81f8f3dd8 100644
--- a/test/DebugInfo/2009-01-15-member.ll
+++ b/test/DebugInfo/2009-01-15-member.ll
@@ -27,4 +27,4 @@
@llvm.dbg.composite11 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, i64 64, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, 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]
@.str12 = internal constant [3 x i8] c"s2\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1]
-@llvm.dbg.global_variable = 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 ([3 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 6, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*), i1 false, i1 true, { }* bitcast (%struct.s* @s2 to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0]
+@llvm.dbg.global_variable = 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 ([3 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 6, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*), i1 false, i1 true, { }* bitcast (%struct.s* @s2 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0] \ No newline at end of file
diff --git a/test/DebugInfo/2009-01-28-ArrayType.ll b/test/DebugInfo/2009-01-28-ArrayType.ll
new file mode 100644
index 000000000000..81905953b717
--- /dev/null
+++ b/test/DebugInfo/2009-01-28-ArrayType.ll
@@ -0,0 +1,23 @@
+; RUN: llvm-as < %s | llc | grep 0x49 | count 3
+; Count number of DW_AT_Type attributes.
+target triple = "i386-apple-darwin*"
+ %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* }
+ %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
+ %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* }
+ %llvm.dbg.subrange.type = type { i32, i64, i64 }
+@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 [8 x i8] c"array.c\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1]
+@.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
+@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (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 ([8 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
+@c = common global [3 x i32] zeroinitializer ; <[3 x i32]*> [#uses=1]
+@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type { i32 458785, i64 0, i64 2 }, 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]
+@.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.composite = 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 96, 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]
+@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
+@.str4 = internal constant [2 x i8] c"c\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
+@llvm.dbg.global_variable = 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 ([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.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true, { }* bitcast ([3 x i32]* @c to { }*) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0]
diff --git a/test/DebugInfo/2009-01-29-HeaderLocation.ll b/test/DebugInfo/2009-01-29-HeaderLocation.ll
new file mode 100644
index 000000000000..c59a1c730cdd
--- /dev/null
+++ b/test/DebugInfo/2009-01-29-HeaderLocation.ll
@@ -0,0 +1,46 @@
+; RUN: llvm-as < %s | llc | grep "m.h" | count 1
+target triple = "i386-apple-darwin9.6"
+ %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* }
+ %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.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"m.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
+@.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
+@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (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 ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, 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.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 { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
+@.str4 = internal constant [4 x i8] c"m.h\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
+@llvm.dbg.compile_unit5 = 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]* @.str4, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.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]
+@.str6 = 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]* @.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_unit5 to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+
+define i32 @main() nounwind {
+entry:
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %0 = alloca i32 ; <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.subprogram to { }*))
+ call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*))
+ store i32 0, i32* %0, align 4
+ %1 = load i32* %0, align 4 ; <i32> [#uses=1]
+ store i32 %1, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %entry
+ %retval1 = load i32* %retval ; <i32> [#uses=1]
+ call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*))
+ call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
+ ret i32 %retval1
+}
+
+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-01-29-MethodDeclaration.ll b/test/DebugInfo/2009-01-29-MethodDeclaration.ll
new file mode 100644
index 000000000000..6d1e1e91b15a
--- /dev/null
+++ b/test/DebugInfo/2009-01-29-MethodDeclaration.ll
@@ -0,0 +1,32 @@
+; RUN: llvm-as < %s | llc | grep 0x3C | count 1
+; Check DW_AT_declaration attribute for class method foo.
+target triple = "i386-apple-darwin*"
+ %llvm.dbg.anchor.type = type { i32, i32 }
+ %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* }
+ %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i8* }
+ %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i8*, i8* }
+ %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, i8*, i8* }
+ %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }*, i8*, i8* }
+ %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, i8*, i8* }
+ %struct.A = type <{ 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 [6 x i8] c"cl.cc\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
+@.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1]
+@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (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 4, i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
+@a = global %struct.A zeroinitializer ; <%struct.A*> [#uses=1]
+@.str3 = internal constant [2 x i8] c"A\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
+@.str4 = 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]* @.str4, 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, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.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.composite.type* @llvm.dbg.composite9 to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
+@llvm.dbg.array = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) ], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1]
+@llvm.dbg.composite5 = 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 { }*), i8* null, i8* null }, 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]
+@.str6 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
+@.str7 = internal constant [12 x i8] c"_ZN1A3fooEv\00", section "llvm.metadata" ; <[12 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 ([4 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str7, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite5 to { }*), i1 false, i1 false, i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@llvm.dbg.array8 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1]
+@llvm.dbg.composite9 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, i64 8, i64 8, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array8 to { }*), i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, 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]
+@.str10 = internal constant [2 x i8] c"a\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
+@llvm.dbg.global_variable = 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 ([2 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([2 x i8]* @.str10, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 7, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite9 to { }*), i1 false, i1 true, { }* bitcast (%struct.A* @a to { }*), i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0]
diff --git a/test/DebugInfo/2009-01-30-Method.ll b/test/DebugInfo/2009-01-30-Method.ll
new file mode 100644
index 000000000000..6b2a8b98ce68
--- /dev/null
+++ b/test/DebugInfo/2009-01-30-Method.ll
@@ -0,0 +1,103 @@
+; RUN: llvm-as < %s | llc | grep "\\"foo" | count 3
+; 1 declaration, 1 definition and 1 pubnames entry.
+target triple = "i386-apple-darwin*"
+ %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* }
+ %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
+ %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
+ %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
+ %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
+ %struct.Fibonancci = type { 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 [10 x i8] c"method.cc\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
+@.str1 = internal constant [64 x i8] c"/Volumes/Nanpura/mainline/llvmgcc42.build/gcc/../../../dbg.test\00", section "llvm.metadata" ; <[64 x i8]*> [#uses=1]
+@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (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 4, i8* getelementptr ([10 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([64 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
+@.str3 = internal constant [11 x i8] c"Fibonancci\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
+@.str4 = 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]* @.str4, 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]
+@.str5 = internal constant [2 x i8] c"N\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
+@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 5, i64 32, i64 32, i64 0, i32 1, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
+@llvm.dbg.derivedtype6 = 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.composite.type* @llvm.dbg.composite11 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
+@llvm.dbg.array = internal constant [3 x { }*] [ { }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype6 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1]
+@llvm.dbg.composite7 = 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 ([3 x { }*]* @llvm.dbg.array to { }*) }, 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]
+@.str8 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
+@.str9 = internal constant [22 x i8] c"_ZN10Fibonancci3fooEi\00", section "llvm.metadata" ; <[22 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 ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str9, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite7 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@llvm.dbg.array10 = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) ], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1]
+@llvm.dbg.composite11 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([11 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, i64 32, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array10 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
+@llvm.dbg.derivedtype12 = 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.composite.type* @llvm.dbg.composite11 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
+@llvm.dbg.array13 = internal constant [3 x { }*] [ { }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[3 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 ([3 x { }*]* @llvm.dbg.array13 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
+@llvm.dbg.subprogram14 = 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 ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str9, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@llvm.dbg.derivedtype15 = internal constant %llvm.dbg.derivedtype.type { i32 458790, { }* 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.derivedtype.type* @llvm.dbg.derivedtype12 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
+@.str16 = internal constant [5 x i8] c"this\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
+@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram14 to { }*), i8* getelementptr ([5 x i8]* @.str16, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype15 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+@.str17 = internal constant [2 x i8] c"i\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
+@llvm.dbg.variable18 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram14 to { }*), i8* getelementptr ([2 x i8]* @.str17, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+@llvm.dbg.array19 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1]
+@llvm.dbg.composite20 = 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.array19 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
+@.str21 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
+@llvm.dbg.subprogram22 = 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]* @.str21, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str21, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 14, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite20 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
+@.str23 = internal constant [4 x i8] c"fib\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
+@llvm.dbg.variable24 = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram22 to { }*), i8* getelementptr ([4 x i8]* @.str23, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 15, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
+
+define void @_ZN10Fibonancci3fooEi(%struct.Fibonancci* %this, i32 %i) nounwind {
+entry:
+ %this_addr = alloca %struct.Fibonancci* ; <%struct.Fibonancci**> [#uses=3]
+ %i_addr = alloca i32 ; <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.subprogram14 to { }*))
+ %0 = bitcast %struct.Fibonancci** %this_addr to { }* ; <{ }*> [#uses=1]
+ call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*))
+ store %struct.Fibonancci* %this, %struct.Fibonancci** %this_addr
+ %1 = bitcast i32* %i_addr to { }* ; <{ }*> [#uses=1]
+ call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable18 to { }*))
+ store i32 %i, i32* %i_addr
+ call void @llvm.dbg.stoppoint(i32 11, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
+ %2 = load %struct.Fibonancci** %this_addr, align 4 ; <%struct.Fibonancci*> [#uses=1]
+ %3 = getelementptr %struct.Fibonancci* %2, i32 0, i32 0 ; <i32*> [#uses=1]
+ %4 = load i32* %i_addr, align 4 ; <i32> [#uses=1]
+ store i32 %4, i32* %3, align 4
+ call void @llvm.dbg.stoppoint(i32 12, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
+ br label %return
+
+return: ; preds = %entry
+ call void @llvm.dbg.stoppoint(i32 12, 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.subprogram14 to { }*))
+ ret void
+}
+
+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
+
+define i32 @main() nounwind {
+entry:
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %fib = alloca %struct.Fibonancci ; <%struct.Fibonancci*> [#uses=2]
+ %0 = alloca i32 ; <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.subprogram22 to { }*))
+ %1 = bitcast %struct.Fibonancci* %fib to { }* ; <{ }*> [#uses=1]
+ call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable24 to { }*))
+ call void @llvm.dbg.stoppoint(i32 16, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
+ call void @_ZN10Fibonancci3fooEi(%struct.Fibonancci* %fib, i32 42) nounwind
+ call void @llvm.dbg.stoppoint(i32 17, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
+ store i32 0, i32* %0, align 4
+ %2 = load i32* %0, align 4 ; <i32> [#uses=1]
+ store i32 %2, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %entry
+ %retval1 = load i32* %retval ; <i32> [#uses=1]
+ call void @llvm.dbg.stoppoint(i32 17, 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.subprogram22 to { }*))
+ ret i32 %retval1
+}
diff --git a/test/ExecutionEngine/2009-01-29-PartSet.ll b/test/ExecutionEngine/2009-01-29-PartSet.ll
new file mode 100644
index 000000000000..ae766876fc7e
--- /dev/null
+++ b/test/ExecutionEngine/2009-01-29-PartSet.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-as %s -o - | lli -force-interpreter | grep FF8F
+
+; ModuleID = 'partset.c.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+@.str = internal constant [4 x i8] c"%X\0A\00" ; <[4 x i8]*> [#uses=1]
+
+define i32 @main() nounwind {
+entry:
+ %part_set = tail call i32 @llvm.part.set.i32.i8( i32 65535, i8 1, i32 7, i32 4 ) ; <i32> [#uses=1]
+ %tmp4 = tail call i32 (i8*, ...)* @printf( i8* noalias getelementptr ([4 x i8]* @.str, i32 0, i64 0), i32 %part_set ) nounwind ; <i32> [#uses=0]
+ ret i32 0
+}
+
+declare i32 @llvm.part.set.i32.i8(i32, i8, i32, i32) nounwind readnone
+
+declare i32 @printf(i8*, ...) nounwind
diff --git a/test/FrontendC++/2006-11-06-StackTrace.cpp b/test/FrontendC++/2006-11-06-StackTrace.cpp
index d1b60c9b59ae..55b34ad82d52 100644
--- a/test/FrontendC++/2006-11-06-StackTrace.cpp
+++ b/test/FrontendC++/2006-11-06-StackTrace.cpp
@@ -10,8 +10,7 @@
// RUN: grep {#7 0x.* in main.*(argc=\[12\],.*argv=.*)}
// Only works on ppc, x86 and x86_64. Should generalize?
-// FIXME: Un-XFAIL this test for Linux when debug stuff is working again.
-// XFAIL: alpha|ia64|arm|linux
+// XFAIL: alpha|ia64|arm
#include <stdlib.h>
diff --git a/test/FrontendC++/2006-11-30-Pubnames.cpp b/test/FrontendC++/2006-11-30-Pubnames.cpp
index 9693169e578a..8af99e37c989 100644
--- a/test/FrontendC++/2006-11-30-Pubnames.cpp
+++ b/test/FrontendC++/2006-11-30-Pubnames.cpp
@@ -4,10 +4,10 @@
// RUN: llc --disable-fp-elim -o %t.s -f
// RUN: %compile_c %t.s -o %t.o
// RUN: %link %t.o -o %t.exe
+// RUN: %llvmdsymutil %t.exe
// RUN: echo {break main\nrun\np Pubnames::pubname} > %t.in
// RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | grep {\$1 = 10}
// XFAIL: alpha|ia64|arm
-// XFAIL: *
struct Pubnames {
static int pubname;
};
diff --git a/test/FrontendC/always-inline.c b/test/FrontendC/always-inline.c
new file mode 100644
index 000000000000..22f6c7a20ef2
--- /dev/null
+++ b/test/FrontendC/always-inline.c
@@ -0,0 +1,12 @@
+// RUN: %llvmgcc -S %s -o - | grep call | not grep foo
+
+void bar() {
+}
+
+inline void __attribute__((__always_inline__)) foo() {
+ bar();
+}
+
+void i_want_bar() {
+ foo();
+}
diff --git a/test/FrontendC/implicit-arg.c b/test/FrontendC/implicit-arg.c
new file mode 100644
index 000000000000..971245f3badc
--- /dev/null
+++ b/test/FrontendC/implicit-arg.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -S -emit-llvm -O0 -o -
+// RUN: %llvmgcc %s -S -emit-llvm -O1 -o -
+// rdar://6518089
+
+static int bar();
+void foo() {
+ int a = bar();
+}
+int bar(unsigned a) {
+}
diff --git a/test/FrontendC/union-align.c b/test/FrontendC/union-align.c
new file mode 100644
index 000000000000..f99a76080569
--- /dev/null
+++ b/test/FrontendC/union-align.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -S %s -o - | grep load | grep "4 x float" | not grep "align 4"
+// RUN: %llvmgcc -S %s -o - | grep load | grep "4 x float" | grep "align 16"
+// PR3432
+// rdar://6536377
+
+typedef float __m128 __attribute__ ((__vector_size__ (16)));
+
+typedef union
+{
+ int i[4];
+ float f[4];
+ __m128 v;
+} u_t;
+
+__m128 t(u_t *a) {
+ return a->v;
+}
diff --git a/test/FrontendObjC/2009-01-26-WriteBarrier-2.m b/test/FrontendObjC/2009-01-26-WriteBarrier-2.m
new file mode 100644
index 000000000000..32833a81e169
--- /dev/null
+++ b/test/FrontendObjC/2009-01-26-WriteBarrier-2.m
@@ -0,0 +1,14 @@
+// RUN: %llvmgcc -x objective-c -S %s -fobjc-gc -o - | grep objc_assign_strongCast
+// rdar://5541393
+
+typedef struct {
+ void (^ivarBlock)(void);
+} StructWithBlock_t;
+
+int main(char *argc, char *argv[]) {
+ StructWithBlock_t *swbp = (StructWithBlock_t *)malloc(sizeof(StructWithBlock_t*));
+ __block int i = 10;
+ // assigning a Block into an struct slot should elicit a write-barrier under GC
+ swbp->ivarBlock = ^ { ++i; };
+ return 0;
+}
diff --git a/test/LLVMC/ExternOptions.td b/test/LLVMC/ExternOptions.td
index 11383cb15bae..a04a88b002aa 100644
--- a/test/LLVMC/ExternOptions.td
+++ b/test/LLVMC/ExternOptions.td
@@ -1,6 +1,7 @@
// Check that extern options work.
// The dummy tool and graph are required to silence warnings.
-// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep {extern .* AutoGeneratedSwitch_Wall}
+// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t
+// RUN: grep {extern .* AutoGeneratedSwitch_Wall} %t
include "llvm/CompilerDriver/Common.td"
diff --git a/test/LLVMC/MultiValuedOption.td b/test/LLVMC/MultiValuedOption.td
new file mode 100644
index 000000000000..d68a115af19d
--- /dev/null
+++ b/test/LLVMC/MultiValuedOption.td
@@ -0,0 +1,21 @@
+// Check that multivalued options work.
+// The dummy tool and graph are required to silence warnings.
+// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t
+// RUN: grep cl::multi_val(2) %t | count 1
+
+include "llvm/CompilerDriver/Common.td"
+
+def OptList : OptionList<[
+ (prefix_list_option "foo", (multi_val 2)),
+ (parameter_list_option "baz", (multi_val 2), (extern))]>;
+
+def dummy_tool : Tool<[
+(cmd_line "dummy_cmd"),
+(in_language "dummy"),
+(out_language "dummy"),
+(actions (case
+ (not_empty "foo"), (forward_as "foo", "bar"),
+ (not_empty "baz"), (forward "baz")))
+]>;
+
+def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>;
diff --git a/test/LLVMC/OneOrMore.td b/test/LLVMC/OneOrMore.td
new file mode 100644
index 000000000000..f27ae9707d70
--- /dev/null
+++ b/test/LLVMC/OneOrMore.td
@@ -0,0 +1,22 @@
+// Check that (one_or_more) and (zero_or_one) properties work.
+// The dummy tool and graph are required to silence warnings.
+// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t
+// RUN: grep cl::ZeroOrOne %t | count 1
+// RUN: grep cl::OneOrMore %t | count 1
+
+include "llvm/CompilerDriver/Common.td"
+
+def OptList : OptionList<[
+ (prefix_list_option "foo", (one_or_more)),
+ (parameter_list_option "baz", (zero_or_one))]>;
+
+def dummy_tool : Tool<[
+(cmd_line "dummy_cmd"),
+(in_language "dummy"),
+(out_language "dummy"),
+(actions (case
+ (not_empty "foo"), (forward_as "foo", "bar"),
+ (not_empty "baz"), (forward "baz")))
+]>;
+
+def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>;
diff --git a/test/Makefile b/test/Makefile
index b6067c372fae..7ce4086f1af4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -81,6 +81,13 @@ endif
clean::
$(RM) -rf `find $(LLVM_OBJ_ROOT)/test -name Output -type d -print`
+# dsymutil is used on the Darwin to manipulate DWARF debugging information.
+ifeq ($(OS),Darwin)
+DSYMUTIL=dsymutil
+else
+DSYMUTIL=true
+endif
+
FORCE:
site.exp: FORCE
@@ -112,6 +119,7 @@ site.exp: FORCE
@echo 'set valgrind "$(VALGRIND)"' >> site.tmp
@echo 'set grep "$(GREP)"' >>site.tmp
@echo 'set gas "$(GAS)"' >>site.tmp
+ @echo 'set llvmdsymutil "$(DSYMUTIL)"' >>site.tmp
@echo '## All variables above are generated by configure. Do Not Edit ## ' >>site.tmp
@test ! -f site.exp || \
sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
diff --git a/test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll b/test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll
new file mode 100644
index 000000000000..d14ce38f3df2
--- /dev/null
+++ b/test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll
@@ -0,0 +1,37 @@
+; RUN: llvm-as < %s | opt -condprop | llvm-dis
+; PR3405
+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 @main(i32 %argc, i8** %argv) nounwind {
+entry:
+ br label %bb2
+
+bb2: ; preds = %bb.bb2_crit_edge, %entry
+ br i1 false, label %bb5.thread2, label %bb
+
+bb: ; preds = %bb2
+ br i1 false, label %bb3, label %bb.bb2_crit_edge
+
+bb.bb2_crit_edge: ; preds = %bb
+ br label %bb2
+
+bb3: ; preds = %bb
+ %.lcssa4 = phi i1 [ false, %bb ] ; <i1> [#uses=1]
+ br i1 %.lcssa4, label %bb5.thread, label %bb6
+
+bb5.thread: ; preds = %bb3
+ br label %bb7
+
+bb7: ; preds = %bb5.thread2, %bb5.thread
+ br label %UnifiedReturnBlock
+
+bb6: ; preds = %bb3
+ br label %UnifiedReturnBlock
+
+bb5.thread2: ; preds = %bb2
+ br label %bb7
+
+UnifiedReturnBlock: ; preds = %bb6, %bb7
+ ret i32 0
+}
diff --git a/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll b/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll
new file mode 100644
index 000000000000..4c7146320485
--- /dev/null
+++ b/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll
@@ -0,0 +1,28 @@
+; RUN: llvm-as < %s | opt -constprop -disable-output
+; PR2529
+define <4 x i32> @test1(i32 %argc, i8** %argv) {
+entry:
+ %foo = vicmp slt <4 x i32> undef, <i32 14, i32 undef, i32 undef, i32 undef>
+ ret <4 x i32> %foo
+}
+
+define <4 x i32> @test2(i32 %argc, i8** %argv) {
+entry:
+ %foo = vicmp slt <4 x i32> <i32 undef, i32 undef, i32 undef, i32
+undef>, <i32 undef, i32 undef, i32 undef, i32 undef>
+ ret <4 x i32> %foo
+}
+
+
+define <4 x i32> @test3() {
+ %foo = vfcmp ueq <4 x float> <float 0.0, float 0.0, float 0.0, float
+undef>, <float 1.0, float 1.0, float 1.0, float undef>
+ ret <4 x i32> %foo
+}
+
+define <4 x i32> @test4() {
+ %foo = vfcmp ueq <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, <float 1.0, float 1.0, float 1.0, float 0.0>
+
+ ret <4 x i32> %foo
+}
+
diff --git a/test/Transforms/GVN/2009-01-22-SortInvalidation.ll b/test/Transforms/GVN/2009-01-22-SortInvalidation.ll
new file mode 100644
index 000000000000..9b7fa0622ab8
--- /dev/null
+++ b/test/Transforms/GVN/2009-01-22-SortInvalidation.ll
@@ -0,0 +1,100 @@
+; RUN: llvm-as < %s | opt -gvn | llvm-dis
+
+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-darwin7"
+ %struct..4sPragmaType = type { i8*, i32 }
+ %struct.AggInfo = type { i8, i8, i32, %struct.ExprList*, i32, %struct.AggInfo_col*, i32, i32, i32, %struct.AggInfo_func*, i32, i32 }
+ %struct.AggInfo_col = type { %struct.Table*, i32, i32, i32, i32, %struct.Expr* }
+ %struct.AggInfo_func = type { %struct.Expr*, %struct.FuncDef*, i32, i32 }
+ %struct.AuxData = type { i8*, void (i8*)* }
+ %struct.Bitvec = type { i32, i32, i32, { [125 x i32] } }
+ %struct.BtCursor = type { %struct.Btree*, %struct.BtShared*, %struct.BtCursor*, %struct.BtCursor*, i32 (i8*, i32, i8*, i32, i8*)*, i8*, i32, %struct.MemPage*, i32, %struct.CellInfo, i8, i8, i8*, i64, i32, i8, i32* }
+ %struct.BtLock = type { %struct.Btree*, i32, i8, %struct.BtLock* }
+ %struct.BtShared = type { %struct.Pager*, %struct.sqlite3*, %struct.BtCursor*, %struct.MemPage*, i8, i8, i8, i8, i8, i8, i8, i8, i32, i16, i16, i32, i32, i32, i32, i8, i32, i8*, void (i8*)*, %struct.sqlite3_mutex*, %struct.BusyHandler, i32, %struct.BtShared*, %struct.BtLock*, %struct.Btree* }
+ %struct.Btree = type { %struct.sqlite3*, %struct.BtShared*, i8, i8, i8, i32, %struct.Btree*, %struct.Btree* }
+ %struct.BtreeMutexArray = type { i32, [11 x %struct.Btree*] }
+ %struct.BusyHandler = type { i32 (i8*, i32)*, i8*, i32 }
+ %struct.CellInfo = type { i8*, i64, i32, i32, i16, i16, i16, i16 }
+ %struct.CollSeq = type { i8*, i8, i8, i8*, i32 (i8*, i32, i8*, i32, i8*)*, void (i8*)* }
+ %struct.Column = type { i8*, %struct.Expr*, i8*, i8*, i8, i8, i8, i8 }
+ %struct.Context = type { i64, i32, %struct.Fifo }
+ %struct.CountCtx = type { i64 }
+ %struct.Cursor = type { %struct.BtCursor*, i32, i64, i64, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i64, %struct.Btree*, i32, i8*, i64, i8*, %struct.KeyInfo*, i32, i64, %struct.sqlite3_vtab_cursor*, %struct.sqlite3_module*, i32, i32, i32*, i32*, i8* }
+ %struct.Db = type { i8*, %struct.Btree*, i8, i8, i8*, void (i8*)*, %struct.Schema* }
+ %struct.Expr = type { i8, i8, i16, %struct.CollSeq*, %struct.Expr*, %struct.Expr*, %struct.ExprList*, %struct..4sPragmaType, %struct..4sPragmaType, i32, i32, %struct.AggInfo*, i32, i32, %struct.Select*, %struct.Table*, i32 }
+ %struct.ExprList = type { i32, i32, i32, %struct.ExprList_item* }
+ %struct.ExprList_item = type { %struct.Expr*, i8*, i8, i8, i8 }
+ %struct.FKey = type { %struct.Table*, %struct.FKey*, i8*, %struct.FKey*, i32, %struct.sColMap*, i8, i8, i8, i8 }
+ %struct.Fifo = type { i32, %struct.FifoPage*, %struct.FifoPage* }
+ %struct.FifoPage = type { i32, i32, i32, %struct.FifoPage*, [1 x i64] }
+ %struct.FuncDef = type { i16, i8, i8, i8, i8*, %struct.FuncDef*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*)*, [1 x i8] }
+ %struct.Hash = type { i8, i8, i32, i32, %struct.HashElem*, %struct._ht* }
+ %struct.HashElem = type { %struct.HashElem*, %struct.HashElem*, i8*, i8*, i32 }
+ %struct.IdList = type { %struct..4sPragmaType*, i32, i32 }
+ %struct.Index = type { i8*, i32, i32*, i32*, %struct.Table*, i32, i8, i8, i8*, %struct.Index*, %struct.Schema*, i8*, i8** }
+ %struct.KeyInfo = type { %struct.sqlite3*, i8, i8, i8, i32, i8*, [1 x %struct.CollSeq*] }
+ %struct.Mem = type { %struct.CountCtx, double, %struct.sqlite3*, i8*, i32, i16, i8, i8, void (i8*)* }
+ %struct.MemPage = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i16, i16, i16, i16, i16, i16, [5 x %struct._OvflCell], %struct.BtShared*, i8*, %struct.PgHdr*, i32, %struct.MemPage* }
+ %struct.Module = type { %struct.sqlite3_module*, i8*, i8*, void (i8*)* }
+ %struct.Op = type { i8, i8, i8, i8, i32, i32, i32, { i32 } }
+ %struct.Pager = type { %struct.sqlite3_vfs*, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.Bitvec*, %struct.Bitvec*, i8*, i8*, i8*, i8*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.BusyHandler*, %struct.PagerLruList, %struct.PgHdr*, %struct.PgHdr*, %struct.PgHdr*, i64, i64, i64, i64, i64, i32, void (%struct.PgHdr*, i32)*, void (%struct.PgHdr*, i32)*, i32, %struct.PgHdr**, i8*, [16 x i8] }
+ %struct.PagerLruLink = type { %struct.PgHdr*, %struct.PgHdr* }
+ %struct.PagerLruList = type { %struct.PgHdr*, %struct.PgHdr*, %struct.PgHdr* }
+ %struct.Parse = type { %struct.sqlite3*, i32, i8*, %struct.Vdbe*, i8, i8, i8, i8, i8, i8, i8, [8 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [12 x i32], i32, %struct.TableLock*, i32, i32, i32, i32, i32, %struct.Expr**, i8, %struct..4sPragmaType, %struct..4sPragmaType, %struct..4sPragmaType, i8*, i8*, %struct.Table*, %struct.Trigger*, %struct.TriggerStack*, i8*, %struct..4sPragmaType, i8, %struct.Table*, i32 }
+ %struct.PgHdr = type { %struct.Pager*, i32, %struct.PgHdr*, %struct.PgHdr*, %struct.PagerLruLink, %struct.PgHdr*, i8, i8, i8, i8, i8, i16, %struct.PgHdr*, %struct.PgHdr*, i8* }
+ %struct.Schema = type { i32, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Table*, i8, i8, i16, i32, %struct.sqlite3* }
+ %struct.Select = type { %struct.ExprList*, i8, i8, i8, i8, i8, i8, i8, %struct.SrcList*, %struct.Expr*, %struct.ExprList*, %struct.Expr*, %struct.ExprList*, %struct.Select*, %struct.Select*, %struct.Select*, %struct.Expr*, %struct.Expr*, i32, i32, [3 x i32] }
+ %struct.SrcList = type { i16, i16, [1 x %struct.SrcList_item] }
+ %struct.SrcList_item = type { i8*, i8*, i8*, %struct.Table*, %struct.Select*, i8, i8, i32, %struct.Expr*, %struct.IdList*, i64 }
+ %struct.Table = type { i8*, i32, %struct.Column*, i32, %struct.Index*, i32, %struct.Select*, i32, %struct.Trigger*, %struct.FKey*, i8*, %struct.Expr*, i32, i8, i8, i8, i8, i8, i8, i8, %struct.Module*, %struct.sqlite3_vtab*, i32, i8**, %struct.Schema* }
+ %struct.TableLock = type { i32, i32, i8, i8* }
+ %struct.Trigger = type { i8*, i8*, i8, i8, %struct.Expr*, %struct.IdList*, %struct..4sPragmaType, %struct.Schema*, %struct.Schema*, %struct.TriggerStep*, %struct.Trigger* }
+ %struct.TriggerStack = type { %struct.Table*, i32, i32, i32, i32, i32, i32, %struct.Trigger*, %struct.TriggerStack* }
+ %struct.TriggerStep = type { i32, i32, %struct.Trigger*, %struct.Select*, %struct..4sPragmaType, %struct.Expr*, %struct.ExprList*, %struct.IdList*, %struct.TriggerStep*, %struct.TriggerStep* }
+ %struct.Vdbe = type { %struct.sqlite3*, %struct.Vdbe*, %struct.Vdbe*, i32, i32, %struct.Op*, i32, i32, i32*, %struct.Mem**, %struct.Mem*, i32, %struct.Cursor**, i32, %struct.Mem*, i8**, i32, i32, i32, %struct.Mem*, i32, i32, %struct.Fifo, i32, i32, %struct.Context*, i32, i32, i32, i32, i32, [25 x i32], i32, i32, i8**, i8*, %struct.Mem*, i8, i8, i8, i8, i8, i8, i32, i64, i32, %struct.BtreeMutexArray, i32, i8*, i32 }
+ %struct.VdbeFunc = type { %struct.FuncDef*, i32, [1 x %struct.AuxData] }
+ %struct._OvflCell = type { i8*, i16 }
+ %struct._ht = type { i32, %struct.HashElem* }
+ %struct.anon = type { double }
+ %struct.sColMap = type { i32, i8* }
+ %struct.sqlite3 = type { %struct.sqlite3_vfs*, i32, %struct.Db*, i32, i32, i32, i32, i8, i8, i8, i8, i32, %struct.CollSeq*, i64, i64, i32, i32, i32, %struct.sqlite3_mutex*, %struct.sqlite3InitInfo, i32, i8**, %struct.Vdbe*, i32, void (i8*, i8*)*, i8*, void (i8*, i8*, i64)*, i8*, i8*, i32 (i8*)*, i8*, void (i8*)*, i8*, void (i8*, i32, i8*, i8*, i64)*, void (i8*, %struct.sqlite3*, i32, i8*)*, void (i8*, %struct.sqlite3*, i32, i8*)*, i8*, %struct.Mem*, i8*, i8*, %struct.anon, i32 (i8*, i32, i8*, i8*, i8*, i8*)*, i8*, i32 (i8*)*, i8*, i32, %struct.Hash, %struct.Table*, %struct.sqlite3_vtab**, i32, %struct.Hash, %struct.Hash, %struct.BusyHandler, i32, [2 x %struct.Db], i8 }
+ %struct.sqlite3InitInfo = type { i32, i32, i8 }
+ %struct.sqlite3_context = type { %struct.FuncDef*, %struct.VdbeFunc*, %struct.Mem, %struct.Mem*, i32, %struct.CollSeq* }
+ %struct.sqlite3_file = type { %struct.sqlite3_io_methods* }
+ %struct.sqlite3_index_constraint = type { i32, i8, i8, i32 }
+ %struct.sqlite3_index_constraint_usage = type { i32, i8 }
+ %struct.sqlite3_index_info = type { i32, %struct.sqlite3_index_constraint*, i32, %struct.sqlite3_index_constraint_usage*, %struct.sqlite3_index_constraint_usage*, i32, i8*, i32, i32, double }
+ %struct.sqlite3_io_methods = type { i32, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i64)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i64*)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i32, i8*)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*)* }
+ %struct.sqlite3_module = type { i32, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_index_info*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_vtab_cursor**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, i32, i8*, i32, %struct.Mem**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, %struct.sqlite3_context*, i32)*, i32 (%struct.sqlite3_vtab_cursor*, i64*)*, i32 (%struct.sqlite3_vtab*, i32, %struct.Mem**, i64*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, i32, i8*, void (%struct.sqlite3_context*, i32, %struct.Mem**)**, i8**)*, i32 (%struct.sqlite3_vtab*, i8*)* }
+ %struct.sqlite3_mutex = type opaque
+ %struct.sqlite3_vfs = type { i32, i32, i32, %struct.sqlite3_vfs*, i8*, i8*, i32 (%struct.sqlite3_vfs*, i8*, %struct.sqlite3_file*, i32, i32*)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i8*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*)*, void (%struct.sqlite3_vfs*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*, i8*)*, void (%struct.sqlite3_vfs*, i8*)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i32)*, i32 (%struct.sqlite3_vfs*, double*)* }
+ %struct.sqlite3_vtab = type { %struct.sqlite3_module*, i32, i8* }
+ %struct.sqlite3_vtab_cursor = type { %struct.sqlite3_vtab* }
+
+define fastcc void @sqlite3Insert(%struct.Parse* %pParse, %struct.SrcList* %pTabList, %struct.ExprList* %pList, %struct.Select* %pSelect, %struct.IdList* %pColumn, i32 %onError) nounwind {
+entry:
+ br i1 false, label %bb54, label %bb69.loopexit
+
+bb54: ; preds = %entry
+ br label %bb69.loopexit
+
+bb59: ; preds = %bb63.preheader
+ %0 = load %struct..4sPragmaType** %3, align 4 ; <%struct..4sPragmaType*> [#uses=0]
+ br label %bb65
+
+bb65: ; preds = %bb63.preheader, %bb59
+ %1 = load %struct..4sPragmaType** %4, align 4 ; <%struct..4sPragmaType*> [#uses=0]
+ br i1 false, label %bb67, label %bb63.preheader
+
+bb67: ; preds = %bb65
+ %2 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=0]
+ unreachable
+
+bb69.loopexit: ; preds = %bb54, %entry
+ %3 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=1]
+ %4 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=1]
+ br label %bb63.preheader
+
+bb63.preheader: ; preds = %bb69.loopexit, %bb65
+ br i1 false, label %bb59, label %bb65
+}
diff --git a/test/Transforms/IndMemRem/2009-01-24-Noalias.ll b/test/Transforms/IndMemRem/2009-01-24-Noalias.ll
new file mode 100644
index 000000000000..bc3d0bfe5e3f
--- /dev/null
+++ b/test/Transforms/IndMemRem/2009-01-24-Noalias.ll
@@ -0,0 +1,11 @@
+; RUN: llvm-as < %s | opt -indmemrem | llvm-dis | grep bounce | grep noalias
+
+declare i8* @malloc(i32)
+
+@g = external global i8*
+
+define void @test() {
+ %A = bitcast i8* (i32) * @malloc to i8*
+ store i8* %A, i8** @g
+ ret void
+}
diff --git a/test/Transforms/IndMemRem/dg.exp b/test/Transforms/IndMemRem/dg.exp
new file mode 100644
index 000000000000..f2005891a59a
--- /dev/null
+++ b/test/Transforms/IndMemRem/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
diff --git a/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll b/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll
new file mode 100644
index 000000000000..38d759656f26
--- /dev/null
+++ b/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll
@@ -0,0 +1,32 @@
+; RUN: llvm-as < %s | opt -inline -prune-eh
+; PR3367
+
+define void @f2() {
+ invoke void @f6()
+ to label %ok1 unwind label %lpad1
+
+ok1:
+ ret void
+
+lpad1:
+ invoke void @f4()
+ to label %ok2 unwind label %lpad2
+
+ok2:
+ call void @f8()
+ unreachable
+
+lpad2:
+ unreachable
+}
+
+declare void @f3()
+
+define void @f4() {
+ call void @f3()
+ ret void
+}
+
+declare void @f6() nounwind
+
+declare void @f8()
diff --git a/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll b/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll
index 1540d41a2652..428a35947d1d 100644
--- a/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll
+++ b/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll
@@ -1,5 +1,4 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep xor
-; XFAIL: *
define i1 @test1(i8 %x, i8 %y) {
%X = xor i8 %x, 128
diff --git a/test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll b/test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll
new file mode 100644
index 000000000000..313e76d028d0
--- /dev/null
+++ b/test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | opt -instcombine
+; PR3381
+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.atomic_t = type { i32 }
+ %struct.inode = type { i32, %struct.mutex }
+ %struct.list_head = type { %struct.list_head*, %struct.list_head* }
+ %struct.lock_class_key = type { }
+ %struct.mutex = type { %struct.atomic_t, %struct.rwlock_t, %struct.list_head }
+ %struct.rwlock_t = type { %struct.lock_class_key }
+
+define void @handle_event(%struct.inode* %bar) nounwind {
+entry:
+ %0 = getelementptr %struct.inode* %bar, i64 -1, i32 1, i32 1 ; <%struct.rwlock_t*> [#uses=1]
+ %1 = bitcast %struct.rwlock_t* %0 to i32* ; <i32*> [#uses=1]
+ store i32 1, i32* %1, align 4
+ ret void
+}
diff --git a/test/Transforms/InstCombine/2009-01-31-InfIterate.ll b/test/Transforms/InstCombine/2009-01-31-InfIterate.ll
new file mode 100644
index 000000000000..6620e4fadd64
--- /dev/null
+++ b/test/Transforms/InstCombine/2009-01-31-InfIterate.ll
@@ -0,0 +1,22 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis
+; PR3452
+define i128 @test(i64 %A, i64 %B, i1 %C, i128 %Z, i128 %Y, i64* %P, i64* %Q) {
+entry:
+ %tmp2 = trunc i128 %Z to i64
+ %tmp4 = trunc i128 %Y to i64
+ store i64 %tmp2, i64* %P
+ store i64 %tmp4, i64* %Q
+ %x = sub i64 %tmp2, %tmp4
+ %c = sub i64 %tmp2, %tmp4
+ %tmp137 = zext i1 %C to i64
+ %tmp138 = sub i64 %c, %tmp137
+ br label %T
+
+T:
+ %G = phi i64 [%tmp138, %entry], [%tmp2, %Fal]
+ %F = zext i64 %G to i128
+ ret i128 %F
+
+Fal:
+ br label %T
+}
diff --git a/test/Transforms/InstCombine/2009-01-31-Pressure.ll b/test/Transforms/InstCombine/2009-01-31-Pressure.ll
new file mode 100644
index 000000000000..0c3066bb90c9
--- /dev/null
+++ b/test/Transforms/InstCombine/2009-01-31-Pressure.ll
@@ -0,0 +1,22 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {%B = add i8 %b, %x}
+; PR2698
+
+declare void @use1(i1)
+declare void @use8(i8)
+
+define void @test1(i8 %a, i8 %b, i8 %x) {
+ %A = add i8 %a, %x
+ %B = add i8 %b, %x
+ %C = icmp eq i8 %A, %B
+ call void @use1(i1 %C)
+ ret void
+}
+
+define void @test2(i8 %a, i8 %b, i8 %x) {
+ %A = add i8 %a, %x
+ %B = add i8 %b, %x
+ %C = icmp eq i8 %A, %B
+ call void @use1(i1 %C)
+ call void @use8(i8 %A)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/cast-sext-zext.ll b/test/Transforms/InstCombine/cast-sext-zext.ll
index da5e7facfad6..1acd7582100f 100644
--- a/test/Transforms/InstCombine/cast-sext-zext.ll
+++ b/test/Transforms/InstCombine/cast-sext-zext.ll
@@ -1,4 +1,5 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep sext
+; XFAIL: *
define zeroext i16 @t(i8 zeroext %on_off, i16* nocapture %puls) nounwind readonly {
entry:
diff --git a/test/Transforms/InstCombine/cast-store-gep.ll b/test/Transforms/InstCombine/cast-store-gep.ll
new file mode 100644
index 000000000000..95a069d60b75
--- /dev/null
+++ b/test/Transforms/InstCombine/cast-store-gep.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep inttoptr
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep alloca
+
+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-darwin10.0"
+ %T = type { i8*, i8 }
+
+define i8* @test(i8* %Val, i64 %V) nounwind {
+entry:
+ %A = alloca %T, align 8
+ %mrv_gep = bitcast %T* %A to i64* ; <i64*> [#uses=1]
+ %B = getelementptr %T* %A, i64 0, i32 0 ; <i8**> [#uses=1]
+
+ store i64 %V, i64* %mrv_gep
+ %C = load i8** %B, align 8 ; <i8*> [#uses=1]
+ ret i8* %C
+}
diff --git a/test/Transforms/InstCombine/dce-iterate.ll b/test/Transforms/InstCombine/dce-iterate.ll
new file mode 100644
index 000000000000..e222970df6d8
--- /dev/null
+++ b/test/Transforms/InstCombine/dce-iterate.ll
@@ -0,0 +1,24 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret double .sy}
+
+define internal double @ScaleObjectAdd(double %sx, double %sy, double %sz) nounwind {
+entry:
+ %sx34 = bitcast double %sx to i64 ; <i64> [#uses=1]
+ %sx3435 = zext i64 %sx34 to i960 ; <i960> [#uses=1]
+ %sy22 = bitcast double %sy to i64 ; <i64> [#uses=1]
+ %sy2223 = zext i64 %sy22 to i960 ; <i960> [#uses=1]
+ %sy222324 = shl i960 %sy2223, 320 ; <i960> [#uses=1]
+ %sy222324.ins = or i960 %sx3435, %sy222324 ; <i960> [#uses=1]
+ %sz10 = bitcast double %sz to i64 ; <i64> [#uses=1]
+ %sz1011 = zext i64 %sz10 to i960 ; <i960> [#uses=1]
+ %sz101112 = shl i960 %sz1011, 640 ; <i960> [#uses=1]
+ %sz101112.ins = or i960 %sy222324.ins, %sz101112
+
+ %a = trunc i960 %sz101112.ins to i64 ; <i64> [#uses=1]
+ %b = bitcast i64 %a to double ; <double> [#uses=1]
+ %c = lshr i960 %sz101112.ins, 320 ; <i960> [#uses=1]
+ %d = trunc i960 %c to i64 ; <i64> [#uses=1]
+ %e = bitcast i64 %d to double ; <double> [#uses=1]
+ %f = add double %b, %e
+
+ ret double %e
+}
diff --git a/test/Transforms/InstCombine/multi-use-or.ll b/test/Transforms/InstCombine/multi-use-or.ll
new file mode 100644
index 000000000000..85a8b34e2f6e
--- /dev/null
+++ b/test/Transforms/InstCombine/multi-use-or.ll
@@ -0,0 +1,24 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {add double .sx, .sy}
+; The 'or' has multiple uses, make sure that this doesn't prevent instcombine
+; from propagating the extends to the truncs.
+
+define double @ScaleObjectAdd(double %sx, double %sy, double %sz) nounwind {
+entry:
+ %sx34 = bitcast double %sx to i64 ; <i64> [#uses=1]
+ %sx3435 = zext i64 %sx34 to i192 ; <i192> [#uses=1]
+ %sy22 = bitcast double %sy to i64 ; <i64> [#uses=1]
+ %sy2223 = zext i64 %sy22 to i192 ; <i192> [#uses=1]
+ %sy222324 = shl i192 %sy2223, 128 ; <i192> [#uses=1]
+ %sy222324.ins = or i192 %sx3435, %sy222324 ; <i192> [#uses=1]
+
+
+ %a = trunc i192 %sy222324.ins to i64 ; <i64> [#uses=1]
+ %b = bitcast i64 %a to double ; <double> [#uses=1]
+ %c = lshr i192 %sy222324.ins, 128 ; <i192> [#uses=1]
+ %d = trunc i192 %c to i64 ; <i64> [#uses=1]
+ %e = bitcast i64 %d to double ; <double> [#uses=1]
+ %f = add double %b, %e
+
+; ret double %e
+ ret double %f
+}
diff --git a/test/Transforms/InstCombine/vec_shuffle2.ll b/test/Transforms/InstCombine/vec_shuffle2.ll
new file mode 100644
index 000000000000..3bd8924903f8
--- /dev/null
+++ b/test/Transforms/InstCombine/vec_shuffle2.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep undef | count 1
+; END.
+
+; Test fold of two shuffles where the first shuffle vectors inputs are a
+; different length then the second.
+
+define void @test_cl(<4 x i8> addrspace(1)* %dest, <16 x i8> addrspace(1)* %old) nounwind {
+entry:
+ %arrayidx = getelementptr <4 x i8> addrspace(1)* %dest, i32 0 ; <<4 x i8> addrspace(1)*> [#uses=1]
+ %arrayidx5 = getelementptr <16 x i8> addrspace(1)* %old, i32 0 ; <<16 x i8> addrspace(1)*> [#uses=1]
+ %tmp6 = load <16 x i8> addrspace(1)* %arrayidx5 ; <<16 x i8>> [#uses=1]
+ %tmp7 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> < i32 13, i32 9, i32 4, i32 13 > ; <<4 x i8>> [#uses=1]
+ %tmp9 = shufflevector <4 x i8> %tmp7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 > ; <<4 x i8>> [#uses=1]
+ store <4 x i8> %tmp9, <4 x i8> addrspace(1)* %arrayidx
+ ret void
+
+return: ; preds = %entry
+ ret void
+} \ No newline at end of file
diff --git a/test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll b/test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll
new file mode 100644
index 000000000000..7cc3951b3cd1
--- /dev/null
+++ b/test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll
@@ -0,0 +1,21 @@
+; RUN: llvm-as < %s | opt -loop-rotate | llvm-dis
+; PR3408
+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.Cls = type { i32, i8, [2 x %struct.Cls*], [2 x %struct.Lit*] }
+ %struct.Lit = type { i8 }
+
+define void @picosat_main_bb13.i.i71.outer_bb132.i.i.i.outer(%struct.Cls**, %struct.Cls**, i32 %collect.i.i.i.1.lcssa, i32 %lcollect.i.i.i.2.lcssa, %struct.Cls*** %rhead.tmp.0236.out, i32* %collect.i.i.i.2.out, i32* %lcollect.i.i.i.3.ph.ph.ph.out) nounwind {
+newFuncRoot:
+ br label %codeRepl
+
+bb133.i.i.i.exitStub: ; preds = %codeRepl
+ ret void
+
+bb130.i.i.i: ; preds = %codeRepl
+ %rhead.tmp.0236.lcssa82 = phi %struct.Cls** [ null, %codeRepl ] ; <%struct.Cls**> [#uses=0]
+ br label %codeRepl
+
+codeRepl: ; preds = %bb130.i.i.i, %newFuncRoot
+ br i1 false, label %bb130.i.i.i, label %bb133.i.i.i.exitStub
+}
diff --git a/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll b/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll
index adfa5f85d2eb..a8a76bc53b5e 100644
--- a/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll
+++ b/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll
@@ -1,9 +1,8 @@
-; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \
-; RUN: grep alloca | grep {4 x}
+; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 undef}
-; Test that an array is not incorrectly deconstructed...
+; Test that an array is not incorrectly deconstructed.
-define i32 @test() {
+define i32 @test() nounwind {
%X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1]
%Y = getelementptr [4 x i32]* %X, i64 0, i64 0 ; <i32*> [#uses=1]
; Must preserve arrayness!
diff --git a/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll b/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll
index 1f3df499c32f..f0253b7bea93 100644
--- a/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll
+++ b/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll
@@ -1,7 +1,6 @@
-; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \
-; RUN: grep -F {alloca \[2 x <4 x i32>\]}
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
-define i32 @func(<4 x float> %v0, <4 x float> %v1) {
+define i32 @func(<4 x float> %v0, <4 x float> %v1) nounwind {
%vsiidx = alloca [2 x <4 x i32>], align 16 ; <[2 x <4 x i32>]*> [#uses=3]
%tmp = call <4 x i32> @llvm.x86.sse2.cvttps2dq( <4 x float> %v0 ) ; <<4 x i32>> [#uses=2]
%tmp.upgrd.1 = bitcast <4 x i32> %tmp to <2 x i64> ; <<2 x i64>> [#uses=0]
diff --git a/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll b/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll
new file mode 100644
index 000000000000..af34baa0c5cf
--- /dev/null
+++ b/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 %x}
+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"
+
+%pair = type { [1 x i32], i32 }
+
+define i32 @f(i32 %x, i32 %y) {
+ %instance = alloca %pair
+ %first = getelementptr %pair* %instance, i32 0, i32 0
+ %cast = bitcast [1 x i32]* %first to i32*
+ store i32 %x, i32* %cast
+ %second = getelementptr %pair* %instance, i32 0, i32 1
+ store i32 %y, i32* %second
+ %v = load i32* %cast
+ ret i32 %v
+}
diff --git a/test/Transforms/ScalarRepl/badarray.ll b/test/Transforms/ScalarRepl/badarray.ll
index 1e4714eae988..acac5a61822f 100644
--- a/test/Transforms/ScalarRepl/badarray.ll
+++ b/test/Transforms/ScalarRepl/badarray.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | opt -scalarrepl -mem2reg | llvm-dis | grep alloca
+; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | not grep alloca
define i32 @test() {
%X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1]
diff --git a/test/Transforms/ScalarRepl/bitfield-sroa.ll b/test/Transforms/ScalarRepl/bitfield-sroa.ll
new file mode 100644
index 000000000000..34dd120e3f8f
--- /dev/null
+++ b/test/Transforms/ScalarRepl/bitfield-sroa.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
+; rdar://6532315
+%t = type { { i32, i16, i8, i8 } }
+
+define i8 @foo(i64 %A) {
+ %ALL = alloca %t, align 8
+ %tmp59172 = bitcast %t* %ALL to i64*
+ store i64 %A, i64* %tmp59172, align 8
+ %C = getelementptr %t* %ALL, i32 0, i32 0, i32 1
+ %D = bitcast i16* %C to i32*
+ %E = load i32* %D, align 4
+ %F = bitcast %t* %ALL to i8*
+ %G = load i8* %F, align 8
+ ret i8 %G
+}
+
diff --git a/test/Transforms/ScalarRepl/memset-aggregate.ll b/test/Transforms/ScalarRepl/memset-aggregate.ll
index 4febda5b9a79..b7b33521bbce 100644
--- a/test/Transforms/ScalarRepl/memset-aggregate.ll
+++ b/test/Transforms/ScalarRepl/memset-aggregate.ll
@@ -1,6 +1,7 @@
; PR1226
; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {ret i32 16843009}
; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
+; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i16 514}
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"
target triple = "i686-apple-darwin8"
@@ -46,3 +47,20 @@ entry:
%tmp7 = load i32* %tmp6 ; <i32> [#uses=1]
ret i32 %tmp7
}
+
+
+ %struct.f = type { i32, i32, i32, i32, i32, i32 }
+
+define i16 @test4() nounwind {
+entry:
+ %A = alloca %struct.f, align 8 ; <%struct.f*> [#uses=3]
+ %0 = getelementptr %struct.f* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ store i32 1, i32* %0, align 8
+ %1 = getelementptr %struct.f* %A, i32 0, i32 1 ; <i32*> [#uses=1]
+ %2 = bitcast i32* %1 to i8* ; <i8*> [#uses=1]
+ call void @llvm.memset.i32(i8* %2, i8 2, i32 12, i32 4)
+ %3 = getelementptr %struct.f* %A, i32 0, i32 2 ; <i32*> [#uses=1]
+ %4 = load i32* %3, align 8 ; <i32> [#uses=1]
+ %retval12 = trunc i32 %4 to i16 ; <i16> [#uses=1]
+ ret i16 %retval12
+}
diff --git a/test/Transforms/ScalarRepl/vector_promote.ll b/test/Transforms/ScalarRepl/vector_promote.ll
index ec22f6464b45..a0d331719f06 100644
--- a/test/Transforms/ScalarRepl/vector_promote.ll
+++ b/test/Transforms/ScalarRepl/vector_promote.ll
@@ -1,6 +1,5 @@
-; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \
-; RUN: not grep alloca
-; END.
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {load <4 x float>}
define void @test(<4 x float>* %F, float %f) {
entry:
@@ -53,3 +52,13 @@ entry:
store float %tmp.upgrd.6, float* %f
ret void
}
+
+define i32 @test5(float %X) { ;; should turn into bitcast.
+ %X_addr = alloca [4 x float]
+ %X1 = getelementptr [4 x float]* %X_addr, i32 0, i32 2
+ store float %X, float* %X1
+ %a = bitcast float* %X1 to i32*
+ %tmp = load i32* %a
+ ret i32 %tmp
+}
+
diff --git a/test/Transforms/ScalarRepl/volatile.ll b/test/Transforms/ScalarRepl/volatile.ll
new file mode 100644
index 000000000000..5f9fe0d89a5a
--- /dev/null
+++ b/test/Transforms/ScalarRepl/volatile.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {volatile load}
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {volatile store}
+
+define i32 @voltest(i32 %T) {
+ %A = alloca {i32, i32}
+ %B = getelementptr {i32,i32}* %A, i32 0, i32 0
+ volatile store i32 %T, i32* %B
+
+ %C = getelementptr {i32,i32}* %A, i32 0, i32 1
+ %X = volatile load i32* %C
+ ret i32 %X
+}
diff --git a/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll b/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
index 7a6128081bf0..e65bafa6805d 100644
--- a/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
+++ b/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
@@ -1,5 +1,4 @@
; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | grep {br i1 } | count 4
-; XFAIL: *
; PR3354
; Do not merge bb1 into the entry block, it might trap.
@@ -23,7 +22,7 @@ define i32 @test2(i32 %tmp21, i32 %tmp24, i1 %tmp34) {
br i1 %tmp34, label %bb5, label %bb6
bb5: ; preds = %bb4
- br i1 icmp sgt (i32 sdiv (i32 32767, i32 0), i32 0), label %bb6, label %bb7
+ br i1 icmp sgt (i32 sdiv (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), label %bb6, label %bb7
bb6:
ret i32 42
bb7:
diff --git a/test/lib/llvm.exp b/test/lib/llvm.exp
index b5d5cffae1e0..ab8522ab6a28 100644
--- a/test/lib/llvm.exp
+++ b/test/lib/llvm.exp
@@ -48,7 +48,7 @@ proc execOneLine { test PRS outcome lineno line } {
proc substitute { line test tmpFile } {
global srcroot objroot srcdir objdir subdir target_triplet prcontext
global llvmgcc llvmgxx llvmgcc_version llvmgccmajvers ocamlc
- global gccpath gxxpath compile_c compile_cxx link shlibext llvmlibsdir
+ global gccpath gxxpath compile_c compile_cxx link shlibext llvmlibsdir llvmdsymutil
global valgrind grep gas
set path [file join $srcdir $subdir]
@@ -73,6 +73,8 @@ proc substitute { line test tmpFile } {
regsub -all {%shlibext} $new_line "$shlibext" new_line
#replace %ocamlc with ocaml compiler command
regsub -all {%ocamlc} $new_line "$ocamlc" new_line
+ #replace %llvmdsymutil with dsymutil command
+ regsub -all {%llvmdsymutil} $new_line "$llvmdsymutil" new_line
#replace %llvmlibsdir with configure library directory
regsub -all {%llvmlibsdir} $new_line "$llvmlibsdir" new_line
#replace %p with path to source,
diff --git a/tools/Makefile b/tools/Makefile
index 2726c1f3e43e..909a54843b5d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -8,6 +8,10 @@
##===----------------------------------------------------------------------===##
LEVEL := ..
+
+# Build clang if present.
+OPTIONAL_PARALLEL_DIRS := clang
+
# NOTE: The tools are organized into five groups of four consisting of one
# large and three small executables. This is done to minimize memory load
# in parallel builds. Please retain this ordering.
@@ -21,8 +25,7 @@ PARALLEL_DIRS := llvm-config \
include $(LEVEL)/Makefile.config
-# only build new lto project on Darwin for now
-ifeq ($(OS),Darwin)
+ifeq ($(ENABLE_PIC),1)
PARALLEL_DIRS += lto
endif
diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst
index 53049d7b3c26..9aca609ca1de 100644
--- a/tools/llvmc/doc/LLVMC-Reference.rst
+++ b/tools/llvmc/doc/LLVMC-Reference.rst
@@ -262,37 +262,47 @@ separate option groups syntactically.
* Possible option types:
- - ``switch_option`` - a simple boolean switch without arguments,
- for example ``-O2`` or ``-time``.
+ - ``switch_option`` - a simple boolean switch without arguments, for example
+ ``-O2`` or ``-time``. At most one occurrence is allowed.
- - ``parameter_option`` - option that takes one argument, for
- example ``-std=c99``. It is also allowed to use spaces instead of
- the equality sign: ``-std c99``.
+ - ``parameter_option`` - option that takes one argument, for example
+ ``-std=c99``. It is also allowed to use spaces instead of the equality
+ sign: ``-std c99``. At most one occurrence is allowed.
- - ``parameter_list_option`` - same as the above, but more than one
- option occurence is allowed.
+ - ``parameter_list_option`` - same as the above, but more than one option
+ occurence is allowed.
- - ``prefix_option`` - same as the parameter_option, but the option
- name and argument do not have to be separated. Example:
- ``-ofile``. This can be also specified as ``-o file``; however,
- ``-o=file`` will be parsed incorrectly (``=file`` will be
- interpreted as option value).
+ - ``prefix_option`` - same as the parameter_option, but the option name and
+ argument do not have to be separated. Example: ``-ofile``. This can be also
+ specified as ``-o file``; however, ``-o=file`` will be parsed incorrectly
+ (``=file`` will be interpreted as option value). At most one occurrence is
+ allowed.
- - ``prefix_list_option`` - same as the above, but more than one
- occurence of the option is allowed; example: ``-lm -lpthread``.
+ - ``prefix_list_option`` - same as the above, but more than one occurence of
+ the option is allowed; example: ``-lm -lpthread``.
- - ``alias_option`` - a special option type for creating
- aliases. Unlike other option types, aliases are not allowed to
- have any properties besides the aliased option name. Usage
- example: ``(alias_option "preprocess", "E")``
+ - ``alias_option`` - a special option type for creating aliases. Unlike other
+ option types, aliases are not allowed to have any properties besides the
+ aliased option name. Usage example: ``(alias_option "preprocess", "E")``
* Possible option properties:
- - ``help`` - help string associated with this option. Used for
- ``--help`` output.
+ - ``help`` - help string associated with this option. Used for ``--help``
+ output.
+
+ - ``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``.
- - ``required`` - this option is obligatory.
+ - ``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``.
+
+ - ``zero_or_one`` - 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``.
- ``hidden`` - the description of this option will not appear in
the ``--help`` output (but will appear in the ``--help-hidden``
@@ -301,6 +311,11 @@ separate option groups syntactically.
- ``really_hidden`` - the option will not be mentioned in any help
output.
+ - ``multi_val n`` - this option takes *n* arguments (can be useful in some
+ special cases). Usage example: ``(parameter_list_option "foo", (multi_val
+ 3))``. Only list options can have this attribute; you can, however, use
+ the ``one_or_more`` and ``zero_or_one`` properties.
+
- ``extern`` - this option is defined in some other plugin, see below.
External options
diff --git a/tools/llvmc/driver/CompilationGraph.cpp b/tools/llvmc/driver/CompilationGraph.cpp
index 2c59ee6314c0..238ef6f42a78 100644
--- a/tools/llvmc/driver/CompilationGraph.cpp
+++ b/tools/llvmc/driver/CompilationGraph.cpp
@@ -390,6 +390,8 @@ int CompilationGraph::CheckMultipleDefaultEdges() const {
int ret = 0;
InputLanguagesSet Dummy;
+ // For all nodes, just iterate over the outgoing edges and check if there is
+ // more than one edge with maximum weight.
for (const_nodes_iterator B = this->NodesMap.begin(),
E = this->NodesMap.end(); B != E; ++B) {
const Node& N = B->second;
@@ -423,6 +425,9 @@ int CompilationGraph::CheckCycles() {
std::queue<Node*> Q;
Q.push(&getNode("root"));
+ // Try to delete all nodes that have no ingoing edges, starting from the
+ // root. If there are any nodes left after this operation, then we have a
+ // cycle. This relies on '--check-graph' not performing the topological sort.
while (!Q.empty()) {
Node* A = Q.front();
Q.pop();
@@ -447,7 +452,6 @@ int CompilationGraph::CheckCycles() {
return 0;
}
-
int CompilationGraph::Check () {
// We try to catch as many errors as we can in one go.
int ret = 0;
diff --git a/tools/lto/Makefile b/tools/lto/Makefile
index 69014d781ff1..f0f6da7191a2 100644
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -16,12 +16,8 @@ LIBRARYNAME = LTO
include $(LEVEL)/Makefile.config
LINK_LIBS_IN_SHARED = 1
-ifeq ($(OS),Darwin)
- SHARED_LIBRARY = 1
- DONT_BUILD_RELINKED = 1
-else
- BUILD_ARCHIVE = 1
-endif
+SHARED_LIBRARY = 1
+DONT_BUILD_RELINKED = 1
LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter
diff --git a/unittests/ADT/APInt.cpp b/unittests/ADT/APInt.cpp
index 5bca5b6b4063..cbcc1390bca8 100644
--- a/unittests/ADT/APInt.cpp
+++ b/unittests/ADT/APInt.cpp
@@ -18,8 +18,83 @@ namespace {
TEST(APIntTest, ShiftLeftByZero) {
APInt One = APInt::getNullValue(65) + 1;
APInt Shl = One.shl(0);
- EXPECT_EQ(Shl[0], true);
- EXPECT_EQ(Shl[1], false);
+ EXPECT_EQ(true, Shl[0]);
+ EXPECT_EQ(false, Shl[1]);
+}
+
+TEST(APIntTest, I128NegativeCount) {
+ APInt Minus3(128, (uint64_t)-3, true);
+ EXPECT_EQ(126u, Minus3.countLeadingOnes());
+ EXPECT_EQ(-3, Minus3.getSExtValue());
+
+ APInt Minus1(128, (uint64_t)-1, true);
+ EXPECT_EQ(0u, Minus1.countLeadingZeros());
+ EXPECT_EQ(128u, Minus1.countLeadingOnes());
+ EXPECT_EQ(128u, Minus1.getActiveBits());
+ EXPECT_EQ(0u, Minus1.countTrailingZeros());
+ EXPECT_EQ(128u, Minus1.countTrailingOnes());
+ EXPECT_EQ(128u, Minus1.countPopulation());
+ EXPECT_EQ(-1, Minus1.getSExtValue());
+}
+
+TEST(APIntTest, I33Count) {
+ APInt i33minus2(33, -2, true);
+ EXPECT_EQ(0u, i33minus2.countLeadingZeros());
+ EXPECT_EQ(32u, i33minus2.countLeadingOnes());
+ EXPECT_EQ(33u, i33minus2.getActiveBits());
+ EXPECT_EQ(1u, i33minus2.countTrailingZeros());
+ EXPECT_EQ(32u, i33minus2.countPopulation());
+ EXPECT_EQ(-2, i33minus2.getSExtValue());
+ EXPECT_EQ(((uint64_t)-2)&((1ull<<33) -1), i33minus2.getZExtValue());
+}
+
+TEST(APIntTest, I65Count) {
+ APInt i65minus(65, 0, true);
+ i65minus.set(64);
+ EXPECT_EQ(0u, i65minus.countLeadingZeros());
+ EXPECT_EQ(1u, i65minus.countLeadingOnes());
+ EXPECT_EQ(65u, i65minus.getActiveBits());
+ EXPECT_EQ(64u, i65minus.countTrailingZeros());
+ EXPECT_EQ(1u, i65minus.countPopulation());
+}
+
+TEST(APIntTest, I128PositiveCount) {
+ APInt u128max = APInt::getAllOnesValue(128);
+ EXPECT_EQ(128u, u128max.countLeadingOnes());
+ EXPECT_EQ(0u, u128max.countLeadingZeros());
+ EXPECT_EQ(128u, u128max.getActiveBits());
+ EXPECT_EQ(0u, u128max.countTrailingZeros());
+ EXPECT_EQ(128u, u128max.countTrailingOnes());
+ EXPECT_EQ(128u, u128max.countPopulation());
+
+ APInt u64max(128, (uint64_t)-1, false);
+ EXPECT_EQ(64u, u64max.countLeadingZeros());
+ EXPECT_EQ(0u, u64max.countLeadingOnes());
+ EXPECT_EQ(64u, u64max.getActiveBits());
+ EXPECT_EQ(0u, u64max.countTrailingZeros());
+ EXPECT_EQ(64u, u64max.countTrailingOnes());
+ EXPECT_EQ(64u, u64max.countPopulation());
+ EXPECT_EQ((uint64_t)~0ull, u64max.getZExtValue());
+
+ APInt zero(128, 0, true);
+ EXPECT_EQ(128u, zero.countLeadingZeros());
+ EXPECT_EQ(0u, zero.countLeadingOnes());
+ EXPECT_EQ(0u, zero.getActiveBits());
+ EXPECT_EQ(128u, zero.countTrailingZeros());
+ EXPECT_EQ(0u, zero.countTrailingOnes());
+ EXPECT_EQ(0u, zero.countPopulation());
+ EXPECT_EQ(0u, zero.getSExtValue());
+ EXPECT_EQ(0u, zero.getZExtValue());
+
+ APInt one(128, 1, true);
+ EXPECT_EQ(127u, one.countLeadingZeros());
+ EXPECT_EQ(0u, one.countLeadingOnes());
+ EXPECT_EQ(1u, one.getActiveBits());
+ EXPECT_EQ(0u, one.countTrailingZeros());
+ EXPECT_EQ(1u, one.countTrailingOnes());
+ EXPECT_EQ(1u, one.countPopulation());
+ EXPECT_EQ(1, one.getSExtValue());
+ EXPECT_EQ(1u, one.getZExtValue());
}
}
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index e70bdb6f6026..f3bdb4fab3f6 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -842,7 +842,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// If sign-extended doesn't fit, does it fit as unsigned?
unsigned ValueMask;
unsigned UnsignedVal;
- ValueMask = unsigned(MVT(VT).getIntegerVTBitMask());
+ ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
UnsignedVal = unsigned(II->getValue());
if ((ValueMask & UnsignedVal) != UnsignedVal) {
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 9f028ed4956c..773b06aa3946 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1059,6 +1059,10 @@ public:
std::string Code = "Opc" + utostr(OpcNo);
+ if (!isRoot || (InputHasChain && !NodeHasChain))
+ // For call to "getTargetNode()".
+ Code += ", N.getDebugLoc()";
+
emitOpcode(II.Namespace + "::" + II.TheDef->getName());
// Output order: results, chain, flags
@@ -1825,9 +1829,6 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
} else
OpVTI->second.push_back(OpVTStr);
- OS << "SDNode *Select_" << getLegalCName(OpName)
- << OpVTStr << "(const SDValue &N) {\n";
-
// 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.
@@ -1869,6 +1870,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
// Next, reverse the list of patterns itself for the same reason.
std::reverse(CodeForPatterns.begin(), CodeForPatterns.end());
+ OS << "SDNode *Select_" << getLegalCName(OpName)
+ << OpVTStr << "(const SDValue &N) {\n";
+
// Emit all of the patterns now, grouped together to share code.
EmitPatterns(CodeForPatterns, 2, OS);
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp
index 3ce764259898..201a2cc5fef5 100644
--- a/utils/TableGen/FastISelEmitter.cpp
+++ b/utils/TableGen/FastISelEmitter.cpp
@@ -440,7 +440,8 @@ void FastISelMap::PrintFunctionDefinitions(std::ostream &OS) {
Operands.PrintArguments(OS, *Memo.PhysRegs);
OS << ");\n";
} else {
- OS << "extractsubreg(Op0, ";
+ OS << "extractsubreg(" << getName(RetVT);
+ OS << ", Op0, ";
OS << (unsigned)Memo.SubRegNo;
OS << ");\n";
}
@@ -534,7 +535,7 @@ void FastISelMap::PrintFunctionDefinitions(std::ostream &OS) {
Operands.PrintArguments(OS, *Memo.PhysRegs);
OS << ");\n";
} else {
- OS << "extractsubreg(Op0, ";
+ OS << "extractsubreg(RetVT, Op0, ";
OS << (unsigned)Memo.SubRegNo;
OS << ");\n";
}
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index ec023ba728a3..fc166ef30934 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -127,13 +127,19 @@ bool oneOf(const char* lst, char c) {
return false;
}
+template <class I, class S>
+void checkedIncrement(I& P, I E, S ErrorString) {
+ ++P;
+ if (P == E)
+ throw ErrorString;
+}
+
//===----------------------------------------------------------------------===//
/// Back-end specific code
/// OptionType - One of six different option types. See the
/// documentation for detailed description of differences.
-/// Extern* options are those that are defined in some other plugin.
namespace OptionType {
enum OptionType { Alias, Switch, Parameter, ParameterList,
Prefix, PrefixList};
@@ -171,7 +177,8 @@ OptionType::OptionType stringToOptionType(const std::string& T) {
namespace OptionDescriptionFlags {
enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
- ReallyHidden = 0x4, Extern = 0x8 };
+ ReallyHidden = 0x4, Extern = 0x8,
+ OneOrMore = 0x10, ZeroOrOne = 0x20 };
}
/// OptionDescription - Represents data contained in a single
@@ -181,11 +188,12 @@ struct OptionDescription {
std::string Name;
unsigned Flags;
std::string Help;
+ unsigned MultiVal;
OptionDescription(OptionType::OptionType t = OptionType::Switch,
const std::string& n = "",
const std::string& h = DefaultHelpString)
- : Type(t), Name(n), Flags(0x0), Help(h)
+ : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1)
{}
/// GenTypeDeclaration - Returns the C++ variable type of this
@@ -203,17 +211,26 @@ struct OptionDescription {
bool isAlias() const;
+ bool isMultiVal() const;
+
bool isExtern() const;
void setExtern();
bool isRequired() const;
void setRequired();
+ bool isOneOrMore() const;
+ void setOneOrMore();
+
+ bool isZeroOrOne() const;
+ void setZeroOrOne();
+
bool isHidden() const;
void setHidden();
bool isReallyHidden() const;
void setReallyHidden();
+
};
void OptionDescription::Merge (const OptionDescription& other)
@@ -235,6 +252,10 @@ bool OptionDescription::isAlias() const {
return Type == OptionType::Alias;
}
+bool OptionDescription::isMultiVal() const {
+ return MultiVal > 1;
+}
+
bool OptionDescription::isExtern() const {
return Flags & OptionDescriptionFlags::Extern;
}
@@ -249,6 +270,20 @@ void OptionDescription::setRequired() {
Flags |= OptionDescriptionFlags::Required;
}
+bool OptionDescription::isOneOrMore() const {
+ return Flags & OptionDescriptionFlags::OneOrMore;
+}
+void OptionDescription::setOneOrMore() {
+ Flags |= OptionDescriptionFlags::OneOrMore;
+}
+
+bool OptionDescription::isZeroOrOne() const {
+ return Flags & OptionDescriptionFlags::ZeroOrOne;
+}
+void OptionDescription::setZeroOrOne() {
+ Flags |= OptionDescriptionFlags::ZeroOrOne;
+}
+
bool OptionDescription::isHidden() const {
return Flags & OptionDescriptionFlags::Hidden;
}
@@ -405,8 +440,11 @@ public:
AddHandler("extern", &CollectOptionProperties::onExtern);
AddHandler("help", &CollectOptionProperties::onHelp);
AddHandler("hidden", &CollectOptionProperties::onHidden);
+ AddHandler("multi_val", &CollectOptionProperties::onMultiVal);
+ AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore);
AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
AddHandler("required", &CollectOptionProperties::onRequired);
+ AddHandler("zero_or_one", &CollectOptionProperties::onZeroOrOne);
staticMembersInitialized_ = true;
}
@@ -439,9 +477,46 @@ private:
void onRequired (const DagInit* d) {
checkNumberOfArguments(d, 0);
+ if (optDesc_.isOneOrMore())
+ throw std::string("An option can't have both (required) "
+ "and (one_or_more) properties!");
optDesc_.setRequired();
}
+ void onOneOrMore (const DagInit* d) {
+ checkNumberOfArguments(d, 0);
+ if (optDesc_.isRequired() || optDesc_.isZeroOrOne())
+ throw std::string("Only one of (required), (zero_or_one) or "
+ "(one_or_more) properties is allowed!");
+ if (!OptionType::IsList(optDesc_.Type))
+ llvm::cerr << "Warning: specifying the 'one_or_more' property "
+ "on a non-list option will have no effect.\n";
+ optDesc_.setOneOrMore();
+ }
+
+ void onZeroOrOne (const DagInit* d) {
+ checkNumberOfArguments(d, 0);
+ if (optDesc_.isRequired() || optDesc_.isOneOrMore())
+ throw std::string("Only one of (required), (zero_or_one) or "
+ "(one_or_more) properties is allowed!");
+ if (!OptionType::IsList(optDesc_.Type))
+ llvm::cerr << "Warning: specifying the 'zero_or_one' property"
+ "on a non-list option will have no effect.\n";
+ optDesc_.setZeroOrOne();
+ }
+
+ void onMultiVal (const DagInit* d) {
+ checkNumberOfArguments(d, 1);
+ int val = InitPtrToInt(d->getArg(0));
+ if (val < 2)
+ throw std::string("Error in the 'multi_val' property: "
+ "the value must be greater than 1!");
+ if (!OptionType::IsList(optDesc_.Type))
+ throw std::string("The multi_val property is valid only "
+ "on list options!");
+ optDesc_.MultiVal = val;
+ }
+
};
/// AddOption - A function object that is applied to every option
@@ -639,7 +714,6 @@ private:
};
-
/// CollectToolDescriptions - Gather information about tool properties
/// from the parsed TableGen data (basically a wrapper for the
/// CollectToolProperties function object).
@@ -1131,13 +1205,6 @@ void TokenizeCmdline(const std::string& CmdLine, StrVector& Out) {
}
}
-template <class I, class S>
-void checkedIncrement(I& P, I E, S ErrorString) {
- ++P;
- if (P == E)
- throw ErrorString;
-}
-
/// SubstituteSpecialCommands - Perform string substitution for $CALL
/// and $ENV. Helper function used by EmitCmdLineVecFill().
StrVector::const_iterator SubstituteSpecialCommands
@@ -1308,18 +1375,31 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
case OptionType::PrefixList:
O << Indent << "for (" << D.GenTypeDeclaration()
<< "::iterator B = " << D.GenVariableName() << ".begin(),\n"
- << Indent << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n"
+ << Indent << "E = " << D.GenVariableName() << ".end(); B != E;) {\n"
<< Indent << Indent1 << "vec.push_back(\"" << Name << "\" + "
- << "*B);\n";
+ << "*B);\n"
+ << Indent << Indent1 << "++B;\n";
+
+ for (int i = 1, j = D.MultiVal; i < j; ++i) {
+ O << Indent << Indent1 << "vec.push_back(*B);\n"
+ << Indent << Indent1 << "++B;\n";
+ }
+
+ O << Indent << "}\n";
break;
case OptionType::ParameterList:
O << Indent << "for (" << D.GenTypeDeclaration()
<< "::iterator B = " << D.GenVariableName() << ".begin(),\n"
<< Indent << "E = " << D.GenVariableName()
- << ".end() ; B != E; ++B) {\n"
- << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n"
- << Indent << Indent1 << "vec.push_back(*B);\n"
- << Indent << "}\n";
+ << ".end() ; B != E;) {\n"
+ << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n";
+
+ for (int i = 0, j = D.MultiVal; i < j; ++i) {
+ O << Indent << Indent1 << "vec.push_back(*B);\n"
+ << Indent << Indent1 << "++B;\n";
+ }
+
+ O << Indent << "}\n";
break;
case OptionType::Alias:
default:
@@ -1376,6 +1456,9 @@ class EmitActionHandler {
const std::string& Name = InitPtrToString(Dag.getArg(0));
const OptionDescription& D = OptDescs.FindOption(Name);
+ if (D.isMultiVal())
+ throw std::string("Can't use unpack_values with multi-valued options!");
+
if (OptionType::IsList(D.Type)) {
O << IndentLevel << "for (" << D.GenTypeDeclaration()
<< "::iterator B = " << D.GenVariableName() << ".begin(),\n"
@@ -1599,27 +1682,28 @@ void EmitOptionDefintions (const OptionDescriptions& descs,
O << ", cl::Prefix";
if (val.isRequired()) {
- switch (val.Type) {
- case OptionType::PrefixList:
- case OptionType::ParameterList:
+ if (OptionType::IsList(val.Type) && !val.isMultiVal())
O << ", cl::OneOrMore";
- break;
- default:
+ else
O << ", cl::Required";
- }
+ }
+ else if (val.isOneOrMore() && OptionType::IsList(val.Type)) {
+ O << ", cl::OneOrMore";
+ }
+ else if (val.isZeroOrOne() && OptionType::IsList(val.Type)) {
+ O << ", cl::ZeroOrOne";
}
- if (val.isReallyHidden() || val.isHidden()) {
- if (val.isRequired())
- O << " |";
- else
- O << ",";
- if (val.isReallyHidden())
- O << " cl::ReallyHidden";
- else
- O << " cl::Hidden";
+ if (val.isReallyHidden()) {
+ O << ", cl::ReallyHidden";
+ }
+ else if (val.isHidden()) {
+ O << ", cl::Hidden";
}
+ if (val.MultiVal > 1)
+ O << ", cl::multi_val(" << val.MultiVal << ")";
+
if (!val.Help.empty())
O << ", cl::desc(\"" << val.Help << "\")";
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 06f43d5d2d2c..67d1cfcf4d34 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -240,83 +240,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
<< RegisterClasses[i].getName() << "RegClass;\n";
std::map<unsigned, std::set<unsigned> > SuperClassMap;
- std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
OS << "\n";
-
- // Emit the sub-register classes for each RegisterClass
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- const CodeGenRegisterClass &RC = RegisterClasses[rc];
-
- // Give the register class a legal C name if it's anonymous.
- std::string Name = RC.TheDef->getName();
-
- OS << " // " << Name
- << " Sub-register Classes...\n"
- << " static const TargetRegisterClass* const "
- << Name << "SubRegClasses [] = {\n ";
-
- bool Empty = true;
-
- for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size();
- subrc != subrcMax; ++subrc) {
- unsigned rc2 = 0, e2 = RegisterClasses.size();
- for (; rc2 != e2; ++rc2) {
- const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
- if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) {
- if (!Empty)
- OS << ", ";
- OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
- Empty = false;
-
- std::map<unsigned, std::set<unsigned> >::iterator SCMI =
- SuperRegClassMap.find(rc2);
- if (SCMI == SuperRegClassMap.end()) {
- SuperRegClassMap.insert(std::make_pair(rc2, std::set<unsigned>()));
- SCMI = SuperRegClassMap.find(rc2);
- }
- SCMI->second.insert(rc);
- break;
- }
- }
- if (rc2 == e2)
- throw "Register Class member '" +
- RC.SubRegClasses[subrc]->getName() +
- "' is not a valid RegisterClass!";
- }
-
- OS << (!Empty ? ", " : "") << "NULL";
- OS << "\n };\n\n";
- }
-
- // Emit the super-register classes for each RegisterClass
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- const CodeGenRegisterClass &RC = RegisterClasses[rc];
-
- // Give the register class a legal C name if it's anonymous.
- std::string Name = RC.TheDef->getName();
-
- OS << " // " << Name
- << " Super-register Classes...\n"
- << " static const TargetRegisterClass* const "
- << Name << "SuperRegClasses [] = {\n ";
-
- bool Empty = true;
- std::map<unsigned, std::set<unsigned> >::iterator I =
- SuperRegClassMap.find(rc);
- if (I != SuperRegClassMap.end()) {
- for (std::set<unsigned>::iterator II = I->second.begin(),
- EE = I->second.end(); II != EE; ++II) {
- const CodeGenRegisterClass &RC2 = RegisterClasses[*II];
- if (!Empty)
- OS << ", ";
- OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
- Empty = false;
- }
- }
-
- OS << (!Empty ? ", " : "") << "NULL";
- OS << "\n };\n\n";
- }
// Emit the sub-classes array for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
@@ -398,8 +322,6 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
<< RC.getName() + "VTs" << ", "
<< RC.getName() + "Subclasses" << ", "
<< RC.getName() + "Superclasses" << ", "
- << RC.getName() + "SubRegClasses" << ", "
- << RC.getName() + "SuperRegClasses" << ", "
<< RC.SpillSize/8 << ", "
<< RC.SpillAlignment/8 << ", "
<< RC.CopyCost << ", "
diff --git a/utils/TableGen/TGParser.h b/utils/TableGen/TGParser.h
index a5435afacf29..fd33aec0fb32 100644
--- a/utils/TableGen/TGParser.h
+++ b/utils/TableGen/TGParser.h
@@ -20,8 +20,8 @@
namespace llvm {
class Record;
class RecordVal;
- class RecTy;
- class Init;
+ struct RecTy;
+ struct Init;
struct MultiClass;
struct SubClassReference;
diff --git a/win32/Analysis/Analysis.vcproj b/win32/Analysis/Analysis.vcproj
index c631a66c208d..e116aa384d97 100644
--- a/win32/Analysis/Analysis.vcproj
+++ b/win32/Analysis/Analysis.vcproj
@@ -341,11 +341,11 @@
>
</File>
<File
- RelativePath="..\..\lib\Analysis\DebugInfo.cpp"
+ RelativePath="..\..\lib\Analysis\DbgInfoPrinter.cpp"
>
</File>
<File
- RelativePath="..\..\lib\Analysis\EscapeAnalysis.cpp"
+ RelativePath="..\..\lib\Analysis\DebugInfo.cpp"
>
</File>
<File
@@ -436,6 +436,10 @@
>
</File>
<File
+ RelativePath="..\..\lib\Analysis\CaptureTracking.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\lib\Analysis\Ipa\FindUsedTypes.cpp"
>
</File>
diff --git a/win32/AsmParser/AsmParser.vcproj b/win32/AsmParser/AsmParser.vcproj
index 782ca2a889c6..96ca6d172b61 100644
--- a/win32/AsmParser/AsmParser.vcproj
+++ b/win32/AsmParser/AsmParser.vcproj
@@ -90,11 +90,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Win32"
+ Name="Debug|x64"
OutputDirectory="$(ProjectDir)..\bin\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops;..\common.vsprops"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
@@ -111,17 +111,22 @@
/>
<Tool
Name="VCMIDLTool"
+ TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="0"
AdditionalIncludeDirectories="..\..\include;..;..\..\lib\AsmParser"
- PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;NDEBUG;_LIB;__STDC_LIMIT_MACROS"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_LIB;__STDC_LIMIT_MACROS"
StringPooling="true"
- RuntimeLibrary="2"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
+ BrowseInformation="1"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
@@ -157,11 +162,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|x64"
+ Name="Release|Win32"
OutputDirectory="$(ProjectDir)..\bin\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops;..\common.vsprops"
CharacterSet="2"
>
<Tool
@@ -178,22 +183,17 @@
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
AdditionalIncludeDirectories="..\..\include;..;..\..\lib\AsmParser"
- PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_LIB;__STDC_LIMIT_MACROS"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;NDEBUG;_LIB;__STDC_LIMIT_MACROS"
StringPooling="true"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
+ RuntimeLibrary="2"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- BrowseInformation="1"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
@@ -310,48 +310,8 @@
>
</File>
<File
- RelativePath="..\..\lib\AsmParser\llvmAsmParser.y"
+ RelativePath="..\..\lib\AsmParser\LLParser.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Bisoning $(InputFileName)"
- CommandLine="..\dobison.cmd llvmAsm debug $(InputName) $(InputPath) ..\..\lib\AsmParser&#x0D;&#x0A;"
- Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output;..\..\lib\AsmParser\$(InputName).h"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Bisoning $(InputFileName)"
- CommandLine="..\dobison.cmd llvmAsm release $(InputName) $(InputPath) ..\..\lib\AsmParser&#x0D;&#x0A;"
- Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output;..\..\lib\AsmParser\$(InputName).h"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Bisoning $(InputFileName)"
- CommandLine="..\dobison.cmd llvmAsm debug $(InputName) $(InputPath) ..\..\lib\AsmParser&#x0D;&#x0A;"
- Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output;..\..\lib\AsmParser\$(InputName).h"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Bisoning $(InputFileName)"
- CommandLine="..\dobison.cmd llvmAsm release $(InputName) $(InputPath) ..\..\lib\AsmParser&#x0D;&#x0A;"
- Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output;..\..\lib\AsmParser\$(InputName).h"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\..\lib\AsmParser\Parser.cpp"
@@ -379,14 +339,6 @@
<Filter
Name="Generated Files"
>
- <File
- RelativePath=".\llvmAsmParser.cpp"
- >
- </File>
- <File
- RelativePath=".\llvmAsmParser.h"
- >
- </File>
</Filter>
</Files>
<Globals>
diff --git a/win32/CodeGen/CodeGen.vcproj b/win32/CodeGen/CodeGen.vcproj
index 1e0976bb681a..b0f33152793e 100644
--- a/win32/CodeGen/CodeGen.vcproj
+++ b/win32/CodeGen/CodeGen.vcproj
@@ -341,6 +341,10 @@
>
</File>
<File
+ RelativePath="..\..\lib\CodeGen\LatencyPriorityQueue.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\lib\CodeGen\LiveInterval.cpp"
>
</File>
@@ -477,6 +481,22 @@
>
</File>
<File
+ RelativePath="..\..\lib\CodeGen\ScheduleDAG.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\CodeGen\ScheduleDAGEmit.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\CodeGen\ScheduleDAGInstrs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\CodeGen\ScheduleDAGPrinter.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\lib\CodeGen\ShadowStackGC.cpp"
>
</File>
@@ -552,23 +572,23 @@
>
</File>
<File
- RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAG.cpp"
+ RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGFast.cpp"
>
</File>
<File
- RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGEmit.cpp"
+ RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGList.cpp"
>
</File>
<File
- RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGFast.cpp"
+ RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGRRList.cpp"
>
</File>
<File
- RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGList.cpp"
+ RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGSDNodes.cpp"
>
</File>
<File
- RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGRRList.cpp"
+ RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGSDNodesEmit.cpp"
>
</File>
<File
diff --git a/win32/Transforms/Transforms.vcproj b/win32/Transforms/Transforms.vcproj
index 0bde3d89ffad..2554a4ea3b67 100644
--- a/win32/Transforms/Transforms.vcproj
+++ b/win32/Transforms/Transforms.vcproj
@@ -344,10 +344,6 @@
Name="IPO"
>
<File
- RelativePath="..\..\lib\Transforms\IPO\FunctionAttrs.cpp"
- >
- </File>
- <File
RelativePath="..\..\lib\Transforms\Ipo\ArgumentPromotion.cpp"
>
</File>
@@ -368,6 +364,10 @@
>
</File>
<File
+ RelativePath="..\..\lib\Transforms\IPO\FunctionAttrs.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\lib\Transforms\Ipo\GlobalDCE.cpp"
>
</File>
@@ -610,10 +610,6 @@
>
</File>
<File
- RelativePath="..\..\lib\Transforms\Utils\DbgInfoUtils.cpp"
- >
- </File>
- <File
RelativePath="..\..\lib\Transforms\Utils\DemoteRegToStack.cpp"
>
</File>
diff --git a/win32/config.h b/win32/config.h
index 90958169f24f..62d4c05d62a9 100644
--- a/win32/config.h
+++ b/win32/config.h
@@ -3,6 +3,7 @@
#define PACKAGE_NAME "LLVM (win32 vc8.0)"
#define PACKAGE_VERSION 2.4
+#define PACKAGE_STRING "llvm 2.6svn"
#define LLVM_HOSTTRIPLE "i686-pc-win32"
#define HAVE_WINDOWS_H 1
#define HAVE_LIMITS_H 1