aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-01-21 13:15:17 -0800
committerStephen Hines <srhines@google.com>2013-01-21 13:15:17 -0800
commit059800f9e3fee2852672f846d91a2da14da7783a (patch)
treea6ef16b7263252ae1b8069295ea9cbbae0d9467d /include
parentcbefa15de4821975bb99fc6d74b3bdb42b2df45c (diff)
parentb6714227eda5d499f7667fc865f931126a8dc488 (diff)
downloadexternal_llvm-059800f9e3fee2852672f846d91a2da14da7783a.zip
external_llvm-059800f9e3fee2852672f846d91a2da14da7783a.tar.gz
external_llvm-059800f9e3fee2852672f846d91a2da14da7783a.tar.bz2
Merge remote-tracking branch 'upstream/master' into merge-llvm
Conflicts: lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp lib/MC/MCAssembler.cpp lib/Support/Atomic.cpp lib/Support/Memory.cpp lib/Target/ARM/ARMJITInfo.cpp Change-Id: Ib339baf88df5b04870c8df1bedcfe1f877ccab8d
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Core.h27
-rw-r--r--include/llvm-c/Disassembler.h28
-rw-r--r--include/llvm-c/EnhancedDisassembly.h530
-rw-r--r--include/llvm-c/Target.h46
-rw-r--r--include/llvm-c/TargetMachine.h3
-rw-r--r--include/llvm-c/Transforms/Vectorize.h3
-rw-r--r--include/llvm-c/lto.h7
-rw-r--r--include/llvm/ADT/APFloat.h12
-rw-r--r--include/llvm/ADT/APInt.h13
-rw-r--r--include/llvm/ADT/APSInt.h2
-rw-r--r--include/llvm/ADT/BitVector.h60
-rw-r--r--include/llvm/ADT/DAGDeltaAlgorithm.h17
-rw-r--r--include/llvm/ADT/DeltaAlgorithm.h16
-rw-r--r--include/llvm/ADT/DenseMap.h44
-rw-r--r--include/llvm/ADT/DenseSet.h4
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h2
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h2
-rw-r--r--include/llvm/ADT/FoldingSet.h2
-rw-r--r--include/llvm/ADT/Hashing.h2
-rw-r--r--include/llvm/ADT/ImmutableList.h7
-rw-r--r--include/llvm/ADT/ImmutableMap.h23
-rw-r--r--include/llvm/ADT/ImmutableSet.h83
-rw-r--r--include/llvm/ADT/IntervalMap.h22
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h2
-rw-r--r--include/llvm/ADT/MapVector.h107
-rw-r--r--include/llvm/ADT/Optional.h20
-rw-r--r--include/llvm/ADT/OwningPtr.h27
-rw-r--r--include/llvm/ADT/PackedVector.h27
-rw-r--r--include/llvm/ADT/PointerIntPair.h27
-rw-r--r--include/llvm/ADT/PointerUnion.h21
-rw-r--r--include/llvm/ADT/SCCIterator.h2
-rw-r--r--include/llvm/ADT/STLExtras.h6
-rw-r--r--include/llvm/ADT/ScopedHashTable.h4
-rw-r--r--include/llvm/ADT/SetVector.h92
-rw-r--r--include/llvm/ADT/SmallBitVector.h34
-rw-r--r--include/llvm/ADT/SmallPtrSet.h7
-rw-r--r--include/llvm/ADT/SmallSet.h2
-rw-r--r--include/llvm/ADT/SmallString.h100
-rw-r--r--include/llvm/ADT/SmallVector.h24
-rw-r--r--include/llvm/ADT/SparseBitVector.h16
-rw-r--r--include/llvm/ADT/SparseSet.h6
-rw-r--r--include/llvm/ADT/StringExtras.h23
-rw-r--r--include/llvm/ADT/StringMap.h8
-rw-r--r--include/llvm/ADT/StringRef.h164
-rw-r--r--include/llvm/ADT/StringSet.h9
-rw-r--r--include/llvm/ADT/TinyPtrVector.h2
-rw-r--r--include/llvm/ADT/Triple.h43
-rw-r--r--include/llvm/ADT/Twine.h28
-rw-r--r--include/llvm/ADT/ValueMap.h7
-rw-r--r--include/llvm/ADT/ilist.h20
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h36
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h9
-rw-r--r--include/llvm/Analysis/BlockFrequencyImpl.h4
-rw-r--r--include/llvm/Analysis/BranchProbabilityInfo.h4
-rw-r--r--include/llvm/Analysis/CFGPrinter.h6
-rw-r--r--include/llvm/Analysis/CallGraph.h12
-rw-r--r--include/llvm/Analysis/CallGraphSCCPass.h (renamed from include/llvm/CallGraphSCCPass.h)5
-rw-r--r--include/llvm/Analysis/CaptureTracking.h6
-rw-r--r--include/llvm/Analysis/CodeMetrics.h17
-rw-r--r--include/llvm/Analysis/ConstantFolding.h16
-rw-r--r--include/llvm/Analysis/DOTGraphTraitsPass.h2
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h895
-rw-r--r--include/llvm/Analysis/DominatorInternals.h2
-rw-r--r--include/llvm/Analysis/Dominators.h6
-rw-r--r--include/llvm/Analysis/IVUsers.h4
-rw-r--r--include/llvm/Analysis/InlineCost.h26
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h97
-rw-r--r--include/llvm/Analysis/IntervalIterator.h2
-rw-r--r--include/llvm/Analysis/IntervalPartition.h4
-rw-r--r--include/llvm/Analysis/LazyValueInfo.h8
-rw-r--r--include/llvm/Analysis/Loads.h6
-rw-r--r--include/llvm/Analysis/LoopDependenceAnalysis.h124
-rw-r--r--include/llvm/Analysis/LoopInfo.h19
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h2
-rw-r--r--include/llvm/Analysis/LoopPass.h5
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h25
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h16
-rw-r--r--include/llvm/Analysis/PHITransAddr.h8
-rw-r--r--include/llvm/Analysis/Passes.h15
-rw-r--r--include/llvm/Analysis/PathNumbering.h6
-rw-r--r--include/llvm/Analysis/PathProfileInfo.h2
-rw-r--r--include/llvm/Analysis/ProfileDataLoader.h4
-rw-r--r--include/llvm/Analysis/ProfileInfo.h2
-rw-r--r--include/llvm/Analysis/ProfileInfoLoader.h2
-rw-r--r--include/llvm/Analysis/PtrUseVisitor.h285
-rw-r--r--include/llvm/Analysis/RegionInfo.h18
-rw-r--r--include/llvm/Analysis/RegionIterator.h2
-rw-r--r--include/llvm/Analysis/RegionPass.h7
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h24
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h6
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h16
-rw-r--r--include/llvm/Analysis/SparsePropagation.h8
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h206
-rw-r--r--include/llvm/Analysis/Trace.h2
-rw-r--r--include/llvm/Analysis/ValueTracking.h37
-rw-r--r--include/llvm/Attributes.h410
-rw-r--r--include/llvm/Bitcode/Archive.h12
-rw-r--r--include/llvm/Bitcode/BitCodes.h27
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h90
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h30
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h18
-rw-r--r--include/llvm/CMakeLists.txt8
-rw-r--r--include/llvm/CodeGen/Analysis.h11
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h14
-rw-r--r--include/llvm/CodeGen/CalcSpillWeights.h2
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h8
-rw-r--r--include/llvm/CodeGen/CommandFlags.h227
-rw-r--r--include/llvm/CodeGen/DAGCombine.h25
-rw-r--r--include/llvm/CodeGen/DFAPacketizer.h4
-rw-r--r--include/llvm/CodeGen/FastISel.h14
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h8
-rw-r--r--include/llvm/CodeGen/GCMetadata.h7
-rw-r--r--include/llvm/CodeGen/GCMetadataPrinter.h7
-rw-r--r--include/llvm/CodeGen/IntrinsicLowering.h8
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h6
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h2
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h2
-rw-r--r--include/llvm/CodeGen/LiveInterval.h30
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h61
-rw-r--r--include/llvm/CodeGen/LiveIntervalUnion.h205
-rw-r--r--include/llvm/CodeGen/LiveRegMatrix.h148
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h4
-rw-r--r--include/llvm/CodeGen/LiveVariables.h14
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h163
-rw-r--r--include/llvm/CodeGen/MachineBranchProbabilityInfo.h2
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h1
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h6
-rw-r--r--include/llvm/CodeGen/MachineDominators.h4
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h42
-rw-r--r--include/llvm/CodeGen/MachineFunction.h27
-rw-r--r--include/llvm/CodeGen/MachineInstr.h195
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h205
-rw-r--r--include/llvm/CodeGen/MachineInstrBundle.h37
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h8
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h6
-rw-r--r--include/llvm/CodeGen/MachineLoopRanges.h112
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h25
-rw-r--r--include/llvm/CodeGen/MachineModuleInfoImpls.h4
-rw-r--r--include/llvm/CodeGen/MachineOperand.h52
-rw-r--r--include/llvm/CodeGen/MachinePostDominators.h87
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h87
-rw-r--r--include/llvm/CodeGen/MachineSSAUpdater.h6
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h260
-rw-r--r--include/llvm/CodeGen/PBQP/Graph.h23
-rw-r--r--include/llvm/CodeGen/PBQP/HeuristicSolver.h2
-rw-r--r--include/llvm/CodeGen/PBQP/Heuristics/Briggs.h3
-rw-r--r--include/llvm/CodeGen/PBQP/Math.h2
-rw-r--r--include/llvm/CodeGen/PBQP/Solution.h3
-rw-r--r--include/llvm/CodeGen/Passes.h18
-rw-r--r--include/llvm/CodeGen/PseudoSourceValue.h6
-rw-r--r--include/llvm/CodeGen/RegAllocPBQP.h6
-rw-r--r--include/llvm/CodeGen/RegisterClassInfo.h25
-rw-r--r--include/llvm/CodeGen/RegisterPressure.h78
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h17
-rw-r--r--include/llvm/CodeGen/ResourcePriorityQueue.h2
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h46
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h148
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h93
-rw-r--r--include/llvm/CodeGen/ScheduleDFS.h152
-rw-r--r--include/llvm/CodeGen/SchedulerRegistry.h5
-rw-r--r--include/llvm/CodeGen/ScoreboardHazardRecognizer.h1
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h33
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h8
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h81
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h24
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h21
-rw-r--r--include/llvm/CodeGen/TargetSchedule.h167
-rw-r--r--include/llvm/CodeGen/ValueTypes.h238
-rw-r--r--include/llvm/CodeGen/ValueTypes.td68
-rw-r--r--include/llvm/CodeGen/VirtRegMap.h190
-rw-r--r--include/llvm/Config/config.h.cmake10
-rw-r--r--include/llvm/Config/config.h.in3
-rw-r--r--include/llvm/Config/llvm-config.h.cmake6
-rw-r--r--include/llvm/Config/llvm-config.h.in6
-rw-r--r--include/llvm/DIBuilder.h24
-rw-r--r--include/llvm/DebugInfo.h119
-rw-r--r--include/llvm/DebugInfo/DIContext.h20
-rw-r--r--include/llvm/DefaultPasses.h168
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h27
-rw-r--r--include/llvm/ExecutionEngine/IntelJITEventsWrapper.h102
-rw-r--r--include/llvm/ExecutionEngine/JITEventListener.h18
-rw-r--r--include/llvm/ExecutionEngine/JITMemoryManager.h30
-rw-r--r--include/llvm/ExecutionEngine/OProfileWrapper.h8
-rw-r--r--include/llvm/ExecutionEngine/ObjectBuffer.h80
-rw-r--r--include/llvm/ExecutionEngine/ObjectImage.h61
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h60
-rw-r--r--include/llvm/ExecutionEngine/SectionMemoryManager.h176
-rw-r--r--include/llvm/IR/Argument.h (renamed from include/llvm/Argument.h)15
-rw-r--r--include/llvm/IR/Attributes.h458
-rw-r--r--include/llvm/IR/BasicBlock.h (renamed from include/llvm/BasicBlock.h)22
-rw-r--r--include/llvm/IR/CMakeLists.txt7
-rw-r--r--include/llvm/IR/CallingConv.h (renamed from include/llvm/CallingConv.h)28
-rw-r--r--include/llvm/IR/Constant.h (renamed from include/llvm/Constant.h)21
-rw-r--r--include/llvm/IR/Constants.h (renamed from include/llvm/Constants.h)211
-rw-r--r--include/llvm/IR/DataLayout.h (renamed from include/llvm/Target/TargetData.h)184
-rw-r--r--include/llvm/IR/DerivedTypes.h (renamed from include/llvm/DerivedTypes.h)37
-rw-r--r--include/llvm/IR/Function.h (renamed from include/llvm/Function.h)128
-rw-r--r--include/llvm/IR/GlobalAlias.h (renamed from include/llvm/GlobalAlias.h)11
-rw-r--r--include/llvm/IR/GlobalValue.h (renamed from include/llvm/GlobalValue.h)5
-rw-r--r--include/llvm/IR/GlobalVariable.h (renamed from include/llvm/GlobalVariable.h)13
-rw-r--r--include/llvm/IR/IRBuilder.h (renamed from include/llvm/IRBuilder.h)160
-rw-r--r--include/llvm/IR/InlineAsm.h (renamed from include/llvm/InlineAsm.h)9
-rw-r--r--include/llvm/IR/InstrTypes.h (renamed from include/llvm/InstrTypes.h)37
-rw-r--r--include/llvm/IR/Instruction.def (renamed from include/llvm/Instruction.def)0
-rw-r--r--include/llvm/IR/Instruction.h (renamed from include/llvm/Instruction.h)135
-rw-r--r--include/llvm/IR/Instructions.h (renamed from include/llvm/Instructions.h)453
-rw-r--r--include/llvm/IR/IntrinsicInst.h (renamed from include/llvm/IntrinsicInst.h)70
-rw-r--r--include/llvm/IR/Intrinsics.h (renamed from include/llvm/Intrinsics.h)8
-rw-r--r--include/llvm/IR/Intrinsics.td (renamed from include/llvm/Intrinsics.td)40
-rw-r--r--include/llvm/IR/IntrinsicsARM.td429
-rw-r--r--include/llvm/IR/IntrinsicsHexagon.td (renamed from include/llvm/IntrinsicsHexagon.td)0
-rw-r--r--include/llvm/IR/IntrinsicsMips.td (renamed from include/llvm/IntrinsicsMips.td)0
-rw-r--r--include/llvm/IR/IntrinsicsNVVM.td (renamed from include/llvm/IntrinsicsNVVM.td)0
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td (renamed from include/llvm/IntrinsicsPowerPC.td)3
-rw-r--r--include/llvm/IR/IntrinsicsR600.td36
-rw-r--r--include/llvm/IR/IntrinsicsX86.td (renamed from include/llvm/IntrinsicsX86.td)12
-rw-r--r--include/llvm/IR/IntrinsicsXCore.td (renamed from include/llvm/IntrinsicsXCore.td)0
-rw-r--r--include/llvm/IR/LLVMContext.h (renamed from include/llvm/LLVMContext.h)56
-rw-r--r--include/llvm/IR/MDBuilder.h (renamed from include/llvm/MDBuilder.h)29
-rw-r--r--include/llvm/IR/Metadata.h (renamed from include/llvm/Metadata.h)12
-rw-r--r--include/llvm/IR/Module.h (renamed from include/llvm/Module.h)38
-rw-r--r--include/llvm/IR/OperandTraits.h (renamed from include/llvm/OperandTraits.h)2
-rw-r--r--include/llvm/IR/Operator.h (renamed from include/llvm/Operator.h)224
-rw-r--r--include/llvm/IR/SymbolTableListTraits.h (renamed from include/llvm/SymbolTableListTraits.h)0
-rw-r--r--include/llvm/IR/Type.h (renamed from include/llvm/Type.h)23
-rw-r--r--include/llvm/IR/TypeBuilder.h (renamed from include/llvm/TypeBuilder.h)4
-rw-r--r--include/llvm/IR/TypeFinder.h (renamed from include/llvm/TypeFinder.h)6
-rw-r--r--include/llvm/IR/Use.h (renamed from include/llvm/Use.h)3
-rw-r--r--include/llvm/IR/User.h (renamed from include/llvm/User.h)48
-rw-r--r--include/llvm/IR/Value.h (renamed from include/llvm/Value.h)14
-rw-r--r--include/llvm/IR/ValueSymbolTable.h (renamed from include/llvm/ValueSymbolTable.h)2
-rw-r--r--include/llvm/InitializePasses.h16
-rw-r--r--include/llvm/InstVisitor.h (renamed from include/llvm/Support/InstVisitor.h)28
-rw-r--r--include/llvm/IntrinsicsARM.td442
-rw-r--r--include/llvm/IntrinsicsCellSPU.td242
-rw-r--r--include/llvm/LinkAllPasses.h15
-rw-r--r--include/llvm/LinkAllVMCore.h14
-rw-r--r--include/llvm/MC/EDInstInfo.h29
-rw-r--r--include/llvm/MC/MCAsmBackend.h20
-rw-r--r--include/llvm/MC/MCAsmInfo.h10
-rw-r--r--include/llvm/MC/MCAsmLayout.h26
-rw-r--r--include/llvm/MC/MCAssembler.h267
-rw-r--r--include/llvm/MC/MCCodeEmitter.h7
-rw-r--r--include/llvm/MC/MCContext.h44
-rw-r--r--include/llvm/MC/MCDisassembler.h12
-rw-r--r--include/llvm/MC/MCDwarf.h130
-rw-r--r--include/llvm/MC/MCELF.h35
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h9
-rw-r--r--include/llvm/MC/MCELFStreamer.h113
-rw-r--r--include/llvm/MC/MCExpr.h33
-rw-r--r--include/llvm/MC/MCInst.h2
-rw-r--r--include/llvm/MC/MCInstBuilder.h68
-rw-r--r--include/llvm/MC/MCInstPrinter.h25
-rw-r--r--include/llvm/MC/MCInstrDesc.h102
-rw-r--r--include/llvm/MC/MCLabel.h2
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h22
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h71
-rw-r--r--include/llvm/MC/MCObjectStreamer.h23
-rw-r--r--include/llvm/MC/MCObjectWriter.h11
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h19
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h36
-rw-r--r--include/llvm/MC/MCParser/MCAsmParserExtension.h6
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h54
-rw-r--r--include/llvm/MC/MCRegisterInfo.h104
-rw-r--r--include/llvm/MC/MCSchedule.h141
-rw-r--r--include/llvm/MC/MCSection.h8
-rw-r--r--include/llvm/MC/MCSectionCOFF.h9
-rw-r--r--include/llvm/MC/MCSectionELF.h10
-rw-r--r--include/llvm/MC/MCSectionMachO.h11
-rw-r--r--include/llvm/MC/MCStreamer.h60
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h65
-rw-r--r--include/llvm/MC/MCSymbol.h6
-rw-r--r--include/llvm/MC/MCTargetAsmLexer.h89
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h79
-rw-r--r--include/llvm/MC/MCValue.h4
-rw-r--r--include/llvm/MC/MCWinCOFFObjectWriter.h3
-rw-r--r--include/llvm/MC/SubtargetFeature.h6
-rw-r--r--include/llvm/Object/Archive.h17
-rw-r--r--include/llvm/Object/Binary.h5
-rw-r--r--include/llvm/Object/COFF.h3
-rw-r--r--include/llvm/Object/ELF.h896
-rw-r--r--include/llvm/Object/MachO.h16
-rw-r--r--include/llvm/Object/MachOFormat.h9
-rw-r--r--include/llvm/Object/MachOObject.h2
-rw-r--r--include/llvm/Object/ObjectFile.h45
-rw-r--r--include/llvm/Object/RelocVisitor.h146
-rw-r--r--include/llvm/Option/Arg.h132
-rw-r--r--include/llvm/Option/ArgList.h414
-rw-r--r--include/llvm/Option/OptParser.td127
-rw-r--r--include/llvm/Option/OptSpecifier.h39
-rw-r--r--include/llvm/Option/OptTable.h161
-rw-r--r--include/llvm/Option/Option.h193
-rw-r--r--include/llvm/Pass.h36
-rw-r--r--include/llvm/PassAnalysisSupport.h4
-rw-r--r--include/llvm/PassManagers.h22
-rw-r--r--include/llvm/PassSupport.h8
-rw-r--r--include/llvm/Support/AlignOf.h188
-rw-r--r--include/llvm/Support/Allocator.h12
-rw-r--r--include/llvm/Support/ArrayRecycler.h143
-rw-r--r--include/llvm/Support/CFG.h4
-rw-r--r--include/llvm/Support/CallSite.h38
-rw-r--r--include/llvm/Support/Casting.h16
-rw-r--r--include/llvm/Support/CommandLine.h21
-rw-r--r--include/llvm/Support/Compiler.h91
-rw-r--r--include/llvm/Support/ConstantFolder.h4
-rw-r--r--include/llvm/Support/DataExtractor.h1
-rw-r--r--include/llvm/Support/DataFlow.h2
-rw-r--r--include/llvm/Support/Dwarf.h33
-rw-r--r--include/llvm/Support/ELF.h76
-rw-r--r--include/llvm/Support/Endian.h161
-rw-r--r--include/llvm/Support/ErrorHandling.h2
-rw-r--r--include/llvm/Support/FileOutputBuffer.h63
-rw-r--r--include/llvm/Support/FileSystem.h62
-rw-r--r--include/llvm/Support/Format.h40
-rw-r--r--include/llvm/Support/FormattedStream.h11
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h12
-rw-r--r--include/llvm/Support/GraphWriter.h6
-rw-r--r--include/llvm/Support/InstIterator.h4
-rw-r--r--include/llvm/Support/IntegersSubset.h15
-rw-r--r--include/llvm/Support/LEB128.h2
-rw-r--r--include/llvm/Support/LockFileManager.h4
-rw-r--r--include/llvm/Support/MathExtras.h19
-rw-r--r--include/llvm/Support/Memory.h65
-rw-r--r--include/llvm/Support/MemoryBuffer.h5
-rw-r--r--include/llvm/Support/Mutex.h5
-rw-r--r--include/llvm/Support/MutexGuard.h4
-rw-r--r--include/llvm/Support/NoFolder.h4
-rw-r--r--include/llvm/Support/PassNameParser.h2
-rw-r--r--include/llvm/Support/PathV2.h109
-rw-r--r--include/llvm/Support/PatternMatch.h312
-rw-r--r--include/llvm/Support/PredIteratorCache.h4
-rw-r--r--include/llvm/Support/PrettyStackTrace.h10
-rw-r--r--include/llvm/Support/Process.h366
-rw-r--r--include/llvm/Support/Program.h20
-rw-r--r--include/llvm/Support/RWMutex.h5
-rw-r--r--include/llvm/Support/Recycler.h11
-rw-r--r--include/llvm/Support/Regex.h21
-rw-r--r--include/llvm/Support/Registry.h7
-rw-r--r--include/llvm/Support/SMLoc.h10
-rw-r--r--include/llvm/Support/SourceMgr.h12
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h22
-rw-r--r--include/llvm/Support/StringPool.h2
-rw-r--r--include/llvm/Support/TargetFolder.h19
-rw-r--r--include/llvm/Support/TargetRegistry.h104
-rw-r--r--include/llvm/Support/ThreadLocal.h2
-rw-r--r--include/llvm/Support/Threading.h4
-rw-r--r--include/llvm/Support/TimeValue.h9
-rw-r--r--include/llvm/Support/Timer.h11
-rw-r--r--include/llvm/Support/Valgrind.h2
-rw-r--r--include/llvm/Support/ValueHandle.h6
-rw-r--r--include/llvm/Support/Win64EH.h81
-rw-r--r--include/llvm/Support/YAMLParser.h20
-rw-r--r--include/llvm/Support/YAMLTraits.h1104
-rw-r--r--include/llvm/Support/circular_raw_ostream.h8
-rw-r--r--include/llvm/Support/raw_os_ostream.h10
-rw-r--r--include/llvm/Support/raw_ostream.h51
-rw-r--r--include/llvm/Support/system_error.h8
-rw-r--r--include/llvm/Support/type_traits.h10
-rw-r--r--include/llvm/TableGen/Error.h16
-rw-r--r--include/llvm/TableGen/Main.h9
-rw-r--r--include/llvm/TableGen/Record.h426
-rw-r--r--include/llvm/TableGen/StringMatcher.h4
-rw-r--r--include/llvm/TableGen/TableGenAction.h35
-rw-r--r--include/llvm/Target/Mangler.h9
-rw-r--r--include/llvm/Target/Target.td57
-rw-r--r--include/llvm/Target/TargetCallingConv.h27
-rw-r--r--include/llvm/Target/TargetELFWriterInfo.h121
-rw-r--r--include/llvm/Target/TargetFrameLowering.h12
-rw-r--r--include/llvm/Target/TargetInstrInfo.h168
-rw-r--r--include/llvm/Target/TargetIntrinsicInfo.h5
-rw-r--r--include/llvm/Target/TargetJITInfo.h2
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h55
-rw-r--r--include/llvm/Target/TargetLowering.h350
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h26
-rw-r--r--include/llvm/Target/TargetMachine.h26
-rw-r--r--include/llvm/Target/TargetOptions.h12
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h146
-rw-r--r--include/llvm/Target/TargetSchedule.td340
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h10
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h30
-rw-r--r--include/llvm/Transforms/IPO.h29
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h5
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h1
-rw-r--r--include/llvm/Transforms/Instrumentation.h22
-rw-r--r--include/llvm/Transforms/Scalar.h12
-rw-r--r--include/llvm/Transforms/Utils/AddrModeMatcher.h108
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h27
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h36
-rw-r--r--include/llvm/Transforms/Utils/BypassSlowDivision.h5
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h17
-rw-r--r--include/llvm/Transforms/Utils/CmpInstAnalysis.h2
-rw-r--r--include/llvm/Transforms/Utils/IntegerDivision.h48
-rw-r--r--include/llvm/Transforms/Utils/Local.h32
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdater.h5
-rw-r--r--include/llvm/Transforms/Utils/SimplifyIndVar.h2
-rw-r--r--include/llvm/Transforms/Utils/SimplifyLibCalls.h53
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h2
-rw-r--r--include/llvm/Transforms/Vectorize.h7
398 files changed, 15289 insertions, 7181 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 6587e77..f2fe764 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -21,8 +21,8 @@
/* Need these includes to support the LLVM 'cast' template for the C++ 'wrap'
and 'unwrap' conversion functions. */
-#include "llvm/IRBuilder.h"
-#include "llvm/Module.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
#include "llvm/PassRegistry.h"
extern "C" {
@@ -1803,7 +1803,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg);
* Set the alignment for a function parameter.
*
* @see llvm::Argument::addAttr()
- * @see llvm::Attribute::constructAlignmentFromInt()
+ * @see llvm::AttrBuilder::addAlignmentAttr()
*/
void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
@@ -1869,6 +1869,27 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len);
/**
+ * Obtain the number of operands from an MDNode value.
+ *
+ * @param V MDNode to get number of operands from.
+ * @return Number of operands of the MDNode.
+ */
+unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V);
+
+/**
+ * Obtain the given MDNode's operands.
+ *
+ * The passed LLVMValueRef pointer should point to enough memory to hold all of
+ * the operands of the given MDNode (see LLVMGetMDNodeNumOperands) as
+ * LLVMValueRefs. This memory will be populated with the LLVMValueRefs of the
+ * MDNode's operands.
+ *
+ * @param V MDNode to get the operands from.
+ * @param Dest Destination array for operands.
+ */
+void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest);
+
+/**
* @}
*/
diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h
index 69fdc64..df65a7b 100644
--- a/include/llvm-c/Disassembler.h
+++ b/include/llvm-c/Disassembler.h
@@ -139,13 +139,39 @@ extern "C" {
* by passing a block of information in the DisInfo parameter and specifying the
* TagType and callback functions as described above. These can all be passed
* as NULL. If successful, this returns a disassembler context. If not, it
- * returns NULL.
+ * returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU()
+ * with an empty CPU name.
*/
LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/**
+ * Create a disassembler for the TripleName and a specific CPU. Symbolic
+ * disassembly is supported by passing a block of information in the DisInfo
+ * parameter and specifying the TagType and callback functions as described
+ * above. These can all be passed * as NULL. If successful, this returns a
+ * disassembler context. If not, it returns NULL.
+ */
+LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
+ void *DisInfo, int TagType,
+ LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp);
+
+/**
+ * Set the disassembler's options. Returns 1 if it can set the Options and 0
+ * otherwise.
+ */
+int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
+
+/* The option to produce marked up assembly. */
+#define LLVMDisassembler_Option_UseMarkup 1
+/* The option to print immediates as hex. */
+#define LLVMDisassembler_Option_PrintImmHex 2
+/* The option use the other assembler printer variant */
+#define LLVMDisassembler_Option_AsmPrinterVariant 4
+
+/**
* Dispose of a disassembler context.
*/
void LLVMDisasmDispose(LLVMDisasmContextRef DC);
diff --git a/include/llvm-c/EnhancedDisassembly.h b/include/llvm-c/EnhancedDisassembly.h
deleted file mode 100644
index 71a0d49..0000000
--- a/include/llvm-c/EnhancedDisassembly.h
+++ /dev/null
@@ -1,530 +0,0 @@
-/*===-- llvm-c/EnhancedDisassembly.h - Disassembler C Interface ---*- C -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* This header declares the C interface to EnhancedDisassembly.so, which *|
-|* implements a disassembler with the ability to extract operand values and *|
-|* individual tokens from assembly instructions. *|
-|* *|
-|* The header declares additional interfaces if the host compiler supports *|
-|* the blocks API. *|
-|* *|
-\*===----------------------------------------------------------------------===*/
-
-#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H
-#define LLVM_C_ENHANCEDDISASSEMBLY_H
-
-#include "llvm/Support/DataTypes.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup LLVMCEnhancedDisassembly Enhanced Disassembly
- * @ingroup LLVMC
- * @deprecated
- *
- * This module contains an interface to the Enhanced Disassembly (edis)
- * library. The edis library is deprecated and will likely disappear in
- * the near future. You should use the @ref LLVMCDisassembler interface
- * instead.
- *
- * @{
- */
-
-/*!
- @typedef EDByteReaderCallback
- Interface to memory from which instructions may be read.
- @param byte A pointer whose target should be filled in with the data returned.
- @param address The address of the byte to be read.
- @param arg An anonymous argument for client use.
- @result 0 on success; -1 otherwise.
- */
-typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
-
-/*!
- @typedef EDRegisterReaderCallback
- Interface to registers from which registers may be read.
- @param value A pointer whose target should be filled in with the value of the
- register.
- @param regID The LLVM register identifier for the register to read.
- @param arg An anonymous argument for client use.
- @result 0 if the register could be read; -1 otherwise.
- */
-typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
- void* arg);
-
-/*!
- @typedef EDAssemblySyntax_t
- An assembly syntax for use in tokenizing instructions.
- */
-enum {
-/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
- kEDAssemblySyntaxX86Intel = 0,
-/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
- kEDAssemblySyntaxX86ATT = 1,
- kEDAssemblySyntaxARMUAL = 2
-};
-typedef unsigned EDAssemblySyntax_t;
-
-/*!
- @typedef EDDisassemblerRef
- Encapsulates a disassembler for a single CPU architecture.
- */
-typedef void *EDDisassemblerRef;
-
-/*!
- @typedef EDInstRef
- Encapsulates a single disassembled instruction in one assembly syntax.
- */
-typedef void *EDInstRef;
-
-/*!
- @typedef EDTokenRef
- Encapsulates a token from the disassembly of an instruction.
- */
-typedef void *EDTokenRef;
-
-/*!
- @typedef EDOperandRef
- Encapsulates an operand of an instruction.
- */
-typedef void *EDOperandRef;
-
-/*!
- @functiongroup Getting a disassembler
- */
-
-/*!
- @function EDGetDisassembler
- Gets the disassembler for a given target.
- @param disassembler A pointer whose target will be filled in with the
- disassembler.
- @param triple Identifies the target. Example: "x86_64-apple-darwin10"
- @param syntax The assembly syntax to use when decoding instructions.
- @result 0 on success; -1 otherwise.
- */
-int EDGetDisassembler(EDDisassemblerRef *disassembler,
- const char *triple,
- EDAssemblySyntax_t syntax);
-
-/*!
- @functiongroup Generic architectural queries
- */
-
-/*!
- @function EDGetRegisterName
- Gets the human-readable name for a given register.
- @param regName A pointer whose target will be pointed at the name of the
- register. The name does not need to be deallocated and will be
- @param disassembler The disassembler to query for the name.
- @param regID The register identifier, as returned by EDRegisterTokenValue.
- @result 0 on success; -1 otherwise.
- */
-int EDGetRegisterName(const char** regName,
- EDDisassemblerRef disassembler,
- unsigned regID);
-
-/*!
- @function EDRegisterIsStackPointer
- Determines if a register is one of the platform's stack-pointer registers.
- @param disassembler The disassembler to query.
- @param regID The register identifier, as returned by EDRegisterTokenValue.
- @result 1 if true; 0 otherwise.
- */
-int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
- unsigned regID);
-
-/*!
- @function EDRegisterIsProgramCounter
- Determines if a register is one of the platform's stack-pointer registers.
- @param disassembler The disassembler to query.
- @param regID The register identifier, as returned by EDRegisterTokenValue.
- @result 1 if true; 0 otherwise.
- */
-int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
- unsigned regID);
-
-/*!
- @functiongroup Creating and querying instructions
- */
-
-/*!
- @function EDCreateInst
- Gets a set of contiguous instructions from a disassembler.
- @param insts A pointer to an array that will be filled in with the
- instructions. Must have at least count entries. Entries not filled in will
- be set to NULL.
- @param count The maximum number of instructions to fill in.
- @param disassembler The disassembler to use when decoding the instructions.
- @param byteReader The function to use when reading the instruction's machine
- code.
- @param address The address of the first byte of the instruction.
- @param arg An anonymous argument to be passed to byteReader.
- @result The number of instructions read on success; 0 otherwise.
- */
-unsigned int EDCreateInsts(EDInstRef *insts,
- unsigned int count,
- EDDisassemblerRef disassembler,
- EDByteReaderCallback byteReader,
- uint64_t address,
- void *arg);
-
-/*!
- @function EDReleaseInst
- Frees the memory for an instruction. The instruction can no longer be accessed
- after this call.
- @param inst The instruction to be freed.
- */
-void EDReleaseInst(EDInstRef inst);
-
-/*!
- @function EDInstByteSize
- @param inst The instruction to be queried.
- @result The number of bytes in the instruction's machine-code representation.
- */
-int EDInstByteSize(EDInstRef inst);
-
-/*!
- @function EDGetInstString
- Gets the disassembled text equivalent of the instruction.
- @param buf A pointer whose target will be filled in with a pointer to the
- string. (The string becomes invalid when the instruction is released.)
- @param inst The instruction to be queried.
- @result 0 on success; -1 otherwise.
- */
-int EDGetInstString(const char **buf,
- EDInstRef inst);
-
-/*!
- @function EDInstID
- @param instID A pointer whose target will be filled in with the LLVM identifier
- for the instruction.
- @param inst The instruction to be queried.
- @result 0 on success; -1 otherwise.
- */
-int EDInstID(unsigned *instID, EDInstRef inst);
-
-/*!
- @function EDInstIsBranch
- @param inst The instruction to be queried.
- @result 1 if the instruction is a branch instruction; 0 if it is some other
- type of instruction; -1 if there was an error.
- */
-int EDInstIsBranch(EDInstRef inst);
-
-/*!
- @function EDInstIsMove
- @param inst The instruction to be queried.
- @result 1 if the instruction is a move instruction; 0 if it is some other
- type of instruction; -1 if there was an error.
- */
-int EDInstIsMove(EDInstRef inst);
-
-/*!
- @function EDBranchTargetID
- @param inst The instruction to be queried.
- @result The ID of the branch target operand, suitable for use with
- EDCopyOperand. -1 if no such operand exists.
- */
-int EDBranchTargetID(EDInstRef inst);
-
-/*!
- @function EDMoveSourceID
- @param inst The instruction to be queried.
- @result The ID of the move source operand, suitable for use with
- EDCopyOperand. -1 if no such operand exists.
- */
-int EDMoveSourceID(EDInstRef inst);
-
-/*!
- @function EDMoveTargetID
- @param inst The instruction to be queried.
- @result The ID of the move source operand, suitable for use with
- EDCopyOperand. -1 if no such operand exists.
- */
-int EDMoveTargetID(EDInstRef inst);
-
-/*!
- @functiongroup Creating and querying tokens
- */
-
-/*!
- @function EDNumTokens
- @param inst The instruction to be queried.
- @result The number of tokens in the instruction, or -1 on error.
- */
-int EDNumTokens(EDInstRef inst);
-
-/*!
- @function EDGetToken
- Retrieves a token from an instruction. The token is valid until the
- instruction is released.
- @param token A pointer to be filled in with the token.
- @param inst The instruction to be queried.
- @param index The index of the token in the instruction.
- @result 0 on success; -1 otherwise.
- */
-int EDGetToken(EDTokenRef *token,
- EDInstRef inst,
- int index);
-
-/*!
- @function EDGetTokenString
- Gets the disassembled text for a token.
- @param buf A pointer whose target will be filled in with a pointer to the
- string. (The string becomes invalid when the token is released.)
- @param token The token to be queried.
- @result 0 on success; -1 otherwise.
- */
-int EDGetTokenString(const char **buf,
- EDTokenRef token);
-
-/*!
- @function EDOperandIndexForToken
- Returns the index of the operand to which a token belongs.
- @param token The token to be queried.
- @result The operand index on success; -1 otherwise
- */
-int EDOperandIndexForToken(EDTokenRef token);
-
-/*!
- @function EDTokenIsWhitespace
- @param token The token to be queried.
- @result 1 if the token is whitespace; 0 if not; -1 on error.
- */
-int EDTokenIsWhitespace(EDTokenRef token);
-
-/*!
- @function EDTokenIsPunctuation
- @param token The token to be queried.
- @result 1 if the token is punctuation; 0 if not; -1 on error.
- */
-int EDTokenIsPunctuation(EDTokenRef token);
-
-/*!
- @function EDTokenIsOpcode
- @param token The token to be queried.
- @result 1 if the token is opcode; 0 if not; -1 on error.
- */
-int EDTokenIsOpcode(EDTokenRef token);
-
-/*!
- @function EDTokenIsLiteral
- @param token The token to be queried.
- @result 1 if the token is a numeric literal; 0 if not; -1 on error.
- */
-int EDTokenIsLiteral(EDTokenRef token);
-
-/*!
- @function EDTokenIsRegister
- @param token The token to be queried.
- @result 1 if the token identifies a register; 0 if not; -1 on error.
- */
-int EDTokenIsRegister(EDTokenRef token);
-
-/*!
- @function EDTokenIsNegativeLiteral
- @param token The token to be queried.
- @result 1 if the token is a negative signed literal; 0 if not; -1 on error.
- */
-int EDTokenIsNegativeLiteral(EDTokenRef token);
-
-/*!
- @function EDLiteralTokenAbsoluteValue
- @param value A pointer whose target will be filled in with the absolute value
- of the literal.
- @param token The token to be queried.
- @result 0 on success; -1 otherwise.
- */
-int EDLiteralTokenAbsoluteValue(uint64_t *value,
- EDTokenRef token);
-
-/*!
- @function EDRegisterTokenValue
- @param registerID A pointer whose target will be filled in with the LLVM
- register identifier for the token.
- @param token The token to be queried.
- @result 0 on success; -1 otherwise.
- */
-int EDRegisterTokenValue(unsigned *registerID,
- EDTokenRef token);
-
-/*!
- @functiongroup Creating and querying operands
- */
-
-/*!
- @function EDNumOperands
- @param inst The instruction to be queried.
- @result The number of operands in the instruction, or -1 on error.
- */
-int EDNumOperands(EDInstRef inst);
-
-/*!
- @function EDGetOperand
- Retrieves an operand from an instruction. The operand is valid until the
- instruction is released.
- @param operand A pointer to be filled in with the operand.
- @param inst The instruction to be queried.
- @param index The index of the operand in the instruction.
- @result 0 on success; -1 otherwise.
- */
-int EDGetOperand(EDOperandRef *operand,
- EDInstRef inst,
- int index);
-
-/*!
- @function EDOperandIsRegister
- @param operand The operand to be queried.
- @result 1 if the operand names a register; 0 if not; -1 on error.
- */
-int EDOperandIsRegister(EDOperandRef operand);
-
-/*!
- @function EDOperandIsImmediate
- @param operand The operand to be queried.
- @result 1 if the operand specifies an immediate value; 0 if not; -1 on error.
- */
-int EDOperandIsImmediate(EDOperandRef operand);
-
-/*!
- @function EDOperandIsMemory
- @param operand The operand to be queried.
- @result 1 if the operand specifies a location in memory; 0 if not; -1 on error.
- */
-int EDOperandIsMemory(EDOperandRef operand);
-
-/*!
- @function EDRegisterOperandValue
- @param value A pointer whose target will be filled in with the LLVM register ID
- of the register named by the operand.
- @param operand The operand to be queried.
- @result 0 on success; -1 otherwise.
- */
-int EDRegisterOperandValue(unsigned *value,
- EDOperandRef operand);
-
-/*!
- @function EDImmediateOperandValue
- @param value A pointer whose target will be filled in with the value of the
- immediate.
- @param operand The operand to be queried.
- @result 0 on success; -1 otherwise.
- */
-int EDImmediateOperandValue(uint64_t *value,
- EDOperandRef operand);
-
-/*!
- @function EDEvaluateOperand
- Evaluates an operand using a client-supplied register state accessor. Register
- operands are evaluated by reading the value of the register; immediate operands
- are evaluated by reporting the immediate value; memory operands are evaluated
- by computing the target address (with only those relocations applied that were
- already applied to the original bytes).
- @param result A pointer whose target is to be filled with the result of
- evaluating the operand.
- @param operand The operand to be evaluated.
- @param regReader The function to use when reading registers from the register
- state.
- @param arg An anonymous argument for client use.
- @result 0 if the operand could be evaluated; -1 otherwise.
- */
-int EDEvaluateOperand(uint64_t *result,
- EDOperandRef operand,
- EDRegisterReaderCallback regReader,
- void *arg);
-
-#ifdef __BLOCKS__
-
-/*!
- @typedef EDByteBlock_t
- Block-based interface to memory from which instructions may be read.
- @param byte A pointer whose target should be filled in with the data returned.
- @param address The address of the byte to be read.
- @result 0 on success; -1 otherwise.
- */
-typedef int (^EDByteBlock_t)(uint8_t *byte, uint64_t address);
-
-/*!
- @typedef EDRegisterBlock_t
- Block-based interface to registers from which registers may be read.
- @param value A pointer whose target should be filled in with the value of the
- register.
- @param regID The LLVM register identifier for the register to read.
- @result 0 if the register could be read; -1 otherwise.
- */
-typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
-
-/*!
- @typedef EDTokenVisitor_t
- Block-based handler for individual tokens.
- @param token The current token being read.
- @result 0 to continue; 1 to stop normally; -1 on error.
- */
-typedef int (^EDTokenVisitor_t)(EDTokenRef token);
-
-/*! @functiongroup Block-based interfaces */
-
-/*!
- @function EDBlockCreateInsts
- Gets a set of contiguous instructions from a disassembler, using a block to
- read memory.
- @param insts A pointer to an array that will be filled in with the
- instructions. Must have at least count entries. Entries not filled in will
- be set to NULL.
- @param count The maximum number of instructions to fill in.
- @param disassembler The disassembler to use when decoding the instructions.
- @param byteBlock The block to use when reading the instruction's machine
- code.
- @param address The address of the first byte of the instruction.
- @result The number of instructions read on success; 0 otherwise.
- */
-unsigned int EDBlockCreateInsts(EDInstRef *insts,
- int count,
- EDDisassemblerRef disassembler,
- EDByteBlock_t byteBlock,
- uint64_t address);
-
-/*!
- @function EDBlockEvaluateOperand
- Evaluates an operand using a block to read registers.
- @param result A pointer whose target is to be filled with the result of
- evaluating the operand.
- @param operand The operand to be evaluated.
- @param regBlock The block to use when reading registers from the register
- state.
- @result 0 if the operand could be evaluated; -1 otherwise.
- */
-int EDBlockEvaluateOperand(uint64_t *result,
- EDOperandRef operand,
- EDRegisterBlock_t regBlock);
-
-/*!
- @function EDBlockVisitTokens
- Visits every token with a visitor.
- @param inst The instruction with the tokens to be visited.
- @param visitor The visitor.
- @result 0 if the visit ended normally; -1 if the visitor encountered an error
- or there was some other error.
- */
-int EDBlockVisitTokens(EDInstRef inst,
- EDTokenVisitor_t visitor);
-
-/**
- * @}
- */
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h
index 8915040..57abfa0 100644
--- a/include/llvm-c/Target.h
+++ b/include/llvm-c/Target.h
@@ -145,7 +145,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
/*===-- Target Data -------------------------------------------------------===*/
/** Creates target data from a target layout string.
- See the constructor llvm::TargetData::TargetData. */
+ See the constructor llvm::DataLayout::DataLayout. */
LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
/** Adds target data information to a pass manager. This does not take ownership
@@ -160,48 +160,58 @@ void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef);
/** Converts target data to a target layout string. The string must be disposed
with LLVMDisposeMessage.
- See the constructor llvm::TargetData::TargetData. */
+ See the constructor llvm::DataLayout::DataLayout. */
char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
/** Returns the byte order of a target, either LLVMBigEndian or
LLVMLittleEndian.
- See the method llvm::TargetData::isLittleEndian. */
+ See the method llvm::DataLayout::isLittleEndian. */
enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
/** Returns the pointer size in bytes for a target.
- See the method llvm::TargetData::getPointerSize. */
+ See the method llvm::DataLayout::getPointerSize. */
unsigned LLVMPointerSize(LLVMTargetDataRef);
+/** Returns the pointer size in bytes for a target for a specified
+ address space.
+ See the method llvm::DataLayout::getPointerSize. */
+unsigned LLVMPointerSizeForAS(LLVMTargetDataRef, unsigned AS);
+
/** Returns the integer type that is the same size as a pointer on a target.
- See the method llvm::TargetData::getIntPtrType. */
+ See the method llvm::DataLayout::getIntPtrType. */
LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef);
+/** Returns the integer type that is the same size as a pointer on a target.
+ This version allows the address space to be specified.
+ See the method llvm::DataLayout::getIntPtrType. */
+LLVMTypeRef LLVMIntPtrTypeForAS(LLVMTargetDataRef, unsigned AS);
+
/** Computes the size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeSizeInBits. */
+ See the method llvm::DataLayout::getTypeSizeInBits. */
unsigned long long LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the storage size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeStoreSize. */
+ See the method llvm::DataLayout::getTypeStoreSize. */
unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeAllocSize. */
+ See the method llvm::DataLayout::getTypeAllocSize. */
unsigned long long LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. */
+ See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the call frame alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. */
+ See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. */
+ See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a global variable in bytes for a target.
- See the method llvm::TargetData::getPreferredAlignment. */
+ See the method llvm::DataLayout::getPreferredAlignment. */
unsigned LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,
LLVMValueRef GlobalVar);
@@ -216,7 +226,7 @@ unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
unsigned Element);
/** Deallocates a TargetData.
- See the destructor llvm::TargetData::~TargetData. */
+ See the destructor llvm::DataLayout::~DataLayout. */
void LLVMDisposeTargetData(LLVMTargetDataRef);
/**
@@ -227,15 +237,15 @@ void LLVMDisposeTargetData(LLVMTargetDataRef);
}
namespace llvm {
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
- inline TargetData *unwrap(LLVMTargetDataRef P) {
- return reinterpret_cast<TargetData*>(P);
+ inline DataLayout *unwrap(LLVMTargetDataRef P) {
+ return reinterpret_cast<DataLayout*>(P);
}
- inline LLVMTargetDataRef wrap(const TargetData *P) {
- return reinterpret_cast<LLVMTargetDataRef>(const_cast<TargetData*>(P));
+ inline LLVMTargetDataRef wrap(const DataLayout *P) {
+ return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
}
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h
index 0d35d73..691abdf 100644
--- a/include/llvm-c/TargetMachine.h
+++ b/include/llvm-c/TargetMachine.h
@@ -20,6 +20,7 @@
#define LLVM_C_TARGETMACHINE_H
#include "llvm-c/Core.h"
+#include "llvm-c/Target.h"
#ifdef __cplusplus
extern "C" {
@@ -104,7 +105,7 @@ char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
LLVMDisposeMessage. */
char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
-/** Returns the llvm::TargetData used for this llvm:TargetMachine. */
+/** Returns the llvm::DataLayout used for this llvm:TargetMachine. */
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
/** Emits an asm or object file for the given module to the filename. This
diff --git a/include/llvm-c/Transforms/Vectorize.h b/include/llvm-c/Transforms/Vectorize.h
index 9e7c754..68a9bdd 100644
--- a/include/llvm-c/Transforms/Vectorize.h
+++ b/include/llvm-c/Transforms/Vectorize.h
@@ -36,6 +36,9 @@ extern "C" {
/** See llvm::createBBVectorizePass function. */
void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
+/** See llvm::createLoopVectorizePass function. */
+void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM);
+
/**
* @}
*/
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h
index f43d365..74915c0 100644
--- a/include/llvm-c/lto.h
+++ b/include/llvm-c/lto.h
@@ -291,6 +291,13 @@ lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
extern void
lto_codegen_debug_options(lto_code_gen_t cg, const char *);
+/**
+ * Initializes LLVM disassemblers.
+ * FIXME: This doesn't really belong here.
+ */
+extern void
+lto_initialize_disassembler(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 5a625a4..93d343a 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -327,6 +327,7 @@ namespace llvm {
bool isNegative() const { return sign; }
bool isPosZero() const { return isZero() && !isNegative(); }
bool isNegZero() const { return isZero() && isNegative(); }
+ bool isDenormal() const;
APFloat& operator=(const APFloat &);
@@ -455,14 +456,11 @@ namespace llvm {
/* The sign bit of this number. */
unsigned int sign: 1;
-
- /* For PPCDoubleDouble, we have a second exponent and sign (the second
- significand is appended to the first one, although it would be wrong to
- regard these as a single number for arithmetic purposes). These fields
- are not meaningful for any other type. */
- exponent_t exponent2 : 11;
- unsigned int sign2: 1;
};
+
+ // See friend declaration above. This additional declaration is required in
+ // order to compile LLVM with IBM xlC compiler.
+ hash_code hash_value(const APFloat &Arg);
} /* namespace llvm */
#endif /* LLVM_FLOAT_H */
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 7f20e33..95cd23d 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -251,7 +251,7 @@ public:
/// constructor.
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
- /// This constructor interprets the string \arg str in the given radix. The
+ /// This constructor interprets the string \p str in the given radix. The
/// interpretation stops when the first character that is not suitable for the
/// radix is encountered, or the end of the string. Acceptable radix values
/// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
@@ -274,7 +274,7 @@ public:
initSlowCase(that);
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
/// @brief Move Constructor.
APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) {
that.BitWidth = 0;
@@ -601,7 +601,7 @@ public:
return AssignSlowCase(RHS);
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
/// @brief Move assignment operator.
APInt& operator=(APInt&& that) {
if (!isSingleWord())
@@ -760,7 +760,7 @@ public:
APInt shl(unsigned shiftAmt) const {
assert(shiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
- if (shiftAmt == BitWidth)
+ if (shiftAmt >= BitWidth)
return APInt(BitWidth, 0); // avoid undefined shift results
return APInt(BitWidth, VAL << shiftAmt);
}
@@ -1231,7 +1231,7 @@ public:
}
/// This method determines how many bits are required to hold the APInt
- /// equivalent of the string given by \arg str.
+ /// equivalent of the string given by \p str.
/// @brief Get bits required for string value.
static unsigned getBitsNeeded(StringRef str, uint8_t radix);
@@ -1780,6 +1780,9 @@ inline APInt Not(const APInt& APIVal) {
} // End of APIntOps namespace
+ // See friend declaration above. This additional declaration is required in
+ // order to compile LLVM with IBM xlC compiler.
+ hash_code hash_value(const APInt &Arg);
} // End of llvm namespace
#endif
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 048c65c..4a5e7a3 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -23,7 +23,7 @@ class APSInt : public APInt {
bool IsUnsigned;
public:
/// Default constructor that creates an uninitialized APInt.
- explicit APSInt() {}
+ explicit APSInt() : IsUnsigned(false) {}
/// APSInt ctor - Create an APSInt with the specified width, default to
/// unsigned.
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 26ec346..82cfdf4 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -98,7 +98,7 @@ public:
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
BitVector(BitVector &&RHS)
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
RHS.Bits = 0;
@@ -237,6 +237,34 @@ public:
return *this;
}
+ /// set - Efficiently set a range of bits in [I, E)
+ BitVector &set(unsigned I, unsigned E) {
+ assert(I <= E && "Attempted to set backwards range!");
+ assert(E <= size() && "Attempted to set out-of-bounds range!");
+
+ if (I == E) return *this;
+
+ if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
+ BitWord EMask = 1UL << (E % BITWORD_SIZE);
+ BitWord IMask = 1UL << (I % BITWORD_SIZE);
+ BitWord Mask = EMask - IMask;
+ Bits[I / BITWORD_SIZE] |= Mask;
+ return *this;
+ }
+
+ BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
+ Bits[I / BITWORD_SIZE] |= PrefixMask;
+ I = RoundUpToAlignment(I, BITWORD_SIZE);
+
+ for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
+ Bits[I / BITWORD_SIZE] = ~0UL;
+
+ BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
+ Bits[I / BITWORD_SIZE] |= PostfixMask;
+
+ return *this;
+ }
+
BitVector &reset() {
init_words(Bits, Capacity, false);
return *this;
@@ -247,6 +275,34 @@ public:
return *this;
}
+ /// reset - Efficiently reset a range of bits in [I, E)
+ BitVector &reset(unsigned I, unsigned E) {
+ assert(I <= E && "Attempted to reset backwards range!");
+ assert(E <= size() && "Attempted to reset out-of-bounds range!");
+
+ if (I == E) return *this;
+
+ if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
+ BitWord EMask = 1UL << (E % BITWORD_SIZE);
+ BitWord IMask = 1UL << (I % BITWORD_SIZE);
+ BitWord Mask = EMask - IMask;
+ Bits[I / BITWORD_SIZE] &= ~Mask;
+ return *this;
+ }
+
+ BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
+ Bits[I / BITWORD_SIZE] &= ~PrefixMask;
+ I = RoundUpToAlignment(I, BITWORD_SIZE);
+
+ for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
+ Bits[I / BITWORD_SIZE] = 0UL;
+
+ BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
+ Bits[I / BITWORD_SIZE] &= ~PostfixMask;
+
+ return *this;
+ }
+
BitVector &flip() {
for (unsigned i = 0; i < NumBitWords(size()); ++i)
Bits[i] = ~Bits[i];
@@ -396,7 +452,7 @@ public:
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
const BitVector &operator=(BitVector &&RHS) {
if (this == &RHS) return *this;
diff --git a/include/llvm/ADT/DAGDeltaAlgorithm.h b/include/llvm/ADT/DAGDeltaAlgorithm.h
index e502ac4..3dd862c 100644
--- a/include/llvm/ADT/DAGDeltaAlgorithm.h
+++ b/include/llvm/ADT/DAGDeltaAlgorithm.h
@@ -9,8 +9,8 @@
#ifndef LLVM_ADT_DAGDELTAALGORITHM_H
#define LLVM_ADT_DAGDELTAALGORITHM_H
-#include <vector>
#include <set>
+#include <vector>
namespace llvm {
@@ -48,17 +48,18 @@ public:
public:
virtual ~DAGDeltaAlgorithm() {}
- /// Run - Minimize the DAG formed by the \arg Changes vertices and the \arg
- /// Dependencies edges by executing \see ExecuteOneTest() on subsets of
+ /// Run - Minimize the DAG formed by the \p Changes vertices and the
+ /// \p Dependencies edges by executing \see ExecuteOneTest() on subsets of
/// changes and returning the smallest set which still satisfies the test
- /// predicate and the input \arg Dependencies.
+ /// predicate and the input \p Dependencies.
///
/// \param Changes The list of changes.
///
/// \param Dependencies The list of dependencies amongst changes. For each
- /// (x,y) in \arg Dependencies, both x and y must be in \arg Changes. The
- /// minimization algorithm guarantees that for each tested changed set S, x
- /// \in S implies y \in S. It is an error to have cyclic dependencies.
+ /// (x,y) in \p Dependencies, both x and y must be in \p Changes. The
+ /// minimization algorithm guarantees that for each tested changed set S,
+ /// \f$ x \in S \f$ implies \f$ y \in S \f$. It is an error to have cyclic
+ /// dependencies.
changeset_ty Run(const changeset_ty &Changes,
const std::vector<edge_ty> &Dependencies);
@@ -67,7 +68,7 @@ public:
const changesetlist_ty &Sets,
const changeset_ty &Required) {}
- /// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
+ /// ExecuteOneTest - Execute a single test predicate on the change set \p S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
};
diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h
index 45ba198..4d07e04 100644
--- a/include/llvm/ADT/DeltaAlgorithm.h
+++ b/include/llvm/ADT/DeltaAlgorithm.h
@@ -9,8 +9,8 @@
#ifndef LLVM_ADT_DELTAALGORITHM_H
#define LLVM_ADT_DELTAALGORITHM_H
-#include <vector>
#include <set>
+#include <vector>
namespace llvm {
@@ -45,23 +45,23 @@ private:
/// since we always reduce following a success.
std::set<changeset_ty> FailedTestsCache;
- /// GetTestResult - Get the test result for the \arg Changes from the
+ /// GetTestResult - Get the test result for the \p Changes from the
/// cache, executing the test if necessary.
///
/// \param Changes - The change set to test.
/// \return - The test result.
bool GetTestResult(const changeset_ty &Changes);
- /// Split - Partition a set of changes \arg S into one or two subsets.
+ /// Split - Partition a set of changes \p S into one or two subsets.
void Split(const changeset_ty &S, changesetlist_ty &Res);
- /// Delta - Minimize a set of \arg Changes which has been partioned into
+ /// Delta - Minimize a set of \p Changes which has been partioned into
/// smaller sets, by attempting to remove individual subsets.
changeset_ty Delta(const changeset_ty &Changes,
const changesetlist_ty &Sets);
- /// Search - Search for a subset (or subsets) in \arg Sets which can be
- /// removed from \arg Changes while still satisfying the predicate.
+ /// Search - Search for a subset (or subsets) in \p Sets which can be
+ /// removed from \p Changes while still satisfying the predicate.
///
/// \param Res - On success, a subset of Changes which satisfies the
/// predicate.
@@ -74,13 +74,13 @@ protected:
virtual void UpdatedSearchState(const changeset_ty &Changes,
const changesetlist_ty &Sets) {}
- /// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
+ /// ExecuteOneTest - Execute a single test predicate on the change set \p S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
public:
virtual ~DeltaAlgorithm();
- /// Run - Minimize the set \arg Changes by executing \see ExecuteOneTest() on
+ /// Run - Minimize the set \p Changes by executing \see ExecuteOneTest() on
/// subsets of changes and returning the smallest set which still satisfies
/// the test predicate.
changeset_ty Run(const changeset_ty &Changes);
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index f60d688..01f7e90 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -14,20 +14,20 @@
#ifndef LLVM_ADT_DENSEMAP_H
#define LLVM_ADT_DENSEMAP_H
-#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
-#include "llvm/ADT/DenseMapInfo.h"
#include <algorithm>
-#include <iterator>
-#include <new>
-#include <utility>
#include <cassert>
#include <climits>
#include <cstddef>
#include <cstring>
+#include <iterator>
+#include <new>
+#include <utility>
namespace llvm {
@@ -75,7 +75,7 @@ public:
void clear() {
if (getNumEntries() == 0 && getNumTombstones() == 0) return;
-
+
// If the capacity of the array is huge, and the # elements used is small,
// shrink the array.
if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
@@ -198,7 +198,7 @@ public:
return FindAndConstruct(Key).second;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
value_type& FindAndConstruct(KeyT &&Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
@@ -383,7 +383,7 @@ private:
return TheBucket;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
BucketT *TheBucket) {
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
@@ -420,16 +420,18 @@ private:
NumBuckets = getNumBuckets();
}
if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) {
- this->grow(NumBuckets);
+ this->grow(NumBuckets * 2);
LookupBucketFor(Key, TheBucket);
}
+ assert(TheBucket);
// Only update the state after we've grown our bucket space appropriately
// so that when growing buckets we have self-consistent entry count.
incrementNumEntries();
// If we are writing over a tombstone, remember this.
- if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
+ const KeyT EmptyKey = getEmptyKey();
+ if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey))
decrementNumTombstones();
return TheBucket;
@@ -530,13 +532,13 @@ public:
init(NumInitBuckets);
}
- DenseMap(const DenseMap &other) {
+ DenseMap(const DenseMap &other) : BaseT() {
init(0);
copyFrom(other);
}
-#if LLVM_USE_RVALUE_REFERENCES
- DenseMap(DenseMap &&other) {
+#if LLVM_HAS_RVALUE_REFERENCES
+ DenseMap(DenseMap &&other) : BaseT() {
init(0);
swap(other);
}
@@ -565,7 +567,7 @@ public:
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
DenseMap& operator=(DenseMap &&other) {
this->destroyAll();
operator delete(Buckets);
@@ -599,7 +601,7 @@ public:
unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets;
- allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast)));
+ allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast-1)));
assert(Buckets);
if (!OldBuckets) {
this->BaseT::initEmpty();
@@ -699,7 +701,7 @@ public:
copyFrom(other);
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap(SmallDenseMap &&other) {
init(0);
swap(other);
@@ -794,7 +796,7 @@ public:
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap& operator=(SmallDenseMap &&other) {
this->destroyAll();
deallocateBuckets();
@@ -825,11 +827,11 @@ public:
}
void grow(unsigned AtLeast) {
- if (AtLeast > InlineBuckets)
- AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast));
+ if (AtLeast >= InlineBuckets)
+ AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
if (Small) {
- if (AtLeast <= InlineBuckets)
+ if (AtLeast < InlineBuckets)
return; // Nothing to do.
// First move the inline buckets into a temporary storage.
@@ -1026,7 +1028,7 @@ private:
++Ptr;
}
};
-
+
template<typename KeyT, typename ValueT, typename KeyInfoT>
static inline size_t
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index 8ab9a33..d699ad5 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -32,8 +32,10 @@ public:
bool empty() const { return TheMap.empty(); }
unsigned size() const { return TheMap.size(); }
+ size_t getMemorySize() const { return TheMap.getMemorySize(); }
- /// Grow the denseset so that it has at least Size buckets. Does not shrink
+ /// Grow the DenseSet so that it has at least Size buckets. Will not shrink
+ /// the Size of the set.
void resize(size_t Size) { TheMap.resize(Size); }
void clear() {
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index 519b180..6445442 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -34,8 +34,8 @@
#define LLVM_ADT_DEPTHFIRSTITERATOR_H
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include <set>
#include <vector>
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
index 771476c..1d81772 100644
--- a/include/llvm/ADT/EquivalenceClasses.h
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -33,6 +33,7 @@ namespace llvm {
///
/// Here is a simple example using integers:
///
+/// \code
/// EquivalenceClasses<int> EC;
/// EC.unionSets(1, 2); // insert 1, 2 into the same set
/// EC.insert(4); EC.insert(5); // insert 4, 5 into own sets
@@ -46,6 +47,7 @@ namespace llvm {
/// cerr << *MI << " "; // Print member.
/// cerr << "\n"; // Finish set.
/// }
+/// \endcode
///
/// This example prints:
/// 4
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 375d84a..91794de 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -16,9 +16,9 @@
#ifndef LLVM_ADT_FOLDINGSET_H
#define LLVM_ADT_FOLDINGSET_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class APFloat;
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index 2363304..cda31a2 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -710,7 +710,7 @@ hash_code hash_combine(const T1 &arg1) {
#endif
-// Implementation details for implementatinos of hash_value overloads provided
+// Implementation details for implementations of hash_value overloads provided
// here.
namespace hashing {
namespace detail {
diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h
index d7c0074..998d785 100644
--- a/include/llvm/ADT/ImmutableList.h
+++ b/include/llvm/ADT/ImmutableList.h
@@ -14,8 +14,8 @@
#ifndef LLVM_ADT_IMLIST_H
#define LLVM_ADT_IMLIST_H
-#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
@@ -33,9 +33,8 @@ class ImmutableListImpl : public FoldingSetNode {
friend class ImmutableListFactory<T>;
- // Do not implement.
- void operator=(const ImmutableListImpl&);
- ImmutableListImpl(const ImmutableListImpl&);
+ void operator=(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
+ ImmutableListImpl(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
public:
const T& getHead() const { return Head; }
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index 8346ffa..f9baec2 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -122,8 +122,8 @@ public:
}
private:
- Factory(const Factory& RHS); // DO NOT IMPLEMENT
- void operator=(const Factory& RHS); // DO NOT IMPLEMENT
+ Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
+ void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
};
bool contains(key_type_ref K) const {
@@ -288,6 +288,13 @@ public:
Factory(F) {
if (Root) { Root->retain(); }
}
+
+ explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X,
+ typename ImmutableMap<KeyT, ValT>::Factory &F)
+ : Root(X.getRootWithoutRetain()),
+ Factory(F.getTreeFactory()) {
+ if (Root) { Root->retain(); }
+ }
ImmutableMapRef(const ImmutableMapRef &X)
: Root(X.Root),
@@ -318,12 +325,20 @@ public:
return ImmutableMapRef(0, F);
}
- ImmutableMapRef add(key_type_ref K, data_type_ref D) {
+ void manualRetain() {
+ if (Root) Root->retain();
+ }
+
+ void manualRelease() {
+ if (Root) Root->release();
+ }
+
+ ImmutableMapRef add(key_type_ref K, data_type_ref D) const {
TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
return ImmutableMapRef(NewT, Factory);
}
- ImmutableMapRef remove(key_type_ref K) {
+ ImmutableMapRef remove(key_type_ref K) const {
TreeTy *NewT = Factory->remove(Root, K);
return ImmutableMapRef(NewT, Factory);
}
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 949dc44..0982657 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -14,15 +14,14 @@
#ifndef LLVM_ADT_IMSET_H
#define LLVM_ADT_IMSET_H
-#include "llvm/Support/Allocator.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <functional>
#include <vector>
-#include <stdio.h>
namespace llvm {
@@ -84,13 +83,13 @@ public:
}
return NULL;
}
-
+
/// getMaxElement - Find the subtree associated with the highest ranged
/// key value.
ImutAVLTree* getMaxElement() {
ImutAVLTree *T = this;
- ImutAVLTree *Right = T->getRight();
- while (Right) { T = right; right = T->getRight(); }
+ ImutAVLTree *Right = T->getRight();
+ while (Right) { T = Right; Right = T->getRight(); }
return T;
}
@@ -258,7 +257,7 @@ private:
/// method returns false for an instance of ImutAVLTree, all subtrees
/// will also have this method return false. The converse is not true.
bool isMutable() const { return IsMutable; }
-
+
/// hasCachedDigest - Returns true if the digest for this tree is cached.
/// This can only be true if the tree is immutable.
bool hasCachedDigest() const { return IsDigestCached; }
@@ -280,7 +279,7 @@ private:
assert(isMutable() && "Mutable flag already removed.");
IsMutable = false;
}
-
+
/// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
void markedCachedDigest() {
assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
@@ -349,7 +348,7 @@ public:
else
factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
}
-
+
// We need to clear the mutability bit in case we are
// destroying the node as part of a sweep in ImutAVLFactory::recoverNodes().
IsMutable = false;
@@ -415,7 +414,7 @@ public:
TreeTy* getEmptyTree() const { return NULL; }
protected:
-
+
//===--------------------------------------------------===//
// A bunch of quick helper functions used for reasoning
// about the properties of trees and their children.
@@ -461,7 +460,7 @@ protected:
// returned to the caller.
//===--------------------------------------------------===//
- TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
+ TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
BumpPtrAllocator& A = getAllocator();
TreeTy* T;
if (!freeNodes.empty()) {
@@ -469,8 +468,7 @@ protected:
freeNodes.pop_back();
assert(T != L);
assert(T != R);
- }
- else {
+ } else {
T = (TreeTy*) A.Allocate<TreeTy>();
}
new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
@@ -513,7 +511,8 @@ protected:
return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
}
- else if (hr > hl + 2) {
+
+ if (hr > hl + 2) {
assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
TreeTy *RL = getLeft(R);
@@ -529,8 +528,8 @@ protected:
return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
}
- else
- return createNode(L,V,R);
+
+ return createNode(L,V,R);
}
/// add_internal - Creates a new tree that includes the specified
@@ -604,7 +603,7 @@ protected:
markImmutable(getLeft(T));
markImmutable(getRight(T));
}
-
+
public:
TreeTy *getCanonicalTree(TreeTy *TNew) {
if (!TNew)
@@ -937,7 +936,7 @@ public:
private:
TreeTy *Root;
-
+
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
@@ -1006,10 +1005,10 @@ public:
typename TreeTy::Factory *getTreeFactory() const {
return const_cast<typename TreeTy::Factory *>(&F);
}
-
+
private:
- Factory(const Factory& RHS); // DO NOT IMPLEMENT
- void operator=(const Factory& RHS); // DO NOT IMPLEMENT
+ Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
+ void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
};
friend class Factory;
@@ -1027,11 +1026,11 @@ public:
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
- TreeTy *getRoot() {
+ TreeTy *getRoot() {
if (Root) { Root->retain(); }
return Root;
}
-
+
TreeTy *getRootWithoutRetain() const {
return Root;
}
@@ -1092,7 +1091,7 @@ public:
void validateTree() const { if (Root) Root->validateTree(); }
};
-
+
// NOTE: This may some day replace the current ImmutableSet.
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
class ImmutableSetRef {
@@ -1101,11 +1100,11 @@ public:
typedef typename ValInfo::value_type_ref value_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy;
typedef typename TreeTy::Factory FactoryTy;
-
+
private:
TreeTy *Root;
FactoryTy *Factory;
-
+
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
@@ -1133,44 +1132,44 @@ public:
~ImmutableSetRef() {
if (Root) { Root->release(); }
}
-
+
static inline ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
}
-
+
ImmutableSetRef add(value_type_ref V) {
return ImmutableSetRef(Factory->add(Root, V), Factory);
}
-
+
ImmutableSetRef remove(value_type_ref V) {
return ImmutableSetRef(Factory->remove(Root, V), Factory);
}
-
+
/// Returns true if the set contains the specified value.
bool contains(value_type_ref V) const {
return Root ? Root->contains(V) : false;
}
-
+
ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
return ImmutableSet<ValT>(canonicalize ?
Factory->getCanonicalTree(Root) : Root);
}
-
+
TreeTy *getRootWithoutRetain() const {
return Root;
}
-
+
bool operator==(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
-
+
bool operator!=(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
-
+
/// isSingleton - Return true if the set contains exactly one element.
/// This method runs in constant time.
bool isSingleton() const { return getHeight() == 1; }
@@ -1178,7 +1177,7 @@ public:
//===--------------------------------------------------===//
// Iterators.
//===--------------------------------------------------===//
-
+
class iterator {
typename TreeTy::iterator itr;
iterator(TreeTy* t) : itr(t) {}
@@ -1194,28 +1193,28 @@ public:
inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
inline value_type *operator->() const { return &(operator*()); }
};
-
+
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
-
+
//===--------------------------------------------------===//
// Utility methods.
//===--------------------------------------------------===//
-
+
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
-
+
static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) {
ID.AddPointer(S.Root);
}
-
+
inline void Profile(FoldingSetNodeID& ID) const {
return Profile(ID,*this);
}
-
+
//===--------------------------------------------------===//
// For testing.
//===--------------------------------------------------===//
-
+
void validateTree() const { if (Root) Root->validateTree(); }
};
diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h
index 931b67e..c4083ee 100644
--- a/include/llvm/ADT/IntervalMap.h
+++ b/include/llvm/ADT/IntervalMap.h
@@ -99,8 +99,8 @@
#ifndef LLVM_ADT_INTERVALMAP_H
#define LLVM_ADT_INTERVALMAP_H
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/RecyclingAllocator.h"
#include <iterator>
@@ -151,6 +151,26 @@ struct IntervalMapInfo {
};
+template <typename T>
+struct IntervalMapHalfOpenInfo {
+
+ /// startLess - Return true if x is not in [a;b).
+ static inline bool startLess(const T &x, const T &a) {
+ return x < a;
+ }
+
+ /// stopLess - Return true if x is not in [a;b).
+ static inline bool stopLess(const T &b, const T &x) {
+ return b <= x;
+ }
+
+ /// adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
+ static inline bool adjacent(const T &a, const T &b) {
+ return a == b;
+ }
+
+};
+
/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
/// It should be considered private to the implementation.
namespace IntervalMapImpl {
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index a9724ee..5849503 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -123,7 +123,7 @@ namespace llvm {
retain();
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
S.Obj = 0;
}
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
new file mode 100644
index 0000000..c34e32a
--- /dev/null
+++ b/include/llvm/ADT/MapVector.h
@@ -0,0 +1,107 @@
+//===- llvm/ADT/MapVector.h - Map with deterministic value order *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a map that provides insertion order iteration. The
+// interface is purposefully minimal. The key is assumed to be cheap to copy
+// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
+// a std::vector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_MAPVECTOR_H
+#define LLVM_ADT_MAPVECTOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+
+namespace llvm {
+
+/// This class implements a map that also provides access to all stored values
+/// in a deterministic order. The values are kept in a std::vector and the
+/// mapping is done with DenseMap from Keys to indexes in that vector.
+template<typename KeyT, typename ValueT,
+ typename MapType = llvm::DenseMap<KeyT, unsigned>,
+ typename VectorType = std::vector<std::pair<KeyT, ValueT> > >
+class MapVector {
+ typedef typename VectorType::size_type SizeType;
+
+ MapType Map;
+ VectorType Vector;
+
+public:
+ typedef typename VectorType::iterator iterator;
+ typedef typename VectorType::const_iterator const_iterator;
+
+ SizeType size() const {
+ return Vector.size();
+ }
+
+ iterator begin() {
+ return Vector.begin();
+ }
+
+ const_iterator begin() const {
+ return Vector.begin();
+ }
+
+ iterator end() {
+ return Vector.end();
+ }
+
+ const_iterator end() const {
+ return Vector.end();
+ }
+
+ bool empty() const {
+ return Vector.empty();
+ }
+
+ void clear() {
+ Map.clear();
+ Vector.clear();
+ }
+
+ ValueT &operator[](const KeyT &Key) {
+ std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
+ std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
+ unsigned &I = Result.first->second;
+ if (Result.second) {
+ Vector.push_back(std::make_pair(Key, ValueT()));
+ I = Vector.size() - 1;
+ }
+ return Vector[I].second;
+ }
+
+ ValueT lookup(const KeyT &Key) const {
+ typename MapType::const_iterator Pos = Map.find(Key);
+ return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
+ }
+
+ unsigned count(const KeyT &Key) const {
+ typename MapType::const_iterator Pos = Map.find(Key);
+ return Pos == Map.end()? 0 : 1;
+ }
+
+ iterator find(const KeyT &Key) {
+ typename MapType::const_iterator Pos = Map.find(Key);
+ return Pos == Map.end()? Vector.end() :
+ (Vector.begin() + Pos->second);
+ }
+
+ const_iterator find(const KeyT &Key) const {
+ typename MapType::const_iterator Pos = Map.find(Key);
+ return Pos == Map.end()? Vector.end() :
+ (Vector.begin() + Pos->second);
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index ee8b69f..06e5af0 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -16,18 +16,27 @@
#ifndef LLVM_ADT_OPTIONAL
#define LLVM_ADT_OPTIONAL
+#include "llvm/Support/Compiler.h"
#include <cassert>
+#if LLVM_HAS_RVALUE_REFERENCES
+#include <utility>
+#endif
+
namespace llvm {
template<typename T>
class Optional {
T x;
- unsigned hasVal : 1;
+ bool hasVal;
public:
explicit Optional() : x(), hasVal(false) {}
Optional(const T &y) : x(y), hasVal(true) {}
+#if LLVM_HAS_RVALUE_REFERENCES
+ Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
+#endif
+
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}
@@ -39,12 +48,17 @@ public:
}
const T* getPointer() const { assert(hasVal); return &x; }
- const T& getValue() const { assert(hasVal); return x; }
+ const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; }
operator bool() const { return hasVal; }
bool hasValue() const { return hasVal; }
const T* operator->() const { return getPointer(); }
- const T& operator*() const { assert(hasVal); return x; }
+ const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; }
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ T&& getValue() && { assert(hasVal); return std::move(x); }
+ T&& operator*() && { assert(hasVal); return std::move(x); }
+#endif
};
template<typename T> struct simplify_type;
diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h
index 6d9c305..ea22991 100644
--- a/include/llvm/ADT/OwningPtr.h
+++ b/include/llvm/ADT/OwningPtr.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ADT_OWNING_PTR_H
#define LLVM_ADT_OWNING_PTR_H
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
@@ -25,12 +26,21 @@ namespace llvm {
/// pointee object can be taken away from OwningPtr by using the take method.
template<class T>
class OwningPtr {
- OwningPtr(OwningPtr const &); // DO NOT IMPLEMENT
- OwningPtr &operator=(OwningPtr const &); // DO NOT IMPLEMENT
+ OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
+ OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
T *Ptr;
public:
explicit OwningPtr(T *P = 0) : Ptr(P) {}
+#if LLVM_HAS_RVALUE_REFERENCES
+ OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
+
+ OwningPtr &operator=(OwningPtr &&Other) {
+ reset(Other.take());
+ return *this;
+ }
+#endif
+
~OwningPtr() {
delete Ptr;
}
@@ -79,12 +89,21 @@ inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
/// functionality as OwningPtr, except that it works for array types.
template<class T>
class OwningArrayPtr {
- OwningArrayPtr(OwningArrayPtr const &); // DO NOT IMPLEMENT
- OwningArrayPtr &operator=(OwningArrayPtr const &); // DO NOT IMPLEMENT
+ OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
+ OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
T *Ptr;
public:
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
+#if LLVM_HAS_RVALUE_REFERENCES
+ OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
+
+ OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
+ reset(Other.take());
+ return *this;
+ }
+#endif
+
~OwningArrayPtr() {
delete [] Ptr;
}
diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h
index 2eaddc2..1ae2a77 100644
--- a/include/llvm/ADT/PackedVector.h
+++ b/include/llvm/ADT/PackedVector.h
@@ -19,32 +19,32 @@
namespace llvm {
-template <typename T, unsigned BitNum, bool isSigned>
+template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
class PackedVectorBase;
// This won't be necessary if we can specialize members without specializing
// the parent template.
-template <typename T, unsigned BitNum>
-class PackedVectorBase<T, BitNum, false> {
+template <typename T, unsigned BitNum, typename BitVectorTy>
+class PackedVectorBase<T, BitNum, BitVectorTy, false> {
protected:
- static T getValue(const llvm::BitVector &Bits, unsigned Idx) {
+ static T getValue(const BitVectorTy &Bits, unsigned Idx) {
T val = T();
for (unsigned i = 0; i != BitNum; ++i)
val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
return val;
}
- static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) {
+ static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
assert((val >> BitNum) == 0 && "value is too big");
for (unsigned i = 0; i != BitNum; ++i)
Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
}
};
-template <typename T, unsigned BitNum>
-class PackedVectorBase<T, BitNum, true> {
+template <typename T, unsigned BitNum, typename BitVectorTy>
+class PackedVectorBase<T, BitNum, BitVectorTy, true> {
protected:
- static T getValue(const llvm::BitVector &Bits, unsigned Idx) {
+ static T getValue(const BitVectorTy &Bits, unsigned Idx) {
T val = T();
for (unsigned i = 0; i != BitNum-1; ++i)
val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
@@ -53,7 +53,7 @@ protected:
return val;
}
- static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) {
+ static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
if (val < 0) {
val = ~val;
Bits.set((Idx << (BitNum-1)) + BitNum-1);
@@ -71,11 +71,12 @@ protected:
/// @endcode
/// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
/// an assertion.
-template <typename T, unsigned BitNum>
-class PackedVector : public PackedVectorBase<T, BitNum,
+template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
+class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> {
- llvm::BitVector Bits;
- typedef PackedVectorBase<T, BitNum, std::numeric_limits<T>::is_signed> base;
+ BitVectorTy Bits;
+ typedef PackedVectorBase<T, BitNum, BitVectorTy,
+ std::numeric_limits<T>::is_signed> base;
public:
class reference {
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index 71c379b..cce2efb 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -57,11 +57,13 @@ class PointerIntPair {
};
public:
PointerIntPair() : Value(0) {}
- PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
+ PointerIntPair(PointerTy Ptr, IntType Int) {
assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
"PointerIntPair formed with integer size too large for pointer");
- setPointer(Ptr);
- setInt(Int);
+ setPointerAndInt(Ptr, Int);
+ }
+ explicit PointerIntPair(PointerTy Ptr) {
+ initWithPointer(Ptr);
}
PointerTy getPointer() const {
@@ -91,6 +93,25 @@ public:
Value |= IntVal << IntShift; // Set new integer.
}
+ void initWithPointer(PointerTy Ptr) {
+ intptr_t PtrVal
+ = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
+ assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ "Pointer is not sufficiently aligned");
+ Value = PtrVal;
+ }
+
+ void setPointerAndInt(PointerTy Ptr, IntType Int) {
+ intptr_t PtrVal
+ = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
+ assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ "Pointer is not sufficiently aligned");
+ intptr_t IntVal = Int;
+ assert(IntVal < (1 << IntBits) && "Integer too large for field");
+
+ Value = PtrVal | (IntVal << IntShift);
+ }
+
PointerTy const *getAddrOfPointer() const {
return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
}
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index a9e86d2..f42515a 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -95,15 +95,11 @@ namespace llvm {
public:
PointerUnion() {}
- PointerUnion(PT1 V) {
- Val.setPointer(
- const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
- Val.setInt(0);
+ PointerUnion(PT1 V) : Val(
+ const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
}
- PointerUnion(PT2 V) {
- Val.setPointer(
- const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
- Val.setInt(1);
+ PointerUnion(PT2 V) : Val(
+ const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
}
/// isNull - Return true if the pointer held in the union is null,
@@ -160,15 +156,14 @@ namespace llvm {
/// Assignment operators - Allow assigning into this union from either
/// pointer type, setting the discriminator to remember what it came from.
const PointerUnion &operator=(const PT1 &RHS) {
- Val.setPointer(
+ Val.initWithPointer(
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
- Val.setInt(0);
return *this;
}
const PointerUnion &operator=(const PT2 &RHS) {
- Val.setPointer(
- const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)));
- Val.setInt(1);
+ Val.setPointerAndInt(
+ const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
+ 1);
return *this;
}
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
index 48436c6..8ce4fd5 100644
--- a/include/llvm/ADT/SCCIterator.h
+++ b/include/llvm/ADT/SCCIterator.h
@@ -21,8 +21,8 @@
#ifndef LLVM_ADT_SCCITERATOR_H
#define LLVM_ADT_SCCITERATOR_H
-#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
#include <vector>
namespace llvm {
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index aee500d..dacda36 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -246,10 +246,10 @@ inline int array_pod_sort_comparator(const void *P1, const void *P2) {
return 0;
}
-/// get_array_pad_sort_comparator - This is an internal helper function used to
+/// get_array_pod_sort_comparator - This is an internal helper function used to
/// get type deduction of T right.
template<typename T>
-inline int (*get_array_pad_sort_comparator(const T &))
+inline int (*get_array_pod_sort_comparator(const T &))
(const void*, const void*) {
return array_pod_sort_comparator<T>;
}
@@ -274,7 +274,7 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
// Don't dereference start iterator of empty sequence.
if (Start == End) return;
qsort(&*Start, End-Start, sizeof(*Start),
- get_array_pad_sort_comparator(*Start));
+ get_array_pod_sort_comparator(*Start));
}
template<class IteratorTy>
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
index a6803ee..efddd9f 100644
--- a/include/llvm/ADT/ScopedHashTable.h
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -90,8 +90,8 @@ class ScopedHashTableScope {
/// LastValInScope - This is the last value that was inserted for this scope
/// or null if none have been inserted yet.
ScopedHashTableVal<K, V> *LastValInScope;
- void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
- ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
+ void operator=(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
+ ScopedHashTableScope(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
public:
ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
~ScopedHashTableScope();
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
index 965f0de..d2f7286 100644
--- a/include/llvm/ADT/SetVector.h
+++ b/include/llvm/ADT/SetVector.h
@@ -27,10 +27,11 @@
namespace llvm {
+/// \brief A vector that has set insertion semantics.
+///
/// This adapter class provides a way to keep a set of things that also has the
/// property of a deterministic iteration order. The order of iteration is the
/// order of insertion.
-/// @brief A vector that has set insertion semantics.
template <typename T, typename Vector = std::vector<T>,
typename Set = SmallSet<T, 16> >
class SetVector {
@@ -45,59 +46,59 @@ public:
typedef typename vector_type::const_iterator const_iterator;
typedef typename vector_type::size_type size_type;
- /// @brief Construct an empty SetVector
+ /// \brief Construct an empty SetVector
SetVector() {}
- /// @brief Initialize a SetVector with a range of elements
+ /// \brief Initialize a SetVector with a range of elements
template<typename It>
SetVector(It Start, It End) {
insert(Start, End);
}
- /// @brief Determine if the SetVector is empty or not.
+ /// \brief Determine if the SetVector is empty or not.
bool empty() const {
return vector_.empty();
}
- /// @brief Determine the number of elements in the SetVector.
+ /// \brief Determine the number of elements in the SetVector.
size_type size() const {
return vector_.size();
}
- /// @brief Get an iterator to the beginning of the SetVector.
+ /// \brief Get an iterator to the beginning of the SetVector.
iterator begin() {
return vector_.begin();
}
- /// @brief Get a const_iterator to the beginning of the SetVector.
+ /// \brief Get a const_iterator to the beginning of the SetVector.
const_iterator begin() const {
return vector_.begin();
}
- /// @brief Get an iterator to the end of the SetVector.
+ /// \brief Get an iterator to the end of the SetVector.
iterator end() {
return vector_.end();
}
- /// @brief Get a const_iterator to the end of the SetVector.
+ /// \brief Get a const_iterator to the end of the SetVector.
const_iterator end() const {
return vector_.end();
}
- /// @brief Return the last element of the SetVector.
+ /// \brief Return the last element of the SetVector.
const T &back() const {
assert(!empty() && "Cannot call back() on empty SetVector!");
return vector_.back();
}
- /// @brief Index into the SetVector.
+ /// \brief Index into the SetVector.
const_reference operator[](size_type n) const {
assert(n < vector_.size() && "SetVector access out of range!");
return vector_[n];
}
- /// @returns true iff the element was inserted into the SetVector.
- /// @brief Insert a new element into the SetVector.
+ /// \brief Insert a new element into the SetVector.
+ /// \returns true iff the element was inserted into the SetVector.
bool insert(const value_type &X) {
bool result = set_.insert(X);
if (result)
@@ -105,7 +106,7 @@ public:
return result;
}
- /// @brief Insert a range of elements into the SetVector.
+ /// \brief Insert a range of elements into the SetVector.
template<typename It>
void insert(It Start, It End) {
for (; Start != End; ++Start)
@@ -113,7 +114,7 @@ public:
vector_.push_back(*Start);
}
- /// @brief Remove an item from the set vector.
+ /// \brief Remove an item from the set vector.
bool remove(const value_type& X) {
if (set_.erase(X)) {
typename vector_type::iterator I =
@@ -125,20 +126,44 @@ public:
return false;
}
-
- /// @returns 0 if the element is not in the SetVector, 1 if it is.
- /// @brief Count the number of elements of a given key in the SetVector.
+ /// \brief Remove items from the set vector based on a predicate function.
+ ///
+ /// This is intended to be equivalent to the following code, if we could
+ /// write it:
+ ///
+ /// \code
+ /// V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
+ /// \endcode
+ ///
+ /// However, SetVector doesn't expose non-const iterators, making any
+ /// algorithm like remove_if impossible to use.
+ ///
+ /// \returns true if any element is removed.
+ template <typename UnaryPredicate>
+ bool remove_if(UnaryPredicate P) {
+ typename vector_type::iterator I
+ = std::remove_if(vector_.begin(), vector_.end(),
+ TestAndEraseFromSet<UnaryPredicate>(P, set_));
+ if (I == vector_.end())
+ return false;
+ vector_.erase(I, vector_.end());
+ return true;
+ }
+
+
+ /// \brief Count the number of elements of a given key in the SetVector.
+ /// \returns 0 if the element is not in the SetVector, 1 if it is.
size_type count(const key_type &key) const {
return set_.count(key);
}
- /// @brief Completely clear the SetVector
+ /// \brief Completely clear the SetVector
void clear() {
set_.clear();
vector_.clear();
}
- /// @brief Remove the last element of the SetVector.
+ /// \brief Remove the last element of the SetVector.
void pop_back() {
assert(!empty() && "Cannot remove an element from an empty SetVector!");
set_.erase(back());
@@ -160,18 +185,41 @@ public:
}
private:
+ /// \brief A wrapper predicate designed for use with std::remove_if.
+ ///
+ /// This predicate wraps a predicate suitable for use with std::remove_if to
+ /// call set_.erase(x) on each element which is slated for removal.
+ template <typename UnaryPredicate>
+ class TestAndEraseFromSet {
+ UnaryPredicate P;
+ set_type &set_;
+
+ public:
+ typedef typename UnaryPredicate::argument_type argument_type;
+
+ TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
+
+ bool operator()(argument_type Arg) {
+ if (P(Arg)) {
+ set_.erase(Arg);
+ return true;
+ }
+ return false;
+ }
+ };
+
set_type set_; ///< The set.
vector_type vector_; ///< The vector.
};
-/// SmallSetVector - A SetVector that performs no allocations if smaller than
+/// \brief A SetVector that performs no allocations if smaller than
/// a certain size.
template <typename T, unsigned N>
class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
public:
SmallSetVector() {}
- /// @brief Initialize a SmallSetVector with a range of elements
+ /// \brief Initialize a SmallSetVector with a range of elements
template<typename It>
SmallSetVector(It Start, It End) {
this->insert(Start, End);
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index 7a645e0..62620fa 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -153,7 +153,7 @@ public:
switchToLarge(new BitVector(*RHS.getPointer()));
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
RHS.X = 1;
}
@@ -300,6 +300,21 @@ public:
return *this;
}
+ /// set - Efficiently set a range of bits in [I, E)
+ SmallBitVector &set(unsigned I, unsigned E) {
+ assert(I <= E && "Attempted to set backwards range!");
+ assert(E <= size() && "Attempted to set out-of-bounds range!");
+ if (I == E) return *this;
+ if (isSmall()) {
+ uintptr_t EMask = ((uintptr_t)1) << E;
+ uintptr_t IMask = ((uintptr_t)1) << I;
+ uintptr_t Mask = EMask - IMask;
+ setSmallBits(getSmallBits() | Mask);
+ } else
+ getPointer()->set(I, E);
+ return *this;
+ }
+
SmallBitVector &reset() {
if (isSmall())
setSmallBits(0);
@@ -316,6 +331,21 @@ public:
return *this;
}
+ /// reset - Efficiently reset a range of bits in [I, E)
+ SmallBitVector &reset(unsigned I, unsigned E) {
+ assert(I <= E && "Attempted to reset backwards range!");
+ assert(E <= size() && "Attempted to reset out-of-bounds range!");
+ if (I == E) return *this;
+ if (isSmall()) {
+ uintptr_t EMask = ((uintptr_t)1) << E;
+ uintptr_t IMask = ((uintptr_t)1) << I;
+ uintptr_t Mask = EMask - IMask;
+ setSmallBits(getSmallBits() & ~Mask);
+ } else
+ getPointer()->reset(I, E);
+ return *this;
+ }
+
SmallBitVector &flip() {
if (isSmall())
setSmallBits(~getSmallBits());
@@ -442,7 +472,7 @@ public:
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
const SmallBitVector &operator=(SmallBitVector &&RHS) {
if (this != &RHS) {
clear();
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index 498a034..3bb8830 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -15,12 +15,13 @@
#ifndef LLVM_ADT_SMALLPTRSET_H
#define LLVM_ADT_SMALLPTRSET_H
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iterator>
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/PointerLikeTypeTraits.h"
namespace llvm {
@@ -132,7 +133,7 @@ private:
/// Grow - Allocate a larger backing store for the buckets and move it over.
void Grow(unsigned NewSize);
- void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
+ void operator=(const SmallPtrSetImpl &RHS) LLVM_DELETED_FUNCTION;
protected:
/// swap - Swaps the elements of two sets.
/// Note: This method assumes that both sets have the same small size.
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index cd117f5..4eb7de8 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -14,8 +14,8 @@
#ifndef LLVM_ADT_SMALLSET_H
#define LLVM_ADT_SMALLSET_H
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include <set>
namespace llvm {
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
index c6f0a5b..8da99d1 100644
--- a/include/llvm/ADT/SmallString.h
+++ b/include/llvm/ADT/SmallString.h
@@ -44,25 +44,25 @@ public:
/// @name String Assignment
/// @{
- /// Assign from a repeated element
+ /// Assign from a repeated element.
void assign(size_t NumElts, char Elt) {
this->SmallVectorImpl<char>::assign(NumElts, Elt);
}
- /// Assign from an iterator pair
+ /// Assign from an iterator pair.
template<typename in_iter>
void assign(in_iter S, in_iter E) {
this->clear();
SmallVectorImpl<char>::append(S, E);
}
- /// Assign from a StringRef
+ /// Assign from a StringRef.
void assign(StringRef RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
- /// Assign from a SmallVector
+ /// Assign from a SmallVector.
void assign(const SmallVectorImpl<char> &RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
@@ -72,7 +72,7 @@ public:
/// @name String Concatenation
/// @{
- /// Append from an iterator pair
+ /// Append from an iterator pair.
template<typename in_iter>
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
@@ -83,12 +83,12 @@ public:
}
- /// Append from a StringRef
+ /// Append from a StringRef.
void append(StringRef RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
- /// Append from a SmallVector
+ /// Append from a SmallVector.
void append(const SmallVectorImpl<char> &RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
@@ -97,19 +97,19 @@ public:
/// @name String Comparison
/// @{
- /// equals - Check for string equality, this is more efficient than
- /// compare() when the relative ordering of inequal strings isn't needed.
+ /// Check for string equality. This is more efficient than compare() when
+ /// the relative ordering of inequal strings isn't needed.
bool equals(StringRef RHS) const {
return str().equals(RHS);
}
- /// equals_lower - Check for string equality, ignoring case.
+ /// Check for string equality, ignoring case.
bool equals_lower(StringRef RHS) const {
return str().equals_lower(RHS);
}
- /// compare - Compare two strings; the result is -1, 0, or 1 if this string
- /// is lexicographically less than, equal to, or greater than the \arg RHS.
+ /// Compare two strings; the result is -1, 0, or 1 if this string is
+ /// lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
return str().compare(RHS);
}
@@ -129,12 +129,12 @@ public:
/// @name String Predicates
/// @{
- /// startswith - Check if this string starts with the given \arg Prefix.
+ /// startswith - Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return str().startswith(Prefix);
}
- /// endswith - Check if this string ends with the given \arg Suffix.
+ /// endswith - Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return str().endswith(Suffix);
}
@@ -143,76 +143,76 @@ public:
/// @name String Searching
/// @{
- /// find - Search for the first character \arg C in the string.
+ /// find - Search for the first character \p C in the string.
///
- /// \return - The index of the first occurrence of \arg C, or npos if not
+ /// \return - The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
return str().find(C, From);
}
- /// find - Search for the first string \arg Str in the string.
+ /// Search for the first string \p Str in the string.
///
- /// \return - The index of the first occurrence of \arg Str, or npos if not
+ /// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const {
return str().find(Str, From);
}
- /// rfind - Search for the last character \arg C in the string.
+ /// Search for the last character \p C in the string.
///
- /// \return - The index of the last occurrence of \arg C, or npos if not
+ /// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = StringRef::npos) const {
return str().rfind(C, From);
}
- /// rfind - Search for the last string \arg Str in the string.
+ /// Search for the last string \p Str in the string.
///
- /// \return - The index of the last occurrence of \arg Str, or npos if not
+ /// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const {
return str().rfind(Str);
}
- /// find_first_of - Find the first character in the string that is \arg C,
- /// or npos if not found. Same as find.
+ /// Find the first character in the string that is \p C, or npos if not
+ /// found. Same as find.
size_t find_first_of(char C, size_t From = 0) const {
return str().find_first_of(C, From);
}
- /// find_first_of - Find the first character in the string that is in \arg
- /// Chars, or npos if not found.
+ /// Find the first character in the string that is in \p Chars, or npos if
+ /// not found.
///
- /// Note: O(size() + Chars.size())
+ /// Complexity: O(size() + Chars.size())
size_t find_first_of(StringRef Chars, size_t From = 0) const {
return str().find_first_of(Chars, From);
}
- /// find_first_not_of - Find the first character in the string that is not
- /// \arg C or npos if not found.
+ /// Find the first character in the string that is not \p C or npos if not
+ /// found.
size_t find_first_not_of(char C, size_t From = 0) const {
return str().find_first_not_of(C, From);
}
- /// find_first_not_of - Find the first character in the string that is not
- /// in the string \arg Chars, or npos if not found.
+ /// Find the first character in the string that is not in the string
+ /// \p Chars, or npos if not found.
///
- /// Note: O(size() + Chars.size())
+ /// Complexity: O(size() + Chars.size())
size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
return str().find_first_not_of(Chars, From);
}
- /// find_last_of - Find the last character in the string that is \arg C, or
- /// npos if not found.
+ /// Find the last character in the string that is \p C, or npos if not
+ /// found.
size_t find_last_of(char C, size_t From = StringRef::npos) const {
return str().find_last_of(C, From);
}
- /// find_last_of - Find the last character in the string that is in \arg C,
- /// or npos if not found.
+ /// Find the last character in the string that is in \p C, or npos if not
+ /// found.
///
- /// Note: O(size() + Chars.size())
+ /// Complexity: O(size() + Chars.size())
size_t find_last_of(
StringRef Chars, size_t From = StringRef::npos) const {
return str().find_last_of(Chars, From);
@@ -222,13 +222,13 @@ public:
/// @name Helpful Algorithms
/// @{
- /// count - Return the number of occurrences of \arg C in the string.
+ /// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
return str().count(C);
}
- /// count - Return the number of non-overlapped occurrences of \arg Str in
- /// the string.
+ /// Return the number of non-overlapped occurrences of \p Str in the
+ /// string.
size_t count(StringRef Str) const {
return str().count(Str);
}
@@ -237,36 +237,36 @@ public:
/// @name Substring Operations
/// @{
- /// substr - Return a reference to the substring from [Start, Start + N).
+ /// Return a reference to the substring from [Start, Start + N).
///
- /// \param Start - The index of the starting character in the substring; if
+ /// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
- /// \param N - The number of characters to included in the substring. If N
+ /// \param N The number of characters to included in the substring. If \p N
/// exceeds the number of characters remaining in the string, the string
- /// suffix (starting with \arg Start) will be returned.
+ /// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = StringRef::npos) const {
return str().substr(Start, N);
}
- /// slice - Return a reference to the substring from [Start, End).
+ /// Return a reference to the substring from [Start, End).
///
- /// \param Start - The index of the starting character in the substring; if
+ /// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
- /// \param End - The index following the last character to include in the
- /// substring. If this is npos, or less than \arg Start, or exceeds the
+ /// \param End The index following the last character to include in the
+ /// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
- /// (starting with \arg Start) will be returned.
+ /// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
return str().slice(Start, End);
}
// Extra methods.
- /// Explicit conversion to StringRef
+ /// Explicit conversion to StringRef.
StringRef str() const { return StringRef(this->begin(), this->size()); }
// TODO: Make this const, if it's safe...
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 769b7dc..951e574 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -178,7 +178,7 @@ protected:
/// std::move, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move(It1 I, It1 E, It2 Dest) {
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
*Dest = ::std::move(*I);
return Dest;
@@ -193,7 +193,7 @@ protected:
/// std::move_backward, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move_backward(It1 I, It1 E, It2 Dest) {
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
while (I != E)
*--Dest = ::std::move(*--E);
return Dest;
@@ -206,7 +206,7 @@ protected:
/// memory starting with "Dest", constructing elements as needed.
template<typename It1, typename It2>
static void uninitialized_move(It1 I, It1 E, It2 Dest) {
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
::new ((void*) &*Dest) T(::std::move(*I));
#else
@@ -239,7 +239,7 @@ public:
goto Retry;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
void push_back(T &&Elt) {
if (this->EndX < this->CapacityX) {
Retry:
@@ -365,7 +365,7 @@ template <typename T>
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
- SmallVectorImpl(const SmallVectorImpl&); // DISABLED.
+ SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION;
public:
typedef typename SuperClass::iterator iterator;
typedef typename SuperClass::size_type size_type;
@@ -422,7 +422,7 @@ public:
}
T pop_back_val() {
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
T Result = ::std::move(this->back());
#else
T Result = this->back();
@@ -495,7 +495,7 @@ public:
return(N);
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
iterator insert(iterator I, T &&Elt) {
if (I == this->end()) { // Important special case for empty vector.
this->push_back(::std::move(Elt));
@@ -667,7 +667,7 @@ public:
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
#endif
@@ -684,8 +684,8 @@ public:
RHS.begin(), RHS.end());
}
- /// set_size - Set the array size to \arg N, which the current array must have
- /// enough capacity for.
+ /// Set the array size to \p N, which the current array must have enough
+ /// capacity for.
///
/// This does not construct or destroy any elements in the vector.
///
@@ -787,7 +787,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
template <typename T>
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
// Avoid self-assignment.
@@ -898,7 +898,7 @@ public:
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 791f108..306e928 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -262,6 +262,22 @@ public:
}
};
+template <unsigned ElementSize>
+struct ilist_traits<SparseBitVectorElement<ElementSize> >
+ : public ilist_default_traits<SparseBitVectorElement<ElementSize> > {
+ typedef SparseBitVectorElement<ElementSize> Element;
+
+ Element *createSentinel() const { return static_cast<Element *>(&Sentinel); }
+ static void destroySentinel(Element *) {}
+
+ Element *provideInitialHead() const { return createSentinel(); }
+ Element *ensureHead(Element *) const { return createSentinel(); }
+ static void noteHead(Element *, Element *) {}
+
+private:
+ mutable ilist_half_node<Element> Sentinel;
+};
+
template <unsigned ElementSize = 128>
class SparseBitVector {
typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
index dc3db4c..267a340 100644
--- a/include/llvm/ADT/SparseSet.h
+++ b/include/llvm/ADT/SparseSet.h
@@ -20,8 +20,8 @@
#ifndef LLVM_ADT_SPARSESET_H
#define LLVM_ADT_SPARSESET_H
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
#include <limits>
@@ -128,8 +128,8 @@ class SparseSet {
// Disable copy construction and assignment.
// This data structure is not meant to be used that way.
- SparseSet(const SparseSet&); // DO NOT IMPLEMENT.
- SparseSet &operator=(const SparseSet&); // DO NOT IMPLEMENT.
+ SparseSet(const SparseSet&) LLVM_DELETED_FUNCTION;
+ SparseSet &operator=(const SparseSet&) LLVM_DELETED_FUNCTION;
public:
typedef ValueT value_type;
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 36df5ac..9503e0f 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -14,14 +14,14 @@
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
template<typename T> class SmallVectorImpl;
/// hexdigit - Return the hexadecimal character for the
-/// given number \arg X (which should be less than 16).
+/// given number \p X (which should be less than 16).
static inline char hexdigit(unsigned X, bool LowerCase = false) {
const char HexChar = LowerCase ? 'a' : 'A';
return X < 10 ? '0' + X : HexChar + X - 10;
@@ -129,6 +129,25 @@ static inline unsigned HashString(StringRef Str, unsigned Result = 0) {
return Result;
}
+/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
+static inline StringRef getOrdinalSuffix(unsigned Val) {
+ // It is critically important that we do this perfectly for
+ // user-written sequences with over 100 elements.
+ switch (Val % 100) {
+ case 11:
+ case 12:
+ case 13:
+ return "th";
+ default:
+ switch (Val % 10) {
+ case 1: return "st";
+ case 2: return "nd";
+ case 3: return "rd";
+ default: return "th";
+ }
+ }
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index b4497a2..0d68d11 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -53,7 +53,7 @@ public:
class StringMapImpl {
protected:
// Array of NumBuckets pointers to entries, null pointers are holes.
- // TheTable[NumBuckets] contains a sentinel value for easy iteration. Follwed
+ // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
// by an array of the actual hash values as unsigned integers.
StringMapEntryBase **TheTable;
unsigned NumBuckets;
@@ -171,7 +171,6 @@ public:
return Create(KeyStart, KeyEnd, Allocator, 0);
}
-
/// Create - Create a StringMapEntry with normal malloc/free.
template<typename InitType>
static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
@@ -204,7 +203,6 @@ public:
return *reinterpret_cast<StringMapEntry*>(Ptr);
}
-
/// Destroy - Destroy this StringMapEntry, releasing memory back to the
/// specified allocator.
template<typename AllocatorTy>
@@ -290,7 +288,7 @@ public:
return const_iterator(TheTable+Bucket, true);
}
- /// lookup - Return the entry for the specified key, or a default
+ /// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
ValueTy lookup(StringRef Key) const {
const_iterator it = find(Key);
@@ -427,7 +425,7 @@ public:
return Ptr != RHS.Ptr;
}
- inline StringMapConstIterator& operator++() { // Preincrement
+ inline StringMapConstIterator& operator++() { // Preincrement
++Ptr;
AdvancePastEmptyBuckets();
return *this;
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index cd84603..0e93f51 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -11,7 +11,6 @@
#define LLVM_ADT_STRINGREF_H
#include "llvm/Support/type_traits.h"
-
#include <algorithm>
#include <cassert>
#include <cstring>
@@ -138,7 +137,7 @@ namespace llvm {
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
- /// is lexicographically less than, equal to, or greater than the \arg RHS.
+ /// is lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
// Check the prefix for a mismatch.
if (int Res = compareMemory(Data, RHS.Data, min(Length, RHS.Length)))
@@ -205,13 +204,13 @@ namespace llvm {
/// @name String Predicates
/// @{
- /// startswith - Check if this string starts with the given \arg Prefix.
+ /// Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return Length >= Prefix.Length &&
compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
}
- /// endswith - Check if this string ends with the given \arg Suffix.
+ /// Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return Length >= Suffix.Length &&
compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
@@ -221,9 +220,9 @@ namespace llvm {
/// @name String Searching
/// @{
- /// find - Search for the first character \arg C in the string.
+ /// Search for the first character \p C in the string.
///
- /// \return - The index of the first occurrence of \arg C, or npos if not
+ /// \returns The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
for (size_t i = min(From, Length), e = Length; i != e; ++i)
@@ -232,15 +231,15 @@ namespace llvm {
return npos;
}
- /// find - Search for the first string \arg Str in the string.
+ /// Search for the first string \p Str in the string.
///
- /// \return - The index of the first occurrence of \arg Str, or npos if not
+ /// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const;
- /// rfind - Search for the last character \arg C in the string.
+ /// Search for the last character \p C in the string.
///
- /// \return - The index of the last occurrence of \arg C, or npos if not
+ /// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = npos) const {
From = min(From, Length);
@@ -253,61 +252,61 @@ namespace llvm {
return npos;
}
- /// rfind - Search for the last string \arg Str in the string.
+ /// Search for the last string \p Str in the string.
///
- /// \return - The index of the last occurrence of \arg Str, or npos if not
+ /// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const;
- /// find_first_of - Find the first character in the string that is \arg C,
- /// or npos if not found. Same as find.
+ /// Find the first character in the string that is \p C, or npos if not
+ /// found. Same as find.
size_type find_first_of(char C, size_t From = 0) const {
return find(C, From);
}
- /// find_first_of - Find the first character in the string that is in \arg
- /// Chars, or npos if not found.
+ /// Find the first character in the string that is in \p Chars, or npos if
+ /// not found.
///
- /// Note: O(size() + Chars.size())
+ /// Complexity: O(size() + Chars.size())
size_type find_first_of(StringRef Chars, size_t From = 0) const;
- /// find_first_not_of - Find the first character in the string that is not
- /// \arg C or npos if not found.
+ /// Find the first character in the string that is not \p C or npos if not
+ /// found.
size_type find_first_not_of(char C, size_t From = 0) const;
- /// find_first_not_of - Find the first character in the string that is not
- /// in the string \arg Chars, or npos if not found.
+ /// Find the first character in the string that is not in the string
+ /// \p Chars, or npos if not found.
///
- /// Note: O(size() + Chars.size())
+ /// Complexity: O(size() + Chars.size())
size_type find_first_not_of(StringRef Chars, size_t From = 0) const;
- /// find_last_of - Find the last character in the string that is \arg C, or
- /// npos if not found.
+ /// Find the last character in the string that is \p C, or npos if not
+ /// found.
size_type find_last_of(char C, size_t From = npos) const {
return rfind(C, From);
}
- /// find_last_of - Find the last character in the string that is in \arg C,
- /// or npos if not found.
+ /// Find the last character in the string that is in \p C, or npos if not
+ /// found.
///
- /// Note: O(size() + Chars.size())
+ /// Complexity: O(size() + Chars.size())
size_type find_last_of(StringRef Chars, size_t From = npos) const;
- /// find_last_not_of - Find the last character in the string that is not
- /// \arg C, or npos if not found.
+ /// Find the last character in the string that is not \p C, or npos if not
+ /// found.
size_type find_last_not_of(char C, size_t From = npos) const;
- /// find_last_not_of - Find the last character in the string that is not in
- /// \arg Chars, or npos if not found.
+ /// Find the last character in the string that is not in \p Chars, or
+ /// npos if not found.
///
- /// Note: O(size() + Chars.size())
+ /// Complexity: O(size() + Chars.size())
size_type find_last_not_of(StringRef Chars, size_t From = npos) const;
/// @}
/// @name Helpful Algorithms
/// @{
- /// count - Return the number of occurrences of \arg C in the string.
+ /// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
size_t Count = 0;
for (size_t i = 0, e = Length; i != e; ++i)
@@ -316,18 +315,17 @@ namespace llvm {
return Count;
}
- /// count - Return the number of non-overlapped occurrences of \arg Str in
+ /// Return the number of non-overlapped occurrences of \p Str in
/// the string.
size_t count(StringRef Str) const;
- /// getAsInteger - Parse the current string as an integer of the specified
- /// radix. If Radix is specified as zero, this does radix autosensing using
+ /// Parse the current string as an integer of the specified radix. If
+ /// \p Radix is specified as zero, this does radix autosensing using
/// extended C rules: 0 is octal, 0x is hex, 0b is binary.
///
/// If the string is invalid or if only a subset of the string is valid,
/// this returns true to signify the error. The string is considered
/// erroneous if empty or if it overflows T.
- ///
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
@@ -350,13 +348,12 @@ namespace llvm {
return false;
}
- /// getAsInteger - Parse the current string as an integer of the
- /// specified radix, or of an autosensed radix if the radix given
- /// is 0. The current value in Result is discarded, and the
- /// storage is changed to be wide enough to store the parsed
- /// integer.
+ /// Parse the current string as an integer of the specified \p Radix, or of
+ /// an autosensed radix if the \p Radix given is 0. The current value in
+ /// \p Result is discarded, and the storage is changed to be wide enough to
+ /// store the parsed integer.
///
- /// Returns true if the string does not solely consist of a valid
+ /// \returns true if the string does not solely consist of a valid
/// non-empty number in the appropriate base.
///
/// APInt::fromString is superficially similar but assumes the
@@ -367,70 +364,70 @@ namespace llvm {
/// @name String Operations
/// @{
- // lower - Convert the given ASCII string to lowercase.
+ // Convert the given ASCII string to lowercase.
std::string lower() const;
- /// upper - Convert the given ASCII string to uppercase.
+ /// Convert the given ASCII string to uppercase.
std::string upper() const;
/// @}
/// @name Substring Operations
/// @{
- /// substr - Return a reference to the substring from [Start, Start + N).
+ /// Return a reference to the substring from [Start, Start + N).
///
- /// \param Start - The index of the starting character in the substring; if
+ /// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
- /// \param N - The number of characters to included in the substring. If N
+ /// \param N The number of characters to included in the substring. If N
/// exceeds the number of characters remaining in the string, the string
- /// suffix (starting with \arg Start) will be returned.
+ /// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = npos) const {
Start = min(Start, Length);
return StringRef(Data + Start, min(N, Length - Start));
}
- /// drop_front - Return a StringRef equal to 'this' but with the first
- /// elements dropped.
+ /// Return a StringRef equal to 'this' but with the first \p N elements
+ /// dropped.
StringRef drop_front(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(N);
}
- /// drop_back - Return a StringRef equal to 'this' but with the last
- /// elements dropped.
+ /// Return a StringRef equal to 'this' but with the last \p N elements
+ /// dropped.
StringRef drop_back(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(0, size()-N);
}
- /// slice - Return a reference to the substring from [Start, End).
+ /// Return a reference to the substring from [Start, End).
///
- /// \param Start - The index of the starting character in the substring; if
+ /// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
- /// \param End - The index following the last character to include in the
- /// substring. If this is npos, or less than \arg Start, or exceeds the
+ /// \param End The index following the last character to include in the
+ /// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
- /// (starting with \arg Start) will be returned.
+ /// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
Start = min(Start, Length);
End = min(max(Start, End), Length);
return StringRef(Data + Start, End - Start);
}
- /// split - Split into two substrings around the first occurrence of a
- /// separator character.
+ /// Split into two substrings around the first occurrence of a separator
+ /// character.
///
- /// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
+ /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
- /// maximal. If \arg Separator is not in the string, then the result is a
+ /// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
- /// \param Separator - The character to split on.
- /// \return - The split substrings.
+ /// \param Separator The character to split on.
+ /// \returns The split substrings.
std::pair<StringRef, StringRef> split(char Separator) const {
size_t Idx = find(Separator);
if (Idx == npos)
@@ -438,12 +435,12 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
- /// split - Split into two substrings around the first occurrence of a
- /// separator string.
+ /// Split into two substrings around the first occurrence of a separator
+ /// string.
///
- /// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
+ /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
- /// maximal. If \arg Separator is not in the string, then the result is a
+ /// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The string to split on.
@@ -455,14 +452,13 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
}
- /// split - Split into substrings around the occurrences of a separator
- /// string.
+ /// Split into substrings around the occurrences of a separator string.
///
- /// Each substring is stored in \arg A. If \arg MaxSplit is >= 0, at most
- /// \arg MaxSplit splits are done and consequently <= \arg MaxSplit
+ /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
+ /// \p MaxSplit splits are done and consequently <= \p MaxSplit
/// elements are added to A.
- /// If \arg KeepEmpty is false, empty strings are not added to \arg A. They
- /// still count when considering \arg MaxSplit
+ /// If \p KeepEmpty is false, empty strings are not added to \p A. They
+ /// still count when considering \p MaxSplit
/// An useful invariant is that
/// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
///
@@ -474,12 +470,12 @@ namespace llvm {
StringRef Separator, int MaxSplit = -1,
bool KeepEmpty = true) const;
- /// rsplit - Split into two substrings around the last occurrence of a
- /// separator character.
+ /// Split into two substrings around the last occurrence of a separator
+ /// character.
///
- /// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
+ /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
- /// minimal. If \arg Separator is not in the string, then the result is a
+ /// minimal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The character to split on.
@@ -491,20 +487,20 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
- /// ltrim - Return string with consecutive characters in \arg Chars starting
- /// from the left removed.
+ /// Return string with consecutive characters in \p Chars starting from
+ /// the left removed.
StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
return drop_front(std::min(Length, find_first_not_of(Chars)));
}
- /// rtrim - Return string with consecutive characters in \arg Chars starting
- /// from the right removed.
+ /// Return string with consecutive characters in \p Chars starting from
+ /// the right removed.
StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1));
}
- /// trim - Return string with consecutive characters in \arg Chars starting
- /// from the left and right removed.
+ /// Return string with consecutive characters in \p Chars starting from
+ /// the left and right removed.
StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
return ltrim(Chars).rtrim(Chars);
}
diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h
index 9c55f6b..b69a964 100644
--- a/include/llvm/ADT/StringSet.h
+++ b/include/llvm/ADT/StringSet.h
@@ -29,8 +29,13 @@ namespace llvm {
assert(!InLang.empty());
const char *KeyStart = InLang.data();
const char *KeyEnd = KeyStart + InLang.size();
- return base::insert(llvm::StringMapEntry<char>::
- Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
+ llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>::
+ Create(KeyStart, KeyEnd, base::getAllocator(), '+');
+ if (!base::insert(Entry)) {
+ Entry->Destroy(base::getAllocator());
+ return false;
+ }
+ return true;
}
};
}
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index d3d33b8..cc0e7b6 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -70,7 +70,7 @@ public:
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
RHS.Val = (EltTy)0;
}
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index ab1f0da..49d9f68 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -44,7 +44,6 @@ public:
UnknownArch,
arm, // ARM; arm, armv.*, xscale
- cellspu, // CellSPU: spu, cellspu
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel
@@ -65,7 +64,9 @@ public:
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
- amdil // amdil: amd IL
+ amdil, // amdil: amd IL
+ spir, // SPIR: standard portable IR for OpenCL 32-bit version
+ spir64 // SPIR: standard portable IR for OpenCL 64-bit version
};
enum VendorType {
UnknownVendor,
@@ -75,7 +76,8 @@ public:
SCEI,
BGP,
BGQ,
- Freescale
+ Freescale,
+ IBM
};
enum OSType {
UnknownOS,
@@ -98,9 +100,10 @@ public:
Haiku,
Minix,
RTEMS,
- NativeClient,
- CNK, // BG/P Compute-Node Kernel
- Bitrig
+ NaCl, // Native Client
+ CNK, // BG/P Compute-Node Kernel
+ Bitrig,
+ AIX
};
enum EnvironmentType {
UnknownEnvironment,
@@ -110,7 +113,8 @@ public:
GNUEABIHF,
EABI,
MachO,
- Android
+ Android,
+ ELF
};
private:
@@ -306,6 +310,11 @@ public:
return getOS() == Triple::Win32 || isOSCygMing();
}
+ /// \brief Tests whether the OS is NaCl (Native Client)
+ bool isOSNaCl() const {
+ return getOS() == Triple::NaCl;
+ }
+
/// \brief Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
return !isOSDarwin() && !isOSWindows();
@@ -342,7 +351,7 @@ public:
/// to a known type.
void setEnvironment(EnvironmentType Kind);
- /// setTriple - Set all components to the new triple \arg Str.
+ /// setTriple - Set all components to the new triple \p Str.
void setTriple(const Twine &Str);
/// setArchName - Set the architecture (first) component of the
@@ -393,11 +402,10 @@ public:
/// @name Static helpers for IDs.
/// @{
- /// getArchTypeName - Get the canonical name for the \arg Kind
- /// architecture.
+ /// getArchTypeName - Get the canonical name for the \p Kind architecture.
static const char *getArchTypeName(ArchType Kind);
- /// getArchTypePrefix - Get the "prefix" canonical name for the \arg Kind
+ /// getArchTypePrefix - Get the "prefix" canonical name for the \p Kind
/// architecture. This is the prefix used by the architecture specific
/// builtins, and is suitable for passing to \see
/// Intrinsic::getIntrinsicForGCCBuiltin().
@@ -405,15 +413,13 @@ public:
/// \return - The architecture prefix, or 0 if none is defined.
static const char *getArchTypePrefix(ArchType Kind);
- /// getVendorTypeName - Get the canonical name for the \arg Kind
- /// vendor.
+ /// getVendorTypeName - Get the canonical name for the \p Kind vendor.
static const char *getVendorTypeName(VendorType Kind);
- /// getOSTypeName - Get the canonical name for the \arg Kind operating
- /// system.
+ /// getOSTypeName - Get the canonical name for the \p Kind operating system.
static const char *getOSTypeName(OSType Kind);
- /// getEnvironmentTypeName - Get the canonical name for the \arg Kind
+ /// getEnvironmentTypeName - Get the canonical name for the \p Kind
/// environment.
static const char *getEnvironmentTypeName(EnvironmentType Kind);
@@ -425,11 +431,6 @@ public:
/// architecture name (e.g., "x86").
static ArchType getArchTypeForLLVMName(StringRef Str);
- /// getArchTypeForDarwinArchName - Get the architecture type for a "Darwin"
- /// architecture name, for example as accepted by "gcc -arch" (see also
- /// arch(3)).
- static ArchType getArchTypeForDarwinArchName(StringRef Str);
-
/// @}
};
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index 9101df8..cc290d5 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -44,7 +44,7 @@ namespace llvm {
/// itself, and renders as an empty string. This can be returned from APIs to
/// effectively nullify any concatenations performed on the result.
///
- /// \b Implementation \n
+ /// \b Implementation
///
/// Given the nature of a Twine, it is not possible for the Twine's
/// concatenation method to construct interior nodes; the result must be
@@ -67,7 +67,7 @@ namespace llvm {
///
/// These invariants are check by \see isValid().
///
- /// \b Efficiency Considerations \n
+ /// \b Efficiency Considerations
///
/// The Twine is designed to yield efficient and small code for common
/// situations. For this reason, the concat() method is inlined so that
@@ -303,37 +303,37 @@ namespace llvm {
LHS.character = static_cast<char>(Val);
}
- /// Construct a twine to print \arg Val as an unsigned decimal integer.
+ /// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(unsigned Val)
: LHSKind(DecUIKind), RHSKind(EmptyKind) {
LHS.decUI = Val;
}
- /// Construct a twine to print \arg Val as a signed decimal integer.
+ /// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(int Val)
: LHSKind(DecIKind), RHSKind(EmptyKind) {
LHS.decI = Val;
}
- /// Construct a twine to print \arg Val as an unsigned decimal integer.
+ /// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long &Val)
: LHSKind(DecULKind), RHSKind(EmptyKind) {
LHS.decUL = &Val;
}
- /// Construct a twine to print \arg Val as a signed decimal integer.
+ /// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long &Val)
: LHSKind(DecLKind), RHSKind(EmptyKind) {
LHS.decL = &Val;
}
- /// Construct a twine to print \arg Val as an unsigned decimal integer.
+ /// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long long &Val)
: LHSKind(DecULLKind), RHSKind(EmptyKind) {
LHS.decULL = &Val;
}
- /// Construct a twine to print \arg Val as a signed decimal integer.
+ /// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long long &Val)
: LHSKind(DecLLKind), RHSKind(EmptyKind) {
LHS.decLL = &Val;
@@ -370,7 +370,7 @@ namespace llvm {
/// @name Numeric Conversions
/// @{
- // Construct a twine to print \arg Val as an unsigned hexadecimal integer.
+ // Construct a twine to print \p Val as an unsigned hexadecimal integer.
static Twine utohexstr(const uint64_t &Val) {
Child LHS, RHS;
LHS.uHex = &Val;
@@ -447,17 +447,17 @@ namespace llvm {
/// The returned StringRef's size does not include the null terminator.
StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
- /// print - Write the concatenated string represented by this twine to the
- /// stream \arg OS.
+ /// Write the concatenated string represented by this twine to the
+ /// stream \p OS.
void print(raw_ostream &OS) const;
- /// dump - Dump the concatenated string represented by this twine to stderr.
+ /// Dump the concatenated string represented by this twine to stderr.
void dump() const;
- /// print - Write the representation of this twine to the stream \arg OS.
+ /// Write the representation of this twine to the stream \p OS.
void printRepr(raw_ostream &OS) const;
- /// dumpRepr - Dump the representation of this twine to stderr.
+ /// Dump the representation of this twine to stderr.
void dumpRepr() const;
/// @}
diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h
index f7e2551..b4fed7a 100644
--- a/include/llvm/ADT/ValueMap.h
+++ b/include/llvm/ADT/ValueMap.h
@@ -27,10 +27,9 @@
#define LLVM_ADT_VALUEMAP_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/type_traits.h"
-#include "llvm/Support/Mutex.h"
-
#include <iterator>
namespace llvm {
@@ -80,8 +79,8 @@ class ValueMap {
typedef typename Config::ExtraData ExtraData;
MapT Map;
ExtraData Data;
- ValueMap(const ValueMap&); // DO NOT IMPLEMENT
- ValueMap& operator=(const ValueMap&); // DO NOT IMPLEMENT
+ ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION;
+ ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION;
public:
typedef KeyT key_type;
typedef ValueT mapped_type;
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
index ba9864a..20cdae3 100644
--- a/include/llvm/ADT/ilist.h
+++ b/include/llvm/ADT/ilist.h
@@ -38,6 +38,7 @@
#ifndef LLVM_ADT_ILIST_H
#define LLVM_ADT_ILIST_H
+#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -331,8 +332,8 @@ class iplist : public Traits {
// No fundamental reason why iplist can't be copyable, but the default
// copy/copy-assign won't do.
- iplist(const iplist &); // do not implement
- void operator=(const iplist &); // do not implement
+ iplist(const iplist &) LLVM_DELETED_FUNCTION;
+ void operator=(const iplist &) LLVM_DELETED_FUNCTION;
public:
typedef NodeTy *pointer;
@@ -464,6 +465,17 @@ public:
return where;
}
+ /// Remove all nodes from the list like clear(), but do not call
+ /// removeNodeFromList() or deleteNode().
+ ///
+ /// This should only be used immediately before freeing nodes in bulk to
+ /// avoid traversing the list and bringing all the nodes into cache.
+ void clearAndLeakNodesUnsafely() {
+ if (Head) {
+ Head = getTail();
+ this->setPrev(Head, Head);
+ }
+ }
private:
// transfer - The heart of the splice function. Move linked list nodes from
@@ -471,6 +483,10 @@ private:
//
void transfer(iterator position, iplist &L2, iterator first, iterator last) {
assert(first != last && "Should be checked by callers");
+ // Position cannot be contained in the range to be transferred.
+ // Check for the most common mistake.
+ assert(position != first &&
+ "Insertion point can't be one of the transferred nodes");
if (position != last) {
// Note: we have to be careful about the case when we move the first node
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index f587220..3ce4732 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -37,15 +37,15 @@
#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H
#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
-#include "llvm/Support/CallSite.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/CallSite.h"
namespace llvm {
class LoadInst;
class StoreInst;
class VAArgInst;
-class TargetData;
+class DataLayout;
class TargetLibraryInfo;
class Pass;
class AnalysisUsage;
@@ -55,7 +55,7 @@ class DominatorTree;
class AliasAnalysis {
protected:
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
private:
@@ -83,17 +83,17 @@ public:
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = ~UINT64_C(0);
- /// getTargetData - Return a pointer to the current TargetData object, or
- /// null if no TargetData object is available.
+ /// getDataLayout - Return a pointer to the current DataLayout object, or
+ /// null if no DataLayout object is available.
///
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
///
const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }
- /// getTypeStoreSize - Return the TargetData store size for the given type,
+ /// getTypeStoreSize - Return the DataLayout store size for the given type,
/// if known, or a conservative value otherwise.
///
uint64_t getTypeStoreSize(Type *Ty);
@@ -373,7 +373,7 @@ public:
return getModRefInfo(I, Location(P, Size));
}
- /// getModRefInfo (for call sites) - Return whether information about whether
+ /// getModRefInfo (for call sites) - Return information about whether
/// a particular call site modifies or reads the specified memory location.
virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
const Location &Loc);
@@ -384,7 +384,7 @@ public:
return getModRefInfo(CS, Location(P, Size));
}
- /// getModRefInfo (for calls) - Return whether information about whether
+ /// getModRefInfo (for calls) - Return information about whether
/// a particular call modifies or reads the specified memory location.
ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
return getModRefInfo(ImmutableCallSite(C), Loc);
@@ -395,7 +395,7 @@ public:
return getModRefInfo(C, Location(P, Size));
}
- /// getModRefInfo (for invokes) - Return whether information about whether
+ /// getModRefInfo (for invokes) - Return information about whether
/// a particular invoke modifies or reads the specified memory location.
ModRefResult getModRefInfo(const InvokeInst *I,
const Location &Loc) {
@@ -408,7 +408,7 @@ public:
return getModRefInfo(I, Location(P, Size));
}
- /// getModRefInfo (for loads) - Return whether information about whether
+ /// getModRefInfo (for loads) - Return information about whether
/// a particular load modifies or reads the specified memory location.
ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
@@ -417,7 +417,7 @@ public:
return getModRefInfo(L, Location(P, Size));
}
- /// getModRefInfo (for stores) - Return whether information about whether
+ /// getModRefInfo (for stores) - Return information about whether
/// a particular store modifies or reads the specified memory location.
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
@@ -426,7 +426,7 @@ public:
return getModRefInfo(S, Location(P, Size));
}
- /// getModRefInfo (for fences) - Return whether information about whether
+ /// getModRefInfo (for fences) - Return information about whether
/// a particular store modifies or reads the specified memory location.
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
// Conservatively correct. (We could possibly be a bit smarter if
@@ -439,7 +439,7 @@ public:
return getModRefInfo(S, Location(P, Size));
}
- /// getModRefInfo (for cmpxchges) - Return whether information about whether
+ /// getModRefInfo (for cmpxchges) - Return information about whether
/// a particular cmpxchg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
@@ -449,7 +449,7 @@ public:
return getModRefInfo(CX, Location(P, Size));
}
- /// getModRefInfo (for atomicrmws) - Return whether information about whether
+ /// getModRefInfo (for atomicrmws) - Return information about whether
/// a particular atomicrmw modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
@@ -459,7 +459,7 @@ public:
return getModRefInfo(RMW, Location(P, Size));
}
- /// getModRefInfo (for va_args) - Return whether information about whether
+ /// getModRefInfo (for va_args) - Return information about whether
/// a particular va_arg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
@@ -587,9 +587,9 @@ 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 (but not Global Aliases)
-/// Allocas and Mallocs
+/// Allocas
/// ByVal and NoAlias Arguments
-/// NoAlias returns
+/// NoAlias returns (e.g. calls to malloc)
///
bool isIdentifiedObject(const Value *V);
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
index 95626d6..163331c 100644
--- a/include/llvm/Analysis/AliasSetTracker.h
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -17,11 +17,11 @@
#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
#define LLVM_ANALYSIS_ALIASSETTRACKER_H
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/ValueHandle.h"
#include <vector>
namespace llvm {
@@ -109,7 +109,6 @@ class AliasSet : public ilist_node<AliasSet> {
PointerRec *PtrList, **PtrListEnd; // Doubly linked list of nodes.
AliasSet *Forward; // Forwarding pointer.
- AliasSet *Next, *Prev; // Doubly linked list of AliasSets.
// All instructions without a specific address in this alias set.
std::vector<AssertingVH<Instruction> > UnknownInsts;
@@ -226,8 +225,8 @@ private:
AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
}
- AliasSet(const AliasSet &AS); // do not implement
- void operator=(const AliasSet &AS); // do not implement
+ AliasSet(const AliasSet &AS) LLVM_DELETED_FUNCTION;
+ void operator=(const AliasSet &AS) LLVM_DELETED_FUNCTION;
PointerRec *getSomePointer() const {
return PtrList;
diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h
index 5168ab7..f220c58 100644
--- a/include/llvm/Analysis/BlockFrequencyImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyImpl.h
@@ -14,17 +14,17 @@
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
-#include "llvm/BasicBlock.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include <vector>
#include <string>
+#include <vector>
namespace llvm {
diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h
index c0567da..6c23f7c 100644
--- a/include/llvm/Analysis/BranchProbabilityInfo.h
+++ b/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -14,10 +14,10 @@
#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
namespace llvm {
diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h
index 4704a92..fa596c3 100644
--- a/include/llvm/Analysis/CFGPrinter.h
+++ b/include/llvm/Analysis/CFGPrinter.h
@@ -15,10 +15,10 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
#include "llvm/Assembly/Writer.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/GraphWriter.h"
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index fb77da7..591484d 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -51,13 +51,13 @@
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
#define LLVM_ANALYSIS_CALLGRAPH_H
-#include "llvm/Function.h"
-#include "llvm/Pass.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Function.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/IncludeFile.h"
+#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {
@@ -185,9 +185,9 @@ private:
/// in the CalledFunctions array of this or other CallGraphNodes.
unsigned NumReferences;
- CallGraphNode(const CallGraphNode &); // DO NOT IMPLEMENT
- void operator=(const CallGraphNode &); // DO NOT IMPLEMENT
-
+ CallGraphNode(const CallGraphNode &) LLVM_DELETED_FUNCTION;
+ void operator=(const CallGraphNode &) LLVM_DELETED_FUNCTION;
+
void DropRef() { --NumReferences; }
void AddRef() { ++NumReferences; }
public:
diff --git a/include/llvm/CallGraphSCCPass.h b/include/llvm/Analysis/CallGraphSCCPass.h
index 7154aa3..4446777 100644
--- a/include/llvm/CallGraphSCCPass.h
+++ b/include/llvm/Analysis/CallGraphSCCPass.h
@@ -21,8 +21,8 @@
#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
#define LLVM_CALL_GRAPH_SCC_PASS_H
-#include "llvm/Pass.h"
#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Pass.h"
namespace llvm {
@@ -39,6 +39,9 @@ public:
/// corresponding to a CallGraph.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
+
/// doInitialization - This method is called before the SCC's of the program
/// has been processed, allowing the pass to do initialization as necessary.
virtual bool doInitialization(CallGraph &CG) {
diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h
index 9b5e842..5e2a5ec 100644
--- a/include/llvm/Analysis/CaptureTracking.h
+++ b/include/llvm/Analysis/CaptureTracking.h
@@ -14,9 +14,9 @@
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
#define LLVM_ANALYSIS_CAPTURETRACKING_H
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
@@ -46,7 +46,7 @@ namespace llvm {
/// capture) return false. To search it, return true.
///
/// U->getUser() is always an Instruction.
- virtual bool shouldExplore(Use *U) = 0;
+ virtual bool shouldExplore(Use *U);
/// captured - Information about the pointer was captured by the user of
/// use U. Return true to stop the traversal or false to continue looking
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
index 03c807c..35eabec 100644
--- a/include/llvm/Analysis/CodeMetrics.h
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -22,11 +22,11 @@ namespace llvm {
class BasicBlock;
class Function;
class Instruction;
- class TargetData;
+ class DataLayout;
class Value;
/// \brief Check whether an instruction is likely to be "free" when lowered.
- bool isInstructionFree(const Instruction *I, const TargetData *TD = 0);
+ bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
/// \brief Check whether a call will lower to something small.
///
@@ -46,8 +46,11 @@ namespace llvm {
/// \brief True if this function calls itself.
bool isRecursive;
- /// \brief True if this function contains one or more indirect branches.
- bool containsIndirectBr;
+ /// \brief True if this function cannot be duplicated.
+ ///
+ /// True if this function contains one or more indirect branches, or it contains
+ /// one or more 'noduplicate' instructions.
+ bool notDuplicatable;
/// \brief True if this function calls alloca (in the C sense).
bool usesDynamicAlloca;
@@ -79,16 +82,16 @@ namespace llvm {
unsigned NumRets;
CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
- containsIndirectBr(false), usesDynamicAlloca(false),
+ notDuplicatable(false), usesDynamicAlloca(false),
NumInsts(0), NumBlocks(0), NumCalls(0),
NumInlineCandidates(0), NumVectorInsts(0),
NumRets(0) {}
/// \brief Add information about a block to the current state.
- void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0);
+ void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
/// \brief Add information about a function to the current state.
- void analyzeFunction(Function *F, const TargetData *TD = 0);
+ void analyzeFunction(Function *F, const DataLayout *TD = 0);
};
}
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index 2fdef5f..12e623e 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -12,7 +12,7 @@
//
// Also, to supplement the basic VMCore ConstantExpr simplifications,
// this file declares some additional folding routines that can make use of
-// TargetData information. These functions cannot go in VMCore due to library
+// DataLayout information. These functions cannot go in VMCore due to library
// dependency issues.
//
//===----------------------------------------------------------------------===//
@@ -24,7 +24,7 @@ namespace llvm {
class Constant;
class ConstantExpr;
class Instruction;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class Function;
class Type;
@@ -36,14 +36,14 @@ namespace llvm {
/// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
-Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0,
+Constant *ConstantFoldInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
-/// using the specified TargetData. If successful, the constant result is
+/// using the specified DataLayout. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
@@ -54,7 +54,7 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
///
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
@@ -63,7 +63,7 @@ Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
///
Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
@@ -75,7 +75,7 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
-Constant *ConstantFoldLoadFromConstPtr(Constant *C, const TargetData *TD = 0);
+Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout *TD = 0);
/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h
index b701b8f..bd8c4a1 100644
--- a/include/llvm/Analysis/DOTGraphTraitsPass.h
+++ b/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -14,8 +14,8 @@
#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
-#include "llvm/Pass.h"
#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/Pass.h"
namespace llvm {
template <class Analysis, bool Simple>
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
new file mode 100644
index 0000000..f49efd9
--- /dev/null
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -0,0 +1,895 @@
+//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// DependenceAnalysis is an LLVM pass that analyses dependences between memory
+// accesses. Currently, it is an implementation of the approach described in
+//
+// Practical Dependence Testing
+// Goff, Kennedy, Tseng
+// PLDI 1991
+//
+// There's a single entry point that analyzes the dependence between a pair
+// of memory references in a function, returning either NULL, for no dependence,
+// or a more-or-less detailed description of the dependence between them.
+//
+// This pass exists to support the DependenceGraph pass. There are two separate
+// passes because there's a useful separation of concerns. A dependence exists
+// if two conditions are met:
+//
+// 1) Two instructions reference the same memory location, and
+// 2) There is a flow of control leading from one instruction to the other.
+//
+// DependenceAnalysis attacks the first condition; DependenceGraph will attack
+// the second (it's not yet ready).
+//
+// Please note that this is work in progress and the interface is subject to
+// change.
+//
+// Plausible changes:
+// Return a set of more precise dependences instead of just one dependence
+// summarizing all.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
+#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
+
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ class AliasAnalysis;
+ class Loop;
+ class LoopInfo;
+ class ScalarEvolution;
+ class SCEV;
+ class SCEVConstant;
+ class raw_ostream;
+
+ /// Dependence - This class represents a dependence between two memory
+ /// memory references in a function. It contains minimal information and
+ /// is used in the very common situation where the compiler is unable to
+ /// determine anything beyond the existence of a dependence; that is, it
+ /// represents a confused dependence (see also FullDependence). In most
+ /// cases (for output, flow, and anti dependences), the dependence implies
+ /// an ordering, where the source must precede the destination; in contrast,
+ /// input dependences are unordered.
+ class Dependence {
+ public:
+ Dependence(Instruction *Source,
+ Instruction *Destination) :
+ Src(Source), Dst(Destination) {}
+ virtual ~Dependence() {}
+
+ /// Dependence::DVEntry - Each level in the distance/direction vector
+ /// has a direction (or perhaps a union of several directions), and
+ /// perhaps a distance.
+ struct DVEntry {
+ enum { NONE = 0,
+ LT = 1,
+ EQ = 2,
+ LE = 3,
+ GT = 4,
+ NE = 5,
+ GE = 6,
+ ALL = 7 };
+ unsigned char Direction : 3; // Init to ALL, then refine.
+ bool Scalar : 1; // Init to true.
+ bool PeelFirst : 1; // Peeling the first iteration will break dependence.
+ bool PeelLast : 1; // Peeling the last iteration will break the dependence.
+ bool Splitable : 1; // Splitting the loop will break dependence.
+ const SCEV *Distance; // NULL implies no distance available.
+ DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false),
+ PeelLast(false), Splitable(false), Distance(NULL) { }
+ };
+
+ /// getSrc - Returns the source instruction for this dependence.
+ ///
+ Instruction *getSrc() const { return Src; }
+
+ /// getDst - Returns the destination instruction for this dependence.
+ ///
+ Instruction *getDst() const { return Dst; }
+
+ /// isInput - Returns true if this is an input dependence.
+ ///
+ bool isInput() const;
+
+ /// isOutput - Returns true if this is an output dependence.
+ ///
+ bool isOutput() const;
+
+ /// isFlow - Returns true if this is a flow (aka true) dependence.
+ ///
+ bool isFlow() const;
+
+ /// isAnti - Returns true if this is an anti dependence.
+ ///
+ bool isAnti() const;
+
+ /// isOrdered - Returns true if dependence is Output, Flow, or Anti
+ ///
+ bool isOrdered() const { return isOutput() || isFlow() || isAnti(); }
+
+ /// isUnordered - Returns true if dependence is Input
+ ///
+ bool isUnordered() const { return isInput(); }
+
+ /// isLoopIndependent - Returns true if this is a loop-independent
+ /// dependence.
+ virtual bool isLoopIndependent() const { return true; }
+
+ /// isConfused - Returns true if this dependence is confused
+ /// (the compiler understands nothing and makes worst-case
+ /// assumptions).
+ virtual bool isConfused() const { return true; }
+
+ /// isConsistent - Returns true if this dependence is consistent
+ /// (occurs every time the source and destination are executed).
+ virtual bool isConsistent() const { return false; }
+
+ /// getLevels - Returns the number of common loops surrounding the
+ /// source and destination of the dependence.
+ virtual unsigned getLevels() const { return 0; }
+
+ /// getDirection - Returns the direction associated with a particular
+ /// level.
+ virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }
+
+ /// getDistance - Returns the distance (or NULL) associated with a
+ /// particular level.
+ virtual const SCEV *getDistance(unsigned Level) const { return NULL; }
+
+ /// isPeelFirst - Returns true if peeling the first iteration from
+ /// this loop will break this dependence.
+ virtual bool isPeelFirst(unsigned Level) const { return false; }
+
+ /// isPeelLast - Returns true if peeling the last iteration from
+ /// this loop will break this dependence.
+ virtual bool isPeelLast(unsigned Level) const { return false; }
+
+ /// isSplitable - Returns true if splitting this loop will break
+ /// the dependence.
+ virtual bool isSplitable(unsigned Level) const { return false; }
+
+ /// isScalar - Returns true if a particular level is scalar; that is,
+ /// if no subscript in the source or destination mention the induction
+ /// variable associated with the loop at this level.
+ virtual bool isScalar(unsigned Level) const;
+
+ /// dump - For debugging purposes, dumps a dependence to OS.
+ ///
+ void dump(raw_ostream &OS) const;
+ private:
+ Instruction *Src, *Dst;
+ friend class DependenceAnalysis;
+ };
+
+
+ /// FullDependence - This class represents a dependence between two memory
+ /// references in a function. It contains detailed information about the
+ /// dependence (direction vectors, etc) and is used when the compiler is
+ /// able to accurately analyze the interaction of the references; that is,
+ /// it is not a confused dependence (see Dependence). In most cases
+ /// (for output, flow, and anti dependences), the dependence implies an
+ /// ordering, where the source must precede the destination; in contrast,
+ /// input dependences are unordered.
+ class FullDependence : public Dependence {
+ public:
+ FullDependence(Instruction *Src,
+ Instruction *Dst,
+ bool LoopIndependent,
+ unsigned Levels);
+ ~FullDependence() {
+ delete[] DV;
+ }
+
+ /// isLoopIndependent - Returns true if this is a loop-independent
+ /// dependence.
+ bool isLoopIndependent() const { return LoopIndependent; }
+
+ /// isConfused - Returns true if this dependence is confused
+ /// (the compiler understands nothing and makes worst-case
+ /// assumptions).
+ bool isConfused() const { return false; }
+
+ /// isConsistent - Returns true if this dependence is consistent
+ /// (occurs every time the source and destination are executed).
+ bool isConsistent() const { return Consistent; }
+
+ /// getLevels - Returns the number of common loops surrounding the
+ /// source and destination of the dependence.
+ unsigned getLevels() const { return Levels; }
+
+ /// getDirection - Returns the direction associated with a particular
+ /// level.
+ unsigned getDirection(unsigned Level) const;
+
+ /// getDistance - Returns the distance (or NULL) associated with a
+ /// particular level.
+ const SCEV *getDistance(unsigned Level) const;
+
+ /// isPeelFirst - Returns true if peeling the first iteration from
+ /// this loop will break this dependence.
+ bool isPeelFirst(unsigned Level) const;
+
+ /// isPeelLast - Returns true if peeling the last iteration from
+ /// this loop will break this dependence.
+ bool isPeelLast(unsigned Level) const;
+
+ /// isSplitable - Returns true if splitting the loop will break
+ /// the dependence.
+ bool isSplitable(unsigned Level) const;
+
+ /// isScalar - Returns true if a particular level is scalar; that is,
+ /// if no subscript in the source or destination mention the induction
+ /// variable associated with the loop at this level.
+ bool isScalar(unsigned Level) const;
+ private:
+ unsigned short Levels;
+ bool LoopIndependent;
+ bool Consistent; // Init to true, then refine.
+ DVEntry *DV;
+ friend class DependenceAnalysis;
+ };
+
+
+ /// DependenceAnalysis - This class is the main dependence-analysis driver.
+ ///
+ class DependenceAnalysis : public FunctionPass {
+ void operator=(const DependenceAnalysis &); // do not implement
+ DependenceAnalysis(const DependenceAnalysis &); // do not implement
+ public:
+ /// depends - Tests for a dependence between the Src and Dst instructions.
+ /// Returns NULL if no dependence; otherwise, returns a Dependence (or a
+ /// FullDependence) with as much information as can be gleaned.
+ /// The flag PossiblyLoopIndependent should be set by the caller
+ /// if it appears that control flow can reach from Src to Dst
+ /// without traversing a loop back edge.
+ Dependence *depends(Instruction *Src,
+ Instruction *Dst,
+ bool PossiblyLoopIndependent);
+
+ /// getSplitIteration - Give a dependence that's splitable at some
+ /// particular level, return the iteration that should be used to split
+ /// the loop.
+ ///
+ /// Generally, the dependence analyzer will be used to build
+ /// a dependence graph for a function (basically a map from instructions
+ /// to dependences). Looking for cycles in the graph shows us loops
+ /// that cannot be trivially vectorized/parallelized.
+ ///
+ /// We can try to improve the situation by examining all the dependences
+ /// that make up the cycle, looking for ones we can break.
+ /// Sometimes, peeling the first or last iteration of a loop will break
+ /// dependences, and there are flags for those possibilities.
+ /// Sometimes, splitting a loop at some other iteration will do the trick,
+ /// and we've got a flag for that case. Rather than waste the space to
+ /// record the exact iteration (since we rarely know), we provide
+ /// a method that calculates the iteration. It's a drag that it must work
+ /// from scratch, but wonderful in that it's possible.
+ ///
+ /// Here's an example:
+ ///
+ /// for (i = 0; i < 10; i++)
+ /// A[i] = ...
+ /// ... = A[11 - i]
+ ///
+ /// There's a loop-carried flow dependence from the store to the load,
+ /// found by the weak-crossing SIV test. The dependence will have a flag,
+ /// indicating that the dependence can be broken by splitting the loop.
+ /// Calling getSplitIteration will return 5.
+ /// Splitting the loop breaks the dependence, like so:
+ ///
+ /// for (i = 0; i <= 5; i++)
+ /// A[i] = ...
+ /// ... = A[11 - i]
+ /// for (i = 6; i < 10; i++)
+ /// A[i] = ...
+ /// ... = A[11 - i]
+ ///
+ /// breaks the dependence and allows us to vectorize/parallelize
+ /// both loops.
+ const SCEV *getSplitIteration(const Dependence *Dep, unsigned Level);
+
+ private:
+ AliasAnalysis *AA;
+ ScalarEvolution *SE;
+ LoopInfo *LI;
+ Function *F;
+
+ /// Subscript - This private struct represents a pair of subscripts from
+ /// a pair of potentially multi-dimensional array references. We use a
+ /// vector of them to guide subscript partitioning.
+ struct Subscript {
+ const SCEV *Src;
+ const SCEV *Dst;
+ enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
+ SmallBitVector Loops;
+ SmallBitVector GroupLoops;
+ SmallBitVector Group;
+ };
+
+ struct CoefficientInfo {
+ const SCEV *Coeff;
+ const SCEV *PosPart;
+ const SCEV *NegPart;
+ const SCEV *Iterations;
+ };
+
+ struct BoundInfo {
+ const SCEV *Iterations;
+ const SCEV *Upper[8];
+ const SCEV *Lower[8];
+ unsigned char Direction;
+ unsigned char DirSet;
+ };
+
+ /// Constraint - This private class represents a constraint, as defined
+ /// in the paper
+ ///
+ /// Practical Dependence Testing
+ /// Goff, Kennedy, Tseng
+ /// PLDI 1991
+ ///
+ /// There are 5 kinds of constraint, in a hierarchy.
+ /// 1) Any - indicates no constraint, any dependence is possible.
+ /// 2) Line - A line ax + by = c, where a, b, and c are parameters,
+ /// representing the dependence equation.
+ /// 3) Distance - The value d of the dependence distance;
+ /// 4) Point - A point <x, y> representing the dependence from
+ /// iteration x to iteration y.
+ /// 5) Empty - No dependence is possible.
+ class Constraint {
+ private:
+ enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
+ ScalarEvolution *SE;
+ const SCEV *A;
+ const SCEV *B;
+ const SCEV *C;
+ const Loop *AssociatedLoop;
+ public:
+ /// isEmpty - Return true if the constraint is of kind Empty.
+ bool isEmpty() const { return Kind == Empty; }
+
+ /// isPoint - Return true if the constraint is of kind Point.
+ bool isPoint() const { return Kind == Point; }
+
+ /// isDistance - Return true if the constraint is of kind Distance.
+ bool isDistance() const { return Kind == Distance; }
+
+ /// isLine - Return true if the constraint is of kind Line.
+ /// Since Distance's can also be represented as Lines, we also return
+ /// true if the constraint is of kind Distance.
+ bool isLine() const { return Kind == Line || Kind == Distance; }
+
+ /// isAny - Return true if the constraint is of kind Any;
+ bool isAny() const { return Kind == Any; }
+
+ /// getX - If constraint is a point <X, Y>, returns X.
+ /// Otherwise assert.
+ const SCEV *getX() const;
+
+ /// getY - If constraint is a point <X, Y>, returns Y.
+ /// Otherwise assert.
+ const SCEV *getY() const;
+
+ /// getA - If constraint is a line AX + BY = C, returns A.
+ /// Otherwise assert.
+ const SCEV *getA() const;
+
+ /// getB - If constraint is a line AX + BY = C, returns B.
+ /// Otherwise assert.
+ const SCEV *getB() const;
+
+ /// getC - If constraint is a line AX + BY = C, returns C.
+ /// Otherwise assert.
+ const SCEV *getC() const;
+
+ /// getD - If constraint is a distance, returns D.
+ /// Otherwise assert.
+ const SCEV *getD() const;
+
+ /// getAssociatedLoop - Returns the loop associated with this constraint.
+ const Loop *getAssociatedLoop() const;
+
+ /// setPoint - Change a constraint to Point.
+ void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
+
+ /// setLine - Change a constraint to Line.
+ void setLine(const SCEV *A, const SCEV *B,
+ const SCEV *C, const Loop *CurrentLoop);
+
+ /// setDistance - Change a constraint to Distance.
+ void setDistance(const SCEV *D, const Loop *CurrentLoop);
+
+ /// setEmpty - Change a constraint to Empty.
+ void setEmpty();
+
+ /// setAny - Change a constraint to Any.
+ void setAny(ScalarEvolution *SE);
+
+ /// dump - For debugging purposes. Dumps the constraint
+ /// out to OS.
+ void dump(raw_ostream &OS) const;
+ };
+
+
+ /// establishNestingLevels - Examines the loop nesting of the Src and Dst
+ /// instructions and establishes their shared loops. Sets the variables
+ /// CommonLevels, SrcLevels, and MaxLevels.
+ /// The source and destination instructions needn't be contained in the same
+ /// loop. The routine establishNestingLevels finds the level of most deeply
+ /// nested loop that contains them both, CommonLevels. An instruction that's
+ /// not contained in a loop is at level = 0. MaxLevels is equal to the level
+ /// of the source plus the level of the destination, minus CommonLevels.
+ /// This lets us allocate vectors MaxLevels in length, with room for every
+ /// distinct loop referenced in both the source and destination subscripts.
+ /// The variable SrcLevels is the nesting depth of the source instruction.
+ /// It's used to help calculate distinct loops referenced by the destination.
+ /// Here's the map from loops to levels:
+ /// 0 - unused
+ /// 1 - outermost common loop
+ /// ... - other common loops
+ /// CommonLevels - innermost common loop
+ /// ... - loops containing Src but not Dst
+ /// SrcLevels - innermost loop containing Src but not Dst
+ /// ... - loops containing Dst but not Src
+ /// MaxLevels - innermost loop containing Dst but not Src
+ /// Consider the follow code fragment:
+ /// for (a = ...) {
+ /// for (b = ...) {
+ /// for (c = ...) {
+ /// for (d = ...) {
+ /// A[] = ...;
+ /// }
+ /// }
+ /// for (e = ...) {
+ /// for (f = ...) {
+ /// for (g = ...) {
+ /// ... = A[];
+ /// }
+ /// }
+ /// }
+ /// }
+ /// }
+ /// If we're looking at the possibility of a dependence between the store
+ /// to A (the Src) and the load from A (the Dst), we'll note that they
+ /// have 2 loops in common, so CommonLevels will equal 2 and the direction
+ /// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
+ /// A map from loop names to level indices would look like
+ /// a - 1
+ /// b - 2 = CommonLevels
+ /// c - 3
+ /// d - 4 = SrcLevels
+ /// e - 5
+ /// f - 6
+ /// g - 7 = MaxLevels
+ void establishNestingLevels(const Instruction *Src,
+ const Instruction *Dst);
+
+ unsigned CommonLevels, SrcLevels, MaxLevels;
+
+ /// mapSrcLoop - Given one of the loops containing the source, return
+ /// its level index in our numbering scheme.
+ unsigned mapSrcLoop(const Loop *SrcLoop) const;
+
+ /// mapDstLoop - Given one of the loops containing the destination,
+ /// return its level index in our numbering scheme.
+ unsigned mapDstLoop(const Loop *DstLoop) const;
+
+ /// isLoopInvariant - Returns true if Expression is loop invariant
+ /// in LoopNest.
+ bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
+
+ /// removeMatchingExtensions - Examines a subscript pair.
+ /// If the source and destination are identically sign (or zero)
+ /// extended, it strips off the extension in an effort to
+ /// simplify the actual analysis.
+ void removeMatchingExtensions(Subscript *Pair);
+
+ /// collectCommonLoops - Finds the set of loops from the LoopNest that
+ /// have a level <= CommonLevels and are referred to by the SCEV Expression.
+ void collectCommonLoops(const SCEV *Expression,
+ const Loop *LoopNest,
+ SmallBitVector &Loops) const;
+
+ /// checkSrcSubscript - Examines the SCEV Src, returning true iff it's
+ /// linear. Collect the set of loops mentioned by Src.
+ bool checkSrcSubscript(const SCEV *Src,
+ const Loop *LoopNest,
+ SmallBitVector &Loops);
+
+ /// checkDstSubscript - Examines the SCEV Dst, returning true iff it's
+ /// linear. Collect the set of loops mentioned by Dst.
+ bool checkDstSubscript(const SCEV *Dst,
+ const Loop *LoopNest,
+ SmallBitVector &Loops);
+
+ /// isKnownPredicate - Compare X and Y using the predicate Pred.
+ /// Basically a wrapper for SCEV::isKnownPredicate,
+ /// but tries harder, especially in the presence of sign and zero
+ /// extensions and symbolics.
+ bool isKnownPredicate(ICmpInst::Predicate Pred,
+ const SCEV *X,
+ const SCEV *Y) const;
+
+ /// collectUpperBound - All subscripts are the same type (on my machine,
+ /// an i64). The loop bound may be a smaller type. collectUpperBound
+ /// find the bound, if available, and zero extends it to the Type T.
+ /// (I zero extend since the bound should always be >= 0.)
+ /// If no upper bound is available, return NULL.
+ const SCEV *collectUpperBound(const Loop *l, Type *T) const;
+
+ /// collectConstantUpperBound - Calls collectUpperBound(), then
+ /// attempts to cast it to SCEVConstant. If the cast fails,
+ /// returns NULL.
+ const SCEVConstant *collectConstantUpperBound(const Loop *l, Type *T) const;
+
+ /// classifyPair - Examines the subscript pair (the Src and Dst SCEVs)
+ /// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
+ /// Collects the associated loops in a set.
+ Subscript::ClassificationKind classifyPair(const SCEV *Src,
+ const Loop *SrcLoopNest,
+ const SCEV *Dst,
+ const Loop *DstLoopNest,
+ SmallBitVector &Loops);
+
+ /// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence.
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// If the dependence isn't proven to exist,
+ /// marks the Result as inconsistent.
+ bool testZIV(const SCEV *Src,
+ const SCEV *Dst,
+ FullDependence &Result) const;
+
+ /// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence.
+ /// Things of the form [c1 + a1*i] and [c2 + a2*j], where
+ /// i and j are induction variables, c1 and c2 are loop invariant,
+ /// and a1 and a2 are constant.
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// Sets appropriate direction vector entry and, when possible,
+ /// the distance vector entry.
+ /// If the dependence isn't proven to exist,
+ /// marks the Result as inconsistent.
+ bool testSIV(const SCEV *Src,
+ const SCEV *Dst,
+ unsigned &Level,
+ FullDependence &Result,
+ Constraint &NewConstraint,
+ const SCEV *&SplitIter) const;
+
+ /// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
+ /// Things of the form [c1 + a1*i] and [c2 + a2*j]
+ /// where i and j are induction variables, c1 and c2 are loop invariant,
+ /// and a1 and a2 are constant.
+ /// With minor algebra, this test can also be used for things like
+ /// [c1 + a1*i + a2*j][c2].
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// Marks the Result as inconsistent.
+ bool testRDIV(const SCEV *Src,
+ const SCEV *Dst,
+ FullDependence &Result) const;
+
+ /// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence.
+ /// Returns true if dependence disproved.
+ /// Can sometimes refine direction vectors.
+ bool testMIV(const SCEV *Src,
+ const SCEV *Dst,
+ const SmallBitVector &Loops,
+ FullDependence &Result) const;
+
+ /// strongSIVtest - Tests the strong SIV subscript pair (Src and Dst)
+ /// for dependence.
+ /// Things of the form [c1 + a*i] and [c2 + a*i],
+ /// where i is an induction variable, c1 and c2 are loop invariant,
+ /// and a is a constant
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// Sets appropriate direction and distance.
+ bool strongSIVtest(const SCEV *Coeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *CurrentLoop,
+ unsigned Level,
+ FullDependence &Result,
+ Constraint &NewConstraint) const;
+
+ /// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
+ /// (Src and Dst) for dependence.
+ /// Things of the form [c1 + a*i] and [c2 - a*i],
+ /// where i is an induction variable, c1 and c2 are loop invariant,
+ /// and a is a constant.
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// Sets appropriate direction entry.
+ /// Set consistent to false.
+ /// Marks the dependence as splitable.
+ bool weakCrossingSIVtest(const SCEV *SrcCoeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *CurrentLoop,
+ unsigned Level,
+ FullDependence &Result,
+ Constraint &NewConstraint,
+ const SCEV *&SplitIter) const;
+
+ /// ExactSIVtest - Tests the SIV subscript pair
+ /// (Src and Dst) for dependence.
+ /// Things of the form [c1 + a1*i] and [c2 + a2*i],
+ /// where i is an induction variable, c1 and c2 are loop invariant,
+ /// and a1 and a2 are constant.
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// Sets appropriate direction entry.
+ /// Set consistent to false.
+ bool exactSIVtest(const SCEV *SrcCoeff,
+ const SCEV *DstCoeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *CurrentLoop,
+ unsigned Level,
+ FullDependence &Result,
+ Constraint &NewConstraint) const;
+
+ /// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
+ /// (Src and Dst) for dependence.
+ /// Things of the form [c1] and [c2 + a*i],
+ /// where i is an induction variable, c1 and c2 are loop invariant,
+ /// and a is a constant. See also weakZeroDstSIVtest.
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// Sets appropriate direction entry.
+ /// Set consistent to false.
+ /// If loop peeling will break the dependence, mark appropriately.
+ bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *CurrentLoop,
+ unsigned Level,
+ FullDependence &Result,
+ Constraint &NewConstraint) const;
+
+ /// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
+ /// (Src and Dst) for dependence.
+ /// Things of the form [c1 + a*i] and [c2],
+ /// where i is an induction variable, c1 and c2 are loop invariant,
+ /// and a is a constant. See also weakZeroSrcSIVtest.
+ /// Returns true if any possible dependence is disproved.
+ /// If there might be a dependence, returns false.
+ /// Sets appropriate direction entry.
+ /// Set consistent to false.
+ /// If loop peeling will break the dependence, mark appropriately.
+ bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *CurrentLoop,
+ unsigned Level,
+ FullDependence &Result,
+ Constraint &NewConstraint) const;
+
+ /// exactRDIVtest - Tests the RDIV subscript pair for dependence.
+ /// Things of the form [c1 + a*i] and [c2 + b*j],
+ /// where i and j are induction variable, c1 and c2 are loop invariant,
+ /// and a and b are constants.
+ /// Returns true if any possible dependence is disproved.
+ /// Marks the result as inconsistent.
+ /// Works in some cases that symbolicRDIVtest doesn't,
+ /// and vice versa.
+ bool exactRDIVtest(const SCEV *SrcCoeff,
+ const SCEV *DstCoeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *SrcLoop,
+ const Loop *DstLoop,
+ FullDependence &Result) const;
+
+ /// symbolicRDIVtest - Tests the RDIV subscript pair for dependence.
+ /// Things of the form [c1 + a*i] and [c2 + b*j],
+ /// where i and j are induction variable, c1 and c2 are loop invariant,
+ /// and a and b are constants.
+ /// Returns true if any possible dependence is disproved.
+ /// Marks the result as inconsistent.
+ /// Works in some cases that exactRDIVtest doesn't,
+ /// and vice versa. Can also be used as a backup for
+ /// ordinary SIV tests.
+ bool symbolicRDIVtest(const SCEV *SrcCoeff,
+ const SCEV *DstCoeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *SrcLoop,
+ const Loop *DstLoop) const;
+
+ /// gcdMIVtest - Tests an MIV subscript pair for dependence.
+ /// Returns true if any possible dependence is disproved.
+ /// Marks the result as inconsistent.
+ /// Can sometimes disprove the equal direction for 1 or more loops.
+ // Can handle some symbolics that even the SIV tests don't get,
+ /// so we use it as a backup for everything.
+ bool gcdMIVtest(const SCEV *Src,
+ const SCEV *Dst,
+ FullDependence &Result) const;
+
+ /// banerjeeMIVtest - Tests an MIV subscript pair for dependence.
+ /// Returns true if any possible dependence is disproved.
+ /// Marks the result as inconsistent.
+ /// Computes directions.
+ bool banerjeeMIVtest(const SCEV *Src,
+ const SCEV *Dst,
+ const SmallBitVector &Loops,
+ FullDependence &Result) const;
+
+ /// collectCoefficientInfo - Walks through the subscript,
+ /// collecting each coefficient, the associated loop bounds,
+ /// and recording its positive and negative parts for later use.
+ CoefficientInfo *collectCoeffInfo(const SCEV *Subscript,
+ bool SrcFlag,
+ const SCEV *&Constant) const;
+
+ /// getPositivePart - X^+ = max(X, 0).
+ ///
+ const SCEV *getPositivePart(const SCEV *X) const;
+
+ /// getNegativePart - X^- = min(X, 0).
+ ///
+ const SCEV *getNegativePart(const SCEV *X) const;
+
+ /// getLowerBound - Looks through all the bounds info and
+ /// computes the lower bound given the current direction settings
+ /// at each level.
+ const SCEV *getLowerBound(BoundInfo *Bound) const;
+
+ /// getUpperBound - Looks through all the bounds info and
+ /// computes the upper bound given the current direction settings
+ /// at each level.
+ const SCEV *getUpperBound(BoundInfo *Bound) const;
+
+ /// exploreDirections - Hierarchically expands the direction vector
+ /// search space, combining the directions of discovered dependences
+ /// in the DirSet field of Bound. Returns the number of distinct
+ /// dependences discovered. If the dependence is disproved,
+ /// it will return 0.
+ unsigned exploreDirections(unsigned Level,
+ CoefficientInfo *A,
+ CoefficientInfo *B,
+ BoundInfo *Bound,
+ const SmallBitVector &Loops,
+ unsigned &DepthExpanded,
+ const SCEV *Delta) const;
+
+ /// testBounds - Returns true iff the current bounds are plausible.
+ ///
+ bool testBounds(unsigned char DirKind,
+ unsigned Level,
+ BoundInfo *Bound,
+ const SCEV *Delta) const;
+
+ /// findBoundsALL - Computes the upper and lower bounds for level K
+ /// using the * direction. Records them in Bound.
+ void findBoundsALL(CoefficientInfo *A,
+ CoefficientInfo *B,
+ BoundInfo *Bound,
+ unsigned K) const;
+
+ /// findBoundsLT - Computes the upper and lower bounds for level K
+ /// using the < direction. Records them in Bound.
+ void findBoundsLT(CoefficientInfo *A,
+ CoefficientInfo *B,
+ BoundInfo *Bound,
+ unsigned K) const;
+
+ /// findBoundsGT - Computes the upper and lower bounds for level K
+ /// using the > direction. Records them in Bound.
+ void findBoundsGT(CoefficientInfo *A,
+ CoefficientInfo *B,
+ BoundInfo *Bound,
+ unsigned K) const;
+
+ /// findBoundsEQ - Computes the upper and lower bounds for level K
+ /// using the = direction. Records them in Bound.
+ void findBoundsEQ(CoefficientInfo *A,
+ CoefficientInfo *B,
+ BoundInfo *Bound,
+ unsigned K) const;
+
+ /// intersectConstraints - Updates X with the intersection
+ /// of the Constraints X and Y. Returns true if X has changed.
+ bool intersectConstraints(Constraint *X,
+ const Constraint *Y);
+
+ /// propagate - Review the constraints, looking for opportunities
+ /// to simplify a subscript pair (Src and Dst).
+ /// Return true if some simplification occurs.
+ /// If the simplification isn't exact (that is, if it is conservative
+ /// in terms of dependence), set consistent to false.
+ bool propagate(const SCEV *&Src,
+ const SCEV *&Dst,
+ SmallBitVector &Loops,
+ SmallVector<Constraint, 4> &Constraints,
+ bool &Consistent);
+
+ /// propagateDistance - Attempt to propagate a distance
+ /// constraint into a subscript pair (Src and Dst).
+ /// Return true if some simplification occurs.
+ /// If the simplification isn't exact (that is, if it is conservative
+ /// in terms of dependence), set consistent to false.
+ bool propagateDistance(const SCEV *&Src,
+ const SCEV *&Dst,
+ Constraint &CurConstraint,
+ bool &Consistent);
+
+ /// propagatePoint - Attempt to propagate a point
+ /// constraint into a subscript pair (Src and Dst).
+ /// Return true if some simplification occurs.
+ bool propagatePoint(const SCEV *&Src,
+ const SCEV *&Dst,
+ Constraint &CurConstraint);
+
+ /// propagateLine - Attempt to propagate a line
+ /// constraint into a subscript pair (Src and Dst).
+ /// Return true if some simplification occurs.
+ /// If the simplification isn't exact (that is, if it is conservative
+ /// in terms of dependence), set consistent to false.
+ bool propagateLine(const SCEV *&Src,
+ const SCEV *&Dst,
+ Constraint &CurConstraint,
+ bool &Consistent);
+
+ /// findCoefficient - Given a linear SCEV,
+ /// return the coefficient corresponding to specified loop.
+ /// If there isn't one, return the SCEV constant 0.
+ /// For example, given a*i + b*j + c*k, returning the coefficient
+ /// corresponding to the j loop would yield b.
+ const SCEV *findCoefficient(const SCEV *Expr,
+ const Loop *TargetLoop) const;
+
+ /// zeroCoefficient - Given a linear SCEV,
+ /// return the SCEV given by zeroing out the coefficient
+ /// corresponding to the specified loop.
+ /// For example, given a*i + b*j + c*k, zeroing the coefficient
+ /// corresponding to the j loop would yield a*i + c*k.
+ const SCEV *zeroCoefficient(const SCEV *Expr,
+ const Loop *TargetLoop) const;
+
+ /// addToCoefficient - Given a linear SCEV Expr,
+ /// return the SCEV given by adding some Value to the
+ /// coefficient corresponding to the specified TargetLoop.
+ /// For example, given a*i + b*j + c*k, adding 1 to the coefficient
+ /// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
+ const SCEV *addToCoefficient(const SCEV *Expr,
+ const Loop *TargetLoop,
+ const SCEV *Value) const;
+
+ /// updateDirection - Update direction vector entry
+ /// based on the current constraint.
+ void updateDirection(Dependence::DVEntry &Level,
+ const Constraint &CurConstraint) const;
+ public:
+ static char ID; // Class identification, replacement for typeinfo
+ DependenceAnalysis() : FunctionPass(ID) {
+ initializeDependenceAnalysisPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F);
+ void releaseMemory();
+ void getAnalysisUsage(AnalysisUsage &) const;
+ void print(raw_ostream &, const Module * = 0) const;
+ }; // class DependenceAnalysis
+
+ /// createDependenceAnalysisPass - This creates an instance of the
+ /// DependenceAnalysis pass.
+ FunctionPass *createDependenceAnalysisPass();
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h
index 0c29236..c0f95cb 100644
--- a/include/llvm/Analysis/DominatorInternals.h
+++ b/include/llvm/Analysis/DominatorInternals.h
@@ -10,8 +10,8 @@
#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
-#include "llvm/Analysis/Dominators.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/Dominators.h"
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index a1cc196..d62a3ac 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -15,13 +15,13 @@
#ifndef LLVM_ANALYSIS_DOMINATORS_H
#define LLVM_ANALYSIS_DOMINATORS_H
-#include "llvm/Pass.h"
-#include "llvm/Function.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Function.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
@@ -346,7 +346,7 @@ public:
DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
- /// properlyDominates - Returns true iff this dominates N and this != N.
+ /// properlyDominates - Returns true iff A dominates B and A != B.
/// Note that this is not a constant time operation!
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index 2bf79b9..9b98013 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -28,7 +28,7 @@ class IVUsers;
class ScalarEvolution;
class SCEV;
class IVUsers;
-class TargetData;
+class DataLayout;
/// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user
@@ -123,7 +123,7 @@ class IVUsers : public LoopPass {
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
- TargetData *TD;
+ DataLayout *TD;
SmallPtrSet<Instruction*,16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index 0cba135..42e329e 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -14,11 +14,11 @@
#ifndef LLVM_ANALYSIS_INLINECOST_H
#define LLVM_ANALYSIS_INLINECOST_H
-#include "llvm/Function.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Analysis/CodeMetrics.h"
+#include "llvm/IR/Function.h"
#include <cassert>
#include <climits>
#include <vector>
@@ -26,7 +26,7 @@
namespace llvm {
class CallSite;
- class TargetData;
+ class DataLayout;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
@@ -36,6 +36,9 @@ namespace llvm {
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
+ /// Do not inline functions which allocate this many bytes on the stack
+ /// when the caller is recursive.
+ const unsigned TotalAllocaSizeRecursiveCaller = 1024;
}
/// \brief Represents the cost of inlining a function.
@@ -101,13 +104,13 @@ namespace llvm {
/// InlineCostAnalyzer - Cost analyzer used by inliner.
class InlineCostAnalyzer {
- // TargetData if available, or null.
- const TargetData *TD;
+ // DataLayout if available, or null.
+ const DataLayout *TD;
public:
InlineCostAnalyzer(): TD(0) {}
- void setTargetData(const TargetData *TData) { TD = TData; }
+ void setDataLayout(const DataLayout *TData) { TD = TData; }
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
@@ -117,15 +120,18 @@ namespace llvm {
/// bound the computation necessary to determine whether the cost is
/// sufficiently low to warrant inlining.
InlineCost getInlineCost(CallSite CS, int Threshold);
- /// getCalledFunction - The heuristic used to determine if we should inline
- /// the function call or not. The callee is explicitly specified, to allow
- /// you to calculate the cost of inlining a function via a pointer. This
- /// behaves exactly as the version with no explicit callee parameter in all
- /// other respects.
+
+ /// \brief Get an InlineCost with the callee explicitly specified.
+ /// This allows you to calculate the cost of inlining a function via a
+ /// pointer. This behaves exactly as the version with no explicit callee
+ /// parameter in all other respects.
//
// Note: This is used by out-of-tree passes, please do not remove without
// adding a replacement API.
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
+
+ /// \brief Minimal filter to detect invalid constructs for inlining.
+ bool isInlineViable(Function &Callee);
};
}
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index 152e885..b653e79 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -19,12 +19,15 @@
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
+#include "llvm/IR/User.h"
+
namespace llvm {
template<typename T>
class ArrayRef;
class DominatorTree;
class Instruction;
- class TargetData;
+ class DataLayout;
+ class FastMathFlags;
class TargetLibraryInfo;
class Type;
class Value;
@@ -32,122 +35,144 @@ namespace llvm {
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+ /// Given operands for an FAdd, see if we can fold the result. If not, this
+ /// returns null.
+ Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+ /// Given operands for an FSub, see if we can fold the result. If not, this
+ /// returns null.
+ Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
+ /// Given operands for an FMul, see if we can fold the result. If not, this
+ /// returns null.
+ Value *SimplifyFMulInst(Value *LHS, Value *RHS,
+ FastMathFlags FMF,
+ const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyFDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyFRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD = 0,
+ Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -155,13 +180,13 @@ namespace llvm {
/// can fold the result. If not, this returns null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
- Value *SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD = 0,
+ Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -171,20 +196,38 @@ namespace llvm {
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
+ /// \brief Given a function and iterators over arguments, see if we can fold
+ /// the result.
+ ///
+ /// If this call could not be simplified returns null.
+ Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
+ User::op_iterator ArgEnd, const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+ /// \brief Given a function and set of arguments, see if we can fold the
+ /// result.
+ ///
+ /// If this call could not be simplified returns null.
+ Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
+ const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
- Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0,
+ Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -198,7 +241,7 @@ namespace llvm {
///
/// The function returns true if any simplifications were performed.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -209,7 +252,7 @@ namespace llvm {
/// of the users impacted. It returns true if any simplifications were
/// performed.
bool recursivelySimplifyInstruction(Instruction *I,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
} // end namespace llvm
diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h
index 0968c74..bd9ab20 100644
--- a/include/llvm/Analysis/IntervalIterator.h
+++ b/include/llvm/Analysis/IntervalIterator.h
@@ -34,7 +34,7 @@
#define LLVM_INTERVAL_ITERATOR_H
#include "llvm/Analysis/IntervalPartition.h"
-#include "llvm/Function.h"
+#include "llvm/IR/Function.h"
#include "llvm/Support/CFG.h"
#include <algorithm>
#include <set>
diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h
index df7313f..bce84be 100644
--- a/include/llvm/Analysis/IntervalPartition.h
+++ b/include/llvm/Analysis/IntervalPartition.h
@@ -33,8 +33,8 @@ namespace llvm {
//
// IntervalPartition - This class builds and holds an "interval partition" for
// a function. This partition divides the control flow graph into a set of
-// maximal intervals, as defined with the properties above. Intuitively, a
-// BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping
+// maximal intervals, as defined with the properties above. Intuitively, an
+// interval is a (possibly nonexistent) loop with a "tail" of non looping
// nodes following it.
//
class IntervalPartition : public FunctionPass {
diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h
index 065c230..197e94e 100644
--- a/include/llvm/Analysis/LazyValueInfo.h
+++ b/include/llvm/Analysis/LazyValueInfo.h
@@ -19,18 +19,18 @@
namespace llvm {
class Constant;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class Value;
/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
/// information.
class LazyValueInfo : public FunctionPass {
- class TargetData *TD;
+ class DataLayout *TD;
class TargetLibraryInfo *TLI;
void *PImpl;
- LazyValueInfo(const LazyValueInfo&); // DO NOT IMPLEMENT.
- void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT.
+ LazyValueInfo(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
+ void operator=(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
public:
static char ID;
LazyValueInfo() : FunctionPass(ID), PImpl(0) {
diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h
index 5f0aefb..ebcb762 100644
--- a/include/llvm/Analysis/Loads.h
+++ b/include/llvm/Analysis/Loads.h
@@ -14,12 +14,12 @@
#ifndef LLVM_ANALYSIS_LOADS_H
#define LLVM_ANALYSIS_LOADS_H
-#include "llvm/BasicBlock.h"
+#include "llvm/IR/BasicBlock.h"
namespace llvm {
class AliasAnalysis;
-class TargetData;
+class DataLayout;
class MDNode;
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
@@ -27,7 +27,7 @@ class MDNode;
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
- unsigned Align, const TargetData *TD = 0);
+ unsigned Align, const DataLayout *TD = 0);
/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
/// the instruction before ScanFrom) checking to see if we have the value at
diff --git a/include/llvm/Analysis/LoopDependenceAnalysis.h b/include/llvm/Analysis/LoopDependenceAnalysis.h
deleted file mode 100644
index f195d27..0000000
--- a/include/llvm/Analysis/LoopDependenceAnalysis.h
+++ /dev/null
@@ -1,124 +0,0 @@
-//===- llvm/Analysis/LoopDependenceAnalysis.h --------------- -*- C++ -*---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// LoopDependenceAnalysis is an LLVM pass that analyses dependences in memory
-// accesses in loops.
-//
-// Please note that this is work in progress and the interface is subject to
-// change.
-//
-// TODO: adapt as interface progresses
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
-#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
-
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Support/Allocator.h"
-
-namespace llvm {
-
-class AliasAnalysis;
-class AnalysisUsage;
-class ScalarEvolution;
-class SCEV;
-class Value;
-class raw_ostream;
-
-class LoopDependenceAnalysis : public LoopPass {
- AliasAnalysis *AA;
- ScalarEvolution *SE;
-
- /// L - The loop we are currently analysing.
- Loop *L;
-
- /// TODO: doc
- enum DependenceResult { Independent = 0, Dependent = 1, Unknown = 2 };
-
- /// TODO: doc
- struct Subscript {
- /// TODO: Add distance, direction, breaking conditions, ...
- };
-
- /// DependencePair - Represents a data dependence relation between to memory
- /// reference instructions.
- struct DependencePair : public FastFoldingSetNode {
- Value *A;
- Value *B;
- DependenceResult Result;
- SmallVector<Subscript, 4> Subscripts;
-
- DependencePair(const FoldingSetNodeID &ID, Value *a, Value *b) :
- FastFoldingSetNode(ID), A(a), B(b), Result(Unknown), Subscripts() {}
- };
-
- /// findOrInsertDependencePair - Return true if a DependencePair for the
- /// given Values already exists, false if a new DependencePair had to be
- /// created. The third argument is set to the pair found or created.
- bool findOrInsertDependencePair(Value*, Value*, DependencePair*&);
-
- /// getLoops - Collect all loops of the loop nest L in which
- /// a given SCEV is variant.
- void getLoops(const SCEV*, DenseSet<const Loop*>*) const;
-
- /// isLoopInvariant - True if a given SCEV is invariant in all loops of the
- /// loop nest starting at the innermost loop L.
- bool isLoopInvariant(const SCEV*) const;
-
- /// isAffine - An SCEV is affine with respect to the loop nest starting at
- /// the innermost loop L if it is of the form A+B*X where A, B are invariant
- /// in the loop nest and X is a induction variable in the loop nest.
- bool isAffine(const SCEV*) const;
-
- /// TODO: doc
- bool isZIVPair(const SCEV*, const SCEV*) const;
- bool isSIVPair(const SCEV*, const SCEV*) const;
- DependenceResult analyseZIV(const SCEV*, const SCEV*, Subscript*) const;
- DependenceResult analyseSIV(const SCEV*, const SCEV*, Subscript*) const;
- DependenceResult analyseMIV(const SCEV*, const SCEV*, Subscript*) const;
- DependenceResult analyseSubscript(const SCEV*, const SCEV*, Subscript*) const;
- DependenceResult analysePair(DependencePair*) const;
-
-public:
- static char ID; // Class identification, replacement for typeinfo
- LoopDependenceAnalysis() : LoopPass(ID) {
- initializeLoopDependenceAnalysisPass(*PassRegistry::getPassRegistry());
- }
-
- /// isDependencePair - Check whether two values can possibly give rise to
- /// a data dependence: that is the case if both are instructions accessing
- /// memory and at least one of those accesses is a write.
- bool isDependencePair(const Value*, const Value*) const;
-
- /// depends - Return a boolean indicating if there is a data dependence
- /// between two instructions.
- bool depends(Value*, Value*);
-
- bool runOnLoop(Loop*, LPPassManager&);
- virtual void releaseMemory();
- virtual void getAnalysisUsage(AnalysisUsage&) const;
- void print(raw_ostream&, const Module* = 0) const;
-
-private:
- FoldingSet<DependencePair> Pairs;
- BumpPtrAllocator PairAllocator;
-}; // class LoopDependenceAnalysis
-
-// createLoopDependenceAnalysisPass - This creates an instance of the
-// LoopDependenceAnalysis pass.
-//
-LoopPass *createLoopDependenceAnalysisPass();
-
-} // namespace llvm
-
-#endif /* LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H */
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index eeb482d..830754d 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -30,14 +30,14 @@
#ifndef LLVM_ANALYSIS_LOOP_INFO_H
#define LLVM_ANALYSIS_LOOP_INFO_H
-#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/Dominators.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -72,10 +72,9 @@ class LoopBase {
// Blocks - The list of blocks in this loop. First entry is the header node.
std::vector<BlockT*> Blocks;
- // DO NOT IMPLEMENT
- LoopBase(const LoopBase<BlockT, LoopT> &);
- // DO NOT IMPLEMENT
- const LoopBase<BlockT, LoopT>&operator=(const LoopBase<BlockT, LoopT> &);
+ LoopBase(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
+ const LoopBase<BlockT, LoopT>&
+ operator=(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
public:
/// Loop ctor - This creates an empty loop.
LoopBase() : ParentLoop(0) {}
@@ -416,8 +415,8 @@ class LoopInfoBase {
friend class LoopBase<BlockT, LoopT>;
friend class LoopInfo;
- void operator=(const LoopInfoBase &); // do not implement
- LoopInfoBase(const LoopInfo &); // do not implement
+ void operator=(const LoopInfoBase &) LLVM_DELETED_FUNCTION;
+ LoopInfoBase(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
LoopInfoBase() { }
~LoopInfoBase() { releaseMemory(); }
@@ -550,8 +549,8 @@ class LoopInfo : public FunctionPass {
LoopInfoBase<BasicBlock, Loop> LI;
friend class LoopBase<BasicBlock, Loop>;
- void operator=(const LoopInfo &); // do not implement
- LoopInfo(const LoopInfo &); // do not implement
+ void operator=(const LoopInfo &) LLVM_DELETED_FUNCTION;
+ LoopInfo(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
static char ID; // Pass identification, replacement for typeid
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 3bb96f9..4b8e4c9 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -15,8 +15,8 @@
#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H
#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H
-#include "llvm/Analysis/LoopInfo.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/Analysis/LoopInfo.h"
namespace llvm {
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
index e6ed9bc..f78472a 100644
--- a/include/llvm/Analysis/LoopPass.h
+++ b/include/llvm/Analysis/LoopPass.h
@@ -16,9 +16,9 @@
#define LLVM_LOOP_PASS_H
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/PassManagers.h"
-#include "llvm/Function.h"
#include <deque>
namespace llvm {
@@ -39,6 +39,9 @@ public:
// whatever action is necessary for the specified Loop.
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
+
// Initialization and finalization hooks.
virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
return false;
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index c3ae603..f2c564f 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -15,19 +15,19 @@
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
#define LLVM_ANALYSIS_MEMORYBUILTINS_H
-#include "llvm/IRBuilder.h"
-#include "llvm/Operator.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/InstVisitor.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
namespace llvm {
class CallInst;
class PointerType;
-class TargetData;
+class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
@@ -81,7 +81,7 @@ static inline CallInst *extractMallocCall(Value *I,
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
-const CallInst *isArrayMalloc(const Value *I, const TargetData *TD,
+const CallInst *isArrayMalloc(const Value *I, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// getMallocType - Returns the PointerType resulting from the malloc call.
@@ -103,7 +103,7 @@ Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
-Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
+Value *getMallocArraySize(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool LookThroughSExt = false);
@@ -141,7 +141,7 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
/// object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
-bool getObjectSize(const Value *Ptr, uint64_t &Size, const TargetData *TD,
+bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
@@ -153,12 +153,12 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
bool RoundToAlign;
unsigned IntTyBits;
APInt Zero;
- SmallPtrSet<Instruction *, 8> SeenInsts;
+ SmallPtrSet<Value*, 8> SeenInsts;
APInt align(APInt Size, uint64_t Align);
@@ -167,7 +167,7 @@ class ObjectSizeOffsetVisitor
}
public:
- ObjectSizeOffsetVisitor(const TargetData *TD, const TargetLibraryInfo *TLI,
+ ObjectSizeOffsetVisitor(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetType compute(Value *V);
@@ -191,6 +191,7 @@ public:
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
SizeOffsetType visitGEPOperator(GEPOperator &GEP);
+ SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
SizeOffsetType visitLoadInst(LoadInst &I);
@@ -213,7 +214,7 @@ class ObjectSizeOffsetEvaluator
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
LLVMContext &Context;
BuilderTy Builder;
@@ -228,7 +229,7 @@ class ObjectSizeOffsetEvaluator
SizeOffsetEvalType compute_(Value *V);
public:
- ObjectSizeOffsetEvaluator(const TargetData *TD, const TargetLibraryInfo *TLI,
+ ObjectSizeOffsetEvaluator(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context);
SizeOffsetEvalType compute(Value *V);
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 7e049d6..b954840 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -14,14 +14,14 @@
#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
-#include "llvm/BasicBlock.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/ValueHandle.h"
namespace llvm {
class Function;
@@ -29,7 +29,7 @@ namespace llvm {
class Instruction;
class CallSite;
class AliasAnalysis;
- class TargetData;
+ class DataLayout;
class MemoryDependenceAnalysis;
class PredIteratorCache;
class DominatorTree;
@@ -323,7 +323,7 @@ namespace llvm {
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
- TargetData *TD;
+ DataLayout *TD;
DominatorTree *DT;
OwningPtr<PredIteratorCache> PredCache;
public:
@@ -412,7 +412,7 @@ namespace llvm {
int64_t MemLocOffs,
unsigned MemLocSize,
const LoadInst *LI,
- const TargetData &TD);
+ const DataLayout &TD);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
index ff9a247..d7a3dd8 100644
--- a/include/llvm/Analysis/PHITransAddr.h
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -14,12 +14,12 @@
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
#define LLVM_ANALYSIS_PHITRANSADDR_H
-#include "llvm/Instruction.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Instruction.h"
namespace llvm {
class DominatorTree;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
/// PHITransAddr - An address value which tracks and handles phi translation.
@@ -37,7 +37,7 @@ class PHITransAddr {
Value *Addr;
/// TD - The target data we are playing with if known, otherwise null.
- const TargetData *TD;
+ const DataLayout *TD;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
@@ -45,7 +45,7 @@ class PHITransAddr {
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
- PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td), TLI(0) {
+ PHITransAddr(Value *addr, const DataLayout *td) : Addr(addr), TD(td), TLI(0) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index c52f846..27726f4 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -180,11 +180,20 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
- // createLoopDependenceAnalysisPass - This creates an instance of the
- // LoopDependenceAnalysis pass.
+ // createDependenceAnalysisPass - This creates an instance of the
+ // DependenceAnalysis pass.
//
- LoopPass *createLoopDependenceAnalysisPass();
+ FunctionPass *createDependenceAnalysisPass();
+ //===--------------------------------------------------------------------===//
+ //
+ // createCostModelAnalysisPass - This creates an instance of the
+ // CostModelAnalysis pass.
+ //
+ FunctionPass *createCostModelAnalysisPass();
+
+ //===--------------------------------------------------------------------===//
+ //
// Minor pass prototypes, allowing us to expose them through bugpoint and
// analyze.
FunctionPass *createInstCountPass();
diff --git a/include/llvm/Analysis/PathNumbering.h b/include/llvm/Analysis/PathNumbering.h
index 7025e28..86b1520 100644
--- a/include/llvm/Analysis/PathNumbering.h
+++ b/include/llvm/Analysis/PathNumbering.h
@@ -26,11 +26,11 @@
#ifndef LLVM_PATH_NUMBERING_H
#define LLVM_PATH_NUMBERING_H
-#include "llvm/BasicBlock.h"
-#include "llvm/Instructions.h"
+#include "llvm/Analysis/ProfileInfoTypes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
-#include "llvm/Analysis/ProfileInfoTypes.h"
#include <map>
#include <stack>
#include <vector>
diff --git a/include/llvm/Analysis/PathProfileInfo.h b/include/llvm/Analysis/PathProfileInfo.h
index cef6d2d..8684f41 100644
--- a/include/llvm/Analysis/PathProfileInfo.h
+++ b/include/llvm/Analysis/PathProfileInfo.h
@@ -14,8 +14,8 @@
#ifndef LLVM_PATHPROFILEINFO_H
#define LLVM_PATHPROFILEINFO_H
-#include "llvm/BasicBlock.h"
#include "llvm/Analysis/PathNumbering.h"
+#include "llvm/IR/BasicBlock.h"
namespace llvm {
diff --git a/include/llvm/Analysis/ProfileDataLoader.h b/include/llvm/Analysis/ProfileDataLoader.h
index bec9fac..90097f7 100644
--- a/include/llvm/Analysis/ProfileDataLoader.h
+++ b/include/llvm/Analysis/ProfileDataLoader.h
@@ -16,6 +16,7 @@
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
@@ -115,9 +116,6 @@ public:
/// been counted yet.
static const unsigned Uncounted;
- /// The maximum value that can be stored in a profiling counter.
- static const unsigned MaxCount;
-
/// getNumExecutions - Return the number of times the target program was run
/// to generate this profiling data.
unsigned getNumExecutions() const { return CommandLines.size(); }
diff --git a/include/llvm/Analysis/ProfileInfo.h b/include/llvm/Analysis/ProfileInfo.h
index 6c2e273..5d17fa1 100644
--- a/include/llvm/Analysis/ProfileInfo.h
+++ b/include/llvm/Analysis/ProfileInfo.h
@@ -26,9 +26,9 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
-#include <string>
#include <map>
#include <set>
+#include <string>
namespace llvm {
class Pass;
diff --git a/include/llvm/Analysis/ProfileInfoLoader.h b/include/llvm/Analysis/ProfileInfoLoader.h
index dcf3b38..e0f49f3 100644
--- a/include/llvm/Analysis/ProfileInfoLoader.h
+++ b/include/llvm/Analysis/ProfileInfoLoader.h
@@ -16,9 +16,9 @@
#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
-#include <vector>
#include <string>
#include <utility>
+#include <vector>
namespace llvm {
diff --git a/include/llvm/Analysis/PtrUseVisitor.h b/include/llvm/Analysis/PtrUseVisitor.h
new file mode 100644
index 0000000..1802fe8
--- /dev/null
+++ b/include/llvm/Analysis/PtrUseVisitor.h
@@ -0,0 +1,285 @@
+//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file provides a collection of visitors which walk the (instruction)
+/// uses of a pointer. These visitors all provide the same essential behavior
+/// as an InstVisitor with similar template-based flexibility and
+/// implementation strategies.
+///
+/// These can be used, for example, to quickly analyze the uses of an alloca,
+/// global variable, or function argument.
+///
+/// FIXME: Provide a variant which doesn't track offsets and is cheaper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H
+#define LLVM_ANALYSIS_PTRUSEVISITOR_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/InstVisitor.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+namespace detail {
+/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor.
+///
+/// See \c PtrUseVisitor for the public interface and detailed comments about
+/// usage. This class is just a helper base class which is not templated and
+/// contains all common code to be shared between different instantiations of
+/// PtrUseVisitor.
+class PtrUseVisitorBase {
+public:
+ /// \brief This class provides information about the result of a visit.
+ ///
+ /// After walking all the users (recursively) of a pointer, the basic
+ /// infrastructure records some commonly useful information such as escape
+ /// analysis and whether the visit completed or aborted early.
+ class PtrInfo {
+ public:
+ PtrInfo() : AbortedInfo(0, false), EscapedInfo(0, false) {}
+
+ /// \brief Reset the pointer info, clearing all state.
+ void reset() {
+ AbortedInfo.setPointer(0);
+ AbortedInfo.setInt(false);
+ EscapedInfo.setPointer(0);
+ EscapedInfo.setInt(false);
+ }
+
+ /// \brief Did we abort the visit early?
+ bool isAborted() const { return AbortedInfo.getInt(); }
+
+ /// \brief Is the pointer escaped at some point?
+ bool isEscaped() const { return EscapedInfo.getInt(); }
+
+ /// \brief Get the instruction causing the visit to abort.
+ /// \returns a pointer to the instruction causing the abort if one is
+ /// available; otherwise returns null.
+ Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); }
+
+ /// \brief Get the instruction causing the pointer to escape.
+ /// \returns a pointer to the instruction which escapes the pointer if one
+ /// is available; otherwise returns null.
+ Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); }
+
+ /// \brief Mark the visit as aborted. Intended for use in a void return.
+ /// \param I The instruction which caused the visit to abort, if available.
+ void setAborted(Instruction *I = 0) {
+ AbortedInfo.setInt(true);
+ AbortedInfo.setPointer(I);
+ }
+
+ /// \brief Mark the pointer as escaped. Intended for use in a void return.
+ /// \param I The instruction which escapes the pointer, if available.
+ void setEscaped(Instruction *I = 0) {
+ EscapedInfo.setInt(true);
+ EscapedInfo.setPointer(I);
+ }
+
+ /// \brief Mark the pointer as escaped, and the visit as aborted. Intended
+ /// for use in a void return.
+ /// \param I The instruction which both escapes the pointer and aborts the
+ /// visit, if available.
+ void setEscapedAndAborted(Instruction *I = 0) {
+ setEscaped(I);
+ setAborted(I);
+ }
+
+ private:
+ PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo;
+ };
+
+protected:
+ const DataLayout &DL;
+
+ /// \name Visitation infrastructure
+ /// @{
+
+ /// \brief The info collected about the pointer being visited thus far.
+ PtrInfo PI;
+
+ /// \brief A struct of the data needed to visit a particular use.
+ ///
+ /// This is used to maintain a worklist fo to-visit uses. This is used to
+ /// make the visit be iterative rather than recursive.
+ struct UseToVisit {
+ typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair;
+ UseAndIsOffsetKnownPair UseAndIsOffsetKnown;
+ APInt Offset;
+ };
+
+ /// \brief The worklist of to-visit uses.
+ SmallVector<UseToVisit, 8> Worklist;
+
+ /// \brief A set of visited uses to break cycles in unreachable code.
+ SmallPtrSet<Use *, 8> VisitedUses;
+
+ /// @}
+
+
+ /// \name Per-visit state
+ /// This state is reset for each instruction visited.
+ /// @{
+
+ /// \brief The use currently being visited.
+ Use *U;
+
+ /// \brief True if we have a known constant offset for the use currently
+ /// being visited.
+ bool IsOffsetKnown;
+
+ /// \brief The constant offset of the use if that is known.
+ APInt Offset;
+
+ /// @}
+
+
+ /// Note that the constructor is protected because this class must be a base
+ /// class, we can't create instances directly of this class.
+ PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {}
+
+ /// \brief Enqueue the users of this instruction in the visit worklist.
+ ///
+ /// This will visit the users with the same offset of the current visit
+ /// (including an unknown offset if that is the current state).
+ void enqueueUsers(Instruction &I);
+
+ /// \brief Walk the operands of a GEP and adjust the offset as appropriate.
+ ///
+ /// This routine does the heavy lifting of the pointer walk by computing
+ /// offsets and looking through GEPs.
+ bool adjustOffsetForGEP(GetElementPtrInst &GEPI);
+};
+} // end namespace detail
+
+/// \brief A base class for visitors over the uses of a pointer value.
+///
+/// Once constructed, a user can call \c visit on a pointer value, and this
+/// will walk its uses and visit each instruction using an InstVisitor. It also
+/// provides visit methods which will recurse through any pointer-to-pointer
+/// transformations such as GEPs and bitcasts.
+///
+/// During the visit, the current Use* being visited is available to the
+/// subclass, as well as the current offset from the original base pointer if
+/// known.
+///
+/// The recursive visit of uses is accomplished with a worklist, so the only
+/// ordering guarantee is that an instruction is visited before any uses of it
+/// are visited. Note that this does *not* mean before any of its users are
+/// visited! This is because users can be visited multiple times due to
+/// multiple, different uses of pointers derived from the same base.
+///
+/// A particular Use will only be visited once, but a User may be visited
+/// multiple times, once per Use. This visits may notably have different
+/// offsets.
+///
+/// All visit methods on the underlying InstVisitor return a boolean. This
+/// return short-circuits the visit, stopping it immediately.
+///
+/// FIXME: Generalize this for all values rather than just instructions.
+template <typename DerivedT>
+class PtrUseVisitor : protected InstVisitor<DerivedT>,
+ public detail::PtrUseVisitorBase {
+ friend class InstVisitor<DerivedT>;
+ typedef InstVisitor<DerivedT> Base;
+
+public:
+ PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {}
+
+ /// \brief Recursively visit the uses of the given pointer.
+ /// \returns An info struct about the pointer. See \c PtrInfo for details.
+ PtrInfo visitPtr(Instruction &I) {
+ // This must be a pointer type. Get an integer type suitable to hold
+ // offsets on this pointer.
+ // FIXME: Support a vector of pointers.
+ assert(I.getType()->isPointerTy());
+ IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType()));
+ IsOffsetKnown = true;
+ Offset = APInt(IntPtrTy->getBitWidth(), 0);
+ PI.reset();
+
+ // Enqueue the uses of this pointer.
+ enqueueUsers(I);
+
+ // Visit all the uses off the worklist until it is empty.
+ while (!Worklist.empty()) {
+ UseToVisit ToVisit = Worklist.pop_back_val();
+ U = ToVisit.UseAndIsOffsetKnown.getPointer();
+ IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt();
+ if (IsOffsetKnown)
+ Offset = llvm_move(ToVisit.Offset);
+
+ Instruction *I = cast<Instruction>(U->getUser());
+ static_cast<DerivedT*>(this)->visit(I);
+ if (PI.isAborted())
+ break;
+ }
+ return PI;
+ }
+
+protected:
+ void visitStoreInst(StoreInst &SI) {
+ if (SI.getValueOperand() == U->get())
+ PI.setEscaped(&SI);
+ }
+
+ void visitBitCastInst(BitCastInst &BC) {
+ enqueueUsers(BC);
+ }
+
+ void visitPtrToIntInst(PtrToIntInst &I) {
+ PI.setEscaped(&I);
+ }
+
+ void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
+ if (GEPI.use_empty())
+ return;
+
+ // If we can't walk the GEP, clear the offset.
+ if (!adjustOffsetForGEP(GEPI)) {
+ IsOffsetKnown = false;
+ Offset = APInt();
+ }
+
+ // Enqueue the users now that the offset has been adjusted.
+ enqueueUsers(GEPI);
+ }
+
+ // No-op intrinsics which we know don't escape the pointer to to logic in
+ // some other function.
+ void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {}
+ void visitMemIntrinsic(MemIntrinsic &I) {}
+ void visitIntrinsicInst(IntrinsicInst &II) {
+ switch (II.getIntrinsicID()) {
+ default:
+ return Base::visitIntrinsicInst(II);
+
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ return; // No-op intrinsics.
+ }
+ }
+
+ // Generically, arguments to calls and invokes escape the pointer to some
+ // other function. Mark that.
+ void visitCallSite(CallSite CS) {
+ PI.setEscaped(CS.getInstruction());
+ Base::visitCallSite(CS);
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index e62040e..48d7ee6 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -54,10 +54,8 @@ class FlatIt {};
/// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
/// Region.
class RegionNode {
- // DO NOT IMPLEMENT
- RegionNode(const RegionNode &);
- // DO NOT IMPLEMENT
- const RegionNode &operator=(const RegionNode &);
+ RegionNode(const RegionNode &) LLVM_DELETED_FUNCTION;
+ const RegionNode &operator=(const RegionNode &) LLVM_DELETED_FUNCTION;
protected:
/// This is the entry basic block that starts this region node. If this is a
@@ -203,10 +201,8 @@ inline Region* RegionNode::getNodeAs<Region>() const {
/// tree, the second one creates a graphical representation using graphviz.
class Region : public RegionNode {
friend class RegionInfo;
- // DO NOT IMPLEMENT
- Region(const Region &);
- // DO NOT IMPLEMENT
- const Region &operator=(const Region &);
+ Region(const Region &) LLVM_DELETED_FUNCTION;
+ const Region &operator=(const Region &) LLVM_DELETED_FUNCTION;
// Information necessary to manage this Region.
RegionInfo* RI;
@@ -565,10 +561,8 @@ class RegionInfo : public FunctionPass {
typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
typedef SmallPtrSet<Region*, 4> RegionSet;
- // DO NOT IMPLEMENT
- RegionInfo(const RegionInfo &);
- // DO NOT IMPLEMENT
- const RegionInfo &operator=(const RegionInfo &);
+ RegionInfo(const RegionInfo &) LLVM_DELETED_FUNCTION;
+ const RegionInfo &operator=(const RegionInfo &) LLVM_DELETED_FUNCTION;
DominatorTree *DT;
PostDominatorTree *PDT;
diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h
index 7adc71c..bcff227 100644
--- a/include/llvm/Analysis/RegionIterator.h
+++ b/include/llvm/Analysis/RegionIterator.h
@@ -12,8 +12,8 @@
#define LLVM_ANALYSIS_REGION_ITERATOR_H
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h
index 68f1201..54f96d6 100644
--- a/include/llvm/Analysis/RegionPass.h
+++ b/include/llvm/Analysis/RegionPass.h
@@ -17,11 +17,9 @@
#define LLVM_REGION_PASS_H
#include "llvm/Analysis/RegionInfo.h"
-
+#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/PassManagers.h"
-#include "llvm/Function.h"
-
#include <deque>
namespace llvm {
@@ -59,6 +57,9 @@ public:
/// @return The pass to print the LLVM IR in the region.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
+
virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
virtual bool doFinalization() { return false; }
//@}
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index c213ade..f8f261f 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -21,16 +21,16 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_H
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Operator.h"
#include "llvm/Pass.h"
-#include "llvm/Instructions.h"
-#include "llvm/Function.h"
-#include "llvm/Operator.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ConstantRange.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {
@@ -40,7 +40,7 @@ namespace llvm {
class DominatorTree;
class Type;
class ScalarEvolution;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class LLVMContext;
class Loop;
@@ -70,8 +70,8 @@ namespace llvm {
unsigned short SubclassData;
private:
- SCEV(const SCEV &); // DO NOT IMPLEMENT
- void operator=(const SCEV &); // DO NOT IMPLEMENT
+ SCEV(const SCEV &) LLVM_DELETED_FUNCTION;
+ void operator=(const SCEV &) LLVM_DELETED_FUNCTION;
public:
/// NoWrapFlags are bitfield indices into SubclassData.
@@ -162,7 +162,6 @@ namespace llvm {
SCEVCouldNotCompute();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVCouldNotCompute *S) { return true; }
static bool classof(const SCEV *S);
};
@@ -227,7 +226,7 @@ namespace llvm {
/// TD - The target data information for the target we are targeting.
///
- TargetData *TD;
+ DataLayout *TD;
/// TLI - The target library information for the target we are targeting.
///
@@ -874,6 +873,7 @@ namespace llvm {
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void print(raw_ostream &OS, const Module* = 0) const;
+ virtual void verifyAnalysis() const;
private:
FoldingSet<SCEV> UniqueSCEVs;
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 3f8f149..ea45aff 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -14,15 +14,15 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
-#include "llvm/IRBuilder.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
#include <set>
namespace llvm {
- class TargetLowering;
+ class TargetTransformInfo;
/// Return true if the given expression is safe to expand in the sense that
/// all materialized values are safe to speculate.
@@ -129,7 +129,7 @@ namespace llvm {
/// representative. Return the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakVH> &DeadInsts,
- const TargetLowering *TLI = NULL);
+ const TargetTransformInfo *TTI = NULL);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index ded1297..b74cb33 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -14,8 +14,8 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
-#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
@@ -46,7 +46,6 @@ namespace llvm {
Type *getType() const { return V->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVConstant *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scConstant;
}
@@ -68,7 +67,6 @@ namespace llvm {
Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVCastExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate ||
S->getSCEVType() == scZeroExtend ||
@@ -88,7 +86,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVTruncateExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate;
}
@@ -106,7 +103,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scZeroExtend;
}
@@ -124,7 +120,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSignExtend;
}
@@ -166,7 +161,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVNAryExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
@@ -188,7 +182,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
@@ -223,7 +216,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVAddExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr;
}
@@ -242,7 +234,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVMulExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scMulExpr;
}
@@ -274,7 +265,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVUDivExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUDivExpr;
}
@@ -358,7 +348,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVAddRecExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddRecExpr;
}
@@ -380,7 +369,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVSMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSMaxExpr;
}
@@ -402,7 +390,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVUMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUMaxExpr;
}
@@ -449,7 +436,6 @@ namespace llvm {
Type *getType() const { return getValPtr()->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVUnknown *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUnknown;
}
diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h
index c3c2f4b..604e306 100644
--- a/include/llvm/Analysis/SparsePropagation.h
+++ b/include/llvm/Analysis/SparsePropagation.h
@@ -17,8 +17,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include <vector>
#include <set>
+#include <vector>
namespace llvm {
class Value;
@@ -130,9 +130,9 @@ class SparseSolver {
/// PHI nodes retriggered.
typedef std::pair<BasicBlock*,BasicBlock*> Edge;
std::set<Edge> KnownFeasibleEdges;
-
- SparseSolver(const SparseSolver&); // DO NOT IMPLEMENT
- void operator=(const SparseSolver&); // DO NOT IMPLEMENT
+
+ SparseSolver(const SparseSolver&) LLVM_DELETED_FUNCTION;
+ void operator=(const SparseSolver&) LLVM_DELETED_FUNCTION;
public:
explicit SparseSolver(AbstractLatticeFunction *Lattice)
: LatticeFunc(Lattice) {}
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
new file mode 100644
index 0000000..ddf615f
--- /dev/null
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -0,0 +1,206 @@
+//===- llvm/Analysis/TargetTransformInfo.h ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass exposes codegen information to IR-level passes. Every
+// transformation that uses codegen information is broken into three parts:
+// 1. The IR-level analysis pass.
+// 2. The IR-level transformation interface which provides the needed
+// information.
+// 3. Codegen-level implementation which uses target-specific hooks.
+//
+// This file defines #2, which is the interface that IR-level transformations
+// use for querying the codegen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_TARGET_TRANSFORM_INTERFACE
+#define LLVM_ANALYSIS_TARGET_TRANSFORM_INTERFACE
+
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// TargetTransformInfo - This pass provides access to the codegen
+/// interfaces that are needed for IR-level transformations.
+class TargetTransformInfo {
+protected:
+ /// \brief The TTI instance one level down the stack.
+ ///
+ /// This is used to implement the default behavior all of the methods which
+ /// is to delegate up through the stack of TTIs until one can answer the
+ /// query.
+ TargetTransformInfo *PrevTTI;
+
+ /// \brief The top of the stack of TTI analyses available.
+ ///
+ /// This is a convenience routine maintained as TTI analyses become available
+ /// that complements the PrevTTI delegation chain. When one part of an
+ /// analysis pass wants to query another part of the analysis pass it can use
+ /// this to start back at the top of the stack.
+ TargetTransformInfo *TopTTI;
+
+ /// All pass subclasses must in their initializePass routine call
+ /// pushTTIStack with themselves to update the pointers tracking the previous
+ /// TTI instance in the analysis group's stack, and the top of the analysis
+ /// group's stack.
+ void pushTTIStack(Pass *P);
+
+ /// All pass subclasses must in their finalizePass routine call popTTIStack
+ /// to update the pointers tracking the previous TTI instance in the analysis
+ /// group's stack, and the top of the analysis group's stack.
+ void popTTIStack();
+
+ /// All pass subclasses must call TargetTransformInfo::getAnalysisUsage.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+public:
+ /// This class is intended to be subclassed by real implementations.
+ virtual ~TargetTransformInfo() = 0;
+
+ /// \name Scalar Target Information
+ /// @{
+
+ /// \brief Flags indicating the kind of support for population count.
+ ///
+ /// Compared to the SW implementation, HW support is supposed to
+ /// significantly boost the performance when the population is dense, and it
+ /// may or may not degrade performance if the population is sparse. A HW
+ /// support is considered as "Fast" if it can outperform, or is on a par
+ /// with, SW implementaion when the population is sparse; otherwise, it is
+ /// considered as "Slow".
+ enum PopcntSupportKind {
+ PSK_Software,
+ PSK_SlowHardware,
+ PSK_FastHardware
+ };
+
+ /// isLegalAddImmediate - Return true if the specified immediate is legal
+ /// add immediate, that is the target has add instructions which can add
+ /// a register with the immediate without having to materialize the
+ /// immediate into a register.
+ virtual bool isLegalAddImmediate(int64_t Imm) const;
+
+ /// isLegalICmpImmediate - Return true if the specified immediate is legal
+ /// icmp immediate, that is the target has icmp instructions which can compare
+ /// a register against the immediate without having to materialize the
+ /// immediate into a register.
+ virtual bool isLegalICmpImmediate(int64_t Imm) const;
+
+ /// isLegalAddressingMode - Return true if the addressing mode represented by
+ /// AM is legal for this target, for a load/store of the specified type.
+ /// The type may be VoidTy, in which case only return true if the addressing
+ /// mode is legal for a load/store of any legal type.
+ /// TODO: Handle pre/postinc as well.
+ virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
+ int64_t BaseOffset, bool HasBaseReg,
+ int64_t Scale) const;
+
+ /// isTruncateFree - Return true if it's free to truncate a value of
+ /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
+ /// register EAX to i16 by referencing its sub-register AX.
+ virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
+
+ /// Is this type legal.
+ virtual bool isTypeLegal(Type *Ty) const;
+
+ /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
+ virtual unsigned getJumpBufAlignment() const;
+
+ /// getJumpBufSize - returns the target's jmp_buf size in bytes.
+ virtual unsigned getJumpBufSize() const;
+
+ /// shouldBuildLookupTables - Return true if switches should be turned into
+ /// lookup tables for the target.
+ virtual bool shouldBuildLookupTables() const;
+
+ /// getPopcntSupport - Return hardware support for population count.
+ virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
+
+ /// getIntImmCost - Return the expected cost of materializing the given
+ /// integer immediate of the specified type.
+ virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
+
+ /// @}
+
+ /// \name Vector Target Information
+ /// @{
+
+ /// \brief The various kinds of shuffle patterns for vector queries.
+ enum ShuffleKind {
+ SK_Broadcast, ///< Broadcast element 0 to all other elements.
+ SK_Reverse, ///< Reverse the order of the vector.
+ SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset.
+ SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset.
+ };
+
+ /// \return The number of scalar or vector registers that the target has.
+ /// If 'Vectors' is true, it returns the number of vector registers. If it is
+ /// set to false, it returns the number of scalar registers.
+ virtual unsigned getNumberOfRegisters(bool Vector) const;
+
+ /// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
+ virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
+
+ /// \return The cost of a shuffle instruction of kind Kind and of type Tp.
+ /// The index and subtype parameters are used by the subvector insertion and
+ /// extraction shuffle kinds.
+ virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0,
+ Type *SubTp = 0) const;
+
+ /// \return The expected cost of cast instructions, such as bitcast, trunc,
+ /// zext, etc.
+ virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
+ Type *Src) const;
+
+ /// \return The expected cost of control-flow related instrutctions such as
+ /// Phi, Ret, Br.
+ virtual unsigned getCFInstrCost(unsigned Opcode) const;
+
+ /// \returns The expected cost of compare and select instructions.
+ virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
+ Type *CondTy = 0) const;
+
+ /// \return The expected cost of vector Insert and Extract.
+ /// Use -1 to indicate that there is no information on the index value.
+ virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
+ unsigned Index = -1) const;
+
+ /// \return The cost of Load and Store instructions.
+ virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
+ unsigned Alignment,
+ unsigned AddressSpace) const;
+
+ /// \returns The cost of Intrinsic instructions.
+ virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
+ ArrayRef<Type *> Tys) const;
+
+ /// \returns The number of pieces into which the provided type must be
+ /// split during legalization. Zero is returned when the answer is unknown.
+ virtual unsigned getNumberOfParts(Type *Tp) const;
+
+ /// @}
+
+ /// Analysis group identification.
+ static char ID;
+};
+
+/// \brief Create the base case instance of a pass in the TTI analysis group.
+///
+/// This class provides the base case for the stack of TTI analyses. It doesn't
+/// delegate to anything and uses the STTI and VTTI objects passed in to
+/// satisfy the queries.
+ImmutablePass *createNoTargetTransformInfoPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/Trace.h b/include/llvm/Analysis/Trace.h
index 99651e1..26947fe 100644
--- a/include/llvm/Analysis/Trace.h
+++ b/include/llvm/Analysis/Trace.h
@@ -18,8 +18,8 @@
#ifndef LLVM_ANALYSIS_TRACE_H
#define LLVM_ANALYSIS_TRACE_H
-#include <vector>
#include <cassert>
+#include <vector>
namespace llvm {
class BasicBlock;
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index e8d45f6..875c47d 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -22,7 +22,7 @@ namespace llvm {
class Value;
class Instruction;
class APInt;
- class TargetData;
+ class DataLayout;
class StringRef;
class MDNode;
@@ -37,27 +37,26 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
- const TargetData *TD = 0, unsigned Depth = 0);
+ const DataLayout *TD = 0, unsigned Depth = 0);
void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around ComputeMaskedBits.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
- const TargetData *TD = 0, unsigned Depth = 0);
+ const DataLayout *TD = 0, unsigned Depth = 0);
- /// isPowerOfTwo - Return true if the given value is known to have exactly one
- /// bit set when defined. For vectors return true if every element is known to
- /// be a power of two when defined. Supports values with integer or pointer
- /// type and vectors of integers. If 'OrZero' is set then returns true if the
- /// given value is either a power of two or zero.
- bool isPowerOfTwo(Value *V, const TargetData *TD = 0, bool OrZero = false,
- unsigned Depth = 0);
+ /// isKnownToBeAPowerOfTwo - Return true if the given value is known to have
+ /// exactly one bit set when defined. For vectors return true if every
+ /// element is known to be a power of two when defined. Supports values with
+ /// integer or pointer type and vectors of integers. If 'OrZero' is set then
+ /// returns true if the given value is either a power of two or zero.
+ bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0);
/// isKnownNonZero - Return true if the given value is known to be non-zero
/// when defined. For vectors return true if every element is known to be
/// non-zero when defined. Supports values with integer or pointer type and
/// vectors of integers.
- bool isKnownNonZero(Value *V, const TargetData *TD = 0, unsigned Depth = 0);
+ bool isKnownNonZero(Value *V, const DataLayout *TD = 0, unsigned Depth = 0);
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be
@@ -69,7 +68,7 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
bool MaskedValueIsZero(Value *V, const APInt &Mask,
- const TargetData *TD = 0, unsigned Depth = 0);
+ const DataLayout *TD = 0, unsigned Depth = 0);
/// ComputeNumSignBits - Return the number of times the sign bit of the
@@ -80,7 +79,7 @@ namespace llvm {
///
/// 'Op' must have a scalar integer type.
///
- unsigned ComputeNumSignBits(Value *Op, const TargetData *TD = 0,
+ unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = 0,
unsigned Depth = 0);
/// ComputeMultiple - This function computes the integer multiple of Base that
@@ -118,10 +117,10 @@ namespace llvm {
/// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller.
Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
- const TargetData &TD);
+ const DataLayout &TD);
static inline const Value *
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
- const TargetData &TD) {
+ const DataLayout &TD) {
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
}
@@ -143,10 +142,10 @@ namespace llvm {
/// being addressed. Note that the returned value has pointer type if the
/// specified value does. If the MaxLookup value is non-zero, it limits the
/// number of instructions to be stripped off.
- Value *GetUnderlyingObject(Value *V, const TargetData *TD = 0,
+ Value *GetUnderlyingObject(Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6);
static inline const Value *
- GetUnderlyingObject(const Value *V, const TargetData *TD = 0,
+ GetUnderlyingObject(const Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6) {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
@@ -156,7 +155,7 @@ namespace llvm {
/// multiple objects.
void GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
@@ -182,7 +181,7 @@ namespace llvm {
/// However, this method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
bool isSafeToSpeculativelyExecute(const Value *V,
- const TargetData *TD = 0);
+ const DataLayout *TD = 0);
} // end namespace llvm
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
deleted file mode 100644
index 0228d86..0000000
--- a/include/llvm/Attributes.h
+++ /dev/null
@@ -1,410 +0,0 @@
-//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the simple types necessary to represent the
-// attributes associated with functions and their calls.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ATTRIBUTES_H
-#define LLVM_ATTRIBUTES_H
-
-#include "llvm/Support/MathExtras.h"
-#include "llvm/ADT/ArrayRef.h"
-#include <cassert>
-#include <string>
-
-namespace llvm {
-class Type;
-
-namespace Attribute {
-/// We use this proxy POD type to allow constructing Attributes constants
-/// using initializer lists. Do not use this class directly.
-struct AttrConst {
- uint64_t v;
- AttrConst operator | (const AttrConst Attrs) const {
- AttrConst Res = {v | Attrs.v};
- return Res;
- }
- AttrConst operator ~ () const {
- AttrConst Res = {~v};
- return Res;
- }
-};
-} // namespace Attribute
-
-
-/// Attributes - A bitset of attributes.
-class Attributes {
- public:
- Attributes() : Bits(0) { }
- explicit Attributes(uint64_t Val) : Bits(Val) { }
- /*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { }
- // This is a "safe bool() operator".
- operator const void *() const { return Bits ? this : 0; }
- bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
- bool operator == (const Attributes &Attrs) const {
- return Bits == Attrs.Bits;
- }
- bool operator != (const Attributes &Attrs) const {
- return Bits != Attrs.Bits;
- }
- Attributes operator | (const Attributes &Attrs) const {
- return Attributes(Bits | Attrs.Bits);
- }
- Attributes operator & (const Attributes &Attrs) const {
- return Attributes(Bits & Attrs.Bits);
- }
- Attributes operator ^ (const Attributes &Attrs) const {
- return Attributes(Bits ^ Attrs.Bits);
- }
- Attributes &operator |= (const Attributes &Attrs) {
- Bits |= Attrs.Bits;
- return *this;
- }
- Attributes &operator &= (const Attributes &Attrs) {
- Bits &= Attrs.Bits;
- return *this;
- }
- Attributes operator ~ () const { return Attributes(~Bits); }
- uint64_t Raw() const { return Bits; }
- private:
- // Currently, we need less than 64 bits.
- uint64_t Bits;
-};
-
-namespace Attribute {
-
-/// Function parameters and results can have attributes to indicate how they
-/// should be treated by optimizations and code generation. This enumeration
-/// lists the attributes that can be associated with parameters, function
-/// results or the function itself.
-/// @brief Function attributes.
-
-// We declare AttrConst objects that will be used throughout the code
-// and also raw uint64_t objects with _i suffix to be used below for other
-// constant declarations. This is done to avoid static CTORs and at the same
-// time to keep type-safety of Attributes.
-#define DECLARE_LLVM_ATTRIBUTE(name, value) \
- const uint64_t name##_i = value; \
- const AttrConst name = {value};
-
-DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set
-DECLARE_LLVM_ATTRIBUTE(ZExt,1<<0) ///< Zero extended before/after call
-DECLARE_LLVM_ATTRIBUTE(SExt,1<<1) ///< Sign extended before/after call
-DECLARE_LLVM_ATTRIBUTE(NoReturn,1<<2) ///< Mark the function as not returning
-DECLARE_LLVM_ATTRIBUTE(InReg,1<<3) ///< Force argument to be passed in register
-DECLARE_LLVM_ATTRIBUTE(StructRet,1<<4) ///< Hidden pointer to structure to return
-DECLARE_LLVM_ATTRIBUTE(NoUnwind,1<<5) ///< Function doesn't unwind stack
-DECLARE_LLVM_ATTRIBUTE(NoAlias,1<<6) ///< Considered to not alias after call
-DECLARE_LLVM_ATTRIBUTE(ByVal,1<<7) ///< Pass structure by value
-DECLARE_LLVM_ATTRIBUTE(Nest,1<<8) ///< Nested function static chain
-DECLARE_LLVM_ATTRIBUTE(ReadNone,1<<9) ///< Function does not access memory
-DECLARE_LLVM_ATTRIBUTE(ReadOnly,1<<10) ///< Function only reads from memory
-DECLARE_LLVM_ATTRIBUTE(NoInline,1<<11) ///< inline=never
-DECLARE_LLVM_ATTRIBUTE(AlwaysInline,1<<12) ///< inline=always
-DECLARE_LLVM_ATTRIBUTE(OptimizeForSize,1<<13) ///< opt_size
-DECLARE_LLVM_ATTRIBUTE(StackProtect,1<<14) ///< Stack protection.
-DECLARE_LLVM_ATTRIBUTE(StackProtectReq,1<<15) ///< Stack protection required.
-DECLARE_LLVM_ATTRIBUTE(Alignment,31<<16) ///< Alignment of parameter (5 bits)
- // stored as log2 of alignment with +1 bias
- // 0 means unaligned different from align 1
-DECLARE_LLVM_ATTRIBUTE(NoCapture,1<<21) ///< Function creates no aliases of pointer
-DECLARE_LLVM_ATTRIBUTE(NoRedZone,1<<22) /// disable redzone
-DECLARE_LLVM_ATTRIBUTE(NoImplicitFloat,1<<23) /// disable implicit floating point
- /// instructions.
-DECLARE_LLVM_ATTRIBUTE(Naked,1<<24) ///< Naked function
-DECLARE_LLVM_ATTRIBUTE(InlineHint,1<<25) ///< source said inlining was
- ///desirable
-DECLARE_LLVM_ATTRIBUTE(StackAlignment,7<<26) ///< Alignment of stack for
- ///function (3 bits) stored as log2
- ///of alignment with +1 bias
- ///0 means unaligned (different from
- ///alignstack= {1))
-DECLARE_LLVM_ATTRIBUTE(ReturnsTwice,1<<29) ///< Function can return twice
-DECLARE_LLVM_ATTRIBUTE(UWTable,1<<30) ///< Function must be in a unwind
- ///table
-DECLARE_LLVM_ATTRIBUTE(NonLazyBind,1U<<31) ///< Function is called early and/or
- /// often, so lazy binding isn't
- /// worthwhile.
-DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is on.
-
-#undef DECLARE_LLVM_ATTRIBUTE
-
-/// Note that uwtable is about the ABI or the user mandating an entry in the
-/// unwind table. The nounwind attribute is about an exception passing by the
-/// function.
-/// In a theoretical system that uses tables for profiling and sjlj for
-/// exceptions, they would be fully independent. In a normal system that
-/// uses tables for both, the semantics are:
-/// nil = Needs an entry because an exception might pass by.
-/// nounwind = No need for an entry
-/// uwtable = Needs an entry because the ABI says so and because
-/// an exception might pass by.
-/// uwtable + nounwind = Needs an entry because the ABI says so.
-
-/// @brief Attributes that only apply to function parameters.
-const AttrConst ParameterOnly = {ByVal_i | Nest_i |
- StructRet_i | NoCapture_i};
-
-/// @brief Attributes that may be applied to the function itself. These cannot
-/// be used on return values or function parameters.
-const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
- ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
- StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
- Naked_i | InlineHint_i | StackAlignment_i |
- UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
-
-/// @brief Parameter attributes that do not apply to vararg call arguments.
-const AttrConst VarArgsIncompatible = {StructRet_i};
-
-/// @brief Attributes that are mutually incompatible.
-const AttrConst MutuallyIncompatible[5] = {
- {ByVal_i | Nest_i | StructRet_i},
- {ByVal_i | Nest_i | InReg_i },
- {ZExt_i | SExt_i},
- {ReadNone_i | ReadOnly_i},
- {NoInline_i | AlwaysInline_i}
-};
-
-/// @brief Which attributes cannot be applied to a type.
-Attributes typeIncompatible(Type *Ty);
-
-/// This turns an int alignment (a power of 2, normally) into the
-/// form used internally in Attributes.
-inline Attributes constructAlignmentFromInt(unsigned i) {
- // Default alignment, allow the target to define how to align it.
- if (i == 0)
- return None;
-
- assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
- assert(i <= 0x40000000 && "Alignment too large.");
- return Attributes((Log2_32(i)+1) << 16);
-}
-
-/// This returns the alignment field of an attribute as a byte alignment value.
-inline unsigned getAlignmentFromAttrs(Attributes A) {
- Attributes Align = A & Attribute::Alignment;
- if (!Align)
- return 0;
-
- return 1U << ((Align.Raw() >> 16) - 1);
-}
-
-/// This turns an int stack alignment (which must be a power of 2) into
-/// the form used internally in Attributes.
-inline Attributes constructStackAlignmentFromInt(unsigned i) {
- // Default alignment, allow the target to define how to align it.
- if (i == 0)
- return None;
-
- assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
- assert(i <= 0x100 && "Alignment too large.");
- return Attributes((Log2_32(i)+1) << 26);
-}
-
-/// This returns the stack alignment field of an attribute as a byte alignment
-/// value.
-inline unsigned getStackAlignmentFromAttrs(Attributes A) {
- Attributes StackAlign = A & Attribute::StackAlignment;
- if (!StackAlign)
- return 0;
-
- return 1U << ((StackAlign.Raw() >> 26) - 1);
-}
-
-/// This returns an integer containing an encoding of all the
-/// LLVM attributes found in the given attribute bitset. Any
-/// change to this encoding is a breaking change to bitcode
-/// compatibility.
-inline uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
- // FIXME: It doesn't make sense to store the alignment information as an
- // expanded out value, we should store it as a log2 value. However, we can't
- // just change that here without breaking bitcode compatibility. If this ever
- // becomes a problem in practice, we should introduce new tag numbers in the
- // bitcode file and have those tags use a more efficiently encoded alignment
- // field.
-
- // Store the alignment in the bitcode as a 16-bit raw value instead of a
- // 5-bit log2 encoded value. Shift the bits above the alignment up by
- // 11 bits.
-
- uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
- if (Attrs & Attribute::Alignment)
- EncodedAttrs |= (1ull << 16) <<
- (((Attrs & Attribute::Alignment).Raw()-1) >> 16);
- EncodedAttrs |= (Attrs.Raw() & (0xfffull << 21)) << 11;
-
- return EncodedAttrs;
-}
-
-/// This returns an attribute bitset containing the LLVM attributes
-/// that have been decoded from the given integer. This function
-/// must stay in sync with 'encodeLLVMAttributesForBitcode'.
-inline Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) {
- // The alignment is stored as a 16-bit raw value from bits 31--16.
- // We shift the bits above 31 down by 11 bits.
-
- unsigned Alignment = (EncodedAttrs & (0xffffull << 16)) >> 16;
- assert((!Alignment || isPowerOf2_32(Alignment)) &&
- "Alignment must be a power of two.");
-
- Attributes Attrs(EncodedAttrs & 0xffff);
- if (Alignment)
- Attrs |= Attribute::constructAlignmentFromInt(Alignment);
- Attrs |= Attributes((EncodedAttrs & (0xfffull << 32)) >> 11);
-
- return Attrs;
-}
-
-
-/// The set of Attributes set in Attributes is converted to a
-/// string of equivalent mnemonics. This is, presumably, for writing out
-/// the mnemonics for the assembly writer.
-/// @brief Convert attribute bits to text
-std::string getAsString(Attributes Attrs);
-} // end namespace Attribute
-
-/// This is just a pair of values to associate a set of attributes
-/// with an index.
-struct AttributeWithIndex {
- Attributes Attrs; ///< The attributes that are set, or'd together.
- unsigned Index; ///< Index of the parameter for which the attributes apply.
- ///< Index 0 is used for return value attributes.
- ///< Index ~0U is used for function attributes.
-
- static AttributeWithIndex get(unsigned Idx, Attributes Attrs) {
- AttributeWithIndex P;
- P.Index = Idx;
- P.Attrs = Attrs;
- return P;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// AttrListPtr Smart Pointer
-//===----------------------------------------------------------------------===//
-
-class AttributeListImpl;
-
-/// AttrListPtr - This class manages the ref count for the opaque
-/// AttributeListImpl object and provides accessors for it.
-class AttrListPtr {
- /// AttrList - The attributes that we are managing. This can be null
- /// to represent the empty attributes list.
- AttributeListImpl *AttrList;
-public:
- AttrListPtr() : AttrList(0) {}
- AttrListPtr(const AttrListPtr &P);
- const AttrListPtr &operator=(const AttrListPtr &RHS);
- ~AttrListPtr();
-
- //===--------------------------------------------------------------------===//
- // Attribute List Construction and Mutation
- //===--------------------------------------------------------------------===//
-
- /// get - Return a Attributes list with the specified parameters in it.
- static AttrListPtr get(ArrayRef<AttributeWithIndex> Attrs);
-
- /// addAttr - Add the specified attribute at the specified index to this
- /// attribute list. Since attribute lists are immutable, this
- /// returns the new list.
- AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const;
-
- /// removeAttr - Remove the specified attribute at the specified index from
- /// this attribute list. Since attribute lists are immutable, this
- /// returns the new list.
- AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const;
-
- //===--------------------------------------------------------------------===//
- // Attribute List Accessors
- //===--------------------------------------------------------------------===//
- /// getParamAttributes - The attributes for the specified index are
- /// returned.
- Attributes getParamAttributes(unsigned Idx) const {
- assert (Idx && Idx != ~0U && "Invalid parameter index!");
- return getAttributes(Idx);
- }
-
- /// getRetAttributes - The attributes for the ret value are
- /// returned.
- Attributes getRetAttributes() const {
- return getAttributes(0);
- }
-
- /// getFnAttributes - The function attributes are returned.
- Attributes getFnAttributes() const {
- return getAttributes(~0U);
- }
-
- /// paramHasAttr - Return true if the specified parameter index has the
- /// specified attribute set.
- bool paramHasAttr(unsigned Idx, Attributes Attr) const {
- return getAttributes(Idx) & Attr;
- }
-
- /// getParamAlignment - Return the alignment for the specified function
- /// parameter.
- unsigned getParamAlignment(unsigned Idx) const {
- return Attribute::getAlignmentFromAttrs(getAttributes(Idx));
- }
-
- /// hasAttrSomewhere - Return true if the specified attribute is set for at
- /// least one parameter or for the return value.
- bool hasAttrSomewhere(Attributes Attr) const;
-
- /// operator==/!= - Provide equality predicates.
- bool operator==(const AttrListPtr &RHS) const
- { return AttrList == RHS.AttrList; }
- bool operator!=(const AttrListPtr &RHS) const
- { return AttrList != RHS.AttrList; }
-
- void dump() const;
-
- //===--------------------------------------------------------------------===//
- // Attribute List Introspection
- //===--------------------------------------------------------------------===//
-
- /// getRawPointer - Return a raw pointer that uniquely identifies this
- /// attribute list.
- void *getRawPointer() const {
- return AttrList;
- }
-
- // Attributes are stored as a dense set of slots, where there is one
- // slot for each argument that has an attribute. This allows walking over the
- // dense set instead of walking the sparse list of attributes.
-
- /// isEmpty - Return true if there are no attributes.
- ///
- bool isEmpty() const {
- return AttrList == 0;
- }
-
- /// getNumSlots - Return the number of slots used in this attribute list.
- /// This is the number of arguments that have an attribute set on them
- /// (including the function itself).
- unsigned getNumSlots() const;
-
- /// getSlot - Return the AttributeWithIndex at the specified slot. This
- /// holds a index number plus a set of attributes.
- const AttributeWithIndex &getSlot(unsigned Slot) const;
-
-private:
- explicit AttrListPtr(AttributeListImpl *L);
-
- /// getAttributes - The attributes for the specified index are
- /// returned. Attributes for the result are denoted with Idx = 0.
- Attributes getAttributes(unsigned Idx) const;
-
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h
index c1c3ec0..7b30c7e 100644
--- a/include/llvm/Bitcode/Archive.h
+++ b/include/llvm/Bitcode/Archive.h
@@ -50,10 +50,10 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table
- BitcodeFlag = 8, ///< Member is bitcode
- HasPathFlag = 16, ///< Member has a full or partial path
+ BitcodeFlag = 8, ///< Member is bitcode
+ HasPathFlag = 16, ///< Member has a full or partial path
HasLongFilenameFlag = 32, ///< Member uses the long filename syntax
- StringTableFlag = 64 ///< Member is an ar(1) format string table
+ StringTableFlag = 64 ///< Member is an ar(1) format string table
};
/// @}
@@ -527,9 +527,9 @@ class Archive {
/// @name Hidden
/// @{
private:
- Archive(); ///< Do not implement
- Archive(const Archive&); ///< Do not implement
- Archive& operator=(const Archive&); ///< Do not implement
+ Archive() LLVM_DELETED_FUNCTION;
+ Archive(const Archive&) LLVM_DELETED_FUNCTION;
+ Archive& operator=(const Archive&) LLVM_DELETED_FUNCTION;
/// @}
};
diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h
index 28e1ab1..b510daf 100644
--- a/include/llvm/Bitcode/BitCodes.h
+++ b/include/llvm/Bitcode/BitCodes.h
@@ -26,8 +26,8 @@
namespace llvm {
namespace bitc {
enum StandardWidths {
- BlockIDWidth = 8, // We use VBR-8 for block IDs.
- CodeLenWidth = 4, // Codelen are VBR-4.
+ BlockIDWidth = 8, // We use VBR-8 for block IDs.
+ CodeLenWidth = 4, // Codelen are VBR-4.
BlockSizeWidth = 32 // BlockSize up to 2^32 32-bit words = 16GB per block.
};
@@ -69,10 +69,11 @@ namespace bitc {
enum BlockInfoCodes {
// DEFINE_ABBREV has magic semantics here, applying to the current SETBID'd
// block, instead of the BlockInfo block.
-
- BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#]
- BLOCKINFO_CODE_BLOCKNAME = 2, // BLOCKNAME: [name]
- BLOCKINFO_CODE_SETRECORDNAME = 3 // BLOCKINFO_CODE_SETRECORDNAME: [id, name]
+
+ BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#]
+ BLOCKINFO_CODE_BLOCKNAME = 2, // BLOCKNAME: [name]
+ BLOCKINFO_CODE_SETRECORDNAME = 3 // BLOCKINFO_CODE_SETRECORDNAME:
+ // [id, name]
};
} // End bitc namespace
@@ -99,7 +100,7 @@ public:
explicit BitCodeAbbrevOp(Encoding E, uint64_t Data = 0)
: Val(Data), IsLiteral(false), Enc(E) {}
- bool isLiteral() const { return IsLiteral; }
+ bool isLiteral() const { return IsLiteral; }
bool isEncoding() const { return !IsLiteral; }
// Accessors for literals.
@@ -138,18 +139,18 @@ public:
if (C >= 'a' && C <= 'z') return C-'a';
if (C >= 'A' && C <= 'Z') return C-'A'+26;
if (C >= '0' && C <= '9') return C-'0'+26+26;
- if (C == '.') return 62;
- if (C == '_') return 63;
+ if (C == '.') return 62;
+ if (C == '_') return 63;
llvm_unreachable("Not a value Char6 character!");
}
static char DecodeChar6(unsigned V) {
assert((V & ~63) == 0 && "Not a Char6 encoded character!");
- if (V < 26) return V+'a';
- if (V < 26+26) return V-26+'A';
+ if (V < 26) return V+'a';
+ if (V < 26+26) return V-26+'A';
if (V < 26+26+10) return V-26-26+'0';
- if (V == 62) return '.';
- if (V == 63) return '_';
+ if (V == 62) return '.';
+ if (V == 63) return '_';
llvm_unreachable("Not a value Char6 character!");
}
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index 6586829..5b60f72 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -35,21 +35,21 @@ public:
unsigned BlockID;
std::vector<BitCodeAbbrev*> Abbrevs;
std::string Name;
-
+
std::vector<std::pair<unsigned, std::string> > RecordNames;
};
private:
OwningPtr<StreamableMemoryObject> BitcodeBytes;
-
+
std::vector<BlockInfo> BlockInfoRecords;
/// IgnoreBlockInfoNames - This is set to true if we don't care about the
/// block/record name information in the BlockInfo block. Only llvm-bcanalyzer
/// uses this.
bool IgnoreBlockInfoNames;
-
- BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT
- void operator=(const BitstreamReader&); // DO NOT IMPLEMENT
+
+ BitstreamReader(const BitstreamReader&) LLVM_DELETED_FUNCTION;
+ void operator=(const BitstreamReader&) LLVM_DELETED_FUNCTION;
public:
BitstreamReader() : IgnoreBlockInfoNames(true) {
}
@@ -86,7 +86,7 @@ public:
/// name information.
void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; }
bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; }
-
+
//===--------------------------------------------------------------------===//
// Block Manipulation
//===--------------------------------------------------------------------===//
@@ -95,7 +95,7 @@ public:
/// block info block for this Bitstream. We only process it for the first
/// cursor that walks over it.
bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); }
-
+
/// getBlockInfo - If there is block info for the specified ID, return it,
/// otherwise return null.
const BlockInfo *getBlockInfo(unsigned BlockID) const {
@@ -126,74 +126,74 @@ class BitstreamCursor {
friend class Deserializer;
BitstreamReader *BitStream;
size_t NextChar;
-
+
/// CurWord - This is the current data we have pulled from the stream but have
/// not returned to the client.
uint32_t CurWord;
-
+
/// BitsInCurWord - This is the number of bits in CurWord that are valid. This
/// is always from [0...31] inclusive.
unsigned BitsInCurWord;
-
+
// CurCodeSize - This is the declared size of code values used for the current
// block, in bits.
unsigned CurCodeSize;
-
+
/// CurAbbrevs - Abbrevs installed at in this block.
std::vector<BitCodeAbbrev*> CurAbbrevs;
-
+
struct Block {
unsigned PrevCodeSize;
std::vector<BitCodeAbbrev*> PrevAbbrevs;
explicit Block(unsigned PCS) : PrevCodeSize(PCS) {}
};
-
+
/// BlockScope - This tracks the codesize of parent blocks.
SmallVector<Block, 8> BlockScope;
-
+
public:
BitstreamCursor() : BitStream(0), NextChar(0) {
}
BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) {
operator=(RHS);
}
-
+
explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) {
NextChar = 0;
CurWord = 0;
BitsInCurWord = 0;
CurCodeSize = 2;
}
-
+
void init(BitstreamReader &R) {
freeState();
-
+
BitStream = &R;
NextChar = 0;
CurWord = 0;
BitsInCurWord = 0;
CurCodeSize = 2;
}
-
+
~BitstreamCursor() {
freeState();
}
-
+
void operator=(const BitstreamCursor &RHS) {
freeState();
-
+
BitStream = RHS.BitStream;
NextChar = RHS.NextChar;
CurWord = RHS.CurWord;
BitsInCurWord = RHS.BitsInCurWord;
CurCodeSize = RHS.CurCodeSize;
-
+
// Copy abbreviations, and bump ref counts.
CurAbbrevs = RHS.CurAbbrevs;
for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
i != e; ++i)
CurAbbrevs[i]->addRef();
-
+
// Copy block scope and bump ref counts.
BlockScope = RHS.BlockScope;
for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
@@ -204,14 +204,14 @@ public:
Abbrevs[i]->addRef();
}
}
-
+
void freeState() {
// Free all the Abbrevs.
for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
i != e; ++i)
CurAbbrevs[i]->dropRef();
CurAbbrevs.clear();
-
+
// Free all the Abbrevs in the block scope.
for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
S != e; ++S) {
@@ -222,10 +222,10 @@ public:
}
BlockScope.clear();
}
-
+
/// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
-
+
bool isEndPos(size_t pos) {
return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
}
@@ -255,37 +255,37 @@ public:
bool AtEndOfStream() {
return isEndPos(NextChar) && BitsInCurWord == 0;
}
-
+
/// GetCurrentBitNo - Return the bit # of the bit we are reading.
uint64_t GetCurrentBitNo() const {
return NextChar*CHAR_BIT - BitsInCurWord;
}
-
+
BitstreamReader *getBitStreamReader() {
return BitStream;
}
const BitstreamReader *getBitStreamReader() const {
return BitStream;
}
-
-
+
+
/// JumpToBit - Reset the stream to the specified bit number.
void JumpToBit(uint64_t BitNo) {
uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3;
uintptr_t WordBitNo = uintptr_t(BitNo) & 31;
assert(canSkipToPos(ByteNo) && "Invalid location");
-
+
// Move the cursor to the right word.
NextChar = ByteNo;
BitsInCurWord = 0;
CurWord = 0;
-
+
// Skip over any bits that are already consumed.
if (WordBitNo)
Read(static_cast<unsigned>(WordBitNo));
}
-
-
+
+
uint32_t Read(unsigned NumBits) {
assert(NumBits <= 32 && "Cannot return more than 32 bits!");
// If the field is fully contained by CurWord, return it quickly.
@@ -409,7 +409,7 @@ public:
}
/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
- /// the block, and return true if the block is valid.
+ /// the block, and return true if the block has an error.
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) {
// Save the current block's state on BlockScope.
BlockScope.push_back(Block(CurCodeSize));
@@ -473,7 +473,7 @@ private:
// If the abbrev specifies the literal value to use, use it.
Vals.push_back(Op.getLiteralValue());
}
-
+
void ReadAbbreviatedField(const BitCodeAbbrevOp &Op,
SmallVectorImpl<uint64_t> &Vals) {
assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");
@@ -494,13 +494,13 @@ private:
}
public:
- /// getAbbrev - Return the abbreviation for the specified AbbrevId.
+ /// getAbbrev - Return the abbreviation for the specified AbbrevId.
const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) {
unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV;
assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
return CurAbbrevs[AbbrevNo];
}
-
+
unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
const char **BlobStart = 0, unsigned *BlobLen = 0) {
if (AbbrevID == bitc::UNABBREV_RECORD) {
@@ -516,7 +516,7 @@ public:
for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
if (Op.isLiteral()) {
- ReadAbbreviatedLiteral(Op, Vals);
+ ReadAbbreviatedLiteral(Op, Vals);
} else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
// Array case. Read the number of elements as a vbr6.
unsigned NumElts = ReadVBR(6);
@@ -535,7 +535,7 @@ public:
// Figure out where the end of this blob will be including tail padding.
size_t NewEnd = NextChar+((NumElts+3)&~3);
-
+
// If this would read off the end of the bitcode file, just set the
// record to empty and return.
if (!canSkipToPos(NewEnd)) {
@@ -543,7 +543,7 @@ public:
NextChar = BitStream->getBitcodeBytes().getExtent();
break;
}
-
+
// Otherwise, read the number of bytes. If we can return a reference to
// the data, do so to avoid copying it.
if (BlobStart) {
@@ -571,7 +571,7 @@ public:
return ReadRecord(AbbrevID, Vals, &BlobStart, &BlobLen);
}
-
+
//===--------------------------------------------------------------------===//
// Abbrev Processing
//===--------------------------------------------------------------------===//
@@ -594,14 +594,14 @@ public:
}
CurAbbrevs.push_back(Abbv);
}
-
+
public:
bool ReadBlockInfoBlock() {
// If this is the second stream to get to the block info block, skip it.
if (BitStream->hasBlockInfoRecords())
return SkipBlock();
-
+
if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
SmallVector<uint64_t, 64> Record;
@@ -662,7 +662,7 @@ public:
}
}
};
-
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
index dea118f..1021fbd 100644
--- a/include/llvm/Bitcode/BitstreamWriter.h
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -15,8 +15,8 @@
#ifndef BITSTREAM_WRITER_H
#define BITSTREAM_WRITER_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitCodes.h"
#include <vector>
@@ -273,7 +273,7 @@ public:
private:
/// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev
- /// record. This is a no-op, since the abbrev specifies the literal to use.
+ /// record. This is a no-op, since the abbrev specifies the literal to use.
template<typename uintty>
void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) {
assert(Op.isLiteral() && "Not a literal");
@@ -282,13 +282,13 @@ private:
assert(V == Op.getLiteralValue() &&
"Invalid abbrev for record!");
}
-
+
/// EmitAbbreviatedField - Emit a single scalar field value with the specified
/// encoding.
template<typename uintty>
void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!");
-
+
// Encode the value as we are commanded.
switch (Op.getEncoding()) {
default: llvm_unreachable("Unknown encoding!");
@@ -305,7 +305,7 @@ private:
break;
}
}
-
+
/// EmitRecordWithAbbrevImpl - This is the core implementation of the record
/// emission code. If BlobData is non-null, then it specifies an array of
/// data that should be emitted as part of the Blob or Array operand that is
@@ -341,11 +341,11 @@ private:
"Blob data and record entries specified for array!");
// Emit a vbr6 to indicate the number of elements present.
EmitVBR(static_cast<uint32_t>(BlobLen), 6);
-
+
// Emit each field.
for (unsigned i = 0; i != BlobLen; ++i)
EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]);
-
+
// Know that blob data is consumed for assertion below.
BlobData = 0;
} else {
@@ -359,7 +359,7 @@ private:
} else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
// If this record has blob data, emit it, otherwise we must have record
// entries to encode this way.
-
+
// Emit a vbr6 to indicate the number of elements present.
if (BlobData) {
EmitVBR(static_cast<uint32_t>(BlobLen), 6);
@@ -368,7 +368,7 @@ private:
} else {
EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
}
-
+
// Flush to a 32-bit alignment boundary.
FlushToWord();
@@ -376,7 +376,7 @@ private:
if (BlobData) {
for (unsigned i = 0; i != BlobLen; ++i)
WriteByte((unsigned char)BlobData[i]);
-
+
// Know that blob data is consumed for assertion below.
BlobData = 0;
} else {
@@ -399,7 +399,7 @@ private:
assert(BlobData == 0 &&
"Blob data specified for record that doesn't use it!");
}
-
+
public:
/// EmitRecord - Emit the specified record to the stream, using an abbrev if
@@ -420,10 +420,10 @@ public:
// Insert the code into Vals to treat it uniformly.
Vals.insert(Vals.begin(), Code);
-
+
EmitRecordWithAbbrev(Abbrev, Vals);
}
-
+
/// EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
/// Unlike EmitRecord, the code for the record should be included in Vals as
/// the first entry.
@@ -431,7 +431,7 @@ public:
void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl<uintty> &Vals) {
EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef());
}
-
+
/// EmitRecordWithBlob - Emit the specified record to the stream, using an
/// abbrev that includes a blob at the end. The blob data to emit is
/// specified by the pointer and length specified at the end. In contrast to
@@ -461,7 +461,7 @@ public:
return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData,
ArrayLen));
}
-
+
//===--------------------------------------------------------------------===//
// Abbrev Emission
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index c1dc190..601777d 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -31,16 +31,16 @@ namespace bitc {
PARAMATTR_BLOCK_ID,
UNUSED_ID1,
-
+
CONSTANTS_BLOCK_ID,
FUNCTION_BLOCK_ID,
-
+
UNUSED_ID2,
-
+
VALUE_SYMTAB_BLOCK_ID,
METADATA_BLOCK_ID,
METADATA_ATTACHMENT_ID,
-
+
TYPE_BLOCK_ID_NEW,
USELIST_BLOCK_ID
@@ -54,6 +54,8 @@ namespace bitc {
MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N]
MODULE_CODE_ASM = 4, // ASM: [strchr x N]
MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N]
+
+ // FIXME: Remove DEPLIB in 4.0.
MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N]
// GLOBALVAR: [pointer type, isconst, initid,
@@ -93,9 +95,9 @@ namespace bitc {
TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty,
// paramty x N]
-
+
TYPE_CODE_HALF = 10, // HALF
-
+
TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty]
TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty]
@@ -109,7 +111,7 @@ namespace bitc {
TYPE_CODE_METADATA = 16, // METADATA
TYPE_CODE_X86_MMX = 17, // X86 MMX
-
+
TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N]
TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N]
@@ -234,7 +236,7 @@ namespace bitc {
OBO_NO_SIGNED_WRAP = 1
};
- /// PossiblyExactOperatorOptionalFlags - Flags for serializing
+ /// PossiblyExactOperatorOptionalFlags - Flags for serializing
/// PossiblyExactOperator's SubclassOptionalData contents.
enum PossiblyExactOperatorOptionalFlags {
PEO_EXACT = 0
diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt
index f8cb425..32ffca7 100644
--- a/include/llvm/CMakeLists.txt
+++ b/include/llvm/CMakeLists.txt
@@ -1,10 +1,4 @@
-set(LLVM_TARGET_DEFINITIONS Intrinsics.td)
-
-tablegen(LLVM Intrinsics.gen -gen-intrinsic)
-
-add_custom_target(intrinsics_gen ALL
- DEPENDS ${llvm_builded_incs_dir}/Intrinsics.gen)
-set_target_properties(intrinsics_gen PROPERTIES FOLDER "Tablegenning")
+add_subdirectory(IR)
if( MSVC_IDE OR XCODE )
# Creates a dummy target containing all headers for the benefit of
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index 0b609ed..81e75d8 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -14,12 +14,12 @@
#ifndef LLVM_CODEGEN_ANALYSIS_H
#define LLVM_CODEGEN_ANALYSIS_H
-#include "llvm/Instructions.h"
-#include "llvm/InlineAsm.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
@@ -86,12 +86,9 @@ ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
/// between it and the return.
///
/// This function only tests target-independent requirements.
-bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
+bool isInTailCallPosition(ImmutableCallSite CS, Attribute CalleeRetAttr,
const TargetLowering &TLI);
-bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
- SDValue &Chain, const TargetLowering &TLI);
-
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 2920675..e0a6e3f 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -17,7 +17,7 @@
#define LLVM_CODEGEN_ASMPRINTER_H
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/InlineAsm.h"
+#include "llvm/IR/InlineAsm.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@@ -48,7 +48,7 @@ namespace llvm {
class DwarfException;
class Mangler;
class TargetLoweringObjectFile;
- class TargetData;
+ class DataLayout;
class TargetMachine;
/// AsmPrinter - This class is intended to be used as a driving class for all
@@ -131,8 +131,8 @@ namespace llvm {
/// getObjFileLowering - Return information about object file lowering.
const TargetLoweringObjectFile &getObjFileLowering() const;
- /// getTargetData - Return information about data layout.
- const TargetData &getTargetData() const;
+ /// getDataLayout - Return information about data layout.
+ const DataLayout &getDataLayout() const;
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
@@ -385,10 +385,8 @@ namespace llvm {
/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
- /// EmitReference - Emit a reference to a label with a specified encoding.
- ///
- void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
- void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
+ /// EmitReference - Emit reference to a ttype global with a specified encoding.
+ void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const;
/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of
/// its section. This can be done with a special directive if the target
diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h
index 2f76a6c..9cd2dec 100644
--- a/include/llvm/CodeGen/CalcSpillWeights.h
+++ b/include/llvm/CodeGen/CalcSpillWeights.h
@@ -11,8 +11,8 @@
#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
-#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/SlotIndexes.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index 3afe309..c035e07 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -16,10 +16,11 @@
#define LLVM_CODEGEN_CALLINGCONVLOWER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/CallingConv.h"
#include "llvm/Target/TargetCallingConv.h"
-#include "llvm/CallingConv.h"
namespace llvm {
class TargetRegisterInfo;
@@ -49,10 +50,10 @@ private:
unsigned Loc;
/// isMem - True if this is a memory loc, false if it is a register loc.
- bool isMem : 1;
+ unsigned isMem : 1;
/// isCustom - True if this arg/retval requires special handling.
- bool isCustom : 1;
+ unsigned isCustom : 1;
/// Information about how the value is assigned.
LocInfo HTP : 6;
@@ -288,6 +289,7 @@ public:
StackOffset = ((StackOffset + Align-1) & ~(Align-1));
unsigned Result = StackOffset;
StackOffset += Size;
+ MF.getFrameInfo()->ensureMaxAlignment(Align);
return Result;
}
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
new file mode 100644
index 0000000..a66e05b
--- /dev/null
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -0,0 +1,227 @@
+//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains codegen-specific flags that are shared between different
+// command line tools. The tools "llc" and "opt" both use this file to prevent
+// flag duplication.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_COMMAND_LINE_FLAGS_H
+#define LLVM_CODEGEN_COMMAND_LINE_FLAGS_H
+
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetMachine.h"
+#include <string>
+using namespace llvm;
+
+cl::opt<std::string>
+MArch("march", cl::desc("Architecture to generate code for (see --version)"));
+
+cl::opt<std::string>
+MCPU("mcpu",
+ cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+ cl::value_desc("cpu-name"),
+ cl::init(""));
+
+cl::list<std::string>
+MAttrs("mattr",
+ cl::CommaSeparated,
+ cl::desc("Target specific attributes (-mattr=help for details)"),
+ cl::value_desc("a1,+a2,-a3,..."));
+
+cl::opt<Reloc::Model>
+RelocModel("relocation-model",
+ cl::desc("Choose relocation model"),
+ cl::init(Reloc::Default),
+ cl::values(
+ clEnumValN(Reloc::Default, "default",
+ "Target default relocation model"),
+ clEnumValN(Reloc::Static, "static",
+ "Non-relocatable code"),
+ clEnumValN(Reloc::PIC_, "pic",
+ "Fully relocatable, position independent code"),
+ clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
+ "Relocatable external references, non-relocatable code"),
+ clEnumValEnd));
+
+cl::opt<llvm::CodeModel::Model>
+CMModel("code-model",
+ cl::desc("Choose code model"),
+ cl::init(CodeModel::Default),
+ cl::values(clEnumValN(CodeModel::Default, "default",
+ "Target default code model"),
+ clEnumValN(CodeModel::Small, "small",
+ "Small code model"),
+ clEnumValN(CodeModel::Kernel, "kernel",
+ "Kernel code model"),
+ clEnumValN(CodeModel::Medium, "medium",
+ "Medium code model"),
+ clEnumValN(CodeModel::Large, "large",
+ "Large code model"),
+ clEnumValEnd));
+
+cl::opt<bool>
+RelaxAll("mc-relax-all",
+ cl::desc("When used with filetype=obj, "
+ "relax all fixups in the emitted object file"));
+
+cl::opt<TargetMachine::CodeGenFileType>
+FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
+ cl::desc("Choose a file type (not all types are supported by all targets):"),
+ cl::values(
+ clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
+ "Emit an assembly ('.s') file"),
+ clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
+ "Emit a native object ('.o') file"),
+ clEnumValN(TargetMachine::CGFT_Null, "null",
+ "Emit nothing, for performance testing"),
+ clEnumValEnd));
+
+cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden,
+ cl::desc("Do not use .loc entries"));
+
+cl::opt<bool> DisableCFI("disable-cfi", cl::Hidden,
+ cl::desc("Do not use .cfi_* directives"));
+
+cl::opt<bool> EnableDwarfDirectory("enable-dwarf-directory", cl::Hidden,
+ cl::desc("Use .file directives with an explicit directory."));
+
+cl::opt<bool>
+DisableRedZone("disable-red-zone",
+ cl::desc("Do not emit code that uses the red zone."),
+ cl::init(false));
+
+cl::opt<bool>
+EnableFPMAD("enable-fp-mad",
+ cl::desc("Enable less precise MAD instructions to be generated"),
+ cl::init(false));
+
+cl::opt<bool>
+DisableFPElim("disable-fp-elim",
+ cl::desc("Disable frame pointer elimination optimization"),
+ cl::init(false));
+
+cl::opt<bool>
+DisableFPElimNonLeaf("disable-non-leaf-fp-elim",
+ cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
+ cl::init(false));
+
+cl::opt<bool>
+EnableUnsafeFPMath("enable-unsafe-fp-math",
+ cl::desc("Enable optimizations that may decrease FP precision"),
+ cl::init(false));
+
+cl::opt<bool>
+EnableNoInfsFPMath("enable-no-infs-fp-math",
+ cl::desc("Enable FP math optimizations that assume no +-Infs"),
+ cl::init(false));
+
+cl::opt<bool>
+EnableNoNaNsFPMath("enable-no-nans-fp-math",
+ cl::desc("Enable FP math optimizations that assume no NaNs"),
+ cl::init(false));
+
+cl::opt<bool>
+EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
+ cl::Hidden,
+ cl::desc("Force codegen to assume rounding mode can change dynamically"),
+ cl::init(false));
+
+cl::opt<bool>
+GenerateSoftFloatCalls("soft-float",
+ cl::desc("Generate software floating point library calls"),
+ cl::init(false));
+
+cl::opt<llvm::FloatABI::ABIType>
+FloatABIForCalls("float-abi",
+ cl::desc("Choose float ABI type"),
+ cl::init(FloatABI::Default),
+ cl::values(
+ clEnumValN(FloatABI::Default, "default",
+ "Target default float ABI type"),
+ clEnumValN(FloatABI::Soft, "soft",
+ "Soft float ABI (implied by -soft-float)"),
+ clEnumValN(FloatABI::Hard, "hard",
+ "Hard float ABI (uses FP registers)"),
+ clEnumValEnd));
+
+cl::opt<llvm::FPOpFusion::FPOpFusionMode>
+FuseFPOps("fp-contract",
+ cl::desc("Enable aggresive formation of fused FP ops"),
+ cl::init(FPOpFusion::Standard),
+ cl::values(
+ clEnumValN(FPOpFusion::Fast, "fast",
+ "Fuse FP ops whenever profitable"),
+ clEnumValN(FPOpFusion::Standard, "on",
+ "Only fuse 'blessed' FP ops."),
+ clEnumValN(FPOpFusion::Strict, "off",
+ "Only fuse FP ops when the result won't be effected."),
+ clEnumValEnd));
+
+cl::opt<bool>
+DontPlaceZerosInBSS("nozero-initialized-in-bss",
+ cl::desc("Don't place zero-initialized symbols into bss section"),
+ cl::init(false));
+
+cl::opt<bool>
+EnableGuaranteedTailCallOpt("tailcallopt",
+ cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
+ cl::init(false));
+
+cl::opt<bool>
+DisableTailCalls("disable-tail-calls",
+ cl::desc("Never emit tail calls"),
+ cl::init(false));
+
+cl::opt<unsigned>
+OverrideStackAlignment("stack-alignment",
+ cl::desc("Override default stack alignment"),
+ cl::init(0));
+
+cl::opt<bool>
+EnableRealignStack("realign-stack",
+ cl::desc("Realign stack if needed"),
+ cl::init(true));
+
+cl::opt<std::string>
+TrapFuncName("trap-func", cl::Hidden,
+ cl::desc("Emit a call to trap function rather than a trap instruction"),
+ cl::init(""));
+
+cl::opt<bool>
+EnablePIE("enable-pie",
+ cl::desc("Assume the creation of a position independent executable."),
+ cl::init(false));
+
+cl::opt<bool>
+SegmentedStacks("segmented-stacks",
+ cl::desc("Use segmented stacks if possible."),
+ cl::init(false));
+
+cl::opt<bool>
+UseInitArray("use-init-array",
+ cl::desc("Use .init_array instead of .ctors."),
+ cl::init(false));
+
+cl::opt<std::string> StopAfter("stop-after",
+ cl::desc("Stop compilation after a specific pass"),
+ cl::value_desc("pass-name"),
+ cl::init(""));
+cl::opt<std::string> StartAfter("start-after",
+ cl::desc("Resume compilation after a specific pass"),
+ cl::value_desc("pass-name"),
+ cl::init(""));
+
+cl::opt<unsigned>
+SSPBufferSize("stack-protector-buffer-size", cl::init(8),
+ cl::desc("Lower bound for a buffer to be considered for "
+ "stack protection"));
+#endif
diff --git a/include/llvm/CodeGen/DAGCombine.h b/include/llvm/CodeGen/DAGCombine.h
new file mode 100644
index 0000000..8b59190
--- /dev/null
+++ b/include/llvm/CodeGen/DAGCombine.h
@@ -0,0 +1,25 @@
+//===-- llvm/CodeGen/DAGCombine.h ------- SelectionDAG Nodes ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+#ifndef LLVM_CODEGEN_DAGCOMBINE_H
+#define LLVM_CODEGEN_DAGCOMBINE_H
+
+namespace llvm {
+
+enum CombineLevel {
+ BeforeLegalizeTypes,
+ AfterLegalizeTypes,
+ AfterLegalizeVectorOps,
+ AfterLegalizeDAG
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/DFAPacketizer.h b/include/llvm/CodeGen/DFAPacketizer.h
index 2d2db78..9d25fd3 100644
--- a/include/llvm/CodeGen/DFAPacketizer.h
+++ b/include/llvm/CodeGen/DFAPacketizer.h
@@ -26,8 +26,8 @@
#ifndef LLVM_CODEGEN_DFAPACKETIZER_H
#define LLVM_CODEGEN_DFAPACKETIZER_H
-#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include <map>
namespace llvm {
@@ -135,7 +135,7 @@ public:
// initPacketizerState - perform initialization before packetizing
// an instruction. This function is supposed to be overrided by
// the target dependent packetizer.
- virtual void initPacketizerState(void) { return; }
+ virtual void initPacketizerState() { return; }
// ignorePseudoInstruction - Ignore bundling of pseudo instructions.
virtual bool ignorePseudoInstruction(MachineInstr *I,
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 7cb9695..0561905 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -15,8 +15,8 @@
#define LLVM_CODEGEN_FASTISEL_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/ValueTypes.h"
namespace llvm {
@@ -32,7 +32,7 @@ class MachineFunction;
class MachineInstr;
class MachineFrameInfo;
class MachineRegisterInfo;
-class TargetData;
+class DataLayout;
class TargetInstrInfo;
class TargetLibraryInfo;
class TargetLowering;
@@ -54,7 +54,7 @@ protected:
MachineConstantPool &MCP;
DebugLoc DL;
const TargetMachine &TM;
- const TargetData &TD;
+ const DataLayout &TD;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
const TargetRegisterInfo &TRI;
@@ -131,6 +131,10 @@ public:
/// into the current block.
void recomputeInsertPt();
+ /// removeDeadCode - Remove all dead instructions between the I and E.
+ void removeDeadCode(MachineBasicBlock::iterator I,
+ MachineBasicBlock::iterator E);
+
struct SavePoint {
MachineBasicBlock::iterator InsertPt;
DebugLoc DL;
@@ -395,10 +399,6 @@ private:
/// hasTrivialKill - Test whether the given value has exactly one use.
bool hasTrivialKill(const Value *V) const;
-
- /// removeDeadCode - Remove all dead instructions between the I and E.
- void removeDeadCode(MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator E);
};
}
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
index 8cf22ec..72e0937 100644
--- a/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -15,8 +15,6 @@
#ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
#define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
-#include "llvm/InlineAsm.h"
-#include "llvm/Instructions.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
@@ -24,9 +22,11 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <vector>
@@ -136,7 +136,7 @@ public:
return ValueMap.count(V);
}
- unsigned CreateReg(EVT VT);
+ unsigned CreateReg(MVT VT);
unsigned CreateRegs(Type *Ty);
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 20e33f7..fa40049 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -33,9 +33,9 @@
#ifndef LLVM_CODEGEN_GCMETADATA_H
#define LLVM_CODEGEN_GCMETADATA_H
-#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Pass.h"
#include "llvm/Support/DebugLoc.h"
namespace llvm {
@@ -122,6 +122,11 @@ namespace llvm {
Roots.push_back(GCRoot(Num, Metadata));
}
+ /// removeStackRoot - Removes a root.
+ roots_iterator removeStackRoot(roots_iterator position) {
+ return Roots.erase(position);
+ }
+
/// addSafePoint - Notes the existence of a safe point. Num is the ID of the
/// label just prior to the safe point (if the code generator is using
/// MachineModuleInfo).
diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h
index 17a2653..4a6b5ac 100644
--- a/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -48,9 +48,10 @@ namespace llvm {
// May only be subclassed.
GCMetadataPrinter();
- // Do not implement.
- GCMetadataPrinter(const GCMetadataPrinter &);
- GCMetadataPrinter &operator=(const GCMetadataPrinter &);
+ private:
+ GCMetadataPrinter(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
+ GCMetadataPrinter &
+ operator=(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
public:
GCStrategy &getStrategy() { return *S; }
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
index 767b666..68389dd 100644
--- a/include/llvm/CodeGen/IntrinsicLowering.h
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -16,20 +16,20 @@
#ifndef LLVM_CODEGEN_INTRINSICLOWERING_H
#define LLVM_CODEGEN_INTRINSICLOWERING_H
-#include "llvm/Intrinsics.h"
+#include "llvm/IR/Intrinsics.h"
namespace llvm {
class CallInst;
class Module;
- class TargetData;
+ class DataLayout;
class IntrinsicLowering {
- const TargetData& TD;
+ const DataLayout& TD;
bool Warned;
public:
- explicit IntrinsicLowering(const TargetData &td) :
+ explicit IntrinsicLowering(const DataLayout &td) :
TD(td), Warned(false) {}
/// AddPrototypes - This method, if called, causes all of the prototypes
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index 89f00e9..21a3f48 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -17,11 +17,11 @@
#ifndef LLVM_CODEGEN_JITCODEEMITTER_H
#define LLVM_CODEGEN_JITCODEEMITTER_H
-#include <string>
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
-#include "llvm/ADT/DenseMap.h"
+#include <string>
namespace llvm {
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index 8414c64..3cb6b4d 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -17,11 +17,11 @@
#ifndef LLVM_CODEGEN_LEXICALSCOPES_H
#define LLVM_CODEGEN_LEXICALSCOPES_H
-#include "llvm/Metadata.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/ValueHandle.h"
#include <utility>
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 46dd004..2145eb8 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
#define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+#include "llvm/CodeGen/GCs.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
-#include "llvm/CodeGen/GCs.h"
#include "llvm/Target/TargetMachine.h"
#include <cstdlib>
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 5aeb1a8..9576075 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -22,9 +22,9 @@
#define LLVM_CODEGEN_LIVEINTERVAL_H
#include "llvm/ADT/IntEqClasses.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/AlignOf.h"
#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
#include <cassert>
#include <climits>
@@ -114,9 +114,6 @@ namespace llvm {
void dump() const;
void print(raw_ostream &os) const;
-
- private:
- LiveRange(); // DO NOT IMPLEMENT
};
template <> struct isPodLike<LiveRange> { static const bool value = true; };
@@ -276,11 +273,6 @@ namespace llvm {
void MergeValueInAsValue(const LiveInterval &RHS,
const VNInfo *RHSValNo, VNInfo *LHSValNo);
- /// Copy - Copy the specified live interval. This copies all the fields
- /// except for the register of the interval.
- void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI,
- VNInfo::Allocator &VNInfoAllocator);
-
bool empty() const { return ranges.empty(); }
/// beginIndex - Return the lowest numbered slot covered by interval.
@@ -313,12 +305,6 @@ namespace llvm {
return r != end() && r->end == index;
}
- /// killedInRange - Return true if the interval has kills in [Start,End).
- /// Note that the kill point is considered the end of a live range, so it is
- /// not contained in the live range. If a live range ends at End, it won't
- /// be counted as a kill by this method.
- bool killedInRange(SlotIndex Start, SlotIndex End) const;
-
/// getLiveRangeContaining - Return the live range that contains the
/// specified index, or null if there is none.
const LiveRange *getLiveRangeContaining(SlotIndex Idx) const {
@@ -478,7 +464,7 @@ namespace llvm {
VNInfo *LHSValNo = 0,
const VNInfo *RHSValNo = 0);
- LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
+ LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION;
};
@@ -510,7 +496,9 @@ namespace llvm {
if (I == E)
return;
// Is this an instruction live-in segment?
- if (SlotIndex::isEarlierInstr(I->start, Idx)) {
+ // If Idx is the start index of a basic block, include live-in segments
+ // that start at Idx.getBaseIndex().
+ if (I->start <= Idx.getBaseIndex()) {
EarlyVal = I->valno;
EndPoint = I->end;
// Move to the potentially live-out segment.
@@ -519,6 +507,12 @@ namespace llvm {
if (++I == E)
return;
}
+ // Special case: A PHIDef value can have its def in the middle of a
+ // segment if the value happens to be live out of the layout
+ // predecessor.
+ // Such a value is not live-in.
+ if (EarlyVal->def == Idx.getBaseIndex())
+ EarlyVal = 0;
}
// I now points to the segment that may be live-through, or defined by
// this instr. Ignore segments starting after the current instr.
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index bf74690..9e89519 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -20,16 +20,16 @@
#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/LiveInterval.h"
-#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include <cmath>
#include <iterator>
@@ -65,12 +65,6 @@ namespace llvm {
/// Live interval pointers for all the virtual registers.
IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;
- /// AllocatableRegs - A bit vector of allocatable registers.
- BitVector AllocatableRegs;
-
- /// ReservedRegs - A bit vector of reserved registers.
- BitVector ReservedRegs;
-
/// RegMaskSlots - Sorted list of instructions with register mask operands.
/// Always use the 'r' slot, RegMasks are normal clobbers, not early
/// clobbers.
@@ -123,18 +117,6 @@ namespace llvm {
return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
}
- /// isAllocatable - is the physical register reg allocatable in the current
- /// function?
- bool isAllocatable(unsigned reg) const {
- return AllocatableRegs.test(reg);
- }
-
- /// isReserved - is the physical register reg reserved in the current
- /// function
- bool isReserved(unsigned reg) const {
- return ReservedRegs.test(reg);
- }
-
// Interval creation.
LiveInterval &getOrCreateInterval(unsigned Reg) {
if (!hasInterval(Reg)) {
@@ -165,6 +147,26 @@ namespace llvm {
bool shrinkToUses(LiveInterval *li,
SmallVectorImpl<MachineInstr*> *dead = 0);
+ /// extendToIndices - Extend the live range of LI to reach all points in
+ /// Indices. The points in the Indices array must be jointly dominated by
+ /// existing defs in LI. PHI-defs are added as needed to maintain SSA form.
+ ///
+ /// If a SlotIndex in Indices is the end index of a basic block, LI will be
+ /// extended to be live out of the basic block.
+ ///
+ /// See also LiveRangeCalc::extend().
+ void extendToIndices(LiveInterval *LI, ArrayRef<SlotIndex> Indices);
+
+ /// pruneValue - If an LI value is live at Kill, prune its live range by
+ /// removing any liveness reachable from Kill. Add live range end points to
+ /// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
+ /// value's live range.
+ ///
+ /// Calling pruneValue() and extendToIndices() can be used to reconstruct
+ /// SSA form after adding defs to a virtual register.
+ void pruneValue(LiveInterval *LI, SlotIndex Kill,
+ SmallVectorImpl<SlotIndex> *EndPoints);
+
SlotIndexes *getSlotIndexes() const {
return Indexes;
}
@@ -258,15 +260,20 @@ namespace llvm {
/// instruction 'mi' has been moved within a basic block. This will update
/// the live intervals for all operands of mi. Moves between basic blocks
/// are not supported.
- void handleMove(MachineInstr* MI);
+ ///
+ /// \param UpdateFlags Update live intervals for nonallocatable physregs.
+ void handleMove(MachineInstr* MI, bool UpdateFlags = false);
/// moveIntoBundle - Update intervals for operands of MI so that they
/// begin/end on the SlotIndex for BundleStart.
///
+ /// \param UpdateFlags Update live intervals for nonallocatable physregs.
+ ///
/// Requires MI and BundleStart to have SlotIndexes, and assumes
/// existing liveness is accurate. BundleStart should be the first
/// instruction in the Bundle.
- void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart);
+ void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
+ bool UpdateFlags = false);
// Register mask functions.
//
@@ -340,6 +347,10 @@ namespace llvm {
return RegUnitIntervals[Unit];
}
+ const LiveInterval *getCachedRegUnit(unsigned Unit) const {
+ return RegUnitIntervals[Unit];
+ }
+
private:
/// computeIntervals - Compute live intervals.
void computeIntervals();
diff --git a/include/llvm/CodeGen/LiveIntervalUnion.h b/include/llvm/CodeGen/LiveIntervalUnion.h
new file mode 100644
index 0000000..6a61614
--- /dev/null
+++ b/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -0,0 +1,205 @@
+//===-- LiveIntervalUnion.h - Live interval union data struct --*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// LiveIntervalUnion is a union of live segments across multiple live virtual
+// registers. This may be used during coalescing to represent a congruence
+// class, or during register allocation to model liveness of a physical
+// register.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVALUNION
+#define LLVM_CODEGEN_LIVEINTERVALUNION
+
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/CodeGen/LiveInterval.h"
+
+namespace llvm {
+
+class TargetRegisterInfo;
+
+#ifndef NDEBUG
+// forward declaration
+template <unsigned Element> class SparseBitVector;
+typedef SparseBitVector<128> LiveVirtRegBitSet;
+#endif
+
+/// Compare a live virtual register segment to a LiveIntervalUnion segment.
+inline bool
+overlap(const LiveRange &VRSeg,
+ const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) {
+ return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end;
+}
+
+/// Union of live intervals that are strong candidates for coalescing into a
+/// single register (either physical or virtual depending on the context). We
+/// expect the constituent live intervals to be disjoint, although we may
+/// eventually make exceptions to handle value-based interference.
+class LiveIntervalUnion {
+ // A set of live virtual register segments that supports fast insertion,
+ // intersection, and removal.
+ // Mapping SlotIndex intervals to virtual register numbers.
+ typedef IntervalMap<SlotIndex, LiveInterval*> LiveSegments;
+
+public:
+ // SegmentIter can advance to the next segment ordered by starting position
+ // which may belong to a different live virtual register. We also must be able
+ // to reach the current segment's containing virtual register.
+ typedef LiveSegments::iterator SegmentIter;
+
+ // LiveIntervalUnions share an external allocator.
+ typedef LiveSegments::Allocator Allocator;
+
+ class Query;
+
+private:
+ unsigned Tag; // unique tag for current contents.
+ LiveSegments Segments; // union of virtual reg segments
+
+public:
+ explicit LiveIntervalUnion(Allocator &a) : Tag(0), Segments(a) {}
+
+ // Iterate over all segments in the union of live virtual registers ordered
+ // by their starting position.
+ SegmentIter begin() { return Segments.begin(); }
+ SegmentIter end() { return Segments.end(); }
+ SegmentIter find(SlotIndex x) { return Segments.find(x); }
+ bool empty() const { return Segments.empty(); }
+ SlotIndex startIndex() const { return Segments.start(); }
+
+ // Provide public access to the underlying map to allow overlap iteration.
+ typedef LiveSegments Map;
+ const Map &getMap() { return Segments; }
+
+ /// getTag - Return an opaque tag representing the current state of the union.
+ unsigned getTag() const { return Tag; }
+
+ /// changedSince - Return true if the union change since getTag returned tag.
+ bool changedSince(unsigned tag) const { return tag != Tag; }
+
+ // Add a live virtual register to this union and merge its segments.
+ void unify(LiveInterval &VirtReg);
+
+ // Remove a live virtual register's segments from this union.
+ void extract(LiveInterval &VirtReg);
+
+ // Remove all inserted virtual registers.
+ void clear() { Segments.clear(); ++Tag; }
+
+ // Print union, using TRI to translate register names
+ void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const;
+
+#ifndef NDEBUG
+ // Verify the live intervals in this union and add them to the visited set.
+ void verify(LiveVirtRegBitSet& VisitedVRegs);
+#endif
+
+ /// Query interferences between a single live virtual register and a live
+ /// interval union.
+ class Query {
+ LiveIntervalUnion *LiveUnion;
+ LiveInterval *VirtReg;
+ LiveInterval::iterator VirtRegI; // current position in VirtReg
+ SegmentIter LiveUnionI; // current position in LiveUnion
+ SmallVector<LiveInterval*,4> InterferingVRegs;
+ bool CheckedFirstInterference;
+ bool SeenAllInterferences;
+ bool SeenUnspillableVReg;
+ unsigned Tag, UserTag;
+
+ public:
+ Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {}
+
+ Query(LiveInterval *VReg, LiveIntervalUnion *LIU):
+ LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false),
+ SeenAllInterferences(false), SeenUnspillableVReg(false)
+ {}
+
+ void clear() {
+ LiveUnion = NULL;
+ VirtReg = NULL;
+ InterferingVRegs.clear();
+ CheckedFirstInterference = false;
+ SeenAllInterferences = false;
+ SeenUnspillableVReg = false;
+ Tag = 0;
+ UserTag = 0;
+ }
+
+ void init(unsigned UTag, LiveInterval *VReg, LiveIntervalUnion *LIU) {
+ assert(VReg && LIU && "Invalid arguments");
+ if (UserTag == UTag && VirtReg == VReg &&
+ LiveUnion == LIU && !LIU->changedSince(Tag)) {
+ // Retain cached results, e.g. firstInterference.
+ return;
+ }
+ clear();
+ LiveUnion = LIU;
+ VirtReg = VReg;
+ Tag = LIU->getTag();
+ UserTag = UTag;
+ }
+
+ LiveInterval &virtReg() const {
+ assert(VirtReg && "uninitialized");
+ return *VirtReg;
+ }
+
+ // Does this live virtual register interfere with the union?
+ bool checkInterference() { return collectInterferingVRegs(1); }
+
+ // Count the virtual registers in this union that interfere with this
+ // query's live virtual register, up to maxInterferingRegs.
+ unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX);
+
+ // Was this virtual register visited during collectInterferingVRegs?
+ bool isSeenInterference(LiveInterval *VReg) const;
+
+ // Did collectInterferingVRegs collect all interferences?
+ bool seenAllInterferences() const { return SeenAllInterferences; }
+
+ // Did collectInterferingVRegs encounter an unspillable vreg?
+ bool seenUnspillableVReg() const { return SeenUnspillableVReg; }
+
+ // Vector generated by collectInterferingVRegs.
+ const SmallVectorImpl<LiveInterval*> &interferingVRegs() const {
+ return InterferingVRegs;
+ }
+
+ private:
+ Query(const Query&) LLVM_DELETED_FUNCTION;
+ void operator=(const Query&) LLVM_DELETED_FUNCTION;
+ };
+
+ // Array of LiveIntervalUnions.
+ class Array {
+ unsigned Size;
+ LiveIntervalUnion *LIUs;
+ public:
+ Array() : Size(0), LIUs(0) {}
+ ~Array() { clear(); }
+
+ // Initialize the array to have Size entries.
+ // Reuse an existing allocation if the size matches.
+ void init(LiveIntervalUnion::Allocator&, unsigned Size);
+
+ unsigned size() const { return Size; }
+
+ void clear();
+
+ LiveIntervalUnion& operator[](unsigned idx) {
+ assert(idx < Size && "idx out of bounds");
+ return LIUs[idx];
+ }
+ };
+};
+
+} // end namespace llvm
+
+#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION)
diff --git a/include/llvm/CodeGen/LiveRegMatrix.h b/include/llvm/CodeGen/LiveRegMatrix.h
new file mode 100644
index 0000000..7a3e9e8
--- /dev/null
+++ b/include/llvm/CodeGen/LiveRegMatrix.h
@@ -0,0 +1,148 @@
+//===-- LiveRegMatrix.h - Track register interference ---------*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The LiveRegMatrix analysis pass keeps track of virtual register interference
+// along two dimensions: Slot indexes and register units. The matrix is used by
+// register allocators to ensure that no interfering virtual registers get
+// assigned to overlapping physical registers.
+//
+// Register units are defined in MCRegisterInfo.h, they represent the smallest
+// unit of interference when dealing with overlapping physical registers. The
+// LiveRegMatrix is represented as a LiveIntervalUnion per register unit. When
+// a virtual register is assigned to a physical register, the live range for
+// the virtual register is inserted into the LiveIntervalUnion for each regunit
+// in the physreg.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEREGMATRIX_H
+#define LLVM_CODEGEN_LIVEREGMATRIX_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/CodeGen/LiveIntervalUnion.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+class LiveInterval;
+class LiveIntervalAnalysis;
+class MachineRegisterInfo;
+class TargetRegisterInfo;
+class VirtRegMap;
+
+class LiveRegMatrix : public MachineFunctionPass {
+ const TargetRegisterInfo *TRI;
+ MachineRegisterInfo *MRI;
+ LiveIntervals *LIS;
+ VirtRegMap *VRM;
+
+ // UserTag changes whenever virtual registers have been modified.
+ unsigned UserTag;
+
+ // The matrix is represented as a LiveIntervalUnion per register unit.
+ LiveIntervalUnion::Allocator LIUAlloc;
+ LiveIntervalUnion::Array Matrix;
+
+ // Cached queries per register unit.
+ OwningArrayPtr<LiveIntervalUnion::Query> Queries;
+
+ // Cached register mask interference info.
+ unsigned RegMaskTag;
+ unsigned RegMaskVirtReg;
+ BitVector RegMaskUsable;
+
+ // MachineFunctionPass boilerplate.
+ virtual void getAnalysisUsage(AnalysisUsage&) const;
+ virtual bool runOnMachineFunction(MachineFunction&);
+ virtual void releaseMemory();
+public:
+ static char ID;
+ LiveRegMatrix();
+
+ //===--------------------------------------------------------------------===//
+ // High-level interface.
+ //===--------------------------------------------------------------------===//
+ //
+ // Check for interference before assigning virtual registers to physical
+ // registers.
+ //
+
+ /// Invalidate cached interference queries after modifying virtual register
+ /// live ranges. Interference checks may return stale information unless
+ /// caches are invalidated.
+ void invalidateVirtRegs() { ++UserTag; }
+
+ enum InterferenceKind {
+ /// No interference, go ahead and assign.
+ IK_Free = 0,
+
+ /// Virtual register interference. There are interfering virtual registers
+ /// assigned to PhysReg or its aliases. This interference could be resolved
+ /// by unassigning those other virtual registers.
+ IK_VirtReg,
+
+ /// Register unit interference. A fixed live range is in the way, typically
+ /// argument registers for a call. This can't be resolved by unassigning
+ /// other virtual registers.
+ IK_RegUnit,
+
+ /// RegMask interference. The live range is crossing an instruction with a
+ /// regmask operand that doesn't preserve PhysReg. This typically means
+ /// VirtReg is live across a call, and PhysReg isn't call-preserved.
+ IK_RegMask
+ };
+
+ /// Check for interference before assigning VirtReg to PhysReg.
+ /// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg).
+ /// When there is more than one kind of interference, the InterferenceKind
+ /// with the highest enum value is returned.
+ InterferenceKind checkInterference(LiveInterval &VirtReg, unsigned PhysReg);
+
+ /// Assign VirtReg to PhysReg.
+ /// This will mark VirtReg's live range as occupied in the LiveRegMatrix and
+ /// update VirtRegMap. The live range is expected to be available in PhysReg.
+ void assign(LiveInterval &VirtReg, unsigned PhysReg);
+
+ /// Unassign VirtReg from its PhysReg.
+ /// Assuming that VirtReg was previously assigned to a PhysReg, this undoes
+ /// the assignment and updates VirtRegMap accordingly.
+ void unassign(LiveInterval &VirtReg);
+
+ //===--------------------------------------------------------------------===//
+ // Low-level interface.
+ //===--------------------------------------------------------------------===//
+ //
+ // Provide access to the underlying LiveIntervalUnions.
+ //
+
+ /// Check for regmask interference only.
+ /// Return true if VirtReg crosses a regmask operand that clobbers PhysReg.
+ /// If PhysReg is null, check if VirtReg crosses any regmask operands.
+ bool checkRegMaskInterference(LiveInterval &VirtReg, unsigned PhysReg = 0);
+
+ /// Check for regunit interference only.
+ /// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's
+ /// register units.
+ bool checkRegUnitInterference(LiveInterval &VirtReg, unsigned PhysReg);
+
+ /// Query a line of the assigned virtual register matrix directly.
+ /// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg.
+ /// This returns a reference to an internal Query data structure that is only
+ /// valid until the next query() call.
+ LiveIntervalUnion::Query &query(LiveInterval &VirtReg, unsigned RegUnit);
+
+ /// Directly access the live interval unions per regunit.
+ /// This returns an array indexed by the regunit number.
+ LiveIntervalUnion *getLiveUnions() { return &Matrix[0]; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_LIVEREGMATRIX_H
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
index 86c4d7c..a3b1855 100644
--- a/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -16,10 +16,10 @@
#ifndef LLVM_CODEGEN_LIVESTACK_ANALYSIS_H
#define LLVM_CODEGEN_LIVESTACK_ANALYSIS_H
-#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LiveInterval.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include <map>
namespace llvm {
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
index d4bb409..3c5ed92 100644
--- a/include/llvm/CodeGen/LiveVariables.h
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -29,16 +29,16 @@
#ifndef LLVM_CODEGEN_LIVEVARIABLES_H
#define LLVM_CODEGEN_LIVEVARIABLES_H
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseBitVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/TargetRegisterInfo.h"
namespace llvm {
@@ -126,12 +126,6 @@ private:
/// building live intervals.
SparseBitVector<> PHIJoins;
- /// ReservedRegisters - This vector keeps track of which registers
- /// are reserved register which are not allocatable by the target machine.
- /// We can not track liveness for values that are in this set.
- ///
- BitVector ReservedRegisters;
-
private: // Intermediate data structures
MachineFunction *MF;
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 77ea4d0..492a3ff 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H
#define LLVM_CODEGEN_MACHINEBASICBLOCK_H
-#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Support/DataTypes.h"
#include <functional>
@@ -146,11 +146,11 @@ public:
bundle_iterator(IterTy mii) : MII(mii) {}
bundle_iterator(Ty &mi) : MII(mi) {
- assert(!mi.isInsideBundle() &&
+ assert(!mi.isBundledWithPred() &&
"It's not legal to initialize bundle_iterator with a bundled MI");
}
bundle_iterator(Ty *mi) : MII(mi) {
- assert((!mi || !mi->isInsideBundle()) &&
+ assert((!mi || !mi->isBundledWithPred()) &&
"It's not legal to initialize bundle_iterator with a bundled MI");
}
// Template allows conversion from const to nonconst.
@@ -174,13 +174,13 @@ public:
// Increment and decrement operators...
bundle_iterator &operator--() { // predecrement - Back up
do --MII;
- while (MII->isInsideBundle());
+ while (MII->isBundledWithPred());
return *this;
}
bundle_iterator &operator++() { // preincrement - Advance
- IterTy E = MII->getParent()->instr_end();
- do ++MII;
- while (MII != E && MII->isInsideBundle());
+ while (MII->isBundledWithSucc())
+ ++MII;
+ ++MII;
return *this;
}
bundle_iterator operator--(int) { // postdecrement operators...
@@ -441,80 +441,107 @@ public:
void pop_back() { Insts.pop_back(); }
void push_back(MachineInstr *MI) { Insts.push_back(MI); }
- template<typename IT>
- void insert(instr_iterator I, IT S, IT E) {
- Insts.insert(I, S, E);
- }
- instr_iterator insert(instr_iterator I, MachineInstr *M) {
- return Insts.insert(I, M);
- }
- instr_iterator insertAfter(instr_iterator I, MachineInstr *M) {
- return Insts.insertAfter(I, M);
- }
+ /// Insert MI into the instruction list before I, possibly inside a bundle.
+ ///
+ /// If the insertion point is inside a bundle, MI will be added to the bundle,
+ /// otherwise MI will not be added to any bundle. That means this function
+ /// alone can't be used to prepend or append instructions to bundles. See
+ /// MIBundleBuilder::insert() for a more reliable way of doing that.
+ instr_iterator insert(instr_iterator I, MachineInstr *M);
+ /// Insert a range of instructions into the instruction list before I.
template<typename IT>
void insert(iterator I, IT S, IT E) {
Insts.insert(I.getInstrIterator(), S, E);
}
- iterator insert(iterator I, MachineInstr *M) {
- return Insts.insert(I.getInstrIterator(), M);
+
+ /// Insert MI into the instruction list before I.
+ iterator insert(iterator I, MachineInstr *MI) {
+ assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
+ "Cannot insert instruction with bundle flags");
+ return Insts.insert(I.getInstrIterator(), MI);
}
- iterator insertAfter(iterator I, MachineInstr *M) {
- return Insts.insertAfter(I.getInstrIterator(), M);
+
+ /// Insert MI into the instruction list after I.
+ iterator insertAfter(iterator I, MachineInstr *MI) {
+ assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
+ "Cannot insert instruction with bundle flags");
+ return Insts.insertAfter(I.getInstrIterator(), MI);
}
- /// erase - Remove the specified element or range from the instruction list.
- /// These functions delete any instructions removed.
+ /// Remove an instruction from the instruction list and delete it.
///
- instr_iterator erase(instr_iterator I) {
- return Insts.erase(I);
- }
- instr_iterator erase(instr_iterator I, instr_iterator E) {
- return Insts.erase(I, E);
- }
+ /// If the instruction is part of a bundle, the other instructions in the
+ /// bundle will still be bundled after removing the single instruction.
+ instr_iterator erase(instr_iterator I);
+
+ /// Remove an instruction from the instruction list and delete it.
+ ///
+ /// If the instruction is part of a bundle, the other instructions in the
+ /// bundle will still be bundled after removing the single instruction.
instr_iterator erase_instr(MachineInstr *I) {
- instr_iterator MII(I);
- return erase(MII);
+ return erase(instr_iterator(I));
}
- iterator erase(iterator I);
+ /// Remove a range of instructions from the instruction list and delete them.
iterator erase(iterator I, iterator E) {
return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
}
+
+ /// Remove an instruction or bundle from the instruction list and delete it.
+ ///
+ /// If I points to a bundle of instructions, they are all erased.
+ iterator erase(iterator I) {
+ return erase(I, llvm::next(I));
+ }
+
+ /// Remove an instruction from the instruction list and delete it.
+ ///
+ /// If I is the head of a bundle of instructions, the whole bundle will be
+ /// erased.
iterator erase(MachineInstr *I) {
- iterator MII(I);
- return erase(MII);
+ return erase(iterator(I));
+ }
+
+ /// Remove the unbundled instruction from the instruction list without
+ /// deleting it.
+ ///
+ /// This function can not be used to remove bundled instructions, use
+ /// remove_instr to remove individual instructions from a bundle.
+ MachineInstr *remove(MachineInstr *I) {
+ assert(!I->isBundled() && "Cannot remove bundled instructions");
+ return Insts.remove(I);
}
- /// remove - Remove the instruction from the instruction list. This function
- /// does not delete the instruction. WARNING: Note, if the specified
- /// instruction is a bundle this function will remove all the bundled
- /// instructions as well. It is up to the caller to keep a list of the
- /// bundled instructions and re-insert them if desired. This function is
- /// *not recommended* for manipulating instructions with bundles. Use
- /// splice instead.
- MachineInstr *remove(MachineInstr *I);
+ /// Remove the possibly bundled instruction from the instruction list
+ /// without deleting it.
+ ///
+ /// If the instruction is part of a bundle, the other instructions in the
+ /// bundle will still be bundled after removing the single instruction.
+ MachineInstr *remove_instr(MachineInstr *I);
+
void clear() {
Insts.clear();
}
- /// splice - Take an instruction from MBB 'Other' at the position From,
- /// and insert it into this MBB right before 'where'.
- void splice(instr_iterator where, MachineBasicBlock *Other,
- instr_iterator From) {
- Insts.splice(where, Other->Insts, From);
+ /// Take an instruction from MBB 'Other' at the position From, and insert it
+ /// into this MBB right before 'Where'.
+ ///
+ /// If From points to a bundle of instructions, the whole bundle is moved.
+ void splice(iterator Where, MachineBasicBlock *Other, iterator From) {
+ // The range splice() doesn't allow noop moves, but this one does.
+ if (Where != From)
+ splice(Where, Other, From, llvm::next(From));
}
- void splice(iterator where, MachineBasicBlock *Other, iterator From);
- /// splice - Take a block of instructions from MBB 'Other' in the range [From,
- /// To), and insert them into this MBB right before 'where'.
- void splice(instr_iterator where, MachineBasicBlock *Other, instr_iterator From,
- instr_iterator To) {
- Insts.splice(where, Other->Insts, From, To);
- }
- void splice(iterator where, MachineBasicBlock *Other, iterator From,
- iterator To) {
- Insts.splice(where.getInstrIterator(), Other->Insts,
+ /// Take a block of instructions from MBB 'Other' in the range [From, To),
+ /// and insert them into this MBB right before 'Where'.
+ ///
+ /// The instruction at 'Where' must not be included in the range of
+ /// instructions to move.
+ void splice(iterator Where, MachineBasicBlock *Other,
+ iterator From, iterator To) {
+ Insts.splice(Where.getInstrIterator(), Other->Insts,
From.getInstrIterator(), To.getInstrIterator());
}
@@ -547,6 +574,28 @@ public:
return findDebugLoc(MBBI.getInstrIterator());
}
+ /// Possible outcome of a register liveness query to computeRegisterLiveness()
+ enum LivenessQueryResult {
+ LQR_Live, ///< Register is known to be live.
+ LQR_OverlappingLive, ///< Register itself is not live, but some overlapping
+ ///< register is.
+ LQR_Dead, ///< Register is known to be dead.
+ LQR_Unknown ///< Register liveness not decidable from local
+ ///< neighborhood.
+ };
+
+ /// computeRegisterLiveness - Return whether (physical) register \c Reg
+ /// has been <def>ined and not <kill>ed as of just before \c MI.
+ ///
+ /// Search is localised to a neighborhood of
+ /// \c Neighborhood instructions before (searching for defs or kills) and
+ /// Neighborhood instructions after (searching just for defs) MI.
+ ///
+ /// \c Reg must be a physical register.
+ LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
+ unsigned Reg, MachineInstr *MI,
+ unsigned Neighborhood=10);
+
// Debugging methods.
void dump() const;
void print(raw_ostream &OS, SlotIndexes* = 0) const;
diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
index 12189ce..1c9bdd9 100644
--- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
+++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
@@ -15,8 +15,8 @@
#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
-#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
#include <climits>
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
index 86e8f27..9e41e6e 100644
--- a/include/llvm/CodeGen/MachineCodeEmitter.h
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -19,7 +19,6 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
-
#include <string>
namespace llvm {
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
index d6d65a2..8ed215d 100644
--- a/include/llvm/CodeGen/MachineConstantPool.h
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -25,7 +25,7 @@ namespace llvm {
class Constant;
class FoldingSetNodeID;
-class TargetData;
+class DataLayout;
class TargetMachine;
class Type;
class MachineConstantPool;
@@ -132,14 +132,14 @@ public:
/// address of the function constant pool values.
/// @brief The machine constant pool.
class MachineConstantPool {
- const TargetData *TD; ///< The machine's TargetData.
+ const DataLayout *TD; ///< The machine's DataLayout.
unsigned PoolAlignment; ///< The alignment for the pool.
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
/// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
public:
/// @brief The only constructor.
- explicit MachineConstantPool(const TargetData *td)
+ explicit MachineConstantPool(const DataLayout *td)
: TD(td), PoolAlignment(1) {}
~MachineConstantPool();
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index 82a4ac8..40b2542 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -15,11 +15,11 @@
#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
#define LLVM_CODEGEN_MACHINEDOMINATORS_H
+#include "llvm/Analysis/DominatorInternals.h"
+#include "llvm/Analysis/Dominators.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/Analysis/DominatorInternals.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 3c07ceb..93d7728 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -21,7 +21,7 @@
namespace llvm {
class raw_ostream;
-class TargetData;
+class DataLayout;
class TargetRegisterClass;
class Type;
class MachineFunction;
@@ -29,6 +29,7 @@ class MachineBasicBlock;
class TargetFrameLowering;
class BitVector;
class Value;
+class AllocaInst;
/// The CalleeSavedInfo class tracks the information need to locate where a
/// callee saved register is in the current frame.
@@ -106,14 +107,14 @@ class MachineFrameInfo {
/// Alloca - If this stack object is originated from an Alloca instruction
/// this value saves the original IR allocation. Can be NULL.
- const Value *Alloca;
+ const AllocaInst *Alloca;
// PreAllocated - If true, the object was mapped into the local frame
// block and doesn't need additional handling for allocation beyond that.
bool PreAllocated;
StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
- bool isSS, bool NSP, const Value *Val)
+ bool isSS, bool NSP, const AllocaInst *Val)
: SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
isSpillSlot(isSS), MayNeedSP(NSP), Alloca(Val), PreAllocated(false) {}
};
@@ -220,8 +221,11 @@ class MachineFrameInfo {
/// just allocate them normally.
bool UseLocalStackAllocationBlock;
+ /// Whether the "realign-stack" option is on.
+ bool RealignOption;
public:
- explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) {
+ explicit MachineFrameInfo(const TargetFrameLowering &tfi, bool RealignOpt)
+ : TFI(tfi), RealignOption(RealignOpt) {
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
HasVarSizedObjects = false;
FrameAddressTaken = false;
@@ -369,7 +373,7 @@ public:
/// getObjectAllocation - Return the underlying Alloca of the specified
/// stack object if it exists. Returns 0 if none exists.
- const Value* getObjectAllocation(int ObjectIdx) const {
+ const AllocaInst* getObjectAllocation(int ObjectIdx) const {
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
return Objects[ObjectIdx+NumFixedObjects].Alloca;
@@ -431,9 +435,7 @@ public:
/// ensureMaxAlignment - Make sure the function is at least Align bytes
/// aligned.
- void ensureMaxAlignment(unsigned Align) {
- if (MaxAlignment < Align) MaxAlignment = Align;
- }
+ void ensureMaxAlignment(unsigned Align);
/// AdjustsStack - Return true if this function adjusts the stack -- e.g.,
/// when calling another function. This is only valid during and after
@@ -495,26 +497,13 @@ public:
/// a nonnegative identifier to represent it.
///
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
- bool MayNeedSP = false, const Value *Alloca = 0) {
- assert(Size != 0 && "Cannot allocate zero size stack objects!");
- Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP,
- Alloca));
- int Index = (int)Objects.size() - NumFixedObjects - 1;
- assert(Index >= 0 && "Bad frame index!");
- ensureMaxAlignment(Alignment);
- return Index;
- }
+ bool MayNeedSP = false, const AllocaInst *Alloca = 0);
/// CreateSpillStackObject - Create a new statically sized stack object that
/// represents a spill slot, returning a nonnegative identifier to represent
/// it.
///
- int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
- CreateStackObject(Size, Alignment, true, false);
- int Index = (int)Objects.size() - NumFixedObjects - 1;
- ensureMaxAlignment(Alignment);
- return Index;
- }
+ int CreateSpillStackObject(uint64_t Size, unsigned Alignment);
/// RemoveStackObject - Remove or mark dead a statically sized stack object.
///
@@ -528,12 +517,7 @@ public:
/// variable sized object is created, whether or not the index returned is
/// actually used.
///
- int CreateVariableSizedObject(unsigned Alignment) {
- HasVarSizedObjects = true;
- Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0));
- ensureMaxAlignment(Alignment);
- return (int)Objects.size()-NumFixedObjects-1;
- }
+ int CreateVariableSizedObject(unsigned Alignment);
/// getCalleeSavedInfo - Returns a reference to call saved info vector for the
/// current function.
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 0eb9d0e..cd704c1 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -18,10 +18,11 @@
#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
#define LLVM_CODEGEN_MACHINEFUNCTION_H
-#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/ADT/ilist.h"
-#include "llvm/Support/DebugLoc.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ArrayRecycler.h"
+#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/Recycler.h"
namespace llvm {
@@ -105,6 +106,9 @@ class MachineFunction {
// Allocation management for instructions in function.
Recycler<MachineInstr> InstructionRecycler;
+ // Allocation management for operand arrays on instructions.
+ ArrayRecycler<MachineOperand> OperandRecycler;
+
// Allocation management for basic blocks in function.
Recycler<MachineBasicBlock> BasicBlockRecycler;
@@ -127,8 +131,8 @@ class MachineFunction {
/// about the control flow of such functions.
bool ExposesReturnsTwice;
- MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT
- void operator=(const MachineFunction&); // DO NOT IMPLEMENT
+ MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
+ void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
public:
MachineFunction(const Function *Fn, const TargetMachine &TM,
unsigned FunctionNum, MachineModuleInfo &MMI,
@@ -394,6 +398,21 @@ public:
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
int64_t Offset, uint64_t Size);
+ typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
+
+ /// Allocate an array of MachineOperands. This is only intended for use by
+ /// internal MachineInstr functions.
+ MachineOperand *allocateOperandArray(OperandCapacity Cap) {
+ return OperandRecycler.allocate(Cap, Allocator);
+ }
+
+ /// Dellocate an array of MachineOperands and recycle the memory. This is
+ /// only intended for use by internal MachineInstr functions.
+ /// Cap must be the same capacity that was used to allocate the array.
+ void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) {
+ OperandRecycler.deallocate(Cap, Array);
+ }
+
/// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
/// pointers. This array is owned by the MachineFunction.
MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 4e1533a..89521e8 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -16,17 +16,18 @@
#ifndef LLVM_CODEGEN_MACHINEINSTR_H
#define LLVM_CODEGEN_MACHINEINSTR_H
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/MC/MCInstrDesc.h"
-#include "llvm/Target/TargetOpcodes.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/InlineAsm.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/DebugLoc.h"
+#include "llvm/Target/TargetOpcodes.h"
#include <vector>
namespace llvm {
@@ -42,6 +43,10 @@ class MachineMemOperand;
//===----------------------------------------------------------------------===//
/// MachineInstr - Representation of each machine instruction.
///
+/// This class isn't a POD type, but it must have a trivial destructor. When a
+/// MachineFunction is deleted, all the contained MachineInstrs are deallocated
+/// without having their destructor called.
+///
class MachineInstr : public ilist_node<MachineInstr> {
public:
typedef MachineMemOperand **mmo_iterator;
@@ -58,11 +63,18 @@ public:
NoFlags = 0,
FrameSetup = 1 << 0, // Instruction is used as a part of
// function frame setup code.
- InsideBundle = 1 << 1 // Instruction is inside a bundle (not
- // the first MI in a bundle)
+ BundledPred = 1 << 1, // Instruction has bundled predecessors.
+ BundledSucc = 1 << 2 // Instruction has bundled successors.
};
private:
const MCInstrDesc *MCID; // Instruction descriptor.
+ MachineBasicBlock *Parent; // Pointer to the owning basic block.
+
+ // Operands are allocated by an ArrayRecycler.
+ MachineOperand *Operands; // Pointer to the first operand.
+ unsigned NumOperands; // Number of operands on instruction.
+ typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
+ OperandCapacity CapOperands; // Capacity of the Operands array.
uint8_t Flags; // Various bits of additional
// information about machine
@@ -75,15 +87,15 @@ private:
// anything other than to convey comment
// information to AsmPrinter.
- uint16_t NumMemRefs; // information on memory references
+ uint8_t NumMemRefs; // Information on memory references.
mmo_iterator MemRefs;
- std::vector<MachineOperand> Operands; // the operands
- MachineBasicBlock *Parent; // Pointer to the owning basic block.
DebugLoc debugLoc; // Source line information.
- MachineInstr(const MachineInstr&); // DO NOT IMPLEMENT
- void operator=(const MachineInstr&); // DO NOT IMPLEMENT
+ MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION;
+ void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION;
+ // Use MachineFunction::DeleteMachineInstr() instead.
+ ~MachineInstr() LLVM_DELETED_FUNCTION;
// Intrusive list support
friend struct ilist_traits<MachineInstr>;
@@ -94,37 +106,11 @@ private:
/// MachineInstr in the given MachineFunction.
MachineInstr(MachineFunction &, const MachineInstr &);
- /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
- /// MCID NULL and no operands.
- MachineInstr();
-
- // The next two constructors have DebugLoc and non-DebugLoc versions;
- // over time, the non-DebugLoc versions should be phased out and eventually
- // removed.
-
- /// MachineInstr ctor - This constructor creates a MachineInstr and adds the
- /// implicit operands. It reserves space for the number of operands specified
- /// by the MCInstrDesc. The version with a DebugLoc should be preferred.
- explicit MachineInstr(const MCInstrDesc &MCID, bool NoImp = false);
-
- /// MachineInstr ctor - Work exactly the same as the ctor above, except that
- /// the MachineInstr is created and added to the end of the specified basic
- /// block. The version with a DebugLoc should be preferred.
- MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &MCID);
-
/// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by
/// MCInstrDesc. An explicit DebugLoc is supplied.
- explicit MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl,
- bool NoImp = false);
-
- /// MachineInstr 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 MCInstrDesc &MCID);
-
- ~MachineInstr();
+ MachineInstr(MachineFunction&, const MCInstrDesc &MCID,
+ const DebugLoc dl, bool NoImp = false);
// MachineInstrs are pool-allocated and owned by MachineFunction.
friend class MachineFunction;
@@ -175,7 +161,9 @@ public:
}
void setFlags(unsigned flags) {
- Flags = flags;
+ // Filter out the automatically maintained flags.
+ unsigned Mask = BundledPred | BundledSucc;
+ Flags = (Flags & Mask) | (flags & ~Mask);
}
/// clearFlag - Clear a MI flag.
@@ -220,21 +208,36 @@ public:
/// The first instruction has the special opcode "BUNDLE". It's not "inside"
/// a bundle, but the next three MIs are.
bool isInsideBundle() const {
- return getFlag(InsideBundle);
- }
-
- /// setIsInsideBundle - Set InsideBundle bit.
- ///
- void setIsInsideBundle(bool Val = true) {
- if (Val)
- setFlag(InsideBundle);
- else
- clearFlag(InsideBundle);
+ return getFlag(BundledPred);
}
/// isBundled - Return true if this instruction part of a bundle. This is true
/// if either itself or its following instruction is marked "InsideBundle".
- bool isBundled() const;
+ bool isBundled() const {
+ return isBundledWithPred() || isBundledWithSucc();
+ }
+
+ /// Return true if this instruction is part of a bundle, and it is not the
+ /// first instruction in the bundle.
+ bool isBundledWithPred() const { return getFlag(BundledPred); }
+
+ /// Return true if this instruction is part of a bundle, and it is not the
+ /// last instruction in the bundle.
+ bool isBundledWithSucc() const { return getFlag(BundledSucc); }
+
+ /// Bundle this instruction with its predecessor. This can be an unbundled
+ /// instruction, or it can be the first instruction in a bundle.
+ void bundleWithPred();
+
+ /// Bundle this instruction with its successor. This can be an unbundled
+ /// instruction, or it can be the last instruction in a bundle.
+ void bundleWithSucc();
+
+ /// Break bundle above this instruction.
+ void unbundleFromPred();
+
+ /// Break bundle below this instruction.
+ void unbundleFromSucc();
/// getDebugLoc - Returns the debug location id of this MachineInstr.
///
@@ -259,7 +262,7 @@ public:
/// Access to explicit operands of the instruction.
///
- unsigned getNumOperands() const { return (unsigned)Operands.size(); }
+ unsigned getNumOperands() const { return NumOperands; }
const MachineOperand& getOperand(unsigned i) const {
assert(i < getNumOperands() && "getOperand() out of range!");
@@ -275,14 +278,14 @@ public:
unsigned getNumExplicitOperands() const;
/// iterator/begin/end - Iterate over all operands of a machine instruction.
- typedef std::vector<MachineOperand>::iterator mop_iterator;
- typedef std::vector<MachineOperand>::const_iterator const_mop_iterator;
+ typedef MachineOperand *mop_iterator;
+ typedef const MachineOperand *const_mop_iterator;
- mop_iterator operands_begin() { return Operands.begin(); }
- mop_iterator operands_end() { return Operands.end(); }
+ mop_iterator operands_begin() { return Operands; }
+ mop_iterator operands_end() { return Operands + NumOperands; }
- const_mop_iterator operands_begin() const { return Operands.begin(); }
- const_mop_iterator operands_end() const { return Operands.end(); }
+ const_mop_iterator operands_begin() const { return Operands; }
+ const_mop_iterator operands_end() const { return Operands + NumOperands; }
/// Access to memory operands of the instruction
mmo_iterator memoperands_begin() const { return MemRefs; }
@@ -460,6 +463,11 @@ public:
/// Instructions with this flag set are not necessarily simple load
/// instructions, they may load a value and modify it, for example.
bool mayLoad(QueryType Type = AnyInBundle) const {
+ if (isInlineAsm()) {
+ unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
+ if (ExtraInfo & InlineAsm::Extra_MayLoad)
+ return true;
+ }
return hasProperty(MCID::MayLoad, Type);
}
@@ -469,6 +477,11 @@ public:
/// instructions, they may store a modified value based on their operands, or
/// may not actually modify anything, for example.
bool mayStore(QueryType Type = AnyInBundle) const {
+ if (isInlineAsm()) {
+ unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
+ if (ExtraInfo & InlineAsm::Extra_MayStore)
+ return true;
+ }
return hasProperty(MCID::MayStore, Type);
}
@@ -583,14 +596,33 @@ public:
bool isIdenticalTo(const MachineInstr *Other,
MICheckType Check = CheckDefs) const;
- /// removeFromParent - This method unlinks 'this' from the containing basic
- /// block, and returns it, but does not delete it.
+ /// Unlink 'this' from the containing basic block, and return it without
+ /// deleting it.
+ ///
+ /// This function can not be used on bundled instructions, use
+ /// removeFromBundle() to remove individual instructions from a bundle.
MachineInstr *removeFromParent();
- /// eraseFromParent - This method unlinks 'this' from the containing basic
- /// block and deletes it.
+ /// Unlink this instruction from its basic block and return it without
+ /// deleting it.
+ ///
+ /// If the instruction is part of a bundle, the other instructions in the
+ /// bundle remain bundled.
+ MachineInstr *removeFromBundle();
+
+ /// Unlink 'this' from the containing basic block and delete it.
+ ///
+ /// If this instruction is the header of a bundle, the whole bundle is erased.
+ /// This function can not be used for instructions inside a bundle, use
+ /// eraseFromBundle() to erase individual bundled instructions.
void eraseFromParent();
+ /// Unlink 'this' form its basic block and delete it.
+ ///
+ /// If the instruction is part of a bundle, the other instructions in the
+ /// bundle remain bundled.
+ void eraseFromBundle();
+
/// isLabel - Returns true if the MachineInstr represents a label.
///
bool isLabel() const {
@@ -826,13 +858,6 @@ public:
///
void clearKillInfo();
- /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
- ///
- void copyKillDeadInfo(const MachineInstr *MI);
-
- /// copyPredicates - Copies predicate operand(s) from MI.
- void copyPredicates(const MachineInstr *MI);
-
/// substituteRegister - Replace all occurrences of FromReg with ToReg:SubIdx,
/// properly composing subreg indices where necessary.
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx,
@@ -914,7 +939,7 @@ public:
/// copyImplicitOps - Copy implicit register operands from specified
/// instruction to this instruction.
- void copyImplicitOps(const MachineInstr *MI);
+ void copyImplicitOps(MachineFunction &MF, const MachineInstr *MI);
//
// Debugging support
@@ -925,10 +950,23 @@ public:
//===--------------------------------------------------------------------===//
// Accessors used to build up machine instructions.
- /// addOperand - Add the specified operand to the instruction. If it is an
- /// implicit operand, it is added to the end of the operand list. If it is
- /// an explicit operand it is added at the end of the explicit operand list
+ /// Add the specified operand to the instruction. If it is an implicit
+ /// operand, it is added to the end of the operand list. If it is an
+ /// explicit operand it is added at the end of the explicit operand list
/// (before the first implicit operand).
+ ///
+ /// MF must be the machine function that was used to allocate this
+ /// instruction.
+ ///
+ /// MachineInstrBuilder provides a more convenient interface for creating
+ /// instructions and adding operands.
+ void addOperand(MachineFunction &MF, const MachineOperand &Op);
+
+ /// Add an operand without providing an MF reference. This only works for
+ /// instructions that are inserted in a basic block.
+ ///
+ /// MachineInstrBuilder and the two-argument addOperand(MF, MO) should be
+ /// preferred.
void addOperand(const MachineOperand &Op);
/// setDesc - Replace the instruction descriptor (thus opcode) of
@@ -955,7 +993,8 @@ public:
/// list. This does not transfer ownership.
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) {
MemRefs = NewMemRefs;
- NumMemRefs = NewMemRefsEnd - NewMemRefs;
+ NumMemRefs = uint8_t(NewMemRefsEnd - NewMemRefs);
+ assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs");
}
private:
@@ -975,7 +1014,7 @@ private:
/// addImplicitDefUseOperands - Add all implicit def and use operands to
/// this instruction.
- void addImplicitDefUseOperands();
+ void addImplicitDefUseOperands(MachineFunction &MF);
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
/// this instruction from their respective use lists. This requires that the
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index 654361f..a2d3d63 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -42,10 +42,14 @@ namespace RegState {
}
class MachineInstrBuilder {
+ MachineFunction *MF;
MachineInstr *MI;
public:
- MachineInstrBuilder() : MI(0) {}
- explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
+ MachineInstrBuilder() : MF(0), MI(0) {}
+
+ /// Create a MachineInstrBuilder for manipulating an existing instruction.
+ /// F must be the machine function that was used to allocate I.
+ MachineInstrBuilder(MachineFunction &F, MachineInstr *I) : MF(&F), MI(I) {}
/// Allow automatic conversion to the machine instruction we are working on.
///
@@ -60,86 +64,94 @@ public:
unsigned SubReg = 0) const {
assert((flags & 0x1) == 0 &&
"Passing in 'true' to addReg is forbidden! Use enums instead.");
- MI->addOperand(MachineOperand::CreateReg(RegNo,
- flags & RegState::Define,
- flags & RegState::Implicit,
- flags & RegState::Kill,
- flags & RegState::Dead,
- flags & RegState::Undef,
- flags & RegState::EarlyClobber,
- SubReg,
- flags & RegState::Debug,
- flags & RegState::InternalRead));
+ MI->addOperand(*MF, MachineOperand::CreateReg(RegNo,
+ flags & RegState::Define,
+ flags & RegState::Implicit,
+ flags & RegState::Kill,
+ flags & RegState::Dead,
+ flags & RegState::Undef,
+ flags & RegState::EarlyClobber,
+ SubReg,
+ flags & RegState::Debug,
+ flags & RegState::InternalRead));
return *this;
}
/// addImm - Add a new immediate operand.
///
const MachineInstrBuilder &addImm(int64_t Val) const {
- MI->addOperand(MachineOperand::CreateImm(Val));
+ MI->addOperand(*MF, MachineOperand::CreateImm(Val));
return *this;
}
const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
- MI->addOperand(MachineOperand::CreateCImm(Val));
+ MI->addOperand(*MF, MachineOperand::CreateCImm(Val));
return *this;
}
const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
- MI->addOperand(MachineOperand::CreateFPImm(Val));
+ MI->addOperand(*MF, MachineOperand::CreateFPImm(Val));
return *this;
}
const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateMBB(MBB, TargetFlags));
return *this;
}
const MachineInstrBuilder &addFrameIndex(int Idx) const {
- MI->addOperand(MachineOperand::CreateFI(Idx));
+ MI->addOperand(*MF, MachineOperand::CreateFI(Idx));
return *this;
}
const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
int Offset = 0,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateTargetIndex(Idx, Offset,
+ TargetFlags));
return *this;
}
const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateJTI(Idx, TargetFlags));
return *this;
}
const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV,
int64_t Offset = 0,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateGA(GV, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addExternalSymbol(const char *FnName,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateES(FnName, TargetFlags));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addBlockAddress(const BlockAddress *BA,
+ int64_t Offset = 0,
+ unsigned char TargetFlags = 0) const {
+ MI->addOperand(*MF, MachineOperand::CreateBA(BA, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
- MI->addOperand(MachineOperand::CreateRegMask(Mask));
+ MI->addOperand(*MF, MachineOperand::CreateRegMask(Mask));
return *this;
}
const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
- MI->addMemOperand(*MI->getParent()->getParent(), MMO);
+ MI->addMemOperand(*MF, MMO);
return *this;
}
@@ -151,17 +163,17 @@ public:
const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
- MI->addOperand(MO);
+ MI->addOperand(*MF, MO);
return *this;
}
const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
- MI->addOperand(MachineOperand::CreateMetadata(MD));
+ MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
return *this;
}
const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
- MI->addOperand(MachineOperand::CreateMCSymbol(Sym));
+ MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym));
return *this;
}
@@ -176,17 +188,32 @@ public:
}
// Add a displacement from an existing MachineOperand with an added offset.
- const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
- int64_t off) const {
+ const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off,
+ unsigned char TargetFlags = 0) const {
switch (Disp.getType()) {
default:
llvm_unreachable("Unhandled operand type in addDisp()");
case MachineOperand::MO_Immediate:
return addImm(Disp.getImm() + off);
- case MachineOperand::MO_GlobalAddress:
- return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off);
+ case MachineOperand::MO_GlobalAddress: {
+ // If caller specifies new TargetFlags then use it, otherwise the
+ // default behavior is to copy the target flags from the existing
+ // MachineOperand. This means if the caller wants to clear the
+ // target flags it needs to do so explicitly.
+ if (TargetFlags)
+ return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
+ TargetFlags);
+ return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
+ Disp.getTargetFlags());
+ }
}
}
+
+ /// Copy all the implicit operands from OtherMI onto this one.
+ const MachineInstrBuilder &copyImplicitOps(const MachineInstr *OtherMI) {
+ MI->copyImplicitOps(*MF, OtherMI);
+ return *this;
+ }
};
/// BuildMI - Builder interface. Specify how to create the initial instruction
@@ -195,7 +222,7 @@ public:
inline MachineInstrBuilder BuildMI(MachineFunction &MF,
DebugLoc DL,
const MCInstrDesc &MCID) {
- return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL));
+ return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL));
}
/// BuildMI - This version of the builder sets up the first operand as a
@@ -205,7 +232,7 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF,
DebugLoc DL,
const MCInstrDesc &MCID,
unsigned DestReg) {
- return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL))
+ return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL))
.addReg(DestReg, RegState::Define);
}
@@ -218,9 +245,10 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
DebugLoc DL,
const MCInstrDesc &MCID,
unsigned DestReg) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ MachineFunction &MF = *BB.getParent();
+ MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
BB.insert(I, MI);
- return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
+ return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define);
}
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
@@ -228,9 +256,10 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
DebugLoc DL,
const MCInstrDesc &MCID,
unsigned DestReg) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ MachineFunction &MF = *BB.getParent();
+ MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
BB.insert(I, MI);
- return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
+ return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define);
}
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
@@ -255,18 +284,20 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
DebugLoc DL,
const MCInstrDesc &MCID) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ MachineFunction &MF = *BB.getParent();
+ MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
BB.insert(I, MI);
- return MachineInstrBuilder(MI);
+ return MachineInstrBuilder(MF, MI);
}
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::instr_iterator I,
DebugLoc DL,
const MCInstrDesc &MCID) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ MachineFunction &MF = *BB.getParent();
+ MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
BB.insert(I, MI);
- return MachineInstrBuilder(MI);
+ return MachineInstrBuilder(MF, MI);
}
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
@@ -321,6 +352,98 @@ inline unsigned getUndefRegState(bool B) {
inline unsigned getInternalReadRegState(bool B) {
return B ? RegState::InternalRead : 0;
}
+inline unsigned getDebugRegState(bool B) {
+ return B ? RegState::Debug : 0;
+}
+
+
+/// Helper class for constructing bundles of MachineInstrs.
+///
+/// MIBundleBuilder can create a bundle from scratch by inserting new
+/// MachineInstrs one at a time, or it can create a bundle from a sequence of
+/// existing MachineInstrs in a basic block.
+class MIBundleBuilder {
+ MachineBasicBlock &MBB;
+ MachineBasicBlock::instr_iterator Begin;
+ MachineBasicBlock::instr_iterator End;
+
+public:
+ /// Create an MIBundleBuilder that inserts instructions into a new bundle in
+ /// BB above the bundle or instruction at Pos.
+ MIBundleBuilder(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator Pos)
+ : MBB(BB), Begin(Pos.getInstrIterator()), End(Begin) {}
+
+ /// Create a bundle from the sequence of instructions between B and E.
+ MIBundleBuilder(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator B,
+ MachineBasicBlock::iterator E)
+ : MBB(BB), Begin(B.getInstrIterator()), End(E.getInstrIterator()) {
+ assert(B != E && "No instructions to bundle");
+ ++B;
+ while (B != E) {
+ MachineInstr *MI = B;
+ ++B;
+ MI->bundleWithPred();
+ }
+ }
+
+ /// Create an MIBundleBuilder representing an existing instruction or bundle
+ /// that has MI as its head.
+ explicit MIBundleBuilder(MachineInstr *MI)
+ : MBB(*MI->getParent()), Begin(MI) {
+ MachineBasicBlock::iterator I = MI;
+ ++I;
+ End = I.getInstrIterator();
+ }
+
+ /// Return a reference to the basic block containing this bundle.
+ MachineBasicBlock &getMBB() const { return MBB; }
+
+ /// Return true if no instructions have been inserted in this bundle yet.
+ /// Empty bundles aren't representable in a MachineBasicBlock.
+ bool empty() const { return Begin == End; }
+
+ /// Return an iterator to the first bundled instruction.
+ MachineBasicBlock::instr_iterator begin() const { return Begin; }
+
+ /// Return an iterator beyond the last bundled instruction.
+ MachineBasicBlock::instr_iterator end() const { return End; }
+
+ /// Insert MI into this bundle before I which must point to an instruction in
+ /// the bundle, or end().
+ MIBundleBuilder &insert(MachineBasicBlock::instr_iterator I,
+ MachineInstr *MI) {
+ MBB.insert(I, MI);
+ if (I == Begin) {
+ if (!empty())
+ MI->bundleWithSucc();
+ Begin = MI;
+ return *this;
+ }
+ if (I == End) {
+ MI->bundleWithPred();
+ return *this;
+ }
+ // MI was inserted in the middle of the bundle, so its neighbors' flags are
+ // already fine. Update MI's bundle flags manually.
+ MI->setFlag(MachineInstr::BundledPred);
+ MI->setFlag(MachineInstr::BundledSucc);
+ return *this;
+ }
+
+ /// Insert MI into MBB by prepending it to the instructions in the bundle.
+ /// MI will become the first instruction in the bundle.
+ MIBundleBuilder &prepend(MachineInstr *MI) {
+ return insert(begin(), MI);
+ }
+
+ /// Insert MI into MBB by appending it to the instructions in the bundle.
+ /// MI will become the last instruction in the bundle.
+ MIBundleBuilder &append(MachineInstr *MI) {
+ return insert(end(), MI);
+ }
+};
} // End llvm namespace
diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h
index dc5f9a6..3c60ad1 100644
--- a/include/llvm/CodeGen/MachineInstrBundle.h
+++ b/include/llvm/CodeGen/MachineInstrBundle.h
@@ -130,9 +130,9 @@ public:
return OpI - InstrI->operands_begin();
}
- /// RegInfo - Information about a virtual register used by a set of operands.
+ /// VirtRegInfo - Information about a virtual register used by a set of operands.
///
- struct RegInfo {
+ struct VirtRegInfo {
/// Reads - One of the operands read the virtual register. This does not
/// include <undef> or <internal> use operands, see MO::readsReg().
bool Reads;
@@ -146,6 +146,29 @@ public:
bool Tied;
};
+ /// PhysRegInfo - Information about a physical register used by a set of
+ /// operands.
+ struct PhysRegInfo {
+ /// Clobbers - Reg or an overlapping register is defined, or a regmask
+ /// clobbers Reg.
+ bool Clobbers;
+
+ /// Defines - Reg or a super-register is defined.
+ bool Defines;
+
+ /// Reads - Read or a super-register is read.
+ bool Reads;
+
+ /// ReadsOverlap - Reg or an overlapping register is read.
+ bool ReadsOverlap;
+
+ /// DefinesDead - All defs of a Reg or a super-register are dead.
+ bool DefinesDead;
+
+ /// There is a kill of Reg or a super-register.
+ bool Kills;
+ };
+
/// analyzeVirtReg - Analyze how the current instruction or bundle uses a
/// virtual register. This function should not be called after operator++(),
/// it expects a fresh iterator.
@@ -154,8 +177,16 @@ public:
/// @param Ops When set, this vector will receive an (MI, OpNum) entry for
/// each operand referring to Reg.
/// @returns A filled-in RegInfo struct.
- RegInfo analyzeVirtReg(unsigned Reg,
+ VirtRegInfo analyzeVirtReg(unsigned Reg,
SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops = 0);
+
+ /// analyzePhysReg - Analyze how the current instruction or bundle uses a
+ /// physical register. This function should not be called after operator++(),
+ /// it expects a fresh iterator.
+ ///
+ /// @param Reg The physical register to analyze.
+ /// @returns A filled-in PhysRegInfo struct.
+ PhysRegInfo analyzePhysReg(unsigned Reg, const TargetRegisterInfo *TRI);
};
/// MIOperands - Iterate over operands of a single instruction.
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
index f7c4e86..adcd1d0 100644
--- a/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -20,13 +20,13 @@
#ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
#define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
-#include <vector>
#include <cassert>
+#include <vector>
namespace llvm {
class MachineBasicBlock;
-class TargetData;
+class DataLayout;
class raw_ostream;
/// MachineJumpTableEntry - One jump table in the jump table info.
@@ -84,9 +84,9 @@ public:
JTEntryKind getEntryKind() const { return EntryKind; }
/// getEntrySize - Return the size of each entry in the jump table.
- unsigned getEntrySize(const TargetData &TD) const;
+ unsigned getEntrySize(const DataLayout &TD) const;
/// getEntryAlignment - Return the alignment of each entry in the jump table.
- unsigned getEntryAlignment(const TargetData &TD) const;
+ unsigned getEntryAlignment(const DataLayout &TD) const;
/// createJumpTableIndex - Create a new jump table.
///
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index 3e204be..99da6b2 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -30,8 +30,8 @@
#ifndef LLVM_CODEGEN_MACHINE_LOOP_INFO_H
#define LLVM_CODEGEN_MACHINE_LOOP_INFO_H
-#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
namespace llvm {
@@ -73,8 +73,8 @@ class MachineLoopInfo : public MachineFunctionPass {
LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
friend class LoopBase<MachineBasicBlock, MachineLoop>;
- void operator=(const MachineLoopInfo &); // do not implement
- MachineLoopInfo(const MachineLoopInfo &); // do not implement
+ void operator=(const MachineLoopInfo &) LLVM_DELETED_FUNCTION;
+ MachineLoopInfo(const MachineLoopInfo &) LLVM_DELETED_FUNCTION;
public:
static char ID; // Pass identification, replacement for typeid
diff --git a/include/llvm/CodeGen/MachineLoopRanges.h b/include/llvm/CodeGen/MachineLoopRanges.h
deleted file mode 100644
index 6a30e8b..0000000
--- a/include/llvm/CodeGen/MachineLoopRanges.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===- MachineLoopRanges.h - Ranges of machine loops -----------*- c++ -*--===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the interface to the MachineLoopRanges analysis.
-//
-// Provide on-demand information about the ranges of machine instructions
-// covered by a loop.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_MACHINELOOPRANGES_H
-#define LLVM_CODEGEN_MACHINELOOPRANGES_H
-
-#include "llvm/ADT/IntervalMap.h"
-#include "llvm/CodeGen/SlotIndexes.h"
-
-namespace llvm {
-
-class MachineLoop;
-class MachineLoopInfo;
-class raw_ostream;
-
-/// MachineLoopRange - Range information for a single loop.
-class MachineLoopRange {
- friend class MachineLoopRanges;
-
-public:
- typedef IntervalMap<SlotIndex, unsigned, 4> Map;
- typedef Map::Allocator Allocator;
-
-private:
- /// The mapped loop.
- const MachineLoop *const Loop;
-
- /// Map intervals to a bit mask.
- /// Bit 0 = inside loop block.
- Map Intervals;
-
- /// Loop area as measured by SlotIndex::distance.
- unsigned Area;
-
- /// Create a MachineLoopRange, only accessible to MachineLoopRanges.
- MachineLoopRange(const MachineLoop*, Allocator&, SlotIndexes&);
-
-public:
- /// getLoop - Return the mapped machine loop.
- const MachineLoop *getLoop() const { return Loop; }
-
- /// overlaps - Return true if this loop overlaps the given range of machine
- /// inteructions.
- bool overlaps(SlotIndex Start, SlotIndex Stop);
-
- /// getNumber - Return the loop number. This is the same as the number of the
- /// header block.
- unsigned getNumber() const;
-
- /// getArea - Return the loop area. This number is approximately proportional
- /// to the number of instructions in the loop.
- unsigned getArea() const { return Area; }
-
- /// getMap - Allow public read-only access for IntervalMapOverlaps.
- const Map &getMap() { return Intervals; }
-
- /// print - Print loop ranges on OS.
- void print(raw_ostream&) const;
-
- /// byNumber - Comparator for array_pod_sort that sorts a list of
- /// MachineLoopRange pointers by number.
- static int byNumber(const void*, const void*);
-
- /// byAreaDesc - Comparator for array_pod_sort that sorts a list of
- /// MachineLoopRange pointers by descending area, then by number.
- static int byAreaDesc(const void*, const void*);
-};
-
-raw_ostream &operator<<(raw_ostream&, const MachineLoopRange&);
-
-/// MachineLoopRanges - Analysis pass that provides on-demand per-loop range
-/// information.
-class MachineLoopRanges : public MachineFunctionPass {
- typedef DenseMap<const MachineLoop*, MachineLoopRange*> CacheMap;
- typedef MachineLoopRange::Allocator MapAllocator;
-
- MapAllocator Allocator;
- SlotIndexes *Indexes;
- CacheMap Cache;
-
-public:
- static char ID; // Pass identification, replacement for typeid
-
- MachineLoopRanges() : MachineFunctionPass(ID), Indexes(0) {}
- ~MachineLoopRanges() { releaseMemory(); }
-
- /// getLoopRange - Return the range of loop.
- MachineLoopRange *getLoopRange(const MachineLoop *Loop);
-
-private:
- virtual bool runOnMachineFunction(MachineFunction&);
- virtual void releaseMemory();
- virtual void getAnalysisUsage(AnalysisUsage&) const;
-};
-
-
-} // end namespace llvm
-
-#endif // LLVM_CODEGEN_MACHINELOOPRANGES_H
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 6b88d4a..6194d05 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -31,19 +31,19 @@
#ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H
#define LLVM_CODEGEN_MACHINEMODULEINFO_H
-#include "llvm/Pass.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/Metadata.h"
-#include "llvm/MC/MachineLocation.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/DebugLoc.h"
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/DebugLoc.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/ValueHandle.h"
namespace llvm {
@@ -180,8 +180,9 @@ public:
const MCObjectFileInfo *MOFI);
~MachineModuleInfo();
- bool doInitialization();
- bool doFinalization();
+ // Initialization and Finalization
+ virtual bool doInitialization(Module &);
+ virtual bool doFinalization(Module &);
/// EndFunction - Discard function meta information.
///
@@ -372,7 +373,7 @@ public:
/// getCurrentCallSite - Get the call site currently being processed, if any.
/// return zero if none.
- unsigned getCurrentCallSite(void) { return CurCallSite; }
+ unsigned getCurrentCallSite() { return CurCallSite; }
/// getTypeInfos - Return a reference to the C++ typeinfo for the current
/// function.
diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 9401ffd..7afc7eb 100644
--- a/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -38,7 +38,7 @@ namespace llvm {
/// this GV is external.
DenseMap<MCSymbol*, StubValueTy> HiddenGVStubs;
- virtual void Anchor(); // Out of line virtual method.
+ virtual void anchor(); // Out of line virtual method.
public:
MachineModuleInfoMachO(const MachineModuleInfo &) {}
@@ -76,7 +76,7 @@ namespace llvm {
/// mode.
DenseMap<MCSymbol*, StubValueTy> GVStubs;
- virtual void Anchor(); // Out of line virtual method.
+ virtual void anchor(); // Out of line virtual method.
public:
MachineModuleInfoELF(const MachineModuleInfo &) {}
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 0b9d67f..414770b 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -35,6 +35,11 @@ class MCSymbol;
/// MachineOperand class - Representation of each machine instruction operand.
///
+/// This class isn't a POD type because it has a private constructor, but its
+/// destructor must be trivial. Functions like MachineInstr::addOperand(),
+/// MachineRegisterInfo::moveOperands(), and MF::DeleteMachineInstr() depend on
+/// not having to call the MachineOperand destructor.
+///
class MachineOperand {
public:
enum MachineOperandType {
@@ -60,15 +65,11 @@ private:
/// union.
unsigned char OpKind; // MachineOperandType
- // This union is discriminated by OpKind.
- union {
- /// SubReg - Subregister number, only valid for MO_Register. A value of 0
- /// indicates the MO_Register has no subReg.
- unsigned char SubReg;
-
- /// TargetFlags - This is a set of target-specific operand flags.
- unsigned char TargetFlags;
- };
+ /// Subregister number for MO_Register. A value of 0 indicates the
+ /// MO_Register has no subReg.
+ ///
+ /// For all other kinds of operands, this field holds target-specific flags.
+ unsigned SubReg_TargetFlags : 12;
/// TiedTo - Non-zero when this register operand is tied to another register
/// operand. The encoding of this field is described in the block comment
@@ -176,24 +177,25 @@ private:
} OffsetedInfo;
} Contents;
- explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {
- TargetFlags = 0;
- }
+ explicit MachineOperand(MachineOperandType K)
+ : OpKind(K), SubReg_TargetFlags(0), ParentMI(0) {}
public:
/// getType - Returns the MachineOperandType for this operand.
///
MachineOperandType getType() const { return (MachineOperandType)OpKind; }
- unsigned char getTargetFlags() const {
- return isReg() ? 0 : TargetFlags;
+ unsigned getTargetFlags() const {
+ return isReg() ? 0 : SubReg_TargetFlags;
}
- void setTargetFlags(unsigned char F) {
+ void setTargetFlags(unsigned F) {
assert(!isReg() && "Register operands can't have target flags");
- TargetFlags = F;
+ SubReg_TargetFlags = F;
+ assert(SubReg_TargetFlags == F && "Target flags out of range");
}
- void addTargetFlag(unsigned char F) {
+ void addTargetFlag(unsigned F) {
assert(!isReg() && "Register operands can't have target flags");
- TargetFlags |= F;
+ SubReg_TargetFlags |= F;
+ assert((SubReg_TargetFlags & F) && "Target flags out of range");
}
@@ -261,7 +263,7 @@ public:
unsigned getSubReg() const {
assert(isReg() && "Wrong MachineOperand accessor");
- return (unsigned)SubReg;
+ return SubReg_TargetFlags;
}
bool isUse() const {
@@ -336,7 +338,8 @@ public:
void setSubReg(unsigned subReg) {
assert(isReg() && "Wrong MachineOperand accessor");
- SubReg = (unsigned char)subReg;
+ SubReg_TargetFlags = subReg;
+ assert(SubReg_TargetFlags == subReg && "SubReg out of range");
}
/// substVirtReg - Substitute the current register with the virtual
@@ -574,7 +577,7 @@ public:
Op.SmallContents.RegNo = Reg;
Op.Contents.Reg.Prev = 0;
Op.Contents.Reg.Next = 0;
- Op.SubReg = SubReg;
+ Op.setSubReg(SubReg);
return Op;
}
static MachineOperand CreateMBB(MachineBasicBlock *MBB,
@@ -628,11 +631,11 @@ public:
Op.setTargetFlags(TargetFlags);
return Op;
}
- static MachineOperand CreateBA(const BlockAddress *BA,
+ static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_BlockAddress);
Op.Contents.OffsetedInfo.Val.BA = BA;
- Op.setOffset(0); // Offset is always 0.
+ Op.setOffset(Offset);
Op.setTargetFlags(TargetFlags);
return Op;
}
@@ -687,6 +690,9 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {
return OS;
}
+ // See friend declaration above. This additional declaration is required in
+ // order to compile LLVM with IBM xlC compiler.
+ hash_code hash_value(const MachineOperand &MO);
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/MachinePostDominators.h b/include/llvm/CodeGen/MachinePostDominators.h
new file mode 100644
index 0000000..00a60cb
--- /dev/null
+++ b/include/llvm/CodeGen/MachinePostDominators.h
@@ -0,0 +1,87 @@
+//=- llvm/CodeGen/MachineDominators.h ----------------------------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes interfaces to post dominance information for
+// target-specific code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H
+#define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H
+
+#include "llvm/Analysis/DominatorInternals.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+///
+/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used
+/// to compute the a post-dominator tree.
+///
+struct MachinePostDominatorTree : public MachineFunctionPass {
+private:
+ DominatorTreeBase<MachineBasicBlock> *DT;
+
+public:
+ static char ID;
+
+ MachinePostDominatorTree();
+
+ ~MachinePostDominatorTree();
+
+ FunctionPass *createMachinePostDominatorTreePass();
+
+ const std::vector<MachineBasicBlock *> &getRoots() const {
+ return DT->getRoots();
+ }
+
+ MachineDomTreeNode *getRootNode() const {
+ return DT->getRootNode();
+ }
+
+ MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ bool dominates(MachineDomTreeNode *A, MachineDomTreeNode *B) const {
+ return DT->dominates(A, B);
+ }
+
+ bool dominates(MachineBasicBlock *A, MachineBasicBlock *B) const {
+ return DT->dominates(A, B);
+ }
+
+ bool
+ properlyDominates(const MachineDomTreeNode *A, MachineDomTreeNode *B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ bool
+ properlyDominates(MachineBasicBlock *A, MachineBasicBlock *B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
+ MachineBasicBlock *B) {
+ return DT->findNearestCommonDominator(A, B);
+ }
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void print(llvm::raw_ostream &OS, const Module *M = 0) const;
+};
+} //end of namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 42a8aa4..36427e9 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H
#define LLVM_CODEGEN_MACHINEREGISTERINFO_H
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include <vector>
namespace llvm {
@@ -77,16 +77,20 @@ class MachineRegisterInfo {
return MO->Contents.Reg.Next;
}
- /// UsedPhysRegs - This is a bit vector that is computed and set by the
+ /// UsedRegUnits - This is a bit vector that is computed and set by the
/// register allocator, and must be kept up to date by passes that run after
/// register allocation (though most don't modify this). This is used
/// so that the code generator knows which callee save registers to save and
/// for other target specific uses.
- /// This vector only has bits set for registers explicitly used, not their
- /// aliases.
- BitVector UsedPhysRegs;
-
- /// UsedPhysRegMask - Additional used physregs, but including aliases.
+ /// This vector has bits set for register units that are modified in the
+ /// current function. It doesn't include registers clobbered by function
+ /// calls with register mask operands.
+ BitVector UsedRegUnits;
+
+ /// UsedPhysRegMask - Additional used physregs including aliases.
+ /// This bit vector represents all the registers clobbered by function calls.
+ /// It can model things that UsedRegUnits can't, such as function calls that
+ /// clobber ymm7 but preserve the low half in xmm7.
BitVector UsedPhysRegMask;
/// ReservedRegs - This is a bit vector of reserved registers. The target
@@ -95,9 +99,6 @@ class MachineRegisterInfo {
/// started.
BitVector ReservedRegs;
- /// AllocatableRegs - From TRI->getAllocatableSet.
- mutable BitVector AllocatableRegs;
-
/// LiveIns/LiveOuts - Keep track of the physical registers that are
/// livein/liveout of the function. Live in values are typically arguments in
/// registers, live out values are typically return values in registers.
@@ -106,8 +107,8 @@ class MachineRegisterInfo {
std::vector<std::pair<unsigned, unsigned> > LiveIns;
std::vector<unsigned> LiveOuts;
- MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT
- void operator=(const MachineRegisterInfo&); // DO NOT IMPLEMENT
+ MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
+ void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
public:
explicit MachineRegisterInfo(const TargetRegisterInfo &TRI);
~MachineRegisterInfo();
@@ -155,6 +156,9 @@ public:
// Strictly for use by MachineInstr.cpp.
void removeRegOperandFromUseList(MachineOperand *MO);
+ // Strictly for use by MachineInstr.cpp.
+ void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumOps);
+
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
/// and uses of a register within the MachineFunction that corresponds to this
/// MachineRegisterInfo object.
@@ -360,29 +364,27 @@ public:
//===--------------------------------------------------------------------===//
/// isPhysRegUsed - Return true if the specified register is used in this
- /// function. This only works after register allocation.
+ /// function. Also check for clobbered aliases and registers clobbered by
+ /// function calls with register mask operands.
+ ///
+ /// This only works after register allocation. It is primarily used by
+ /// PrologEpilogInserter to determine which callee-saved registers need
+ /// spilling.
bool isPhysRegUsed(unsigned Reg) const {
- return UsedPhysRegs.test(Reg) || UsedPhysRegMask.test(Reg);
- }
-
- /// isPhysRegOrOverlapUsed - Return true if Reg or any overlapping register
- /// is used in this function.
- bool isPhysRegOrOverlapUsed(unsigned Reg) const {
if (UsedPhysRegMask.test(Reg))
return true;
- for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
- if (UsedPhysRegs.test(*AI))
+ for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ if (UsedRegUnits.test(*Units))
return true;
return false;
}
/// setPhysRegUsed - Mark the specified register used in this function.
/// This should only be called during and after register allocation.
- void setPhysRegUsed(unsigned Reg) { UsedPhysRegs.set(Reg); }
-
- /// addPhysRegsUsed - Mark the specified registers used in this function.
- /// This should only be called during and after register allocation.
- void addPhysRegsUsed(const BitVector &Regs) { UsedPhysRegs |= Regs; }
+ void setPhysRegUsed(unsigned Reg) {
+ for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ UsedRegUnits.set(*Units);
+ }
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
/// This corresponds to the bit mask attached to register mask operands.
@@ -393,8 +395,9 @@ public:
/// setPhysRegUnused - Mark the specified register unused in this function.
/// This should only be called during and after register allocation.
void setPhysRegUnused(unsigned Reg) {
- UsedPhysRegs.reset(Reg);
UsedPhysRegMask.reset(Reg);
+ for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ UsedRegUnits.reset(*Units);
}
@@ -427,6 +430,34 @@ public:
return !reservedRegsFrozen() || ReservedRegs.test(PhysReg);
}
+ /// getReservedRegs - Returns a reference to the frozen set of reserved
+ /// registers. This method should always be preferred to calling
+ /// TRI::getReservedRegs() when possible.
+ const BitVector &getReservedRegs() const {
+ assert(reservedRegsFrozen() &&
+ "Reserved registers haven't been frozen yet. "
+ "Use TRI::getReservedRegs().");
+ return ReservedRegs;
+ }
+
+ /// isReserved - Returns true when PhysReg is a reserved register.
+ ///
+ /// Reserved registers may belong to an allocatable register class, but the
+ /// target has explicitly requested that they are not used.
+ ///
+ bool isReserved(unsigned PhysReg) const {
+ return getReservedRegs().test(PhysReg);
+ }
+
+ /// isAllocatable - Returns true when PhysReg belongs to an allocatable
+ /// register class and it hasn't been reserved.
+ ///
+ /// Allocatable registers may show up in the allocation order of some virtual
+ /// register, so a register allocator needs to track its liveness and
+ /// availability.
+ bool isAllocatable(unsigned PhysReg) const {
+ return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg);
+ }
//===--------------------------------------------------------------------===//
// LiveIn/LiveOut Management
diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h
index cbb45a7..edf93d1 100644
--- a/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -14,6 +14,8 @@
#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H
#define LLVM_CODEGEN_MACHINESSAUPDATER_H
+#include "llvm/Support/Compiler.h"
+
namespace llvm {
class MachineBasicBlock;
class MachineFunction;
@@ -106,8 +108,8 @@ private:
void ReplaceRegWith(unsigned OldReg, unsigned NewReg);
unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
- void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT
- MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT
+ void operator=(const MachineSSAUpdater&) LLVM_DELETED_FUNCTION;
+ MachineSSAUpdater(const MachineSSAUpdater&) LLVM_DELETED_FUNCTION;
};
} // End llvm namespace
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index 8da2045..88f347e 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -28,9 +28,15 @@
#define MACHINESCHEDULER_H
#include "llvm/CodeGen/MachinePassRegistry.h"
+#include "llvm/CodeGen/RegisterPressure.h"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
+#include "llvm/Target/TargetInstrInfo.h"
namespace llvm {
+extern cl::opt<bool> ForceTopDown;
+extern cl::opt<bool> ForceBottomUp;
+
class AliasAnalysis;
class LiveIntervals;
class MachineDominatorTree;
@@ -93,6 +99,260 @@ public:
}
};
+class ScheduleDAGMI;
+
+/// MachineSchedStrategy - Interface to the scheduling algorithm used by
+/// ScheduleDAGMI.
+class MachineSchedStrategy {
+public:
+ virtual ~MachineSchedStrategy() {}
+
+ /// Initialize the strategy after building the DAG for a new region.
+ virtual void initialize(ScheduleDAGMI *DAG) = 0;
+
+ /// Notify this strategy that all roots have been released (including those
+ /// that depend on EntrySU or ExitSU).
+ virtual void registerRoots() {}
+
+ /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
+ /// schedule the node at the top of the unscheduled region. Otherwise it will
+ /// be scheduled at the bottom.
+ virtual SUnit *pickNode(bool &IsTopNode) = 0;
+
+ /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
+ /// instruction and updated scheduled/remaining flags in the DAG nodes.
+ virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
+
+ /// When all predecessor dependencies have been resolved, free this node for
+ /// top-down scheduling.
+ virtual void releaseTopNode(SUnit *SU) = 0;
+ /// When all successor dependencies have been resolved, free this node for
+ /// bottom-up scheduling.
+ virtual void releaseBottomNode(SUnit *SU) = 0;
+};
+
+/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
+/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
+/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
+///
+/// This is a convenience class that may be used by implementations of
+/// MachineSchedStrategy.
+class ReadyQueue {
+ unsigned ID;
+ std::string Name;
+ std::vector<SUnit*> Queue;
+
+public:
+ ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
+
+ unsigned getID() const { return ID; }
+
+ StringRef getName() const { return Name; }
+
+ // SU is in this queue if it's NodeQueueID is a superset of this ID.
+ bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
+
+ bool empty() const { return Queue.empty(); }
+
+ void clear() { Queue.clear(); }
+
+ unsigned size() const { return Queue.size(); }
+
+ typedef std::vector<SUnit*>::iterator iterator;
+
+ iterator begin() { return Queue.begin(); }
+
+ iterator end() { return Queue.end(); }
+
+ iterator find(SUnit *SU) {
+ return std::find(Queue.begin(), Queue.end(), SU);
+ }
+
+ void push(SUnit *SU) {
+ Queue.push_back(SU);
+ SU->NodeQueueId |= ID;
+ }
+
+ iterator remove(iterator I) {
+ (*I)->NodeQueueId &= ~ID;
+ *I = Queue.back();
+ unsigned idx = I - Queue.begin();
+ Queue.pop_back();
+ return Queue.begin() + idx;
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ void dump();
+#endif
+};
+
+/// Mutate the DAG as a postpass after normal DAG building.
+class ScheduleDAGMutation {
+public:
+ virtual ~ScheduleDAGMutation() {}
+
+ virtual void apply(ScheduleDAGMI *DAG) = 0;
+};
+
+/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules
+/// machine instructions while updating LiveIntervals and tracking regpressure.
+class ScheduleDAGMI : public ScheduleDAGInstrs {
+protected:
+ AliasAnalysis *AA;
+ RegisterClassInfo *RegClassInfo;
+ MachineSchedStrategy *SchedImpl;
+
+ /// Topo - A topological ordering for SUnits which permits fast IsReachable
+ /// and similar queries.
+ ScheduleDAGTopologicalSort Topo;
+
+ /// Ordered list of DAG postprocessing steps.
+ std::vector<ScheduleDAGMutation*> Mutations;
+
+ MachineBasicBlock::iterator LiveRegionEnd;
+
+ /// Register pressure in this region computed by buildSchedGraph.
+ IntervalPressure RegPressure;
+ RegPressureTracker RPTracker;
+
+ /// List of pressure sets that exceed the target's pressure limit before
+ /// scheduling, listed in increasing set ID order. Each pressure set is paired
+ /// with its max pressure in the currently scheduled regions.
+ std::vector<PressureElement> RegionCriticalPSets;
+
+ /// The top of the unscheduled zone.
+ MachineBasicBlock::iterator CurrentTop;
+ IntervalPressure TopPressure;
+ RegPressureTracker TopRPTracker;
+
+ /// The bottom of the unscheduled zone.
+ MachineBasicBlock::iterator CurrentBottom;
+ IntervalPressure BotPressure;
+ RegPressureTracker BotRPTracker;
+
+ /// Record the next node in a scheduled cluster.
+ const SUnit *NextClusterPred;
+ const SUnit *NextClusterSucc;
+
+#ifndef NDEBUG
+ /// The number of instructions scheduled so far. Used to cut off the
+ /// scheduler at the point determined by misched-cutoff.
+ unsigned NumInstrsScheduled;
+#endif
+
+public:
+ ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
+ ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
+ AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
+ Topo(SUnits, &ExitSU), RPTracker(RegPressure), CurrentTop(),
+ TopRPTracker(TopPressure), CurrentBottom(), BotRPTracker(BotPressure),
+ NextClusterPred(NULL), NextClusterSucc(NULL) {
+#ifndef NDEBUG
+ NumInstrsScheduled = 0;
+#endif
+ }
+
+ virtual ~ScheduleDAGMI() {
+ DeleteContainerPointers(Mutations);
+ delete SchedImpl;
+ }
+
+ /// Add a postprocessing step to the DAG builder.
+ /// Mutations are applied in the order that they are added after normal DAG
+ /// building and before MachineSchedStrategy initialization.
+ ///
+ /// ScheduleDAGMI takes ownership of the Mutation object.
+ void addMutation(ScheduleDAGMutation *Mutation) {
+ Mutations.push_back(Mutation);
+ }
+
+ /// \brief Add a DAG edge to the given SU with the given predecessor
+ /// dependence data.
+ ///
+ /// \returns true if the edge may be added without creating a cycle OR if an
+ /// equivalent edge already existed (false indicates failure).
+ bool addEdge(SUnit *SuccSU, const SDep &PredDep);
+
+ MachineBasicBlock::iterator top() const { return CurrentTop; }
+ MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
+
+ /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
+ /// region. This covers all instructions in a block, while schedule() may only
+ /// cover a subset.
+ void enterRegion(MachineBasicBlock *bb,
+ MachineBasicBlock::iterator begin,
+ MachineBasicBlock::iterator end,
+ unsigned endcount);
+
+
+ /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
+ /// reorderable instructions.
+ virtual void schedule();
+
+ /// Get current register pressure for the top scheduled instructions.
+ const IntervalPressure &getTopPressure() const { return TopPressure; }
+ const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
+
+ /// Get current register pressure for the bottom scheduled instructions.
+ const IntervalPressure &getBotPressure() const { return BotPressure; }
+ const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
+
+ /// Get register pressure for the entire scheduling region before scheduling.
+ const IntervalPressure &getRegPressure() const { return RegPressure; }
+
+ const std::vector<PressureElement> &getRegionCriticalPSets() const {
+ return RegionCriticalPSets;
+ }
+
+ const SUnit *getNextClusterPred() const { return NextClusterPred; }
+
+ const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
+
+protected:
+ // Top-Level entry points for the schedule() driver...
+
+ /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking
+ /// enabled. This sets up three trackers. RPTracker will cover the entire DAG
+ /// region, TopTracker and BottomTracker will be initialized to the top and
+ /// bottom of the DAG region without covereing any unscheduled instruction.
+ void buildDAGWithRegPressure();
+
+ /// Apply each ScheduleDAGMutation step in order. This allows different
+ /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
+ void postprocessDAG();
+
+ /// Identify DAG roots and setup scheduler queues.
+ void initQueues();
+
+ /// Move an instruction and update register pressure.
+ void scheduleMI(SUnit *SU, bool IsTopNode);
+
+ /// Update scheduler DAG and queues after scheduling an instruction.
+ void updateQueues(SUnit *SU, bool IsTopNode);
+
+ /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
+ void placeDebugValues();
+
+ /// \brief dump the scheduled Sequence.
+ void dumpSchedule() const;
+
+ // Lesser helpers...
+
+ void initRegPressure();
+
+ void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
+
+ void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
+ bool checkSchedLimit();
+
+ void releaseRoots();
+
+ void releaseSucc(SUnit *SU, SDep *SuccEdge);
+ void releaseSuccessors(SUnit *SU);
+ void releasePred(SUnit *SU, SDep *PredEdge);
+ void releasePredecessors(SUnit *SU);
+};
+
} // namespace llvm
#endif
diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h
index a5d8b0d..85bf511 100644
--- a/include/llvm/CodeGen/PBQP/Graph.h
+++ b/include/llvm/CodeGen/PBQP/Graph.h
@@ -16,7 +16,8 @@
#define LLVM_CODEGEN_PBQP_GRAPH_H
#include "Math.h"
-
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
#include <list>
#include <map>
@@ -31,16 +32,16 @@ namespace PBQP {
class NodeEntry;
class EdgeEntry;
- typedef std::list<NodeEntry> NodeList;
- typedef std::list<EdgeEntry> EdgeList;
+ typedef llvm::ilist<NodeEntry> NodeList;
+ typedef llvm::ilist<EdgeEntry> EdgeList;
public:
- typedef NodeList::iterator NodeItr;
- typedef NodeList::const_iterator ConstNodeItr;
+ typedef NodeEntry* NodeItr;
+ typedef const NodeEntry* ConstNodeItr;
- typedef EdgeList::iterator EdgeItr;
- typedef EdgeList::const_iterator ConstEdgeItr;
+ typedef EdgeEntry* EdgeItr;
+ typedef const EdgeEntry* ConstEdgeItr;
private:
@@ -52,12 +53,14 @@ namespace PBQP {
private:
- class NodeEntry {
+ class NodeEntry : public llvm::ilist_node<NodeEntry> {
+ friend struct llvm::ilist_sentinel_traits<NodeEntry>;
private:
Vector costs;
AdjEdgeList adjEdges;
unsigned degree;
void *data;
+ NodeEntry() : costs(0, 0) {}
public:
NodeEntry(const Vector &costs) : costs(costs), degree(0) {}
Vector& getCosts() { return costs; }
@@ -77,12 +80,14 @@ namespace PBQP {
void* getData() { return data; }
};
- class EdgeEntry {
+ class EdgeEntry : public llvm::ilist_node<EdgeEntry> {
+ friend struct llvm::ilist_sentinel_traits<EdgeEntry>;
private:
NodeItr node1, node2;
Matrix costs;
AdjEdgeItr node1AEItr, node2AEItr;
void *data;
+ EdgeEntry() : costs(0, 0, 0) {}
public:
EdgeEntry(NodeItr node1, NodeItr node2, const Matrix &costs)
: node1(node1), node2(node2), costs(costs) {}
diff --git a/include/llvm/CodeGen/PBQP/HeuristicSolver.h b/include/llvm/CodeGen/PBQP/HeuristicSolver.h
index 35514f9..47e15b2 100644
--- a/include/llvm/CodeGen/PBQP/HeuristicSolver.h
+++ b/include/llvm/CodeGen/PBQP/HeuristicSolver.h
@@ -18,8 +18,8 @@
#include "Graph.h"
#include "Solution.h"
-#include <vector>
#include <limits>
+#include <vector>
namespace PBQP {
diff --git a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
index a859e58..307d81e 100644
--- a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
+++ b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
@@ -18,9 +18,8 @@
#ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
#define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
-#include "../HeuristicSolver.h"
#include "../HeuristicBase.h"
-
+#include "../HeuristicSolver.h"
#include <limits>
namespace PBQP {
diff --git a/include/llvm/CodeGen/PBQP/Math.h b/include/llvm/CodeGen/PBQP/Math.h
index e7598bf..4e51913 100644
--- a/include/llvm/CodeGen/PBQP/Math.h
+++ b/include/llvm/CodeGen/PBQP/Math.h
@@ -10,8 +10,8 @@
#ifndef LLVM_CODEGEN_PBQP_MATH_H
#define LLVM_CODEGEN_PBQP_MATH_H
-#include <cassert>
#include <algorithm>
+#include <cassert>
#include <functional>
namespace PBQP {
diff --git a/include/llvm/CodeGen/PBQP/Solution.h b/include/llvm/CodeGen/PBQP/Solution.h
index 57d9b95..b9f288b 100644
--- a/include/llvm/CodeGen/PBQP/Solution.h
+++ b/include/llvm/CodeGen/PBQP/Solution.h
@@ -14,9 +14,8 @@
#ifndef LLVM_CODEGEN_PBQP_SOLUTION_H
#define LLVM_CODEGEN_PBQP_SOLUTION_H
-#include "Math.h"
#include "Graph.h"
-
+#include "Math.h"
#include <map>
namespace PBQP {
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 7bd5764..0d02700 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -141,6 +141,10 @@ public:
/// Add passes to lower exception handling for the code generator.
void addPassesToHandleExceptions();
+ /// Add pass to prepare the LLVM IR for code generation. This should be done
+ /// before exception handling preparation passes.
+ virtual void addCodeGenPrepare();
+
/// Add common passes that perform LLVM IR to IR transforms in preparation for
/// instruction selection.
virtual void addISelPrepare();
@@ -237,6 +241,11 @@ protected:
return false;
}
+ /// addGCPasses - Add late codegen passes that analyze code for garbage
+ /// collection. This should return true if GC info should be printed after
+ /// these passes.
+ virtual bool addGCPasses();
+
/// Add standard basic block placement passes.
virtual void addBlockPlacement();
@@ -271,6 +280,12 @@ protected:
/// List of target independent CodeGen pass IDs.
namespace llvm {
+ /// \brief Create a basic TargetTransformInfo analysis pass.
+ ///
+ /// This pass implements the target transform info analysis using the target
+ /// independent information available to the LLVM code generator.
+ ImmutablePass *createBasicTargetTransformInfoPass(const TargetLowering *TLI);
+
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a
/// block that cannot be reached?). As such, a code generator should either
@@ -288,9 +303,6 @@ namespace llvm {
/// MachineLoopInfo - This pass is a loop analysis pass.
extern char &MachineLoopInfoID;
- /// MachineLoopRanges - This pass is an on-demand loop coverage analysis.
- extern char &MachineLoopRangesID;
-
/// MachineDominators - This pass is a machine dominators analysis pass.
extern char &MachineDominatorsID;
diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h
index 7dab4f9..df74d088 100644
--- a/include/llvm/CodeGen/PseudoSourceValue.h
+++ b/include/llvm/CodeGen/PseudoSourceValue.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H
#define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H
-#include "llvm/Value.h"
+#include "llvm/IR/Value.h"
namespace llvm {
class MachineFrameInfo;
@@ -50,7 +50,6 @@ namespace llvm {
/// classof - Methods for support type inquiry through isa, cast, and
/// dyn_cast:
///
- static inline bool classof(const PseudoSourceValue *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == PseudoSourceValueVal ||
V->getValueID() == FixedStackPseudoSourceValueVal;
@@ -90,9 +89,6 @@ namespace llvm {
/// classof - Methods for support type inquiry through isa, cast, and
/// dyn_cast:
///
- static inline bool classof(const FixedStackPseudoSourceValue *) {
- return true;
- }
static inline bool classof(const Value *V) {
return V->getValueID() == FixedStackPseudoSourceValueVal;
}
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index bce3ec7..b617c14 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -20,7 +20,6 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/PBQP/Graph.h"
#include "llvm/CodeGen/PBQP/Solution.h"
-
#include <map>
#include <set>
@@ -29,6 +28,7 @@ namespace llvm {
class LiveIntervals;
class MachineFunction;
class MachineLoopInfo;
+ class TargetRegisterInfo;
/// This class wraps up a PBQP instance representing a register allocation
/// problem, plus the structures necessary to map back from the PBQP solution
@@ -109,8 +109,8 @@ namespace llvm {
/// class to support additional constraints for your architecture.
class PBQPBuilder {
private:
- PBQPBuilder(const PBQPBuilder&) {}
- void operator=(const PBQPBuilder&) {}
+ PBQPBuilder(const PBQPBuilder&) LLVM_DELETED_FUNCTION;
+ void operator=(const PBQPBuilder&) LLVM_DELETED_FUNCTION;
public:
typedef std::set<unsigned> RegSet;
diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h
index 400e1f4..12bd1c6 100644
--- a/include/llvm/CodeGen/RegisterClassInfo.h
+++ b/include/llvm/CodeGen/RegisterClassInfo.h
@@ -29,10 +29,10 @@ class RegisterClassInfo {
unsigned Tag;
unsigned NumRegs;
bool ProperSubClass;
- OwningArrayPtr<unsigned> Order;
+ OwningArrayPtr<MCPhysReg> Order;
RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {}
- operator ArrayRef<unsigned>() const {
+ operator ArrayRef<MCPhysReg>() const {
return makeArrayRef(Order.get(), NumRegs);
}
};
@@ -84,7 +84,7 @@ public:
/// getOrder - Returns the preferred allocation order for RC. The order
/// contains no reserved registers, and registers that alias callee saved
/// registers come last.
- ArrayRef<unsigned> getOrder(const TargetRegisterClass *RC) const {
+ ArrayRef<MCPhysReg> getOrder(const TargetRegisterClass *RC) const {
return get(RC);
}
@@ -106,25 +106,6 @@ public:
return CalleeSaved[N-1];
return 0;
}
-
- /// isReserved - Returns true when PhysReg is a reserved register.
- ///
- /// Reserved registers may belong to an allocatable register class, but the
- /// target has explicitly requested that they are not used.
- ///
- bool isReserved(unsigned PhysReg) const {
- return Reserved.test(PhysReg);
- }
-
- /// isAllocatable - Returns true when PhysReg belongs to an allocatable
- /// register class and it hasn't been reserved.
- ///
- /// Allocatable registers may show up in the allocation order of some virtual
- /// register, so a register allocator needs to track its liveness and
- /// availability.
- bool isAllocatable(unsigned PhysReg) const {
- return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg);
- }
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
index 2043155..2670180 100644
--- a/include/llvm/CodeGen/RegisterPressure.h
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -15,13 +15,14 @@
#ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
#define LLVM_CODEGEN_REGISTERPRESSURE_H
+#include "llvm/ADT/SparseSet.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/ADT/SparseSet.h"
namespace llvm {
class LiveIntervals;
+class LiveInterval;
class RegisterClassInfo;
class MachineInstr;
@@ -30,20 +31,26 @@ struct RegisterPressure {
/// Map of max reg pressure indexed by pressure set ID, not class ID.
std::vector<unsigned> MaxSetPressure;
- /// List of live in registers.
+ /// List of live in virtual registers or physical register units.
SmallVector<unsigned,8> LiveInRegs;
SmallVector<unsigned,8> LiveOutRegs;
/// Increase register pressure for each pressure set impacted by this register
/// class. Normally called by RegPressureTracker, but may be called manually
/// to account for live through (global liveness).
- void increase(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI);
+ ///
+ /// \param Reg is either a virtual register number or register unit number.
+ void increase(unsigned Reg, const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo *MRI);
/// Decrease register pressure for each pressure set impacted by this register
/// class. This is only useful to account for spilling or rematerialization.
- void decrease(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI);
+ ///
+ /// \param Reg is either a virtual register number or register unit number.
+ void decrease(unsigned Reg, const TargetRegisterInfo *TRI,
+ const MachineRegisterInfo *MRI);
- void dump(const TargetRegisterInfo *TRI);
+ void dump(const TargetRegisterInfo *TRI) const;
};
/// RegisterPressure computed within a region of instructions delimited by
@@ -116,6 +123,33 @@ struct RegPressureDelta {
RegPressureDelta() {}
};
+/// \brief A set of live virtual registers and physical register units.
+///
+/// Virtual and physical register numbers require separate sparse sets, but most
+/// of the RegisterPressureTracker handles them uniformly.
+struct LiveRegSet {
+ SparseSet<unsigned> PhysRegs;
+ SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs;
+
+ bool contains(unsigned Reg) {
+ if (TargetRegisterInfo::isVirtualRegister(Reg))
+ return VirtRegs.count(Reg);
+ return PhysRegs.count(Reg);
+ }
+
+ bool insert(unsigned Reg) {
+ if (TargetRegisterInfo::isVirtualRegister(Reg))
+ return VirtRegs.insert(Reg).second;
+ return PhysRegs.insert(Reg).second;
+ }
+
+ bool erase(unsigned Reg) {
+ if (TargetRegisterInfo::isVirtualRegister(Reg))
+ return VirtRegs.erase(Reg);
+ return PhysRegs.erase(Reg);
+ }
+};
+
/// Track the current register pressure at some position in the instruction
/// stream, and remember the high water mark within the region traversed. This
/// does not automatically consider live-through ranges. The client may
@@ -150,15 +184,15 @@ class RegPressureTracker {
bool RequireIntervals;
/// Register pressure corresponds to liveness before this instruction
- /// iterator. It may point to the end of the block rather than an instruction.
+ /// iterator. It may point to the end of the block or a DebugValue rather than
+ /// an instruction.
MachineBasicBlock::const_iterator CurrPos;
/// Pressure map indexed by pressure set ID, not class ID.
std::vector<unsigned> CurrSetPressure;
- /// List of live registers.
- SparseSet<unsigned> LivePhysRegs;
- SparseSet<unsigned, VirtReg2IndexFunctor> LiveVirtRegs;
+ /// Set of live registers.
+ LiveRegSet LiveRegs;
public:
RegPressureTracker(IntervalPressure &rp) :
@@ -171,8 +205,9 @@ public:
const LiveIntervals *lis, const MachineBasicBlock *mbb,
MachineBasicBlock::const_iterator pos);
- /// Force liveness of registers. Particularly useful to initialize the
- /// livein/out state of the tracker before the first call to advance/recede.
+ /// Force liveness of virtual registers or physical register
+ /// units. Particularly useful to initialize the livein/out state of the
+ /// tracker before the first call to advance/recede.
void addLiveRegs(ArrayRef<unsigned> Regs);
/// Get the MI position corresponding to this register pressure.
@@ -184,6 +219,10 @@ public:
// position changes while pressure does not.
void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
+ /// \brief Get the SlotIndex for the first nondebug instruction including or
+ /// after the current position.
+ SlotIndex getCurrSlot() const;
+
/// Recede across the previous instruction.
bool recede();
@@ -197,16 +236,14 @@ public:
/// This result is complete if either advance() or recede() has returned true,
/// or if closeRegion() was explicitly invoked.
RegisterPressure &getPressure() { return P; }
+ const RegisterPressure &getPressure() const { return P; }
/// Get the register set pressure at the current position, which may be less
/// than the pressure across the traversed region.
std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; }
- void discoverPhysLiveIn(unsigned Reg);
- void discoverPhysLiveOut(unsigned Reg);
-
- void discoverVirtLiveIn(unsigned Reg);
- void discoverVirtLiveOut(unsigned Reg);
+ void discoverLiveOut(unsigned Reg);
+ void discoverLiveIn(unsigned Reg);
bool isTopClosed() const;
bool isBottomClosed() const;
@@ -267,12 +304,13 @@ public:
return getDownwardPressure(MI, PressureResult, MaxPressureResult);
}
+ void dump() const;
+
protected:
- void increasePhysRegPressure(ArrayRef<unsigned> Regs);
- void decreasePhysRegPressure(ArrayRef<unsigned> Regs);
+ const LiveInterval *getInterval(unsigned Reg) const;
- void increaseVirtRegPressure(ArrayRef<unsigned> Regs);
- void decreaseVirtRegPressure(ArrayRef<unsigned> Regs);
+ void increaseRegPressure(ArrayRef<unsigned> Regs);
+ void decreaseRegPressure(ArrayRef<unsigned> Regs);
void bumpUpwardPressure(const MachineInstr *MI);
void bumpDownwardPressure(const MachineInstr *MI);
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index 3986a8d..6604d4c 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -17,8 +17,9 @@
#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
-#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
namespace llvm {
@@ -59,10 +60,6 @@ class RegScavenger {
///
BitVector CalleeSavedRegs;
- /// ReservedRegs - A bitvector of reserved registers.
- ///
- BitVector ReservedRegs;
-
/// RegsAvailable - The current state of all the physical registers immediately
/// before MBBI. One bit per physical register. If bit is set that means it's
/// available, unset means the register is currently being used.
@@ -130,12 +127,14 @@ public:
void setUsed(unsigned Reg);
private:
/// isReserved - Returns true if a register is reserved. It is never "unused".
- bool isReserved(unsigned Reg) const { return ReservedRegs.test(Reg); }
+ bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }
- /// isUsed / isUnused - Test if a register is currently being used.
+ /// isUsed - Test if a register is currently being used. When called by the
+ /// isAliasUsed function, we only check isReserved if this is the original
+ /// register, not an alias register.
///
- bool isUsed(unsigned Reg) const {
- return !RegsAvailable.test(Reg) || ReservedRegs.test(Reg);
+ bool isUsed(unsigned Reg, bool CheckReserved = true) const {
+ return !RegsAvailable.test(Reg) || (CheckReserved && isReserved(Reg));
}
/// isAliasUsed - Is Reg or an alias currently in use?
diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h
index 56b5855..66a6039 100644
--- a/include/llvm/CodeGen/ResourcePriorityQueue.h
+++ b/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -18,8 +18,8 @@
#define RESOURCE_PRIORITY_QUEUE_H
#include "llvm/CodeGen/DFAPacketizer.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
index 4bfd4ab..1a9dc1c 100644
--- a/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -86,100 +86,126 @@ namespace RTLIB {
ADD_F32,
ADD_F64,
ADD_F80,
+ ADD_F128,
ADD_PPCF128,
SUB_F32,
SUB_F64,
SUB_F80,
+ SUB_F128,
SUB_PPCF128,
MUL_F32,
MUL_F64,
MUL_F80,
+ MUL_F128,
MUL_PPCF128,
DIV_F32,
DIV_F64,
DIV_F80,
+ DIV_F128,
DIV_PPCF128,
REM_F32,
REM_F64,
REM_F80,
+ REM_F128,
REM_PPCF128,
FMA_F32,
FMA_F64,
FMA_F80,
+ FMA_F128,
FMA_PPCF128,
POWI_F32,
POWI_F64,
POWI_F80,
+ POWI_F128,
POWI_PPCF128,
SQRT_F32,
SQRT_F64,
SQRT_F80,
+ SQRT_F128,
SQRT_PPCF128,
LOG_F32,
LOG_F64,
LOG_F80,
+ LOG_F128,
LOG_PPCF128,
LOG2_F32,
LOG2_F64,
LOG2_F80,
+ LOG2_F128,
LOG2_PPCF128,
LOG10_F32,
LOG10_F64,
LOG10_F80,
+ LOG10_F128,
LOG10_PPCF128,
EXP_F32,
EXP_F64,
EXP_F80,
+ EXP_F128,
EXP_PPCF128,
EXP2_F32,
EXP2_F64,
EXP2_F80,
+ EXP2_F128,
EXP2_PPCF128,
SIN_F32,
SIN_F64,
SIN_F80,
+ SIN_F128,
SIN_PPCF128,
COS_F32,
COS_F64,
COS_F80,
+ COS_F128,
COS_PPCF128,
POW_F32,
POW_F64,
POW_F80,
+ POW_F128,
POW_PPCF128,
CEIL_F32,
CEIL_F64,
CEIL_F80,
+ CEIL_F128,
CEIL_PPCF128,
TRUNC_F32,
TRUNC_F64,
TRUNC_F80,
+ TRUNC_F128,
TRUNC_PPCF128,
RINT_F32,
RINT_F64,
RINT_F80,
+ RINT_F128,
RINT_PPCF128,
NEARBYINT_F32,
NEARBYINT_F64,
NEARBYINT_F80,
+ NEARBYINT_F128,
NEARBYINT_PPCF128,
FLOOR_F32,
FLOOR_F64,
FLOOR_F80,
+ FLOOR_F128,
FLOOR_PPCF128,
COPYSIGN_F32,
COPYSIGN_F64,
COPYSIGN_F80,
+ COPYSIGN_F128,
COPYSIGN_PPCF128,
// CONVERSION
+ FPEXT_F64_F128,
+ FPEXT_F32_F128,
FPEXT_F32_F64,
FPEXT_F16_F32,
FPROUND_F32_F16,
FPROUND_F64_F32,
FPROUND_F80_F32,
+ FPROUND_F128_F32,
FPROUND_PPCF128_F32,
FPROUND_F80_F64,
+ FPROUND_F128_F64,
FPROUND_PPCF128_F64,
FPTOSINT_F32_I8,
FPTOSINT_F32_I16,
@@ -194,6 +220,9 @@ namespace RTLIB {
FPTOSINT_F80_I32,
FPTOSINT_F80_I64,
FPTOSINT_F80_I128,
+ FPTOSINT_F128_I32,
+ FPTOSINT_F128_I64,
+ FPTOSINT_F128_I128,
FPTOSINT_PPCF128_I32,
FPTOSINT_PPCF128_I64,
FPTOSINT_PPCF128_I128,
@@ -210,51 +239,68 @@ namespace RTLIB {
FPTOUINT_F80_I32,
FPTOUINT_F80_I64,
FPTOUINT_F80_I128,
+ FPTOUINT_F128_I32,
+ FPTOUINT_F128_I64,
+ FPTOUINT_F128_I128,
FPTOUINT_PPCF128_I32,
FPTOUINT_PPCF128_I64,
FPTOUINT_PPCF128_I128,
SINTTOFP_I32_F32,
SINTTOFP_I32_F64,
SINTTOFP_I32_F80,
+ SINTTOFP_I32_F128,
SINTTOFP_I32_PPCF128,
SINTTOFP_I64_F32,
SINTTOFP_I64_F64,
SINTTOFP_I64_F80,
+ SINTTOFP_I64_F128,
SINTTOFP_I64_PPCF128,
SINTTOFP_I128_F32,
SINTTOFP_I128_F64,
SINTTOFP_I128_F80,
+ SINTTOFP_I128_F128,
SINTTOFP_I128_PPCF128,
UINTTOFP_I32_F32,
UINTTOFP_I32_F64,
UINTTOFP_I32_F80,
+ UINTTOFP_I32_F128,
UINTTOFP_I32_PPCF128,
UINTTOFP_I64_F32,
UINTTOFP_I64_F64,
UINTTOFP_I64_F80,
+ UINTTOFP_I64_F128,
UINTTOFP_I64_PPCF128,
UINTTOFP_I128_F32,
UINTTOFP_I128_F64,
UINTTOFP_I128_F80,
+ UINTTOFP_I128_F128,
UINTTOFP_I128_PPCF128,
// COMPARISON
OEQ_F32,
OEQ_F64,
+ OEQ_F128,
UNE_F32,
UNE_F64,
+ UNE_F128,
OGE_F32,
OGE_F64,
+ OGE_F128,
OLT_F32,
OLT_F64,
+ OLT_F128,
OLE_F32,
OLE_F64,
+ OLE_F128,
OGT_F32,
OGT_F64,
+ OGT_F128,
UO_F32,
UO_F64,
+ UO_F128,
O_F32,
O_F64,
+ O_F128,
// MEMORY
MEMCPY,
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 2567a65..aa91b03 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -16,13 +16,13 @@
#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
#define LLVM_CODEGEN_SCHEDULEDAG_H
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetLowering.h"
namespace llvm {
class AliasAnalysis;
@@ -31,6 +31,7 @@ namespace llvm {
class MachineFunction;
class MachineRegisterInfo;
class MachineInstr;
+ struct MCSchedClassDesc;
class TargetRegisterInfo;
class ScheduleDAG;
class SDNode;
@@ -52,6 +53,14 @@ namespace llvm {
Order ///< Any other ordering dependency.
};
+ enum OrderKind {
+ Barrier, ///< An unknown scheduling barrier.
+ MayAliasMem, ///< Nonvolatile load/Store instructions that may alias.
+ MustAliasMem, ///< Nonvolatile load/Store instructions that must alias.
+ Artificial, ///< Arbitrary weak DAG edge (no actual dependence).
+ Cluster ///< Weak DAG edge linking a chain of clustered instrs.
+ };
+
private:
/// Dep - A pointer to the depending/depended-on SUnit, and an enum
/// indicating the kind of the dependency.
@@ -65,20 +74,7 @@ namespace llvm {
unsigned Reg;
/// Order - Additional information about Order dependencies.
- struct {
- /// isNormalMemory - True if both sides of the dependence
- /// access memory in non-volatile and fully modeled ways.
- bool isNormalMemory : 1;
-
- /// isMustAlias - True if both sides of the dependence are known to
- /// access the same memory.
- bool isMustAlias : 1;
-
- /// isArtificial - True if this is an artificial dependency, meaning
- /// it is not necessary for program correctness, and may be safely
- /// deleted if necessary.
- bool isArtificial : 1;
- } Order;
+ unsigned OrdKind; // enum OrderKind
} Contents;
/// Latency - The time associated with this edge. Often this is just
@@ -86,6 +82,9 @@ namespace llvm {
/// models may provide additional information about specific edges.
unsigned Latency;
/// Record MinLatency seperately from "expected" Latency.
+ ///
+ /// FIXME: this field is not packed on LP64. Convert to 16-bit DAG edge
+ /// latency after introducing saturating truncation.
unsigned MinLatency;
public:
@@ -95,28 +94,28 @@ namespace llvm {
SDep() : Dep(0, Data) {}
/// SDep - Construct an SDep with the specified values.
- SDep(SUnit *S, Kind kind, unsigned latency = 1, unsigned Reg = 0,
- bool isNormalMemory = false, bool isMustAlias = false,
- bool isArtificial = false)
- : Dep(S, kind), Contents(), Latency(latency), MinLatency(latency) {
+ SDep(SUnit *S, Kind kind, unsigned Reg)
+ : Dep(S, kind), Contents() {
switch (kind) {
+ default:
+ llvm_unreachable("Reg given for non-register dependence!");
case Anti:
case Output:
assert(Reg != 0 &&
"SDep::Anti and SDep::Output must use a non-zero Reg!");
- // fall through
- case Data:
- assert(!isMustAlias && "isMustAlias only applies with SDep::Order!");
- assert(!isArtificial && "isArtificial only applies with SDep::Order!");
Contents.Reg = Reg;
+ Latency = 0;
break;
- case Order:
- assert(Reg == 0 && "Reg given for non-register dependence!");
- Contents.Order.isNormalMemory = isNormalMemory;
- Contents.Order.isMustAlias = isMustAlias;
- Contents.Order.isArtificial = isArtificial;
+ case Data:
+ Contents.Reg = Reg;
+ Latency = 1;
break;
}
+ MinLatency = Latency;
+ }
+ SDep(SUnit *S, OrderKind kind)
+ : Dep(S, Order), Contents(), Latency(0), MinLatency(0) {
+ Contents.OrdKind = kind;
}
/// Return true if the specified SDep is equivalent except for latency.
@@ -128,10 +127,7 @@ namespace llvm {
case Output:
return Contents.Reg == Other.Contents.Reg;
case Order:
- return Contents.Order.isNormalMemory ==
- Other.Contents.Order.isNormalMemory &&
- Contents.Order.isMustAlias == Other.Contents.Order.isMustAlias &&
- Contents.Order.isArtificial == Other.Contents.Order.isArtificial;
+ return Contents.OrdKind == Other.Contents.OrdKind;
}
llvm_unreachable("Invalid dependency kind!");
}
@@ -194,20 +190,35 @@ namespace llvm {
/// memory accesses where both sides of the dependence access memory
/// in non-volatile and fully modeled ways.
bool isNormalMemory() const {
- return getKind() == Order && Contents.Order.isNormalMemory;
+ return getKind() == Order && (Contents.OrdKind == MayAliasMem
+ || Contents.OrdKind == MustAliasMem);
}
/// isMustAlias - Test if this is an Order dependence that is marked
/// as "must alias", meaning that the SUnits at either end of the edge
/// have a memory dependence on a known memory location.
bool isMustAlias() const {
- return getKind() == Order && Contents.Order.isMustAlias;
+ return getKind() == Order && Contents.OrdKind == MustAliasMem;
+ }
+
+ /// isWeak - Test if this a weak dependence. Weak dependencies are
+ /// considered DAG edges for height computation and other heuristics, but do
+ /// not force ordering. Breaking a weak edge may require the scheduler to
+ /// compensate, for example by inserting a copy.
+ bool isWeak() const {
+ return getKind() == Order && Contents.OrdKind == Cluster;
}
/// isArtificial - Test if this is an Order dependence that is marked
/// as "artificial", meaning it isn't necessary for correctness.
bool isArtificial() const {
- return getKind() == Order && Contents.Order.isArtificial;
+ return getKind() == Order && Contents.OrdKind == Artificial;
+ }
+
+ /// isCluster - Test if this is an Order dependence that is marked
+ /// as "cluster", meaning it is artificial and wants to be adjacent.
+ bool isCluster() const {
+ return getKind() == Order && Contents.OrdKind == Cluster;
}
/// isAssignedRegDep - Test if this is a Data dependence that is
@@ -254,6 +265,8 @@ namespace llvm {
// this node was cloned.
// (SD scheduling only)
+ const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.
+
// Preds/Succs - The SUnits before/after us in the graph.
SmallVector<SDep, 4> Preds; // All sunit predecessors.
SmallVector<SDep, 4> Succs; // All sunit successors.
@@ -269,6 +282,8 @@ namespace llvm {
unsigned NumSuccs; // # of SDep::Data sucss.
unsigned NumPredsLeft; // # of preds not scheduled.
unsigned NumSuccsLeft; // # of succs not scheduled.
+ unsigned WeakPredsLeft; // # of weak preds not scheduled.
+ unsigned WeakSuccsLeft; // # of weak succs not scheduled.
unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use.
unsigned short Latency; // Node latency.
bool isVRegCycle : 1; // May use and def the same vreg.
@@ -301,41 +316,41 @@ namespace llvm {
/// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
/// an SDNode and any nodes flagged to it.
SUnit(SDNode *node, unsigned nodenum)
- : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum),
+ : Node(node), Instr(0), OrigNode(0), SchedClass(0), NodeNum(nodenum),
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
- NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
- isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
- isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
- isPending(false), isAvailable(false), isScheduled(false),
- isScheduleHigh(false), isScheduleLow(false), isCloned(false),
- SchedulingPref(Sched::None),
+ NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
+ Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
+ isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
+ hasPhysRegClobbers(false), isPending(false), isAvailable(false),
+ isScheduled(false), isScheduleHigh(false), isScheduleLow(false),
+ isCloned(false), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
/// SUnit - Construct an SUnit for post-regalloc scheduling to represent
/// a MachineInstr.
SUnit(MachineInstr *instr, unsigned nodenum)
- : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum),
+ : Node(0), Instr(instr), OrigNode(0), SchedClass(0), NodeNum(nodenum),
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
- NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
- isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
- isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
- isPending(false), isAvailable(false), isScheduled(false),
- isScheduleHigh(false), isScheduleLow(false), isCloned(false),
- SchedulingPref(Sched::None),
+ NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
+ Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
+ isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
+ hasPhysRegClobbers(false), isPending(false), isAvailable(false),
+ isScheduled(false), isScheduleHigh(false), isScheduleLow(false),
+ isCloned(false), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
/// SUnit - Construct a placeholder SUnit.
SUnit()
- : Node(0), Instr(0), OrigNode(0), NodeNum(~0u),
+ : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(~0u),
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
- NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
- isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
- isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
- isPending(false), isAvailable(false), isScheduled(false),
- isScheduleHigh(false), isScheduleLow(false), isCloned(false),
- SchedulingPref(Sched::None),
+ NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
+ Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
+ isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
+ hasPhysRegClobbers(false), isPending(false), isAvailable(false),
+ isScheduled(false), isScheduleHigh(false), isScheduleLow(false),
+ isCloned(false), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
@@ -374,7 +389,7 @@ namespace llvm {
/// addPred - This adds the specified edge as a pred of the current node if
/// not already. It also adds the current node as a successor of the
/// specified node.
- bool addPred(const SDep &D);
+ bool addPred(const SDep &D, bool Required = true);
/// removePred - This removes the specified edge as a pred of the current
/// node if it exists. It also removes the current node as a successor of
@@ -570,16 +585,6 @@ namespace llvm {
unsigned VerifyScheduledDAG(bool isBottomUp);
#endif
- protected:
- /// ComputeLatency - Compute node latency.
- ///
- virtual void computeLatency(SUnit *SU) = 0;
-
- /// ForceUnitLatencies - Return true if all scheduling edges should be given
- /// a latency value of one. The default is to return false; schedulers may
- /// override this as needed.
- virtual bool forceUnitLatencies() const { return false; }
-
private:
// Return the MCInstrDesc of this SDNode or NULL.
const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
@@ -666,6 +671,7 @@ namespace llvm {
class ScheduleDAGTopologicalSort {
/// SUnits - A reference to the ScheduleDAG's SUnits.
std::vector<SUnit> &SUnits;
+ SUnit *ExitSU;
/// Index2Node - Maps topological index to the node number.
std::vector<int> Index2Node;
@@ -687,7 +693,7 @@ namespace llvm {
void Allocate(int n, int index);
public:
- explicit ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits);
+ ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
/// InitDAGTopologicalSorting - create the initial topological
/// ordering from the DAG to be scheduled.
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 8b52b5a..ffc442e 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -15,13 +15,14 @@
#ifndef SCHEDULEDAGINSTRS_H
#define SCHEDULEDAGINSTRS_H
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SparseSet.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SparseSet.h"
#include <map>
namespace llvm {
@@ -30,72 +31,6 @@ namespace llvm {
class LiveIntervals;
class RegPressureTracker;
- /// LoopDependencies - This class analyzes loop-oriented register
- /// dependencies, which are used to guide scheduling decisions.
- /// For example, loop induction variable increments should be
- /// scheduled as soon as possible after the variable's last use.
- ///
- class LoopDependencies {
- const MachineDominatorTree &MDT;
-
- public:
- typedef std::map<unsigned, std::pair<const MachineOperand *, unsigned> >
- LoopDeps;
- LoopDeps Deps;
-
- LoopDependencies(const MachineDominatorTree &mdt) : MDT(mdt) {}
-
- /// VisitLoop - Clear out any previous state and analyze the given loop.
- ///
- void VisitLoop(const MachineLoop *Loop) {
- assert(Deps.empty() && "stale loop dependencies");
-
- MachineBasicBlock *Header = Loop->getHeader();
- SmallSet<unsigned, 8> LoopLiveIns;
- for (MachineBasicBlock::livein_iterator LI = Header->livein_begin(),
- LE = Header->livein_end(); LI != LE; ++LI)
- LoopLiveIns.insert(*LI);
-
- const MachineDomTreeNode *Node = MDT.getNode(Header);
- const MachineBasicBlock *MBB = Node->getBlock();
- assert(Loop->contains(MBB) &&
- "Loop does not contain header!");
- VisitRegion(Node, MBB, Loop, LoopLiveIns);
- }
-
- private:
- void VisitRegion(const MachineDomTreeNode *Node,
- const MachineBasicBlock *MBB,
- const MachineLoop *Loop,
- const SmallSet<unsigned, 8> &LoopLiveIns) {
- unsigned Count = 0;
- for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
- I != E; ++I) {
- const MachineInstr *MI = I;
- if (MI->isDebugValue())
- continue;
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
- if (!MO.isReg() || !MO.isUse())
- continue;
- unsigned MOReg = MO.getReg();
- if (LoopLiveIns.count(MOReg))
- Deps.insert(std::make_pair(MOReg, std::make_pair(&MO, Count)));
- }
- ++Count; // Not every iteration due to dbg_value above.
- }
-
- const std::vector<MachineDomTreeNode*> &Children = Node->getChildren();
- for (std::vector<MachineDomTreeNode*>::const_iterator I =
- Children.begin(), E = Children.end(); I != E; ++I) {
- const MachineDomTreeNode *ChildNode = *I;
- MachineBasicBlock *ChildBlock = ChildNode->getBlock();
- if (Loop->contains(ChildBlock))
- VisitRegion(ChildNode, ChildBlock, Loop, LoopLiveIns);
- }
- }
- };
-
/// An individual mapping from virtual register number to SUnit.
struct VReg2SUnit {
unsigned VirtReg;
@@ -176,11 +111,13 @@ namespace llvm {
const MachineLoopInfo &MLI;
const MachineDominatorTree &MDT;
const MachineFrameInfo *MFI;
- const InstrItineraryData *InstrItins;
/// Live Intervals provides reaching defs in preRA scheduling.
LiveIntervals *LIS;
+ /// TargetSchedModel provides an interface to the machine model.
+ TargetSchedModel SchedModel;
+
/// isPostRA flag indicates vregs cannot be present.
bool IsPostRA;
@@ -232,10 +169,6 @@ namespace llvm {
/// to minimize construction/destruction.
std::vector<SUnit *> PendingLoads;
- /// LoopRegs - Track which registers are used for loop-carried dependencies.
- ///
- LoopDependencies LoopRegs;
-
/// DbgValues - Remember instruction that precedes DBG_VALUE.
/// These are generated by buildSchedGraph but persist so they can be
/// referenced when emitting the final schedule.
@@ -253,6 +186,16 @@ namespace llvm {
virtual ~ScheduleDAGInstrs() {}
+ /// \brief Get the machine model for instruction scheduling.
+ const TargetSchedModel *getSchedModel() const { return &SchedModel; }
+
+ /// \brief Resolve and cache a resolved scheduling class for an SUnit.
+ const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
+ if (!SU->SchedClass)
+ SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
+ return SU->SchedClass;
+ }
+
/// begin - Return an iterator to the top of the current scheduling region.
MachineBasicBlock::iterator begin() const { return RegionBegin; }
@@ -293,10 +236,6 @@ namespace llvm {
/// used by instructions in the fallthrough block.
void addSchedBarrierDeps();
- /// computeLatency - Compute node latency.
- ///
- virtual void computeLatency(SUnit *SU);
-
/// schedule - Order nodes according to selected style, filling
/// in the Sequence member.
///
diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h
new file mode 100644
index 0000000..fbbadd9
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDFS.h
@@ -0,0 +1,152 @@
+//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Definition of an ILP metric for machine level instruction scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H
+#define LLVM_CODEGEN_SCHEDULEDAGILP_H
+
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class raw_ostream;
+class IntEqClasses;
+class ScheduleDAGInstrs;
+class SUnit;
+
+/// \brief Represent the ILP of the subDAG rooted at a DAG node.
+///
+/// When computed using bottom-up DFS, this metric assumes that the DAG is a
+/// forest of trees with roots at the bottom of the schedule branching upward.
+struct ILPValue {
+ unsigned InstrCount;
+ /// Length may either correspond to depth or height, depending on direction,
+ /// and cycles or nodes depending on context.
+ unsigned Length;
+
+ ILPValue(unsigned count, unsigned length):
+ InstrCount(count), Length(length) {}
+
+ // Order by the ILP metric's value.
+ bool operator<(ILPValue RHS) const {
+ return (uint64_t)InstrCount * RHS.Length
+ < (uint64_t)Length * RHS.InstrCount;
+ }
+ bool operator>(ILPValue RHS) const {
+ return RHS < *this;
+ }
+ bool operator<=(ILPValue RHS) const {
+ return (uint64_t)InstrCount * RHS.Length
+ <= (uint64_t)Length * RHS.InstrCount;
+ }
+ bool operator>=(ILPValue RHS) const {
+ return RHS <= *this;
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ void print(raw_ostream &OS) const;
+
+ void dump() const;
+#endif
+};
+
+/// \brief Compute the values of each DAG node for various metrics during DFS.
+///
+/// ILPValues summarize the DAG subtree rooted at each node up to
+/// SubtreeLimit. ILPValues are also valid for interior nodes of a subtree, not
+/// just the root.
+class SchedDFSResult {
+ friend class SchedDFSImpl;
+
+ /// \brief Per-SUnit data computed during DFS for various metrics.
+ struct NodeData {
+ unsigned InstrCount;
+ unsigned SubtreeID;
+
+ NodeData(): InstrCount(0), SubtreeID(0) {}
+ };
+
+ /// \brief Record a connection between subtrees and the connection level.
+ struct Connection {
+ unsigned TreeID;
+ unsigned Level;
+
+ Connection(unsigned tree, unsigned level): TreeID(tree), Level(level) {}
+ };
+
+ bool IsBottomUp;
+ unsigned SubtreeLimit;
+ /// DFS results for each SUnit in this DAG.
+ std::vector<NodeData> DFSData;
+
+ // For each subtree discovered during DFS, record its connections to other
+ // subtrees.
+ std::vector<SmallVector<Connection, 4> > SubtreeConnections;
+
+ /// Cache the current connection level of each subtree.
+ /// This mutable array is updated during scheduling.
+ std::vector<unsigned> SubtreeConnectLevels;
+
+public:
+ SchedDFSResult(bool IsBU, unsigned lim)
+ : IsBottomUp(IsBU), SubtreeLimit(lim) {}
+
+ /// \brief Clear the results.
+ void clear() {
+ DFSData.clear();
+ SubtreeConnections.clear();
+ SubtreeConnectLevels.clear();
+ }
+
+ /// \brief Initialize the result data with the size of the DAG.
+ void resize(unsigned NumSUnits) {
+ DFSData.resize(NumSUnits);
+ }
+
+ /// \brief Compute various metrics for the DAG with given roots.
+ void compute(ArrayRef<SUnit *> Roots);
+
+ /// \brief Get the ILP value for a DAG node.
+ ///
+ /// A leaf node has an ILP of 1/1.
+ ILPValue getILP(const SUnit *SU) {
+ return ILPValue(DFSData[SU->NodeNum].InstrCount, 1 + SU->getDepth());
+ }
+
+ /// \brief The number of subtrees detected in this DAG.
+ unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); }
+
+ /// \brief Get the ID of the subtree the given DAG node belongs to.
+ unsigned getSubtreeID(const SUnit *SU) {
+ return DFSData[SU->NodeNum].SubtreeID;
+ }
+
+ /// \brief Get the connection level of a subtree.
+ ///
+ /// For bottom-up trees, the connection level is the latency depth (in cycles)
+ /// of the deepest connection to another subtree.
+ unsigned getSubtreeLevel(unsigned SubtreeID) {
+ return SubtreeConnectLevels[SubtreeID];
+ }
+
+ /// \brief Scheduler callback to update SubtreeConnectLevels when a tree is
+ /// initially scheduled.
+ void scheduleTree(unsigned SubtreeID);
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val);
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
index a582b0c..836b73a 100644
--- a/include/llvm/CodeGen/SchedulerRegistry.h
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -102,6 +102,11 @@ ScheduleDAGSDNodes *createVLIWDAGScheduler(SelectionDAGISel *IS,
ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
CodeGenOpt::Level OptLevel);
+/// createDAGLinearizer - This creates a "no-scheduling" scheduler which
+/// linearize the DAG using topological order.
+ScheduleDAGSDNodes *createDAGLinearizer(SelectionDAGISel *IS,
+ CodeGenOpt::Level OptLevel);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
index 060e89a..c2103fb 100644
--- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -18,7 +18,6 @@
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/Support/DataTypes.h"
-
#include <cassert>
#include <cstring>
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 1ccfe54..c5cc8f5 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -15,16 +15,17 @@
#ifndef LLVM_CODEGEN_SELECTIONDAG_H
#define LLVM_CODEGEN_SELECTIONDAG_H
-#include "llvm/ADT/ilist.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Support/RecyclingAllocator.h"
#include "llvm/Target/TargetMachine.h"
#include <cassert>
-#include <vector>
#include <map>
#include <string>
+#include <vector>
namespace llvm {
@@ -36,6 +37,7 @@ class SDNodeOrdering;
class SDDbgValue;
class TargetLowering;
class TargetSelectionDAGInfo;
+class TargetTransformInfo;
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
private:
@@ -73,8 +75,8 @@ class SDDbgInfo {
SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap;
- void operator=(const SDDbgInfo&); // Do not implement.
- SDDbgInfo(const SDDbgInfo&); // Do not implement.
+ void operator=(const SDDbgInfo&) LLVM_DELETED_FUNCTION;
+ SDDbgInfo(const SDDbgInfo&) LLVM_DELETED_FUNCTION;
public:
SDDbgInfo() {}
@@ -111,13 +113,6 @@ public:
DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); }
};
-enum CombineLevel {
- BeforeLegalizeTypes,
- AfterLegalizeTypes,
- AfterLegalizeVectorOps,
- AfterLegalizeDAG
-};
-
class SelectionDAG;
void checkForCycles(const SDNode *N);
void checkForCycles(const SelectionDAG *DAG);
@@ -137,6 +132,7 @@ class SelectionDAG {
const TargetMachine &TM;
const TargetLowering &TLI;
const TargetSelectionDAGInfo &TSI;
+ const TargetTransformInfo *TTI;
MachineFunction *MF;
LLVMContext *Context;
CodeGenOpt::Level OptLevel;
@@ -222,8 +218,8 @@ private:
DenseSet<SDNode *> &visited,
int level, bool &printed);
- void operator=(const SelectionDAG&); // Do not implement.
- SelectionDAG(const SelectionDAG&); // Do not implement.
+ void operator=(const SelectionDAG&) LLVM_DELETED_FUNCTION;
+ SelectionDAG(const SelectionDAG&) LLVM_DELETED_FUNCTION;
public:
explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level);
@@ -232,7 +228,7 @@ public:
/// init - Prepare this SelectionDAG to process code in the given
/// MachineFunction.
///
- void init(MachineFunction &mf);
+ void init(MachineFunction &mf, const TargetTransformInfo *TTI);
/// clear - Clear state and free memory necessary to make this
/// SelectionDAG ready to process a new block.
@@ -243,6 +239,7 @@ public:
const TargetMachine &getTarget() const { return TM; }
const TargetLowering &getTargetLoweringInfo() const { return TLI; }
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
+ const TargetTransformInfo *getTargetTransformInfo() const { return TTI; }
LLVMContext *getContext() const {return Context; }
/// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
@@ -437,7 +434,13 @@ public:
SDValue getRegisterMask(const uint32_t *RegMask);
SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label);
SDValue getBlockAddress(const BlockAddress *BA, EVT VT,
- bool isTarget = false, unsigned char TargetFlags = 0);
+ int64_t Offset = 0, bool isTarget = false,
+ unsigned char TargetFlags = 0);
+ SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT,
+ int64_t Offset = 0,
+ unsigned char TargetFlags = 0) {
+ return getBlockAddress(BA, VT, Offset, true, TargetFlags);
+ }
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index c42f655..16aacc0 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -15,10 +15,10 @@
#ifndef LLVM_CODEGEN_SELECTIONDAG_ISEL_H
#define LLVM_CODEGEN_SELECTIONDAG_ISEL_H
-#include "llvm/BasicBlock.h"
-#include "llvm/Pass.h"
-#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/Pass.h"
namespace llvm {
class FastISel;
@@ -31,6 +31,7 @@ namespace llvm {
class TargetLowering;
class TargetLibraryInfo;
class TargetInstrInfo;
+ class TargetTransformInfo;
class FunctionLoweringInfo;
class ScheduleHazardRecognizer;
class GCFunctionInfo;
@@ -44,6 +45,7 @@ public:
const TargetMachine &TM;
const TargetLowering &TLI;
const TargetLibraryInfo *LibInfo;
+ const TargetTransformInfo *TTI;
FunctionLoweringInfo *FuncInfo;
MachineFunction *MF;
MachineRegisterInfo *RegInfo;
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 3bea2de..2c34b4f 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -19,20 +19,20 @@
#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
#define LLVM_CODEGEN_SELECTIONDAGNODES_H
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ilist_node.h"
#include "llvm/CodeGen/ISDOpcodes.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineMemOperand.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
+#include "llvm/Support/MathExtras.h"
#include <cassert>
namespace llvm {
@@ -49,7 +49,7 @@ template <typename T> struct simplify_type;
template <typename T> struct ilist_traits;
void checkForCycles(const SDNode *N);
-
+
/// SDVTList - This represents a list of ValueType's that has been intern'd by
/// a SelectionDAG. Instances of this simple value class are returned by
/// SelectionDAG::getVTList(...).
@@ -108,7 +108,7 @@ public:
void setNode(SDNode *N) { Node = N; }
inline SDNode *operator->() const { return Node; }
-
+
bool operator==(const SDValue &O) const {
return Node == O.Node && ResNo == O.ResNo;
}
@@ -130,6 +130,11 @@ public:
///
inline EVT getValueType() const;
+ /// Return the simple ValueType of the referenced return value.
+ MVT getSimpleValueType() const {
+ return getValueType().getSimpleVT();
+ }
+
/// getValueSizeInBits - Returns the size of the value in bits.
///
unsigned getValueSizeInBits() const {
@@ -216,8 +221,8 @@ class SDUse {
/// this operand.
SDUse **Prev, *Next;
- SDUse(const SDUse &U); // Do not implement
- void operator=(const SDUse &U); // Do not implement
+ SDUse(const SDUse &U) LLVM_DELETED_FUNCTION;
+ void operator=(const SDUse &U) LLVM_DELETED_FUNCTION;
public:
SDUse() : Val(), User(NULL), Prev(NULL), Next(NULL) {}
@@ -525,7 +530,7 @@ public:
/// NOTE: This is still very expensive. Use carefully.
bool hasPredecessorHelper(const SDNode *N,
SmallPtrSet<const SDNode *, 32> &Visited,
- SmallVector<const SDNode *, 16> &Worklist) const;
+ SmallVector<const SDNode *, 16> &Worklist) const;
/// getNumOperands - Return the number of values used by this operation.
///
@@ -595,6 +600,12 @@ public:
return ValueList[ResNo];
}
+ /// Return the type of a specified result as a simple type.
+ ///
+ MVT getSimpleValueType(unsigned ResNo) const {
+ return getValueType(ResNo).getSimpleVT();
+ }
+
/// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)).
///
unsigned getValueSizeInBits(unsigned ResNo) const {
@@ -662,9 +673,6 @@ public:
///
void dumprWithDepth(const SelectionDAG *G = 0, unsigned depth = 100) const;
-
- static bool classof(const SDNode *) { return true; }
-
/// Profile - Gather unique data for the node.
///
void Profile(FoldingSetNodeID &ID) const;
@@ -956,7 +964,12 @@ public:
const MachinePointerInfo &getPointerInfo() const {
return MMO->getPointerInfo();
}
-
+
+ /// getAddressSpace - Return the address space for the associated pointer
+ unsigned getAddressSpace() const {
+ return getPointerInfo().getAddrSpace();
+ }
+
/// refineAlignment - Update this MemSDNode's MachineMemOperand information
/// to reflect the alignment of NewMMO, if it has a greater alignment.
/// This must only be used when the new alignment applies to all users of
@@ -971,7 +984,6 @@ public:
}
// Methods to support isa and dyn_cast
- static bool classof(const MemSDNode *) { return true; }
static bool classof(const SDNode *N) {
// For some targets, we lower some target intrinsics to a MemIntrinsicNode
// with either an intrinsic or a target opcode.
@@ -1056,7 +1068,6 @@ public:
}
// Methods to support isa and dyn_cast
- static bool classof(const AtomicSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
N->getOpcode() == ISD::ATOMIC_SWAP ||
@@ -1088,7 +1099,6 @@ public:
}
// Methods to support isa and dyn_cast
- static bool classof(const MemIntrinsicSDNode *) { return true; }
static bool classof(const SDNode *N) {
// We lower some target intrinsics to their target opcode
// early a node with a target opcode can be of this class
@@ -1143,7 +1153,6 @@ public:
}
static bool isSplatMask(const int *Mask, EVT VT);
- static bool classof(const ShuffleVectorSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::VECTOR_SHUFFLE;
}
@@ -1167,7 +1176,6 @@ public:
bool isNullValue() const { return Value->isNullValue(); }
bool isAllOnesValue() const { return Value->isAllOnesValue(); }
- static bool classof(const ConstantSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::Constant ||
N->getOpcode() == ISD::TargetConstant;
@@ -1202,9 +1210,6 @@ public:
/// have to duplicate its logic everywhere it's called.
bool isExactlyValue(double V) const {
bool ignored;
- // convert is not supported on this type
- if (&Value->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
- return false;
APFloat Tmp(V);
Tmp.convert(Value->getValueAPF().getSemantics(),
APFloat::rmNearestTiesToEven, &ignored);
@@ -1214,7 +1219,6 @@ public:
static bool isValueValidForType(EVT VT, const APFloat& Val);
- static bool classof(const ConstantFPSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::ConstantFP ||
N->getOpcode() == ISD::TargetConstantFP;
@@ -1236,7 +1240,6 @@ public:
// Return the address space this GlobalAddress belongs to.
unsigned getAddressSpace() const;
- static bool classof(const GlobalAddressSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::GlobalAddress ||
N->getOpcode() == ISD::TargetGlobalAddress ||
@@ -1256,7 +1259,6 @@ public:
int getIndex() const { return FI; }
- static bool classof(const FrameIndexSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::FrameIndex ||
N->getOpcode() == ISD::TargetFrameIndex;
@@ -1276,7 +1278,6 @@ public:
int getIndex() const { return JTI; }
unsigned char getTargetFlags() const { return TargetFlags; }
- static bool classof(const JumpTableSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::JumpTable ||
N->getOpcode() == ISD::TargetJumpTable;
@@ -1337,7 +1338,6 @@ public:
Type *getType() const;
- static bool classof(const ConstantPoolSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::ConstantPool ||
N->getOpcode() == ISD::TargetConstantPool;
@@ -1361,7 +1361,6 @@ public:
int getIndex() const { return Index; }
int64_t getOffset() const { return Offset; }
- static bool classof(const TargetIndexSDNode*) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::TargetIndex;
}
@@ -1380,7 +1379,6 @@ public:
MachineBasicBlock *getBasicBlock() const { return MBB; }
- static bool classof(const BasicBlockSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::BasicBlock;
}
@@ -1390,7 +1388,7 @@ public:
/// BUILD_VECTORs.
class BuildVectorSDNode : public SDNode {
// These are constructed as SDNodes and then cast to BuildVectorSDNodes.
- explicit BuildVectorSDNode(); // Do not implement
+ explicit BuildVectorSDNode() LLVM_DELETED_FUNCTION;
public:
/// isConstantSplat - Check if this is a constant splat, and if so, find the
/// smallest element size that splats the vector. If MinSplatBits is
@@ -1405,7 +1403,6 @@ public:
unsigned &SplatBitSize, bool &HasAnyUndefs,
unsigned MinSplatBits = 0, bool isBigEndian = false);
- static inline bool classof(const BuildVectorSDNode *) { return true; }
static inline bool classof(const SDNode *N) {
return N->getOpcode() == ISD::BUILD_VECTOR;
}
@@ -1426,7 +1423,6 @@ public:
/// getValue - return the contained Value.
const Value *getValue() const { return V; }
- static bool classof(const SrcValueSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::SRCVALUE;
}
@@ -1441,7 +1437,6 @@ public:
const MDNode *getMD() const { return MD; }
- static bool classof(const MDNodeSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::MDNODE_SDNODE;
}
@@ -1458,7 +1453,6 @@ public:
unsigned getReg() const { return Reg; }
- static bool classof(const RegisterSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::Register;
}
@@ -1475,7 +1469,6 @@ public:
const uint32_t *getRegMask() const { return RegMask; }
- static bool classof(const RegisterMaskSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::RegisterMask;
}
@@ -1483,18 +1476,19 @@ public:
class BlockAddressSDNode : public SDNode {
const BlockAddress *BA;
+ int64_t Offset;
unsigned char TargetFlags;
friend class SelectionDAG;
BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
- unsigned char Flags)
+ int64_t o, unsigned char Flags)
: SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
- BA(ba), TargetFlags(Flags) {
+ BA(ba), Offset(o), TargetFlags(Flags) {
}
public:
const BlockAddress *getBlockAddress() const { return BA; }
+ int64_t getOffset() const { return Offset; }
unsigned char getTargetFlags() const { return TargetFlags; }
- static bool classof(const BlockAddressSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::BlockAddress ||
N->getOpcode() == ISD::TargetBlockAddress;
@@ -1512,7 +1506,6 @@ class EHLabelSDNode : public SDNode {
public:
MCSymbol *getLabel() const { return Label; }
- static bool classof(const EHLabelSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::EH_LABEL;
}
@@ -1532,7 +1525,6 @@ public:
const char *getSymbol() const { return Symbol; }
unsigned char getTargetFlags() const { return TargetFlags; }
- static bool classof(const ExternalSymbolSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::ExternalSymbol ||
N->getOpcode() == ISD::TargetExternalSymbol;
@@ -1550,7 +1542,6 @@ public:
ISD::CondCode get() const { return Condition; }
- static bool classof(const CondCodeSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::CONDCODE;
}
@@ -1570,7 +1561,6 @@ class CvtRndSatSDNode : public SDNode {
public:
ISD::CvtCode getCvtCode() const { return CvtCode; }
- static bool classof(const CvtRndSatSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::CONVERT_RNDSAT;
}
@@ -1589,7 +1579,6 @@ public:
EVT getVT() const { return ValueType; }
- static bool classof(const VTSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::VALUETYPE;
}
@@ -1633,7 +1622,6 @@ public:
/// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store.
bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
- static bool classof(const LSBaseSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::LOAD ||
N->getOpcode() == ISD::STORE;
@@ -1665,7 +1653,6 @@ public:
const SDValue &getBasePtr() const { return getOperand(1); }
const SDValue &getOffset() const { return getOperand(2); }
- static bool classof(const LoadSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::LOAD;
}
@@ -1696,7 +1683,6 @@ public:
const SDValue &getBasePtr() const { return getOperand(2); }
const SDValue &getOffset() const { return getOperand(3); }
- static bool classof(const StoreSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::STORE;
}
@@ -1737,7 +1723,6 @@ public:
MemRefsEnd = NewMemRefsEnd;
}
- static bool classof(const MachineSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->isMachineOpcode();
}
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index c52599b..b46d153 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -19,13 +19,14 @@
#ifndef LLVM_CODEGEN_SLOTINDEXES_H
#define LLVM_CODEGEN_SLOTINDEXES_H
-#include "llvm/CodeGen/MachineInstrBundle.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/ilist.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
@@ -631,17 +632,8 @@ namespace llvm {
// Specialize IntervalMapInfo for half-open slot index intervals.
- template <typename> struct IntervalMapInfo;
- template <> struct IntervalMapInfo<SlotIndex> {
- static inline bool startLess(const SlotIndex &x, const SlotIndex &a) {
- return x < a;
- }
- static inline bool stopLess(const SlotIndex &b, const SlotIndex &x) {
- return b <= x;
- }
- static inline bool adjacent(const SlotIndex &a, const SlotIndex &b) {
- return a == b;
- }
+ template <>
+ struct IntervalMapInfo<SlotIndex> : IntervalMapHalfOpenInfo<SlotIndex> {
};
}
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 9849e92..e7098e4 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/ADT/StringRef.h"
namespace llvm {
class MachineModuleInfo;
@@ -55,13 +55,12 @@ public:
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
- /// getExprForDwarfGlobalReference - Return an MCExpr to use for a reference
- /// to the specified global variable from exception handling information.
- ///
+ /// getTTypeGlobalReference - Return an MCExpr to use for a reference to the
+ /// specified type info global variable from exception handling information.
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
@@ -103,12 +102,12 @@ public:
virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
Mangler *) const;
- /// getExprForDwarfGlobalReference - The mach-o version of this method
+ /// getTTypeGlobalReference - The mach-o version of this method
/// defaults to returning a stub reference.
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h
new file mode 100644
index 0000000..4c4a2a8
--- /dev/null
+++ b/include/llvm/CodeGen/TargetSchedule.h
@@ -0,0 +1,167 @@
+//===-- llvm/CodeGen/TargetSchedule.h - Sched Machine Model -----*- 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 wrapper around MCSchedModel that allows the interface to
+// benefit from information currently only available in TargetInstrInfo.
+// Ideally, the scheduling interface would be fully defined in the MC layer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSCHEDMODEL_H
+#define LLVM_TARGET_TARGETSCHEDMODEL_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/MCSchedule.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+
+namespace llvm {
+
+class TargetRegisterInfo;
+class TargetSubtargetInfo;
+class TargetInstrInfo;
+class MachineInstr;
+
+/// Provide an instruction scheduling machine model to CodeGen passes.
+class TargetSchedModel {
+ // For efficiency, hold a copy of the statically defined MCSchedModel for this
+ // processor.
+ MCSchedModel SchedModel;
+ InstrItineraryData InstrItins;
+ const TargetSubtargetInfo *STI;
+ const TargetInstrInfo *TII;
+
+ SmallVector<unsigned, 16> ResourceFactors;
+ unsigned MicroOpFactor; // Multiply to normalize microops to resource units.
+ unsigned ResourceLCM; // Resource units per cycle. Latency normalization factor.
+public:
+ TargetSchedModel(): STI(0), TII(0) {}
+
+ /// \brief Initialize the machine model for instruction scheduling.
+ ///
+ /// The machine model API keeps a copy of the top-level MCSchedModel table
+ /// indices and may query TargetSubtargetInfo and TargetInstrInfo to resolve
+ /// dynamic properties.
+ void init(const MCSchedModel &sm, const TargetSubtargetInfo *sti,
+ const TargetInstrInfo *tii);
+
+ /// Return the MCSchedClassDesc for this instruction.
+ const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const;
+
+ /// \brief TargetInstrInfo getter.
+ const TargetInstrInfo *getInstrInfo() const { return TII; }
+
+ /// \brief Return true if this machine model includes an instruction-level
+ /// scheduling model.
+ ///
+ /// This is more detailed than the course grain IssueWidth and default
+ /// latency properties, but separate from the per-cycle itinerary data.
+ bool hasInstrSchedModel() const;
+
+ const MCSchedModel *getMCSchedModel() const { return &SchedModel; }
+
+ /// \brief Return true if this machine model includes cycle-to-cycle itinerary
+ /// data.
+ ///
+ /// This models scheduling at each stage in the processor pipeline.
+ bool hasInstrItineraries() const;
+
+ const InstrItineraryData *getInstrItineraries() const {
+ if (hasInstrItineraries())
+ return &InstrItins;
+ return 0;
+ }
+
+ /// \brief Identify the processor corresponding to the current subtarget.
+ unsigned getProcessorID() const { return SchedModel.getProcessorID(); }
+
+ /// \brief Maximum number of micro-ops that may be scheduled per cycle.
+ unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
+
+ /// \brief Return the number of issue slots required for this MI.
+ unsigned getNumMicroOps(const MachineInstr *MI,
+ const MCSchedClassDesc *SC = 0) const;
+
+ /// \brief Get the number of kinds of resources for this target.
+ unsigned getNumProcResourceKinds() const {
+ return SchedModel.getNumProcResourceKinds();
+ }
+
+ /// \brief Get a processor resource by ID for convenience.
+ const MCProcResourceDesc *getProcResource(unsigned PIdx) const {
+ return SchedModel.getProcResource(PIdx);
+ }
+
+ typedef const MCWriteProcResEntry *ProcResIter;
+
+ // \brief Get an iterator into the processor resources consumed by this
+ // scheduling class.
+ ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const {
+ // The subtarget holds a single resource table for all processors.
+ return STI->getWriteProcResBegin(SC);
+ }
+ ProcResIter getWriteProcResEnd(const MCSchedClassDesc *SC) const {
+ return STI->getWriteProcResEnd(SC);
+ }
+
+ /// \brief Multiply the number of units consumed for a resource by this factor
+ /// to normalize it relative to other resources.
+ unsigned getResourceFactor(unsigned ResIdx) const {
+ return ResourceFactors[ResIdx];
+ }
+
+ /// \brief Multiply number of micro-ops by this factor to normalize it
+ /// relative to other resources.
+ unsigned getMicroOpFactor() const {
+ return MicroOpFactor;
+ }
+
+ /// \brief Multiply cycle count by this factor to normalize it relative to
+ /// other resources. This is the number of resource units per cycle.
+ unsigned getLatencyFactor() const {
+ return ResourceLCM;
+ }
+
+ /// \brief Compute operand latency based on the available machine model.
+ ///
+ /// Computes and return the latency of the given data dependent def and use
+ /// when the operand indices are already known. UseMI may be NULL for an
+ /// unknown user.
+ ///
+ /// FindMin may be set to get the minimum vs. expected latency. Minimum
+ /// latency is used for scheduling groups, while expected latency is for
+ /// instruction cost and critical path.
+ unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
+ const MachineInstr *UseMI, unsigned UseOperIdx,
+ bool FindMin) const;
+
+ /// \brief Compute the instruction latency based on the available machine
+ /// model.
+ ///
+ /// Compute and return the expected latency of this instruction independent of
+ /// a particular use. computeOperandLatency is the prefered API, but this is
+ /// occasionally useful to help estimate instruction cost.
+ unsigned computeInstrLatency(const MachineInstr *MI) const;
+
+ /// \brief Output dependency latency of a pair of defs of the same register.
+ ///
+ /// This is typically one cycle.
+ unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *DepMI) const;
+
+private:
+ /// getDefLatency is a helper for computeOperandLatency. Return the
+ /// instruction's latency if operand lookup is not required.
+ /// Otherwise return -1.
+ int getDefLatency(const MachineInstr *DefMI, bool FindMin) const;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index eb38cd3..f8a6503 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -33,6 +33,10 @@ namespace llvm {
class MVT {
public:
enum SimpleValueType {
+ // INVALID_SIMPLE_VALUE_TYPE - Simple value types less than zero are
+ // considered extended value types.
+ INVALID_SIMPLE_VALUE_TYPE = -1,
+
// If you change this numbering, you must change the values in
// ValueTypes.td as well!
Other = 0, // This is a non-standard value
@@ -56,50 +60,65 @@ namespace llvm {
FIRST_FP_VALUETYPE = f16,
LAST_FP_VALUETYPE = ppcf128,
- v2i8 = 13, // 2 x i8
- v4i8 = 14, // 4 x i8
- v8i8 = 15, // 8 x i8
- v16i8 = 16, // 16 x i8
- v32i8 = 17, // 32 x i8
- v2i16 = 18, // 2 x i16
- v4i16 = 19, // 4 x i16
- v8i16 = 20, // 8 x i16
- v16i16 = 21, // 16 x i16
- v2i32 = 22, // 2 x i32
- v4i32 = 23, // 4 x i32
- v8i32 = 24, // 8 x i32
- v16i32 = 25, // 16 x i32
- v1i64 = 26, // 1 x i64
- v2i64 = 27, // 2 x i64
- v4i64 = 28, // 4 x i64
- v8i64 = 29, // 8 x i64
- v16i64 = 30, // 16 x i64
-
- v2f16 = 31, // 2 x f16
- v2f32 = 32, // 2 x f32
- v4f32 = 33, // 4 x f32
- v8f32 = 34, // 8 x f32
- v2f64 = 35, // 2 x f64
- v4f64 = 36, // 4 x f64
-
- FIRST_VECTOR_VALUETYPE = v2i8,
- LAST_VECTOR_VALUETYPE = v4f64,
- FIRST_INTEGER_VECTOR_VALUETYPE = v2i8,
+ v2i1 = 13, // 2 x i1
+ v4i1 = 14, // 4 x i1
+ v8i1 = 15, // 8 x i1
+ v16i1 = 16, // 16 x i1
+ v32i1 = 17, // 32 x i1
+ v64i1 = 18, // 64 x i1
+
+ v2i8 = 19, // 2 x i8
+ v4i8 = 20, // 4 x i8
+ v8i8 = 21, // 8 x i8
+ v16i8 = 22, // 16 x i8
+ v32i8 = 23, // 32 x i8
+ v64i8 = 24, // 64 x i8
+ v1i16 = 25, // 1 x i16
+ v2i16 = 26, // 2 x i16
+ v4i16 = 27, // 4 x i16
+ v8i16 = 28, // 8 x i16
+ v16i16 = 29, // 16 x i16
+ v32i16 = 30, // 32 x i16
+ v1i32 = 31, // 1 x i32
+ v2i32 = 32, // 2 x i32
+ v4i32 = 33, // 4 x i32
+ v8i32 = 34, // 8 x i32
+ v16i32 = 35, // 16 x i32
+ v1i64 = 36, // 1 x i64
+ v2i64 = 37, // 2 x i64
+ v4i64 = 38, // 4 x i64
+ v8i64 = 39, // 8 x i64
+ v16i64 = 40, // 16 x i64
+
+ FIRST_INTEGER_VECTOR_VALUETYPE = v2i1,
LAST_INTEGER_VECTOR_VALUETYPE = v16i64,
+
+ v2f16 = 41, // 2 x f16
+ v2f32 = 42, // 2 x f32
+ v4f32 = 43, // 4 x f32
+ v8f32 = 44, // 8 x f32
+ v16f32 = 45, // 16 x f32
+ v2f64 = 46, // 2 x f64
+ v4f64 = 47, // 4 x f64
+ v8f64 = 48, // 8 x f64
+
FIRST_FP_VECTOR_VALUETYPE = v2f16,
- LAST_FP_VECTOR_VALUETYPE = v4f64,
+ LAST_FP_VECTOR_VALUETYPE = v8f64,
- x86mmx = 37, // This is an X86 MMX value
+ FIRST_VECTOR_VALUETYPE = v2i1,
+ LAST_VECTOR_VALUETYPE = v8f64,
- Glue = 38, // This glues nodes together during pre-RA sched
+ x86mmx = 49, // This is an X86 MMX value
- isVoid = 39, // This has no value
+ Glue = 50, // This glues nodes together during pre-RA sched
- Untyped = 40, // This value takes a register, but has
+ isVoid = 51, // This has no value
+
+ Untyped = 52, // This value takes a register, but has
// unspecified type. The register class
// will be determined by the opcode.
- LAST_VALUETYPE = 41, // This always remains at the end of the list.
+ LAST_VALUETYPE = 53, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
@@ -131,14 +150,7 @@ namespace llvm {
// iPTR - An int value the size of the pointer of the current
// target. This should only be used internal to tblgen!
- iPTR = 255,
-
- // LastSimpleValueType - The greatest valid SimpleValueType value.
- LastSimpleValueType = 255,
-
- // INVALID_SIMPLE_VALUE_TYPE - Simple value types greater than or equal
- // to this are considered extended value types.
- INVALID_SIMPLE_VALUE_TYPE = LastSimpleValueType + 1
+ iPTR = 255
};
SimpleValueType SimpleTy;
@@ -175,6 +187,18 @@ namespace llvm {
SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
}
+ /// is16BitVector - Return true if this is a 16-bit vector type.
+ bool is16BitVector() const {
+ return (SimpleTy == MVT::v2i8 || SimpleTy == MVT::v1i16 ||
+ SimpleTy == MVT::v16i1);
+ }
+
+ /// is32BitVector - Return true if this is a 32-bit vector type.
+ bool is32BitVector() const {
+ return (SimpleTy == MVT::v4i8 || SimpleTy == MVT::v2i16 ||
+ SimpleTy == MVT::v1i32);
+ }
+
/// is64BitVector - Return true if this is a 64-bit vector type.
bool is64BitVector() const {
return (SimpleTy == MVT::v8i8 || SimpleTy == MVT::v4i16 ||
@@ -198,7 +222,9 @@ namespace llvm {
/// is512BitVector - Return true if this is a 512-bit vector type.
bool is512BitVector() const {
- return (SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32);
+ return (SimpleTy == MVT::v8f64 || SimpleTy == MVT::v16f32 ||
+ SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 ||
+ SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32);
}
/// is1024BitVector - Return true if this is a 1024-bit vector type.
@@ -233,15 +259,25 @@ namespace llvm {
switch (SimpleTy) {
default:
llvm_unreachable("Not a vector MVT!");
+ case v2i1 :
+ case v4i1 :
+ case v8i1 :
+ case v16i1 :
+ case v32i1 :
+ case v64i1: return i1;
case v2i8 :
case v4i8 :
case v8i8 :
case v16i8:
- case v32i8: return i8;
+ case v32i8:
+ case v64i8: return i8;
+ case v1i16:
case v2i16:
case v4i16:
case v8i16:
- case v16i16: return i16;
+ case v16i16:
+ case v32i16: return i16;
+ case v1i32:
case v2i32:
case v4i32:
case v8i32:
@@ -254,9 +290,11 @@ namespace llvm {
case v2f16: return f16;
case v2f32:
case v4f32:
- case v8f32: return f32;
+ case v8f32:
+ case v16f32: return f32;
case v2f64:
- case v4f64: return f64;
+ case v4f64:
+ case v8f64: return f64;
}
}
@@ -264,22 +302,32 @@ namespace llvm {
switch (SimpleTy) {
default:
llvm_unreachable("Not a vector MVT!");
- case v32i8: return 32;
+ case v32i1:
+ case v32i8:
+ case v32i16: return 32;
+ case v64i1:
+ case v64i8: return 64;
+ case v16i1:
case v16i8:
case v16i16:
case v16i32:
- case v16i64:return 16;
+ case v16i64:
+ case v16f32: return 16;
+ case v8i1 :
case v8i8 :
case v8i16:
case v8i32:
case v8i64:
- case v8f32: return 8;
+ case v8f32:
+ case v8f64: return 8;
+ case v4i1:
case v4i8:
case v4i16:
case v4i32:
case v4i64:
case v4f32:
case v4f64: return 4;
+ case v2i1:
case v2i8:
case v2i16:
case v2i32:
@@ -287,6 +335,8 @@ namespace llvm {
case v2f16:
case v2f32:
case v2f64: return 2;
+ case v1i16:
+ case v1i32:
case v1i64: return 1;
}
}
@@ -298,22 +348,33 @@ namespace llvm {
case iPTRAny:
case iAny:
case fAny:
+ case vAny:
llvm_unreachable("Value type is overloaded.");
+ case Metadata:
+ llvm_unreachable("Value type is metadata.");
default:
llvm_unreachable("getSizeInBits called on extended MVT.");
case i1 : return 1;
- case i8 : return 8;
+ case v2i1: return 2;
+ case v4i1: return 4;
+ case i8 :
+ case v8i1: return 8;
case i16 :
case f16:
- case v2i8: return 16;
+ case v16i1:
+ case v2i8:
+ case v1i16: return 16;
case f32 :
case i32 :
+ case v32i1:
case v4i8:
case v2i16:
- case v2f16: return 32;
+ case v2f16:
+ case v1i32: return 32;
case x86mmx:
case f64 :
case i64 :
+ case v64i1:
case v8i8:
case v4i16:
case v2i32:
@@ -335,8 +396,12 @@ namespace llvm {
case v4i64:
case v8f32:
case v4f64: return 256;
+ case v64i8:
+ case v32i16:
case v16i32:
- case v8i64: return 512;
+ case v8i64:
+ case v16f32:
+ case v8f64: return 512;
case v16i64:return 1024;
}
}
@@ -353,6 +418,27 @@ namespace llvm {
return getStoreSize() * 8;
}
+ /// Return true if this has more bits than VT.
+ bool bitsGT(MVT VT) const {
+ return getSizeInBits() > VT.getSizeInBits();
+ }
+
+ /// Return true if this has no less bits than VT.
+ bool bitsGE(MVT VT) const {
+ return getSizeInBits() >= VT.getSizeInBits();
+ }
+
+ /// Return true if this has less bits than VT.
+ bool bitsLT(MVT VT) const {
+ return getSizeInBits() < VT.getSizeInBits();
+ }
+
+ /// Return true if this has no more bits than VT.
+ bool bitsLE(MVT VT) const {
+ return getSizeInBits() <= VT.getSizeInBits();
+ }
+
+
static MVT getFloatingPointVT(unsigned BitWidth) {
switch (BitWidth) {
default:
@@ -393,20 +479,32 @@ namespace llvm {
switch (VT.SimpleTy) {
default:
break;
+ case MVT::i1:
+ if (NumElements == 2) return MVT::v2i1;
+ if (NumElements == 4) return MVT::v4i1;
+ if (NumElements == 8) return MVT::v8i1;
+ if (NumElements == 16) return MVT::v16i1;
+ if (NumElements == 32) return MVT::v32i1;
+ if (NumElements == 64) return MVT::v64i1;
+ break;
case MVT::i8:
if (NumElements == 2) return MVT::v2i8;
if (NumElements == 4) return MVT::v4i8;
if (NumElements == 8) return MVT::v8i8;
if (NumElements == 16) return MVT::v16i8;
if (NumElements == 32) return MVT::v32i8;
+ if (NumElements == 64) return MVT::v64i8;
break;
case MVT::i16:
+ if (NumElements == 1) return MVT::v1i16;
if (NumElements == 2) return MVT::v2i16;
if (NumElements == 4) return MVT::v4i16;
if (NumElements == 8) return MVT::v8i16;
if (NumElements == 16) return MVT::v16i16;
+ if (NumElements == 32) return MVT::v32i16;
break;
case MVT::i32:
+ if (NumElements == 1) return MVT::v1i32;
if (NumElements == 2) return MVT::v2i32;
if (NumElements == 4) return MVT::v4i32;
if (NumElements == 8) return MVT::v8i32;
@@ -426,14 +524,22 @@ namespace llvm {
if (NumElements == 2) return MVT::v2f32;
if (NumElements == 4) return MVT::v4f32;
if (NumElements == 8) return MVT::v8f32;
+ if (NumElements == 16) return MVT::v16f32;
break;
case MVT::f64:
if (NumElements == 2) return MVT::v2f64;
if (NumElements == 4) return MVT::v4f64;
+ if (NumElements == 8) return MVT::v8f64;
break;
}
return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
}
+
+ /// Return the value type corresponding to the specified type. This returns
+ /// all pointers as iPTR. If HandleUnknown is true, unknown types are
+ /// returned as Other, otherwise they are invalid.
+ static MVT getVT(Type *Ty, bool HandleUnknown = false);
+
};
@@ -457,7 +563,7 @@ namespace llvm {
bool operator!=(EVT VT) const {
if (V.SimpleTy != VT.V.SimpleTy)
return true;
- if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
+ if (V.SimpleTy < 0)
return LLVMTy != VT.LLVMTy;
return false;
}
@@ -473,7 +579,7 @@ namespace llvm {
/// number of bits.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
MVT M = MVT::getIntegerVT(BitWidth);
- if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
+ if (M.SimpleTy >= 0)
return M;
return getExtendedIntegerVT(Context, BitWidth);
}
@@ -482,7 +588,7 @@ namespace llvm {
/// length, where each element is of type VT.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
MVT M = MVT::getVectorVT(VT.V, NumElements);
- if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
+ if (M.SimpleTy >= 0)
return M;
return getExtendedVectorVT(Context, VT, NumElements);
}
@@ -497,7 +603,7 @@ namespace llvm {
unsigned BitWidth = EltTy.getSizeInBits();
MVT IntTy = MVT::getIntegerVT(BitWidth);
MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements());
- assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
+ assert(VecTy.SimpleTy >= 0 &&
"Simple vector VT not representable by simple integer vector VT!");
return VecTy;
}
@@ -505,7 +611,7 @@ namespace llvm {
/// isSimple - Test if the given EVT is simple (as opposed to being
/// extended).
bool isSimple() const {
- return V.SimpleTy <= MVT::LastSimpleValueType;
+ return V.SimpleTy >= 0;
}
/// isExtended - Test if the given EVT is extended (as opposed to
@@ -529,6 +635,16 @@ namespace llvm {
return isSimple() ? V.isVector() : isExtendedVector();
}
+ /// is16BitVector - Return true if this is a 16-bit vector type.
+ bool is16BitVector() const {
+ return isSimple() ? V.is16BitVector() : isExtended16BitVector();
+ }
+
+ /// is32BitVector - Return true if this is a 32-bit vector type.
+ bool is32BitVector() const {
+ return isSimple() ? V.is32BitVector() : isExtended32BitVector();
+ }
+
/// is64BitVector - Return true if this is a 64-bit vector type.
bool is64BitVector() const {
return isSimple() ? V.is64BitVector() : isExtended64BitVector();
@@ -740,6 +856,8 @@ namespace llvm {
bool isExtendedFloatingPoint() const;
bool isExtendedInteger() const;
bool isExtendedVector() const;
+ bool isExtended16BitVector() const;
+ bool isExtended32BitVector() const;
bool isExtended64BitVector() const;
bool isExtended128BitVector() const;
bool isExtended256BitVector() const;
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
index f4b75bd..76df6ac 100644
--- a/include/llvm/CodeGen/ValueTypes.td
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -33,37 +33,49 @@ def f80 : ValueType<80 , 10>; // 80-bit floating point value
def f128 : ValueType<128, 11>; // 128-bit floating point value
def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value
-def v2i8 : ValueType<16 , 13>; // 2 x i8 vector value
-def v4i8 : ValueType<32 , 14>; // 4 x i8 vector value
-def v8i8 : ValueType<64 , 15>; // 8 x i8 vector value
-def v16i8 : ValueType<128, 16>; // 16 x i8 vector value
-def v32i8 : ValueType<256, 17>; // 32 x i8 vector value
-def v2i16 : ValueType<32 , 18>; // 2 x i16 vector value
-def v4i16 : ValueType<64 , 19>; // 4 x i16 vector value
-def v8i16 : ValueType<128, 20>; // 8 x i16 vector value
-def v16i16 : ValueType<256, 21>; // 16 x i16 vector value
-def v2i32 : ValueType<64 , 22>; // 2 x i32 vector value
-def v4i32 : ValueType<128, 23>; // 4 x i32 vector value
-def v8i32 : ValueType<256, 24>; // 8 x i32 vector value
-def v16i32 : ValueType<512, 25>; // 16 x i32 vector value
-def v1i64 : ValueType<64 , 26>; // 1 x i64 vector value
-def v2i64 : ValueType<128, 27>; // 2 x i64 vector value
-def v4i64 : ValueType<256, 28>; // 4 x i64 vector value
-def v8i64 : ValueType<512, 29>; // 8 x i64 vector value
-def v16i64 : ValueType<1024,30>; // 16 x i64 vector value
+def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value
+def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value
+def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value
+def v16i1 : ValueType<16, 16>; // 16 x i1 vector value
+def v32i1 : ValueType<32 , 17>; // 32 x i1 vector value
+def v64i1 : ValueType<64 , 18>; // 64 x i1 vector value
+def v2i8 : ValueType<16 , 19>; // 2 x i8 vector value
+def v4i8 : ValueType<32 , 20>; // 4 x i8 vector value
+def v8i8 : ValueType<64 , 21>; // 8 x i8 vector value
+def v16i8 : ValueType<128, 22>; // 16 x i8 vector value
+def v32i8 : ValueType<256, 23>; // 32 x i8 vector value
+def v64i8 : ValueType<256, 24>; // 64 x i8 vector value
+def v1i16 : ValueType<16 , 25>; // 1 x i16 vector value
+def v2i16 : ValueType<32 , 26>; // 2 x i16 vector value
+def v4i16 : ValueType<64 , 27>; // 4 x i16 vector value
+def v8i16 : ValueType<128, 28>; // 8 x i16 vector value
+def v16i16 : ValueType<256, 29>; // 16 x i16 vector value
+def v32i16 : ValueType<256, 30>; // 32 x i16 vector value
+def v1i32 : ValueType<32 , 31>; // 1 x i32 vector value
+def v2i32 : ValueType<64 , 32>; // 2 x i32 vector value
+def v4i32 : ValueType<128, 33>; // 4 x i32 vector value
+def v8i32 : ValueType<256, 34>; // 8 x i32 vector value
+def v16i32 : ValueType<512, 35>; // 16 x i32 vector value
+def v1i64 : ValueType<64 , 36>; // 1 x i64 vector value
+def v2i64 : ValueType<128, 37>; // 2 x i64 vector value
+def v4i64 : ValueType<256, 38>; // 4 x i64 vector value
+def v8i64 : ValueType<512, 39>; // 8 x i64 vector value
+def v16i64 : ValueType<1024,40>; // 16 x i64 vector value
-def v2f16 : ValueType<32 , 31>; // 2 x f16 vector value
-def v2f32 : ValueType<64 , 32>; // 2 x f32 vector value
-def v4f32 : ValueType<128, 33>; // 4 x f32 vector value
-def v8f32 : ValueType<256, 34>; // 8 x f32 vector value
-def v2f64 : ValueType<128, 35>; // 2 x f64 vector value
-def v4f64 : ValueType<256, 36>; // 4 x f64 vector value
+def v2f16 : ValueType<32 , 41>; // 2 x f16 vector value
+def v2f32 : ValueType<64 , 42>; // 2 x f32 vector value
+def v4f32 : ValueType<128, 43>; // 4 x f32 vector value
+def v8f32 : ValueType<256, 44>; // 8 x f32 vector value
+def v16f32 : ValueType<512, 45>; // 16 x f32 vector value
+def v2f64 : ValueType<128, 46>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 47>; // 4 x f64 vector value
+def v8f64 : ValueType<512, 48>; // 8 x f64 vector value
-def x86mmx : ValueType<64 , 37>; // X86 MMX value
-def FlagVT : ValueType<0 , 38>; // Pre-RA sched glue
-def isVoid : ValueType<0 , 39>; // Produces no value
-def untyped: ValueType<8 , 40>; // Produces an untyped value
+def x86mmx : ValueType<64 , 49>; // X86 MMX value
+def FlagVT : ValueType<0 , 50>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 51>; // Produces no value
+def untyped: ValueType<8 , 52>; // Produces an untyped value
def MetadataVT: ValueType<0, 250>; // Metadata
// Pseudo valuetype mapped to the current pointer size to any address space.
diff --git a/include/llvm/CodeGen/VirtRegMap.h b/include/llvm/CodeGen/VirtRegMap.h
new file mode 100644
index 0000000..3bc6ebd
--- /dev/null
+++ b/include/llvm/CodeGen/VirtRegMap.h
@@ -0,0 +1,190 @@
+//===-- llvm/CodeGen/VirtRegMap.h - Virtual Register Map -*- C++ -*--------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a virtual register map. This maps virtual registers to
+// physical registers and virtual registers to stack slots. It is created and
+// updated by a register allocator and then used by a machine code rewriter that
+// adds spill code and rewrites virtual into physical register references.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_VIRTREGMAP_H
+#define LLVM_CODEGEN_VIRTREGMAP_H
+
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+ class MachineInstr;
+ class MachineFunction;
+ class MachineRegisterInfo;
+ class TargetInstrInfo;
+ class raw_ostream;
+ class SlotIndexes;
+
+ class VirtRegMap : public MachineFunctionPass {
+ public:
+ enum {
+ NO_PHYS_REG = 0,
+ NO_STACK_SLOT = (1L << 30)-1,
+ MAX_STACK_SLOT = (1L << 18)-1
+ };
+
+ private:
+ MachineRegisterInfo *MRI;
+ const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
+ MachineFunction *MF;
+
+ /// Virt2PhysMap - This is a virtual to physical register
+ /// mapping. Each virtual register is required to have an entry in
+ /// it; even spilled virtual registers (the register mapped to a
+ /// spilled register is the temporary used to load it from the
+ /// stack).
+ IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap;
+
+ /// Virt2StackSlotMap - This is virtual register to stack slot
+ /// mapping. Each spilled virtual register has an entry in it
+ /// which corresponds to the stack slot this register is spilled
+ /// at.
+ IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
+
+ /// Virt2SplitMap - This is virtual register to splitted virtual register
+ /// mapping.
+ IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap;
+
+ /// createSpillSlot - Allocate a spill slot for RC from MFI.
+ unsigned createSpillSlot(const TargetRegisterClass *RC);
+
+ VirtRegMap(const VirtRegMap&) LLVM_DELETED_FUNCTION;
+ void operator=(const VirtRegMap&) LLVM_DELETED_FUNCTION;
+
+ public:
+ static char ID;
+ VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG),
+ Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) { }
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ MachineFunction &getMachineFunction() const {
+ assert(MF && "getMachineFunction called before runOnMachineFunction");
+ return *MF;
+ }
+
+ MachineRegisterInfo &getRegInfo() const { return *MRI; }
+ const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
+
+ void grow();
+
+ /// @brief returns true if the specified virtual register is
+ /// mapped to a physical register
+ bool hasPhys(unsigned virtReg) const {
+ return getPhys(virtReg) != NO_PHYS_REG;
+ }
+
+ /// @brief returns the physical register mapped to the specified
+ /// virtual register
+ unsigned getPhys(unsigned virtReg) const {
+ assert(TargetRegisterInfo::isVirtualRegister(virtReg));
+ return Virt2PhysMap[virtReg];
+ }
+
+ /// @brief creates a mapping for the specified virtual register to
+ /// the specified physical register
+ void assignVirt2Phys(unsigned virtReg, unsigned physReg) {
+ assert(TargetRegisterInfo::isVirtualRegister(virtReg) &&
+ TargetRegisterInfo::isPhysicalRegister(physReg));
+ assert(Virt2PhysMap[virtReg] == NO_PHYS_REG &&
+ "attempt to assign physical register to already mapped "
+ "virtual register");
+ Virt2PhysMap[virtReg] = physReg;
+ }
+
+ /// @brief clears the specified virtual register's, physical
+ /// register mapping
+ void clearVirt(unsigned virtReg) {
+ assert(TargetRegisterInfo::isVirtualRegister(virtReg));
+ assert(Virt2PhysMap[virtReg] != NO_PHYS_REG &&
+ "attempt to clear a not assigned virtual register");
+ Virt2PhysMap[virtReg] = NO_PHYS_REG;
+ }
+
+ /// @brief clears all virtual to physical register mappings
+ void clearAllVirt() {
+ Virt2PhysMap.clear();
+ grow();
+ }
+
+ /// @brief returns true if VirtReg is assigned to its preferred physreg.
+ bool hasPreferredPhys(unsigned VirtReg);
+
+ /// @brief returns true if VirtReg has a known preferred register.
+ /// This returns false if VirtReg has a preference that is a virtual
+ /// register that hasn't been assigned yet.
+ bool hasKnownPreference(unsigned VirtReg);
+
+ /// @brief records virtReg is a split live interval from SReg.
+ void setIsSplitFromReg(unsigned virtReg, unsigned SReg) {
+ Virt2SplitMap[virtReg] = SReg;
+ }
+
+ /// @brief returns the live interval virtReg is split from.
+ unsigned getPreSplitReg(unsigned virtReg) const {
+ return Virt2SplitMap[virtReg];
+ }
+
+ /// getOriginal - Return the original virtual register that VirtReg descends
+ /// from through splitting.
+ /// A register that was not created by splitting is its own original.
+ /// This operation is idempotent.
+ unsigned getOriginal(unsigned VirtReg) const {
+ unsigned Orig = getPreSplitReg(VirtReg);
+ return Orig ? Orig : VirtReg;
+ }
+
+ /// @brief returns true if the specified virtual register is not
+ /// mapped to a stack slot or rematerialized.
+ bool isAssignedReg(unsigned virtReg) const {
+ if (getStackSlot(virtReg) == NO_STACK_SLOT)
+ return true;
+ // Split register can be assigned a physical register as well as a
+ // stack slot or remat id.
+ return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG);
+ }
+
+ /// @brief returns the stack slot mapped to the specified virtual
+ /// register
+ int getStackSlot(unsigned virtReg) const {
+ assert(TargetRegisterInfo::isVirtualRegister(virtReg));
+ return Virt2StackSlotMap[virtReg];
+ }
+
+ /// @brief create a mapping for the specifed virtual register to
+ /// the next available stack slot
+ int assignVirt2StackSlot(unsigned virtReg);
+ /// @brief create a mapping for the specified virtual register to
+ /// the specified stack slot
+ void assignVirt2StackSlot(unsigned virtReg, int frameIndex);
+
+ void print(raw_ostream &OS, const Module* M = 0) const;
+ void dump() const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
+ VRM.print(OS);
+ return OS;
+ }
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index eb20b64..ff765cc 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -1,6 +1,4 @@
-/**************************************
-** Created by Kevin from config.h.in **
-***************************************/
+/* include/llvm/Config/config.h.cmake corresponding to config.h.in. */
#ifndef CONFIG_H
#define CONFIG_H
@@ -8,6 +6,9 @@
/* Bug report URL. */
#define BUG_REPORT_URL "${BUG_REPORT_URL}"
+/* Define if we have libxml2 */
+#cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
+
/* Relative directory for resource files */
#define CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}"
@@ -17,6 +18,9 @@
/* Default <path> to all compiler invocations for --sysroot=<path>. */
#undef DEFAULT_SYSROOT
+/* Define if you want backtraces on crash */
+#cmakedefine ENABLE_BACKTRACES
+
/* Define if position independent code is enabled */
#cmakedefine ENABLE_PIC
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 5a60ba5..a4f8af4 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -18,6 +18,9 @@
/* Default <path> to all compiler invocations for --sysroot=<path>. */
#undef DEFAULT_SYSROOT
+/* Define if you want backtraces on crash */
+#undef ENABLE_BACKTRACES
+
/* Define if position independent code is enabled */
#undef ENABLE_PIC
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index 3944292..fbc3040 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -112,6 +112,12 @@
/* Installation prefix directory */
#cmakedefine LLVM_PREFIX "${LLVM_PREFIX}"
+/* Define if we have the Intel JIT API runtime support library */
+#cmakedefine LLVM_USE_INTEL_JITEVENTS 1
+
+/* Define if we have the oprofile JIT-support library */
+#cmakedefine LLVM_USE_OPROFILE 1
+
/* Major version of the LLVM API */
#cmakedefine LLVM_VERSION_MAJOR ${LLVM_VERSION_MAJOR}
diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in
index 9489dfe..af3a324 100644
--- a/include/llvm/Config/llvm-config.h.in
+++ b/include/llvm/Config/llvm-config.h.in
@@ -112,6 +112,12 @@
/* Installation prefix directory */
#undef LLVM_PREFIX
+/* Define if we have the Intel JIT API runtime support library */
+#undef LLVM_USE_INTEL_JITEVENTS
+
+/* Define if we have the oprofile JIT-support library */
+#undef LLVM_USE_OPROFILE
+
/* Major version of the LLVM API */
#undef LLVM_VERSION_MAJOR
diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h
index dd4ea96..0a59cdd 100644
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
@@ -15,9 +15,9 @@
#ifndef LLVM_ANALYSIS_DIBUILDER_H
#define LLVM_ANALYSIS_DIBUILDER_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class BasicBlock;
@@ -63,8 +63,8 @@ namespace llvm {
SmallVector<Value *, 4> AllSubprograms;
SmallVector<Value *, 4> AllGVs;
- DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT
- void operator=(const DIBuilder &); // DO NOT IMPLEMENT
+ DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION;
+ void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION;
public:
explicit DIBuilder(Module &M);
@@ -126,6 +126,11 @@ namespace llvm {
uint64_t AlignInBits = 0,
StringRef Name = StringRef());
+ /// \brief Create debugging information entry for a pointer to member.
+ /// @param PointeeTy Type pointed to by this pointer.
+ /// @param Class Type for which this pointer points to members of.
+ DIType createMemberPointerType(DIType PointeeTy, DIType Class);
+
/// createReferenceType - Create debugging information entry for a c++
/// style reference or rvalue reference type.
DIType createReferenceType(unsigned Tag, DIType RTy);
@@ -331,12 +336,10 @@ namespace llvm {
/// @param SizeInBits Member size.
/// @param AlignInBits Member alignment.
/// @param Elements Enumeration elements.
- /// @param Flags Flags (e.g. forward decl)
DIType createEnumerationType(DIDescriptor Scope, StringRef Name,
DIFile File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
- DIArray Elements, DIType ClassType,
- unsigned Flags);
+ DIArray Elements, DIType ClassType);
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
@@ -347,13 +350,18 @@ namespace llvm {
/// createArtificialType - Create a new DIType with "artificial" flag set.
DIType createArtificialType(DIType Ty);
+ /// createObjectPointerType - Create a new DIType with the "object pointer"
+ /// flag set.
+ DIType createObjectPointerType(DIType Ty);
+
/// createTemporaryType - Create a temporary forward-declared type.
DIType createTemporaryType();
DIType createTemporaryType(DIFile F);
/// createForwardDecl - Create a temporary forward-declared type.
DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
- DIFile F, unsigned Line, unsigned RuntimeLang = 0);
+ DIFile F, unsigned Line, unsigned RuntimeLang = 0,
+ uint64_t SizeInBits = 0, uint64_t AlignInBits = 0);
/// retainType - Retain DIType in a module even if it is not referenced
/// through debug info anchors.
@@ -368,7 +376,7 @@ namespace llvm {
/// getOrCreateSubrange - Create a descriptor for a value range. This
/// implicitly uniques the values returned.
- DISubrange getOrCreateSubrange(int64_t Lo, int64_t Hi);
+ DISubrange getOrCreateSubrange(int64_t Lo, int64_t Count);
/// createGlobalVariable - Create a new descriptor for the specified global.
/// @param Name Name of the variable.
diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h
index 618220f..cc1c6a0 100644
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
@@ -17,8 +17,8 @@
#ifndef LLVM_ANALYSIS_DEBUGINFO_H
#define LLVM_ANALYSIS_DEBUGINFO_H
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Dwarf.h"
@@ -60,7 +60,9 @@ namespace llvm {
FlagArtificial = 1 << 6,
FlagExplicit = 1 << 7,
FlagPrototyped = 1 << 8,
- FlagObjcClassComplete = 1 << 9
+ FlagObjcClassComplete = 1 << 9,
+ FlagObjectPointer = 1 << 10,
+ FlagVector = 1 << 11
};
protected:
const MDNode *DbgNode;
@@ -70,6 +72,7 @@ namespace llvm {
return (unsigned)getUInt64Field(Elt);
}
uint64_t getUInt64Field(unsigned Elt) const;
+ int64_t getInt64Field(unsigned Elt) const;
DIDescriptor getDescriptorField(unsigned Elt) const;
template <typename DescTy>
@@ -80,6 +83,7 @@ namespace llvm {
GlobalVariable *getGlobalVariableField(unsigned Elt) const;
Constant *getConstantField(unsigned Elt) const;
Function *getFunctionField(unsigned Elt) const;
+ void replaceFunctionField(unsigned Elt, Function *F);
public:
explicit DIDescriptor() : DbgNode(0) {}
@@ -139,8 +143,8 @@ namespace llvm {
public:
explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
- uint64_t getLo() const { return getUInt64Field(1); }
- uint64_t getHi() const { return getUInt64Field(2); }
+ int64_t getLo() const { return getInt64Field(1); }
+ int64_t getCount() const { return getInt64Field(2); }
};
/// DIArray - This descriptor holds an array of descriptors.
@@ -213,9 +217,9 @@ namespace llvm {
}
StringRef getFilename() const { return getStringField(1); }
StringRef getDirectory() const { return getStringField(2); }
- DICompileUnit getCompileUnit() const{
+ DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!");
- return getFieldAs<DICompileUnit>(3);
+ return getFieldAs<DICompileUnit>(3);
}
};
@@ -250,11 +254,11 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
- DICompileUnit getCompileUnit() const{
+ DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
-
+
return getFieldAs<DIFile>(3).getCompileUnit();
}
DIFile getFile() const { return getFieldAs<DIFile>(3); }
@@ -287,19 +291,25 @@ namespace llvm {
bool isArtificial() const {
return (getFlags() & FlagArtificial) != 0;
}
+ bool isObjectPointer() const {
+ return (getFlags() & FlagObjectPointer) != 0;
+ }
bool isObjcClassComplete() const {
return (getFlags() & FlagObjcClassComplete) != 0;
}
+ bool isVector() const {
+ return (getFlags() & FlagVector) != 0;
+ }
bool isValid() const {
return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
}
- StringRef getDirectory() const {
+ StringRef getDirectory() const {
if (getVersion() == llvm::LLVMDebugVersion7)
return getCompileUnit().getDirectory();
return getFieldAs<DIFile>(3).getDirectory();
}
- StringRef getFilename() const {
+ StringRef getFilename() const {
if (getVersion() == llvm::LLVMDebugVersion7)
return getCompileUnit().getFilename();
@@ -344,14 +354,19 @@ namespace llvm {
/// return base type size.
uint64_t getOriginalTypeSize() const;
- /// getObjCProperty - Return property node, if this ivar is
+ /// getObjCProperty - Return property node, if this ivar is
/// associated with one.
MDNode *getObjCProperty() const;
- StringRef getObjCPropertyName() const {
+ DIType getClassType() const {
+ assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
+ return getFieldAs<DIType>(10);
+ }
+
+ StringRef getObjCPropertyName() const {
if (getVersion() > LLVMDebugVersion11)
return StringRef();
- return getStringField(10);
+ return getStringField(10);
}
StringRef getObjCPropertyGetterName() const {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
@@ -422,10 +437,10 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DIType getType() const { return getFieldAs<DIType>(3); }
- StringRef getFilename() const {
+ StringRef getFilename() const {
return getFieldAs<DIFile>(4).getFilename();
}
- StringRef getDirectory() const {
+ StringRef getDirectory() const {
return getFieldAs<DIFile>(4).getDirectory();
}
unsigned getLineNumber() const { return getUnsignedField(5); }
@@ -441,10 +456,10 @@ namespace llvm {
StringRef getName() const { return getStringField(2); }
DIType getType() const { return getFieldAs<DIType>(3); }
uint64_t getValue() const { return getUInt64Field(4); }
- StringRef getFilename() const {
+ StringRef getFilename() const {
return getFieldAs<DIFile>(5).getFilename();
}
- StringRef getDirectory() const {
+ StringRef getDirectory() const {
return getFieldAs<DIFile>(5).getDirectory();
}
unsigned getLineNumber() const { return getUnsignedField(6); }
@@ -462,12 +477,12 @@ namespace llvm {
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
- DICompileUnit getCompileUnit() const{
+ DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
- return getFieldAs<DIFile>(6).getCompileUnit();
+ return getFieldAs<DIFile>(6).getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(7); }
DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
@@ -497,33 +512,33 @@ namespace llvm {
return getFieldAs<DICompositeType>(13);
}
- unsigned isArtificial() const {
+ unsigned isArtificial() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
- return getUnsignedField(14);
+ return getUnsignedField(14);
return (getUnsignedField(14) & FlagArtificial) != 0;
}
/// isPrivate - Return true if this subprogram has "private"
/// access specifier.
- bool isPrivate() const {
+ bool isPrivate() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return false;
return (getUnsignedField(14) & FlagPrivate) != 0;
}
/// isProtected - Return true if this subprogram has "protected"
/// access specifier.
- bool isProtected() const {
+ bool isProtected() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return false;
return (getUnsignedField(14) & FlagProtected) != 0;
}
/// isExplicit - Return true if this subprogram is marked as explicit.
- bool isExplicit() const {
+ bool isExplicit() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return false;
return (getUnsignedField(14) & FlagExplicit) != 0;
}
/// isPrototyped - Return true if this subprogram is prototyped.
- bool isPrototyped() const {
+ bool isPrototyped() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return false;
return (getUnsignedField(14) & FlagPrototyped) != 0;
@@ -531,18 +546,18 @@ namespace llvm {
unsigned isOptimized() const;
- StringRef getFilename() const {
+ StringRef getFilename() const {
if (getVersion() == llvm::LLVMDebugVersion7)
return getCompileUnit().getFilename();
- return getFieldAs<DIFile>(6).getFilename();
+ return getFieldAs<DIFile>(6).getFilename();
}
- StringRef getDirectory() const {
+ StringRef getDirectory() const {
if (getVersion() == llvm::LLVMDebugVersion7)
return getCompileUnit().getFilename();
- return getFieldAs<DIFile>(6).getDirectory();
+ return getFieldAs<DIFile>(6).getDirectory();
}
/// getScopeLineNumber - Get the beginning of the scope of the
@@ -558,6 +573,7 @@ namespace llvm {
bool describes(const Function *F);
Function *getFunction() const { return getFunctionField(16); }
+ void replaceFunction(Function *F) { replaceFunctionField(16, F); }
DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
DISubprogram getFunctionDeclaration() const {
return getFieldAs<DISubprogram>(18);
@@ -577,25 +593,25 @@ namespace llvm {
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
- DICompileUnit getCompileUnit() const{
+ DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
- DIFile F = getFieldAs<DIFile>(6);
+ DIFile F = getFieldAs<DIFile>(6);
return F.getCompileUnit();
}
StringRef getFilename() const {
if (getVersion() <= llvm::LLVMDebugVersion10)
return getContext().getFilename();
return getFieldAs<DIFile>(6).getFilename();
- }
+ }
StringRef getDirectory() const {
if (getVersion() <= llvm::LLVMDebugVersion10)
return getContext().getDirectory();
return getFieldAs<DIFile>(6).getDirectory();
- }
+ }
unsigned getLineNumber() const { return getUnsignedField(7); }
DIType getType() const { return getFieldAs<DIType>(8); }
@@ -620,30 +636,35 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
- DICompileUnit getCompileUnit() const {
+ DICompileUnit getCompileUnit() const {
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
- DIFile F = getFieldAs<DIFile>(3);
+ DIFile F = getFieldAs<DIFile>(3);
return F.getCompileUnit();
}
- unsigned getLineNumber() const {
- return (getUnsignedField(4) << 8) >> 8;
+ DIFile getFile() const { return getFieldAs<DIFile>(3); }
+ unsigned getLineNumber() const {
+ return (getUnsignedField(4) << 8) >> 8;
}
unsigned getArgNumber() const {
- unsigned L = getUnsignedField(4);
+ unsigned L = getUnsignedField(4);
return L >> 24;
}
DIType getType() const { return getFieldAs<DIType>(5); }
-
+
/// isArtificial - Return true if this variable is marked as "artificial".
- bool isArtificial() const {
+ bool isArtificial() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return false;
return (getUnsignedField(6) & FlagArtificial) != 0;
}
+ bool isObjectPointer() const {
+ return (getUnsignedField(6) & FlagObjectPointer) != 0;
+ }
+
/// getInlinedAt - If this variable is inlined then return inline location.
MDNode *getInlinedAt() const;
@@ -656,7 +677,7 @@ namespace llvm {
}
unsigned getNumAddrElements() const;
-
+
uint64_t getAddrElement(unsigned Idx) const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return getUInt64Field(Idx+6);
@@ -716,23 +737,23 @@ namespace llvm {
};
/// DINameSpace - A wrapper for a C++ style name space.
- class DINameSpace : public DIScope {
+ class DINameSpace : public DIScope {
public:
explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
- StringRef getDirectory() const {
+ StringRef getDirectory() const {
return getFieldAs<DIFile>(3).getDirectory();
}
- StringRef getFilename() const {
+ StringRef getFilename() const {
return getFieldAs<DIFile>(3).getFilename();
}
- DICompileUnit getCompileUnit() const{
+ DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
- return getFieldAs<DIFile>(3).getCompileUnit();
+ return getFieldAs<DIFile>(3).getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(4); }
bool Verify() const;
@@ -808,7 +829,7 @@ namespace llvm {
/// to hold function specific information.
NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
- /// getFnSpecificMDNode - Return a NameMDNode, if available, that is
+ /// getFnSpecificMDNode - Return a NameMDNode, if available, that is
/// suitable to hold function specific information.
NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
@@ -826,7 +847,7 @@ namespace llvm {
public:
/// processModule - Process entire module and collect debug info
/// anchors.
- void processModule(Module &M);
+ void processModule(const Module &M);
private:
/// processType - Process DIType.
@@ -839,7 +860,7 @@ namespace llvm {
void processSubprogram(DISubprogram SP);
/// processDeclare - Process DbgDeclareInst.
- void processDeclare(DbgDeclareInst *DDI);
+ void processDeclare(const DbgDeclareInst *DDI);
/// processLocation - Process DILocation.
void processLocation(DILocation Loc);
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index 8d6054a..5ebf4b0 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -15,9 +15,12 @@
#ifndef LLVM_DEBUGINFO_DICONTEXT_H
#define LLVM_DEBUGINFO_DICONTEXT_H
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/RelocVisitor.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -89,18 +92,19 @@ public:
}
};
+// In place of applying the relocations to the data we've read from disk we use
+// a separate mapping table to the side and checking that at locations in the
+// dwarf where we expect relocated values. This adds a bit of complexity to the
+// dwarf parsing/extraction at the benefit of not allocating memory for the
+// entire size of the debug info sections.
+typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
+
class DIContext {
public:
virtual ~DIContext();
/// getDWARFContext - get a context for binary DWARF data.
- static DIContext *getDWARFContext(bool isLittleEndian,
- StringRef infoSection,
- StringRef abbrevSection,
- StringRef aRangeSection = StringRef(),
- StringRef lineSection = StringRef(),
- StringRef stringSection = StringRef(),
- StringRef rangeSection = StringRef());
+ static DIContext *getDWARFContext(object::ObjectFile *);
virtual void dump(raw_ostream &OS) = 0;
diff --git a/include/llvm/DefaultPasses.h b/include/llvm/DefaultPasses.h
deleted file mode 100644
index 929569d..0000000
--- a/include/llvm/DefaultPasses.h
+++ /dev/null
@@ -1,168 +0,0 @@
-//===- llvm/DefaultPasses.h - Default Pass Support code --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// This file defines the infrastructure for registering the standard pass list.
-// This defines sets of standard optimizations that plugins can modify and
-// front ends can use.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEFAULT_PASS_SUPPORT_H
-#define LLVM_DEFAULT_PASS_SUPPORT_H
-
-#include <llvm/PassSupport.h>
-
-namespace llvm {
-
-class PassManagerBase;
-
-/// Unique identifiers for the default standard passes. The addresses of
-/// these symbols are used to uniquely identify passes from the default list.
-namespace DefaultStandardPasses {
-extern unsigned char AggressiveDCEID;
-extern unsigned char ArgumentPromotionID;
-extern unsigned char BasicAliasAnalysisID;
-extern unsigned char CFGSimplificationID;
-extern unsigned char ConstantMergeID;
-extern unsigned char CorrelatedValuePropagationID;
-extern unsigned char DeadArgEliminationID;
-extern unsigned char DeadStoreEliminationID;
-extern unsigned char EarlyCSEID;
-extern unsigned char FunctionAttrsID;
-extern unsigned char FunctionInliningID;
-extern unsigned char GVNID;
-extern unsigned char GlobalDCEID;
-extern unsigned char GlobalOptimizerID;
-extern unsigned char GlobalsModRefID;
-extern unsigned char IPSCCPID;
-extern unsigned char IndVarSimplifyID;
-extern unsigned char InlinerPlaceholderID;
-extern unsigned char InstructionCombiningID;
-extern unsigned char JumpThreadingID;
-extern unsigned char LICMID;
-extern unsigned char LoopDeletionID;
-extern unsigned char LoopIdiomID;
-extern unsigned char LoopRotateID;
-extern unsigned char LoopUnrollID;
-extern unsigned char LoopUnswitchID;
-extern unsigned char MemCpyOptID;
-extern unsigned char PruneEHID;
-extern unsigned char ReassociateID;
-extern unsigned char SCCPID;
-extern unsigned char ScalarReplAggregatesID;
-extern unsigned char SimplifyLibCallsID;
-extern unsigned char StripDeadPrototypesID;
-extern unsigned char TailCallEliminationID;
-extern unsigned char TypeBasedAliasAnalysisID;
-}
-
-/// StandardPass - The class responsible for maintaining the lists of standard
-class StandardPass {
- friend class RegisterStandardPassLists;
- public:
- /// Predefined standard sets of passes
- enum StandardSet {
- AliasAnalysis,
- Function,
- Module,
- LTO
- };
- /// Flags to specify whether a pass should be enabled. Passes registered
- /// with the standard sets may specify a minimum optimization level and one
- /// or more flags that must be set when constructing the set for the pass to
- /// be used.
- enum OptimizationFlags {
- /// Optimize for size was requested.
- OptimizeSize = 1<<0,
- /// Allow passes which may make global module changes.
- UnitAtATime = 1<<1,
- /// UnrollLoops - Allow loop unrolling.
- UnrollLoops = 1<<2,
- /// Allow library calls to be simplified.
- SimplifyLibCalls = 1<<3,
- /// Whether the module may have code using exceptions.
- HaveExceptions = 1<<4,
- // Run an inliner pass as part of this set.
- RunInliner = 1<<5
- };
- enum OptimizationFlagComponents {
- /// The low bits are used to store the optimization level. When requesting
- /// passes, this should store the requested optimisation level. When
- /// setting passes, this should set the minimum optimization level at which
- /// the pass will run.
- OptimizationLevelMask=0xf,
- /// The maximum optimisation level at which the pass is run.
- MaxOptimizationLevelMask=0xf0,
- // Flags that must be set
- RequiredFlagMask=0xff00,
- // Flags that may not be set.
- DisallowedFlagMask=0xff0000,
- MaxOptimizationLevelShift=4,
- RequiredFlagShift=8,
- DisallowedFlagShift=16
- };
- /// Returns the optimisation level from a set of flags.
- static unsigned OptimizationLevel(unsigned flags) {
- return flags & OptimizationLevelMask;
- }
- /// Returns the maximum optimization level for this set of flags
- static unsigned MaxOptimizationLevel(unsigned flags) {
- return (flags & MaxOptimizationLevelMask) >> 4;
- }
- /// Constructs a set of flags from the specified minimum and maximum
- /// optimisation level
- static unsigned OptimzationFlags(unsigned minLevel=0, unsigned maxLevel=0xf,
- unsigned requiredFlags=0, unsigned disallowedFlags=0) {
- return ((minLevel & OptimizationLevelMask) |
- ((maxLevel<<MaxOptimizationLevelShift) & MaxOptimizationLevelMask)
- | ((requiredFlags<<RequiredFlagShift) & RequiredFlagMask)
- | ((disallowedFlags<<DisallowedFlagShift) & DisallowedFlagMask));
- }
- /// Returns the flags that must be set for this to match
- static unsigned RequiredFlags(unsigned flags) {
- return (flags & RequiredFlagMask) >> RequiredFlagShift;
- }
- /// Returns the flags that must not be set for this to match
- static unsigned DisallowedFlags(unsigned flags) {
- return (flags & DisallowedFlagMask) >> DisallowedFlagShift;
- }
- /// Register a standard pass in the specified set. If flags is non-zero,
- /// then the pass will only be returned when the specified flags are set.
- template<typename passName>
- class RegisterStandardPass {
- public:
- RegisterStandardPass(StandardSet set, unsigned char *runBefore=0,
- unsigned flags=0, unsigned char *ID=0) {
- // Use the pass's ID if one is not specified
- RegisterDefaultPass(PassInfo::NormalCtor_t(callDefaultCtor<passName>),
- ID ? ID : (unsigned char*)&passName::ID, runBefore, set, flags);
- }
- };
- /// Adds the passes from the specified set to the provided pass manager
- static void AddPassesFromSet(PassManagerBase *PM,
- StandardSet set,
- unsigned flags=0,
- bool VerifyEach=false,
- Pass *inliner=0);
- private:
- /// Registers the default passes. This is set by RegisterStandardPassLists
- /// and is called lazily.
- static void (*RegisterDefaultPasses)(void);
- /// Creates the verifier pass that is inserted when a VerifyEach is passed to
- /// AddPassesFromSet()
- static Pass* (*CreateVerifierPass)(void);
- /// Registers the pass
- static void RegisterDefaultPass(PassInfo::NormalCtor_t constructor,
- unsigned char *newPass,
- unsigned char *oldPass,
- StandardSet set,
- unsigned flags=0);
-};
-
-} // namespace llvm
-
-#endif
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index ae8b68d..2d60c36 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -15,19 +15,19 @@
#ifndef LLVM_EXECUTION_ENGINE_H
#define LLVM_EXECUTION_ENGINE_H
-#include "llvm/MC/MCCodeGenInfo.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Mutex.h"
+#include "llvm/Support/ValueHandle.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include <vector>
#include <map>
#include <string>
+#include <vector>
namespace llvm {
@@ -42,7 +42,7 @@ class JITMemoryManager;
class MachineCodeInfo;
class Module;
class MutexGuard;
-class TargetData;
+class DataLayout;
class Triple;
class Type;
@@ -88,7 +88,7 @@ public:
/// \brief Erase an entry from the mapping table.
///
- /// \returns The address that \arg ToUnmap was happed to.
+ /// \returns The address that \p ToUnmap was happed to.
void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap);
};
@@ -104,7 +104,7 @@ class ExecutionEngine {
ExecutionEngineState EEState;
/// The target data for the platform for which execution is being performed.
- const TargetData *TD;
+ const DataLayout *TD;
/// Whether lazy JIT compilation is enabled.
bool CompilingLazily;
@@ -123,7 +123,7 @@ protected:
/// optimize for the case where there is only one module.
SmallVector<Module*, 1> Modules;
- void setTargetData(const TargetData *td) { TD = td; }
+ void setDataLayout(const DataLayout *td) { TD = td; }
/// getMemoryforGV - Allocate memory for a global variable.
virtual char *getMemoryForGV(const GlobalVariable *GV);
@@ -213,7 +213,7 @@ public:
//===--------------------------------------------------------------------===//
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
/// removeModule - Remove a Module from the list of modules. Returns true if
/// M is found.
@@ -244,11 +244,18 @@ public:
/// Map the address of a JIT section as returned from the memory manager
/// to the address in the target process as the running code will see it.
/// This is the address which will be used for relocation resolution.
- virtual void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress) {
+ virtual void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) {
llvm_unreachable("Re-mapping of section addresses not supported with this "
"EE!");
}
+ // finalizeObject - This method should be called after sections within an
+ // object have been relocated using mapSectionAddress. When this method is
+ // called the MCJIT execution engine will reapply relocations for a loaded
+ // object. This method has no effect for the legacy JIT engine or the
+ // interpeter.
+ virtual void finalizeObject() {}
+
/// runStaticConstructorsDestructors - This method is used to execute all of
/// the static constructors or destructors for a program.
///
diff --git a/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h b/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h
deleted file mode 100644
index ca87342..0000000
--- a/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h
+++ /dev/null
@@ -1,102 +0,0 @@
-//===-- IntelJITEventsWrapper.h - Intel JIT Events API Wrapper --*- 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 wrapper for the Intel JIT Events API. It allows for the
-// implementation of the jitprofiling library to be swapped with an alternative
-// implementation (for testing). To include this file, you must have the
-// jitprofiling.h header available; it is available in Intel(R) VTune(TM)
-// Amplifier XE 2011.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef INTEL_JIT_EVENTS_WRAPPER_H
-#define INTEL_JIT_EVENTS_WRAPPER_H
-
-#include <jitprofiling.h>
-
-namespace llvm {
-
-class IntelJITEventsWrapper {
- // Function pointer types for testing implementation of Intel jitprofiling
- // library
- typedef int (*NotifyEventPtr)(iJIT_JVM_EVENT, void*);
- typedef void (*RegisterCallbackExPtr)(void *, iJIT_ModeChangedEx );
- typedef iJIT_IsProfilingActiveFlags (*IsProfilingActivePtr)(void);
- typedef void (*FinalizeThreadPtr)(void);
- typedef void (*FinalizeProcessPtr)(void);
- typedef unsigned int (*GetNewMethodIDPtr)(void);
-
- NotifyEventPtr NotifyEventFunc;
- RegisterCallbackExPtr RegisterCallbackExFunc;
- IsProfilingActivePtr IsProfilingActiveFunc;
- FinalizeThreadPtr FinalizeThreadFunc;
- FinalizeProcessPtr FinalizeProcessFunc;
- GetNewMethodIDPtr GetNewMethodIDFunc;
-
-public:
- bool isAmplifierRunning() {
- return iJIT_IsProfilingActive() == iJIT_SAMPLING_ON;
- }
-
- IntelJITEventsWrapper()
- : NotifyEventFunc(::iJIT_NotifyEvent),
- RegisterCallbackExFunc(::iJIT_RegisterCallbackEx),
- IsProfilingActiveFunc(::iJIT_IsProfilingActive),
- FinalizeThreadFunc(::FinalizeThread),
- FinalizeProcessFunc(::FinalizeProcess),
- GetNewMethodIDFunc(::iJIT_GetNewMethodID) {
- }
-
- IntelJITEventsWrapper(NotifyEventPtr NotifyEventImpl,
- RegisterCallbackExPtr RegisterCallbackExImpl,
- IsProfilingActivePtr IsProfilingActiveImpl,
- FinalizeThreadPtr FinalizeThreadImpl,
- FinalizeProcessPtr FinalizeProcessImpl,
- GetNewMethodIDPtr GetNewMethodIDImpl)
- : NotifyEventFunc(NotifyEventImpl),
- RegisterCallbackExFunc(RegisterCallbackExImpl),
- IsProfilingActiveFunc(IsProfilingActiveImpl),
- FinalizeThreadFunc(FinalizeThreadImpl),
- FinalizeProcessFunc(FinalizeProcessImpl),
- GetNewMethodIDFunc(GetNewMethodIDImpl) {
- }
-
- // Sends an event anncouncing that a function has been emitted
- // return values are event-specific. See Intel documentation for details.
- int iJIT_NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
- if (!NotifyEventFunc)
- return -1;
- return NotifyEventFunc(EventType, EventSpecificData);
- }
-
- // Registers a callback function to receive notice of profiling state changes
- void iJIT_RegisterCallbackEx(void *UserData,
- iJIT_ModeChangedEx NewModeCallBackFuncEx) {
- if (RegisterCallbackExFunc)
- RegisterCallbackExFunc(UserData, NewModeCallBackFuncEx);
- }
-
- // Returns the current profiler mode
- iJIT_IsProfilingActiveFlags iJIT_IsProfilingActive(void) {
- if (!IsProfilingActiveFunc)
- return iJIT_NOTHING_RUNNING;
- return IsProfilingActiveFunc();
- }
-
- // Generates a locally unique method ID for use in code registration
- unsigned int iJIT_GetNewMethodID(void) {
- if (!GetNewMethodIDFunc)
- return -1;
- return GetNewMethodIDFunc();
- }
-};
-
-} //namespace llvm
-
-#endif //INTEL_JIT_EVENTS_WRAPPER_H
diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h
index eea603f..3aa014e 100644
--- a/include/llvm/ExecutionEngine/JITEventListener.h
+++ b/include/llvm/ExecutionEngine/JITEventListener.h
@@ -15,10 +15,9 @@
#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
-
#include <vector>
namespace llvm {
@@ -26,6 +25,7 @@ class Function;
class MachineFunction;
class OProfileWrapper;
class IntelJITEventsWrapper;
+class ObjectImage;
/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
/// about a generated machine code function.
@@ -76,6 +76,20 @@ public:
/// matching NotifyFreeingMachineCode call.
virtual void NotifyFreeingMachineCode(void *) {}
+ /// NotifyObjectEmitted - Called after an object has been successfully
+ /// emitted to memory. NotifyFunctionEmitted will not be called for
+ /// individual functions in the object.
+ ///
+ /// ELF-specific information
+ /// The ObjectImage contains the generated object image
+ /// with section headers updated to reflect the address at which sections
+ /// were loaded and with relocations performed in-place on debug sections.
+ virtual void NotifyObjectEmitted(const ObjectImage &Obj) {}
+
+ /// NotifyFreeingObject - Called just before the memory associated with
+ /// a previously emitted object is released.
+ virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
+
#if LLVM_USE_INTEL_JITEVENTS
// Construct an IntelJITEventListener
static JITEventListener *createIntelJITEventListener();
diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h
index 4c75b6a..29e01aa 100644
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -10,6 +10,7 @@
#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Support/DataTypes.h"
#include <string>
@@ -22,7 +23,7 @@ namespace llvm {
/// memory for the code generated by the JIT. This can be reimplemented by
/// clients that have a strong desire to control how the layout of JIT'd memory
/// works.
-class JITMemoryManager {
+class JITMemoryManager : public RTDyldMemoryManager {
protected:
bool HasGOT;
@@ -47,17 +48,6 @@ public:
/// debugging, and may be turned on by default in debug mode.
virtual void setPoisonMemory(bool poison) = 0;
- /// getPointerToNamedFunction - This method returns the address of the
- /// specified function. As such it is only useful for resolving library
- /// symbols, not code generated symbols.
- ///
- /// If AbortOnFailure is false and no function with the given name is
- /// found, this function silently returns a null pointer. Otherwise,
- /// it prints a message to stderr and aborts.
- ///
- virtual void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true) = 0;
-
//===--------------------------------------------------------------------===//
// Global Offset Table Management
//===--------------------------------------------------------------------===//
@@ -112,22 +102,6 @@ public:
virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
uint8_t *FunctionEnd) = 0;
- /// allocateCodeSection - Allocate a memory block of (at least) the given
- /// size suitable for executable code. The SectionID is a unique identifier
- /// assigned by the JIT and passed through to the memory manager for
- /// the instance class to use if it needs to communicate to the JIT about
- /// a given section after the fact.
- virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) = 0;
-
- /// allocateDataSection - Allocate a memory block of (at least) the given
- /// size suitable for data. The SectionID is a unique identifier
- /// assigned by the JIT and passed through to the memory manager for
- /// the instance class to use if it needs to communicate to the JIT about
- /// a given section after the fact.
- virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) = 0;
-
/// allocateSpace - Allocate a memory block of the given size. This method
/// cannot be called between calls to startFunctionBody and endFunctionBody.
virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) = 0;
diff --git a/include/llvm/ExecutionEngine/OProfileWrapper.h b/include/llvm/ExecutionEngine/OProfileWrapper.h
index ab7f25e..99553a3 100644
--- a/include/llvm/ExecutionEngine/OProfileWrapper.h
+++ b/include/llvm/ExecutionEngine/OProfileWrapper.h
@@ -41,10 +41,10 @@ class OProfileWrapper {
typedef int (*op_unload_native_code_ptr_t)(op_agent_t, uint64_t);
// Also used for op_minor_version function which has the same signature
- typedef int (*op_major_version_ptr_t)(void);
+ typedef int (*op_major_version_ptr_t)();
// This is not a part of the opagent API, but is useful nonetheless
- typedef bool (*IsOProfileRunningPtrT)(void);
+ typedef bool (*IsOProfileRunningPtrT)();
op_agent_t Agent;
@@ -99,8 +99,8 @@ public:
size_t num_entries,
struct debug_line_info const* info);
int op_unload_native_code(uint64_t addr);
- int op_major_version(void);
- int op_minor_version(void);
+ int op_major_version();
+ int op_minor_version();
// Returns true if the oprofiled process is running, the opagent library is
// loaded and a connection to the agent has been established, and false
diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
new file mode 100644
index 0000000..96a48b2
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectBuffer.h
@@ -0,0 +1,80 @@
+//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a wrapper class to hold the memory into which an
+// object will be generated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+/// ObjectBuffer - This class acts as a container for the memory buffer used during
+/// generation and loading of executable objects using MCJIT and RuntimeDyld. The
+/// underlying memory for the object will be owned by the ObjectBuffer instance
+/// throughout its lifetime. The getMemBuffer() method provides a way to create a
+/// MemoryBuffer wrapper object instance to be owned by other classes (such as
+/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the
+/// actual memory it points to.
+class ObjectBuffer {
+public:
+ ObjectBuffer() {}
+ ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {}
+ virtual ~ObjectBuffer() {}
+
+ /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function
+ /// returns a pointer to an object that is owned by the caller. However,
+ /// the caller does not take ownership of the underlying memory.
+ MemoryBuffer *getMemBuffer() const {
+ return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), "", false);
+ }
+
+ const char *getBufferStart() const { return Buffer->getBufferStart(); }
+ size_t getBufferSize() const { return Buffer->getBufferSize(); }
+
+protected:
+ // The memory contained in an ObjectBuffer
+ OwningPtr<MemoryBuffer> Buffer;
+};
+
+/// ObjectBufferStream - This class encapsulates the SmallVector and
+/// raw_svector_ostream needed to generate an object using MC code emission
+/// while providing a common ObjectBuffer interface for access to the
+/// memory once the object has been generated.
+class ObjectBufferStream : public ObjectBuffer {
+public:
+ ObjectBufferStream() : OS(SV) {}
+ virtual ~ObjectBufferStream() {}
+
+ raw_ostream &getOStream() { return OS; }
+ void flush()
+ {
+ OS.flush();
+
+ // Make the data accessible via the ObjectBuffer::Buffer
+ Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()),
+ "",
+ false));
+ }
+
+protected:
+ SmallVector<char, 4096> SV; // Working buffer into which we JIT.
+ raw_svector_ostream OS; // streaming wrapper
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h
new file mode 100644
index 0000000..d09e4de
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectImage.h
@@ -0,0 +1,61 @@
+//===---- ObjectImage.h - Format independent executuable object image -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectImage class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/Object/ObjectFile.h"
+
+namespace llvm {
+
+
+/// ObjectImage - A container class that represents an ObjectFile that has been
+/// or is in the process of being loaded into memory for execution.
+class ObjectImage {
+ ObjectImage() LLVM_DELETED_FUNCTION;
+ ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
+
+protected:
+ OwningPtr<ObjectBuffer> Buffer;
+
+public:
+ ObjectImage(ObjectBuffer *Input) : Buffer(Input) {}
+ virtual ~ObjectImage() {}
+
+ virtual object::symbol_iterator begin_symbols() const = 0;
+ virtual object::symbol_iterator end_symbols() const = 0;
+
+ virtual object::section_iterator begin_sections() const = 0;
+ virtual object::section_iterator end_sections() const = 0;
+
+ virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+ // Subclasses can override these methods to update the image with loaded
+ // addresses for sections and common symbols
+ virtual void updateSectionAddress(const object::SectionRef &Sec,
+ uint64_t Addr) = 0;
+ virtual void updateSymbolAddress(const object::SymbolRef &Sym,
+ uint64_t Addr) = 0;
+
+ virtual StringRef getData() const = 0;
+
+ // Subclasses can override these methods to provide JIT debugging support
+ virtual void registerWithDebugger() = 0;
+ virtual void deregisterWithDebugger() = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index 9e5ad2f..e2905e3 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -15,43 +15,62 @@
#define LLVM_RUNTIME_DYLD_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/Support/Memory.h"
namespace llvm {
class RuntimeDyldImpl;
-class MemoryBuffer;
+class ObjectImage;
// RuntimeDyld clients often want to handle the memory management of
-// what gets placed where. For JIT clients, this is an abstraction layer
-// over the JITMemoryManager, which references objects by their source
-// representations in LLVM IR.
+// what gets placed where. For JIT clients, this is the subset of
+// JITMemoryManager required for dynamic loading of binaries.
+//
// FIXME: As the RuntimeDyld fills out, additional routines will be needed
// for the varying types of objects to be allocated.
class RTDyldMemoryManager {
- RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
- void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
+ RTDyldMemoryManager(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION;
+ void operator=(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION;
public:
RTDyldMemoryManager() {}
virtual ~RTDyldMemoryManager();
- /// allocateCodeSection - Allocate a memory block of (at least) the given
- /// size suitable for executable code.
+ /// Allocate a memory block of (at least) the given size suitable for
+ /// executable code. The SectionID is a unique identifier assigned by the JIT
+ /// engine, and optionally recorded by the memory manager to access a loaded
+ /// section.
virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID) = 0;
- /// allocateDataSection - Allocate a memory block of (at least) the given
- /// size suitable for data.
+ /// Allocate a memory block of (at least) the given size suitable for data.
+ /// The SectionID is a unique identifier assigned by the JIT engine, and
+ /// optionally recorded by the memory manager to access a loaded section.
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) = 0;
-
+ unsigned SectionID, bool IsReadOnly) = 0;
+
+ /// This method returns the address of the specified function. As such it is
+ /// only useful for resolving library symbols, not code generated symbols.
+ ///
+ /// If AbortOnFailure is false and no function with the given name is
+ /// found, this function returns a null pointer. Otherwise, it prints a
+ /// message to stderr and aborts.
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) = 0;
+
+ /// This method is called when object loading is complete and section page
+ /// permissions can be applied. It is up to the memory manager implementation
+ /// to decide whether or not to act on this method. The memory manager will
+ /// typically allocate all sections as read-write and then apply specific
+ /// permissions when this method is called.
+ ///
+ /// Returns true if an error occurred, false otherwise.
+ virtual bool applyPermissions(std::string *ErrMsg = 0) = 0;
};
class RuntimeDyld {
- RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT
- void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT
+ RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION;
+ void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION;
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
// interface.
@@ -62,11 +81,14 @@ protected:
// Any relocations already associated with the symbol will be re-resolved.
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
public:
- RuntimeDyld(RTDyldMemoryManager*);
+ RuntimeDyld(RTDyldMemoryManager *);
~RuntimeDyld();
- /// Load an in-memory object file into the dynamic linker.
- bool loadObject(MemoryBuffer *InputBuffer);
+ /// Prepare the object contained in the input buffer for execution.
+ /// Ownership of the input buffer is transferred to the ObjectImage
+ /// instance returned from this function if successful. In the case of load
+ /// failure, the input buffer will be deleted.
+ ObjectImage *loadObject(ObjectBuffer *InputBuffer);
/// Get the address of our local copy of the symbol. This may or may not
/// be the address used for relocation (clients can copy the data around
@@ -80,11 +102,11 @@ public:
/// Resolve the relocations for all symbols we currently know about.
void resolveRelocations();
- /// mapSectionAddress - map a section to its target address space value.
+ /// Map a section to its target address space value.
/// Map the address of a JIT section as returned from the memory manager
/// to the address in the target process as the running code will see it.
/// This is the address which will be used for relocation resolution.
- void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress);
+ void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
StringRef getErrorString();
};
diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h
new file mode 100644
index 0000000..ba4ba8d0
--- /dev/null
+++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -0,0 +1,176 @@
+//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of a section-based memory manager used by
+// the MCJIT execution engine and RuntimeDyld.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
+#define LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Memory.h"
+
+namespace llvm {
+
+/// This is a simple memory manager which implements the methods called by
+/// the RuntimeDyld class to allocate memory for section-based loading of
+/// objects, usually those generated by the MCJIT execution engine.
+///
+/// This memory manager allocates all section memory as read-write. The
+/// RuntimeDyld will copy JITed section memory into these allocated blocks
+/// and perform any necessary linking and relocations.
+///
+/// Any client using this memory manager MUST ensure that section-specific
+/// page permissions have been applied before attempting to execute functions
+/// in the JITed object. Permissions can be applied either by calling
+/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions
+/// directly. Clients of MCJIT should call MCJIT::finalizeObject.
+class SectionMemoryManager : public JITMemoryManager {
+ SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
+ void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
+
+public:
+ SectionMemoryManager() { }
+ virtual ~SectionMemoryManager();
+
+ /// \brief Allocates a memory block of (at least) the given size suitable for
+ /// executable code.
+ ///
+ /// The value of \p Alignment must be a power of two. If \p Alignment is zero
+ /// a default alignment of 16 will be used.
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID);
+
+ /// \brief Allocates a memory block of (at least) the given size suitable for
+ /// executable code.
+ ///
+ /// The value of \p Alignment must be a power of two. If \p Alignment is zero
+ /// a default alignment of 16 will be used.
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ bool isReadOnly);
+
+ /// \brief Applies section-specific memory permissions.
+ ///
+ /// This method is called when object loading is complete and section page
+ /// permissions can be applied. It is up to the memory manager implementation
+ /// to decide whether or not to act on this method. The memory manager will
+ /// typically allocate all sections as read-write and then apply specific
+ /// permissions when this method is called. Code sections cannot be executed
+ /// until this function has been called.
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ virtual bool applyPermissions(std::string *ErrMsg = 0);
+
+ /// This method returns the address of the specified function. As such it is
+ /// only useful for resolving library symbols, not code generated symbols.
+ ///
+ /// If \p AbortOnFailure is false and no function with the given name is
+ /// found, this function returns a null pointer. Otherwise, it prints a
+ /// message to stderr and aborts.
+ virtual void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true);
+
+ /// \brief Invalidate instruction cache for code sections.
+ ///
+ /// Some platforms with separate data cache and instruction cache require
+ /// explicit cache flush, otherwise JIT code manipulations (like resolved
+ /// relocations) will get to the data cache but not to the instruction cache.
+ ///
+ /// This method is not called by RuntimeDyld or MCJIT during the load
+ /// process. Clients may call this function when needed. See the lli
+ /// tool for example use.
+ virtual void invalidateInstructionCache();
+
+private:
+ struct MemoryGroup {
+ SmallVector<sys::MemoryBlock, 16> AllocatedMem;
+ SmallVector<sys::MemoryBlock, 16> FreeMem;
+ sys::MemoryBlock Near;
+ };
+
+ uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size,
+ unsigned Alignment);
+
+ error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup,
+ unsigned Permissions);
+
+ MemoryGroup CodeMem;
+ MemoryGroup RWDataMem;
+ MemoryGroup RODataMem;
+
+public:
+ ///
+ /// Functions below are not used by MCJIT or RuntimeDyld, but must be
+ /// implemented because they are declared as pure virtuals in the base class.
+ ///
+
+ virtual void setMemoryWritable() {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void setMemoryExecutable() {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void setPoisonMemory(bool poison) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void AllocateGOT() {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual uint8_t *getGOTBase() const {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual uint8_t *startFunctionBody(const Function *F,
+ uintptr_t &ActualSize){
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize,
+ unsigned Alignment) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
+ uint8_t *FunctionEnd) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual void deallocateFunctionBody(void *Body) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual uint8_t *startExceptionTable(const Function *F,
+ uintptr_t &ActualSize) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
+ uint8_t *TableEnd, uint8_t *FrameRegister) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void deallocateExceptionTable(void *ET) {
+ llvm_unreachable("Unexpected call!");
+ }
+};
+
+}
+
+#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
+
diff --git a/include/llvm/Argument.h b/include/llvm/IR/Argument.h
index e66075c..f737e40 100644
--- a/include/llvm/Argument.h
+++ b/include/llvm/IR/Argument.h
@@ -14,10 +14,10 @@
#ifndef LLVM_ARGUMENT_H
#define LLVM_ARGUMENT_H
-#include "llvm/Value.h"
-#include "llvm/Attributes.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Value.h"
namespace llvm {
@@ -68,20 +68,19 @@ public:
/// attribute on it in its containing function.
bool hasNoCaptureAttr() const;
- /// hasSRetAttr - Return true if this argument has the sret attribute on it in
- /// its containing function.
+ /// hasStructRetAttr - Return true if this argument has the sret attribute on
+ /// it in its containing function.
bool hasStructRetAttr() const;
/// addAttr - Add a Attribute to an argument
- void addAttr(Attributes);
+ void addAttr(Attribute);
/// removeAttr - Remove a Attribute from an argument
- void removeAttr(Attributes);
+ void removeAttr(Attribute);
/// classof - Methods for support type inquiry through isa, cast, and
/// dyn_cast:
///
- static inline bool classof(const Argument *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
}
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
new file mode 100644
index 0000000..95b654c
--- /dev/null
+++ b/include/llvm/IR/Attributes.h
@@ -0,0 +1,458 @@
+//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file contains the simple types necessary to represent the
+/// attributes associated with functions and their calls.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ATTRIBUTES_H
+#define LLVM_ATTRIBUTES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+
+class AttrBuilder;
+class AttributeImpl;
+class Constant;
+class LLVMContext;
+class Type;
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief Functions, function parameters, and return types can have attributes
+/// to indicate how they should be treated by optimizations and code
+/// generation. This class represents one of those attributes. It's light-weight
+/// and should be passed around by-value.
+class Attribute {
+public:
+ /// This enumeration lists the attributes that can be associated with
+ /// parameters, function results or the function itself.
+ ///
+ /// Note: uwtable is about the ABI or the user mandating an entry in the
+ /// unwind table. The nounwind attribute is about an exception passing by the
+ /// function.
+ ///
+ /// In a theoretical system that uses tables for profiling and sjlj for
+ /// exceptions, they would be fully independent. In a normal system that uses
+ /// tables for both, the semantics are:
+ ///
+ /// nil = Needs an entry because an exception might pass by.
+ /// nounwind = No need for an entry
+ /// uwtable = Needs an entry because the ABI says so and because
+ /// an exception might pass by.
+ /// uwtable + nounwind = Needs an entry because the ABI says so.
+
+ enum AttrKind {
+ // IR-Level Attributes
+ None, ///< No attributes have been set
+ AddressSafety, ///< Address safety checking is on.
+ Alignment, ///< Alignment of parameter (5 bits)
+ ///< stored as log2 of alignment with +1 bias
+ ///< 0 means unaligned (different from align(1))
+ AlwaysInline, ///< inline=always
+ ByVal, ///< Pass structure by value
+ InlineHint, ///< Source said inlining was desirable
+ InReg, ///< Force argument to be passed in register
+ MinSize, ///< Function must be optimized for size first
+ Naked, ///< Naked function
+ Nest, ///< Nested function static chain
+ NoAlias, ///< Considered to not alias after call
+ NoCapture, ///< Function creates no aliases of pointer
+ NoDuplicate, ///< Call cannot be duplicated
+ NoImplicitFloat, ///< Disable implicit floating point insts
+ NoInline, ///< inline=never
+ NonLazyBind, ///< Function is called early and/or
+ ///< often, so lazy binding isn't worthwhile
+ NoRedZone, ///< Disable redzone
+ NoReturn, ///< Mark the function as not returning
+ NoUnwind, ///< Function doesn't unwind stack
+ OptimizeForSize, ///< opt_size
+ ReadNone, ///< Function does not access memory
+ ReadOnly, ///< Function only reads from memory
+ ReturnsTwice, ///< Function can return twice
+ SExt, ///< Sign extended before/after call
+ StackAlignment, ///< Alignment of stack for function (3 bits)
+ ///< stored as log2 of alignment with +1 bias 0
+ ///< means unaligned (different from
+ ///< alignstack=(1))
+ StackProtect, ///< Stack protection.
+ StackProtectReq, ///< Stack protection required.
+ StructRet, ///< Hidden pointer to structure to return
+ UWTable, ///< Function must be in a unwind table
+ ZExt, ///< Zero extended before/after call
+
+ EndAttrKinds, ///< Sentinal value useful for loops
+
+ AttrKindEmptyKey, ///< Empty key value for DenseMapInfo
+ AttrKindTombstoneKey ///< Tombstone key value for DenseMapInfo
+ };
+private:
+ AttributeImpl *pImpl;
+ Attribute(AttributeImpl *A) : pImpl(A) {}
+public:
+ Attribute() : pImpl(0) {}
+
+ /// \brief Return a uniquified Attribute object. This takes the uniquified
+ /// value from the Builder and wraps it in the Attribute class.
+ static Attribute get(LLVMContext &Context, ArrayRef<AttrKind> Vals);
+ static Attribute get(LLVMContext &Context, AttrBuilder &B);
+
+ /// \brief Return true if the attribute is present.
+ bool hasAttribute(AttrKind Val) const;
+
+ /// \brief Return true if attributes exist
+ bool hasAttributes() const;
+
+ /// \brief Returns the alignment field of an attribute as a byte alignment
+ /// value.
+ unsigned getAlignment() const;
+
+ /// \brief Set the alignment field of an attribute.
+ void setAlignment(unsigned Align);
+
+ /// \brief Returns the stack alignment field of an attribute as a byte
+ /// alignment value.
+ unsigned getStackAlignment() const;
+
+ /// \brief Set the stack alignment field of an attribute.
+ void setStackAlignment(unsigned Align);
+
+ /// \brief Equality and non-equality query methods.
+ bool operator==(AttrKind K) const;
+ bool operator!=(AttrKind K) const;
+
+ // FIXME: Remove these 'operator' methods.
+ bool operator==(const Attribute &A) const {
+ return pImpl == A.pImpl;
+ }
+ bool operator!=(const Attribute &A) const {
+ return pImpl != A.pImpl;
+ }
+
+ uint64_t getBitMask() const;
+
+ /// \brief Which attributes cannot be applied to a type.
+ static Attribute typeIncompatible(Type *Ty);
+
+ /// \brief This returns an integer containing an encoding of all the LLVM
+ /// attributes found in the given attribute bitset. Any change to this
+ /// encoding is a breaking change to bitcode compatibility.
+ static uint64_t encodeLLVMAttributesForBitcode(Attribute Attrs);
+
+ /// \brief This returns an attribute bitset containing the LLVM attributes
+ /// that have been decoded from the given integer. This function must stay in
+ /// sync with 'encodeLLVMAttributesForBitcode'.
+ static Attribute decodeLLVMAttributesForBitcode(LLVMContext &C,
+ uint64_t EncodedAttrs);
+
+ /// \brief The Attribute is converted to a string of equivalent mnemonic. This
+ /// is, presumably, for writing out the mnemonics for the assembly writer.
+ std::string getAsString() const;
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief Provide DenseMapInfo for Attribute::AttrKinds. This is used by
+/// AttrBuilder.
+template<> struct DenseMapInfo<Attribute::AttrKind> {
+ static inline Attribute::AttrKind getEmptyKey() {
+ return Attribute::AttrKindEmptyKey;
+ }
+ static inline Attribute::AttrKind getTombstoneKey() {
+ return Attribute::AttrKindTombstoneKey;
+ }
+ static unsigned getHashValue(const Attribute::AttrKind &Val) {
+ return Val * 37U;
+ }
+ static bool isEqual(const Attribute::AttrKind &LHS,
+ const Attribute::AttrKind &RHS) {
+ return LHS == RHS;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This is just a pair of values to associate a set of attributes with
+/// an index.
+struct AttributeWithIndex {
+ Attribute Attrs; ///< The attributes that are set, or'd together.
+ Constant *Val; ///< Value attached to attribute, e.g. alignment.
+ unsigned Index; ///< Index of the parameter for which the attributes apply.
+ ///< Index 0 is used for return value attributes.
+ ///< Index ~0U is used for function attributes.
+
+ static AttributeWithIndex get(LLVMContext &C, unsigned Idx,
+ ArrayRef<Attribute::AttrKind> Attrs) {
+ return get(Idx, Attribute::get(C, Attrs));
+ }
+ static AttributeWithIndex get(unsigned Idx, Attribute Attrs) {
+ AttributeWithIndex P;
+ P.Index = Idx;
+ P.Attrs = Attrs;
+ P.Val = 0;
+ return P;
+ }
+ static AttributeWithIndex get(unsigned Idx, Attribute Attrs, Constant *Val) {
+ AttributeWithIndex P;
+ P.Index = Idx;
+ P.Attrs = Attrs;
+ P.Val = Val;
+ return P;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// AttributeSet Smart Pointer
+//===----------------------------------------------------------------------===//
+
+class AttrBuilder;
+class AttributeSetImpl;
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class manages the ref count for the opaque AttributeSetImpl
+/// object and provides accessors for it.
+class AttributeSet {
+public:
+ enum AttrIndex {
+ ReturnIndex = 0U,
+ FunctionIndex = ~0U
+ };
+private:
+ friend class AttrBuilder;
+
+ /// \brief The attributes that we are managing. This can be null to represent
+ /// the empty attributes list.
+ AttributeSetImpl *AttrList;
+
+ /// \brief The attributes for the specified index are returned. Attributes
+ /// for the result are denoted with Idx = 0.
+ Attribute getAttributes(unsigned Idx) const;
+
+ explicit AttributeSet(AttributeSetImpl *LI) : AttrList(LI) {}
+public:
+ AttributeSet() : AttrList(0) {}
+ AttributeSet(const AttributeSet &P) : AttrList(P.AttrList) {}
+ const AttributeSet &operator=(const AttributeSet &RHS);
+
+ //===--------------------------------------------------------------------===//
+ // Attribute List Construction and Mutation
+ //===--------------------------------------------------------------------===//
+
+ /// \brief Return an AttributeSet with the specified parameters in it.
+ static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
+ static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B);
+
+ /// \brief Add the specified attribute at the specified index to this
+ /// attribute list. Since attribute lists are immutable, this returns the new
+ /// list.
+ AttributeSet addAttr(LLVMContext &C, unsigned Idx, Attribute Attrs) const;
+
+ /// \brief Remove the specified attribute at the specified index from this
+ /// attribute list. Since attribute lists are immutable, this returns the new
+ /// list.
+ AttributeSet removeAttr(LLVMContext &C, unsigned Idx, Attribute Attrs) const;
+
+ //===--------------------------------------------------------------------===//
+ // Attribute List Accessors
+ //===--------------------------------------------------------------------===//
+
+ /// \brief The attributes for the specified index are returned.
+ Attribute getParamAttributes(unsigned Idx) const {
+ return getAttributes(Idx);
+ }
+
+ /// \brief The attributes for the ret value are returned.
+ Attribute getRetAttributes() const {
+ return getAttributes(ReturnIndex);
+ }
+
+ /// \brief The function attributes are returned.
+ Attribute getFnAttributes() const {
+ return getAttributes(FunctionIndex);
+ }
+
+ /// \brief Return the alignment for the specified function parameter.
+ unsigned getParamAlignment(unsigned Idx) const {
+ return getAttributes(Idx).getAlignment();
+ }
+
+ /// \brief Return true if the attribute exists at the given index.
+ bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
+
+ /// \brief Return true if attribute exists at the given index.
+ bool hasAttributes(unsigned Index) const;
+
+ /// \brief Get the stack alignment.
+ unsigned getStackAlignment(unsigned Index) const;
+
+ /// \brief Return the attributes at the index as a string.
+ std::string getAsString(unsigned Index) const;
+
+ uint64_t getBitMask(unsigned Index) const;
+
+ /// \brief Return true if the specified attribute is set for at least one
+ /// parameter or for the return value.
+ bool hasAttrSomewhere(Attribute::AttrKind Attr) const;
+
+ /// operator==/!= - Provide equality predicates.
+ bool operator==(const AttributeSet &RHS) const {
+ return AttrList == RHS.AttrList;
+ }
+ bool operator!=(const AttributeSet &RHS) const {
+ return AttrList != RHS.AttrList;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Attribute List Introspection
+ //===--------------------------------------------------------------------===//
+
+ /// \brief Return a raw pointer that uniquely identifies this attribute list.
+ void *getRawPointer() const {
+ return AttrList;
+ }
+
+ // Attributes are stored as a dense set of slots, where there is one slot for
+ // each argument that has an attribute. This allows walking over the dense
+ // set instead of walking the sparse list of attributes.
+
+ /// \brief Return true if there are no attributes.
+ bool isEmpty() const {
+ return AttrList == 0;
+ }
+
+ /// \brief Return the number of slots used in this attribute list. This is
+ /// the number of arguments that have an attribute set on them (including the
+ /// function itself).
+ unsigned getNumSlots() const;
+
+ /// \brief Return the AttributeWithIndex at the specified slot. This holds a
+ /// index number plus a set of attributes.
+ const AttributeWithIndex &getSlot(unsigned Slot) const;
+
+ void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class is used in conjunction with the Attribute::get method to
+/// create an Attribute object. The object itself is uniquified. The Builder's
+/// value, however, is not. So this can be used as a quick way to test for
+/// equality, presence of attributes, etc.
+class AttrBuilder {
+ DenseSet<Attribute::AttrKind> Attrs;
+ uint64_t Alignment;
+ uint64_t StackAlignment;
+public:
+ AttrBuilder() : Alignment(0), StackAlignment(0) {}
+ explicit AttrBuilder(uint64_t B) : Alignment(0), StackAlignment(0) {
+ addRawValue(B);
+ }
+ AttrBuilder(const Attribute &A) : Alignment(0), StackAlignment(0) {
+ addAttributes(A);
+ }
+ AttrBuilder(AttributeSet AS, unsigned Idx);
+
+ void clear();
+
+ /// \brief Add an attribute to the builder.
+ AttrBuilder &addAttribute(Attribute::AttrKind Val);
+
+ /// \brief Remove an attribute from the builder.
+ AttrBuilder &removeAttribute(Attribute::AttrKind Val);
+
+ /// \brief Add the attributes from A to the builder.
+ AttrBuilder &addAttributes(const Attribute &A);
+
+ /// \brief Remove the attributes from A from the builder.
+ AttrBuilder &removeAttributes(const Attribute &A);
+
+ /// \brief Return true if the builder has the specified attribute.
+ bool contains(Attribute::AttrKind A) const;
+
+ /// \brief Return true if the builder has IR-level attributes.
+ bool hasAttributes() const;
+
+ /// \brief Return true if the builder has any attribute that's in the
+ /// specified attribute.
+ bool hasAttributes(const Attribute &A) const;
+
+ /// \brief Return true if the builder has an alignment attribute.
+ bool hasAlignmentAttr() const;
+
+ /// \brief Retrieve the alignment attribute, if it exists.
+ uint64_t getAlignment() const { return Alignment; }
+
+ /// \brief Retrieve the stack alignment attribute, if it exists.
+ uint64_t getStackAlignment() const { return StackAlignment; }
+
+ /// \brief This turns an int alignment (which must be a power of 2) into the
+ /// form used internally in Attribute.
+ AttrBuilder &addAlignmentAttr(unsigned Align);
+
+ /// \brief This turns an int stack alignment (which must be a power of 2) into
+ /// the form used internally in Attribute.
+ AttrBuilder &addStackAlignmentAttr(unsigned Align);
+
+ typedef DenseSet<Attribute::AttrKind>::iterator iterator;
+ typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator;
+
+ iterator begin() { return Attrs.begin(); }
+ iterator end() { return Attrs.end(); }
+
+ const_iterator begin() const { return Attrs.begin(); }
+ const_iterator end() const { return Attrs.end(); }
+
+ /// \brief Add the raw value to the internal representation.
+ ///
+ /// N.B. This should be used ONLY for decoding LLVM bitcode!
+ AttrBuilder &addRawValue(uint64_t Val);
+
+ /// \brief Remove attributes that are used on functions only.
+ void removeFunctionOnlyAttrs() {
+ removeAttribute(Attribute::NoReturn)
+ .removeAttribute(Attribute::NoUnwind)
+ .removeAttribute(Attribute::ReadNone)
+ .removeAttribute(Attribute::ReadOnly)
+ .removeAttribute(Attribute::NoInline)
+ .removeAttribute(Attribute::AlwaysInline)
+ .removeAttribute(Attribute::OptimizeForSize)
+ .removeAttribute(Attribute::StackProtect)
+ .removeAttribute(Attribute::StackProtectReq)
+ .removeAttribute(Attribute::NoRedZone)
+ .removeAttribute(Attribute::NoImplicitFloat)
+ .removeAttribute(Attribute::Naked)
+ .removeAttribute(Attribute::InlineHint)
+ .removeAttribute(Attribute::StackAlignment)
+ .removeAttribute(Attribute::UWTable)
+ .removeAttribute(Attribute::NonLazyBind)
+ .removeAttribute(Attribute::ReturnsTwice)
+ .removeAttribute(Attribute::AddressSafety)
+ .removeAttribute(Attribute::MinSize)
+ .removeAttribute(Attribute::NoDuplicate);
+ }
+
+ uint64_t getBitMask() const;
+
+ bool operator==(const AttrBuilder &B);
+ bool operator!=(const AttrBuilder &B) {
+ return !(*this == B);
+ }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index d2aa167..15f4aa7 100644
--- a/include/llvm/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -14,10 +14,10 @@
#ifndef LLVM_BASICBLOCK_H
#define LLVM_BASICBLOCK_H
-#include "llvm/Instruction.h"
-#include "llvm/SymbolTableListTraits.h"
-#include "llvm/ADT/ilist.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -79,8 +79,8 @@ private:
void setParent(Function *parent);
friend class SymbolTableListTraits<BasicBlock, Function>;
- BasicBlock(const BasicBlock &); // Do not implement
- void operator=(const BasicBlock &); // Do not implement
+ BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION;
+ void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION;
/// BasicBlock ctor - If the function parameter is specified, the basic block
/// is automatically inserted at either the end of the function (if
@@ -93,8 +93,10 @@ public:
LLVMContext &getContext() const;
/// Instruction iterators...
- typedef InstListType::iterator iterator;
- typedef InstListType::const_iterator const_iterator;
+ typedef InstListType::iterator iterator;
+ typedef InstListType::const_iterator const_iterator;
+ typedef InstListType::reverse_iterator reverse_iterator;
+ typedef InstListType::const_reverse_iterator const_reverse_iterator;
/// Create - Creates a new BasicBlock. If the Parent parameter is specified,
/// the basic block is automatically inserted at either the end of the
@@ -191,6 +193,11 @@ public:
inline iterator end () { return InstList.end(); }
inline const_iterator end () const { return InstList.end(); }
+ inline reverse_iterator rbegin() { return InstList.rbegin(); }
+ inline const_reverse_iterator rbegin() const { return InstList.rbegin(); }
+ inline reverse_iterator rend () { return InstList.rend(); }
+ inline const_reverse_iterator rend () const { return InstList.rend(); }
+
inline size_t size() const { return InstList.size(); }
inline bool empty() const { return InstList.empty(); }
inline const Instruction &front() const { return InstList.front(); }
@@ -213,7 +220,6 @@ public:
ValueSymbolTable *getValueSymbolTable();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const BasicBlock *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::BasicBlockVal;
}
diff --git a/include/llvm/IR/CMakeLists.txt b/include/llvm/IR/CMakeLists.txt
new file mode 100644
index 0000000..2d52a89
--- /dev/null
+++ b/include/llvm/IR/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(LLVM_TARGET_DEFINITIONS Intrinsics.td)
+
+tablegen(LLVM Intrinsics.gen -gen-intrinsic)
+
+add_custom_target(intrinsics_gen ALL
+ DEPENDS ${llvm_builded_incs_dir}/IR/Intrinsics.gen)
+set_target_properties(intrinsics_gen PROPERTIES FOLDER "Tablegenning")
diff --git a/include/llvm/CallingConv.h b/include/llvm/IR/CallingConv.h
index 4c5ee62..699cea3 100644
--- a/include/llvm/CallingConv.h
+++ b/include/llvm/IR/CallingConv.h
@@ -47,6 +47,10 @@ namespace CallingConv {
// GHC - Calling convention used by the Glasgow Haskell Compiler (GHC).
GHC = 10,
+ // HiPE - Calling convention used by the High-Performance Erlang Compiler
+ // (HiPE).
+ HiPE = 11,
+
// Target - This is the start of the target-specific calling conventions,
// e.g. fastcall and thiscall on X86.
FirstTargetCC = 64,
@@ -94,7 +98,29 @@ namespace CallingConv {
/// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
/// routines (i.e. GCC's save_volatiles attribute).
- MBLAZE_SVOL = 74
+ MBLAZE_SVOL = 74,
+
+ /// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
+ /// No lowering or expansion of arguments.
+ /// Structures are passed as a pointer to a struct with the byval attribute.
+ /// Functions can only call SPIR_FUNC and SPIR_KERNEL functions.
+ /// Functions can only have zero or one return values.
+ /// Variable arguments are not allowed, except for printf.
+ /// How arguments/return values are lowered are not specified.
+ /// Functions are only visible to the devices.
+ SPIR_FUNC = 75,
+
+ /// SPIR_KERNEL - Calling convention for SPIR kernel functions.
+ /// Inherits the restrictions of SPIR_FUNC, except
+ /// Cannot have non-void return values.
+ /// Cannot have variable arguments.
+ /// Can also be called by the host.
+ /// Is externally visible.
+ SPIR_KERNEL = 76,
+
+ /// Intel_OCL_BI - Calling conventions for Intel OpenCL built-ins
+ Intel_OCL_BI = 77
+
};
} // End CallingConv namespace
diff --git a/include/llvm/Constant.h b/include/llvm/IR/Constant.h
index e0e516d..36a4538 100644
--- a/include/llvm/Constant.h
+++ b/include/llvm/IR/Constant.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CONSTANT_H
#define LLVM_CONSTANT_H
-#include "llvm/User.h"
+#include "llvm/IR/User.h"
namespace llvm {
class APInt;
@@ -39,8 +39,8 @@ namespace llvm {
/// don't have to worry about the lifetime of the objects.
/// @brief LLVM Constant Representation
class Constant : public User {
- void operator=(const Constant &); // Do not implement
- Constant(const Constant &); // Do not implement
+ void operator=(const Constant &) LLVM_DELETED_FUNCTION;
+ Constant(const Constant &) LLVM_DELETED_FUNCTION;
virtual void anchor();
protected:
@@ -65,6 +65,9 @@ public:
/// true for things like constant expressions that could divide by zero.
bool canTrap() const;
+ /// isThreadDependent - Return true if the value can vary between threads.
+ bool isThreadDependent() const;
+
/// isConstantUsed - Return true if the constant has users other than constant
/// exprs and other dangling things.
bool isConstantUsed() const;
@@ -97,7 +100,15 @@ public:
/// 'this' is a constant expr.
Constant *getAggregateElement(unsigned Elt) const;
Constant *getAggregateElement(Constant *Elt) const;
-
+
+ /// getSplatValue - If this is a splat vector constant, meaning that all of
+ /// the elements have the same value, return that value. Otherwise return 0.
+ Constant *getSplatValue() const;
+
+ /// If C is a constant integer then return its value, otherwise C must be a
+ /// vector of constant integers, all equal, and the common value is returned.
+ const APInt &getUniqueInteger() const;
+
/// destroyConstant - Called if some element of this constant is no longer
/// valid. At this point only other constants may be on the use_list for this
/// constant. Any constants on our Use list must also be destroy'd. The
@@ -108,8 +119,6 @@ public:
virtual void destroyConstant() { llvm_unreachable("Not reached!"); }
//// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Constant *) { return true; }
- static inline bool classof(const GlobalValue *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() >= ConstantFirstVal &&
V->getValueID() <= ConstantLastVal;
diff --git a/include/llvm/Constants.h b/include/llvm/IR/Constants.h
index fdd5382..0f49fe5 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===//
//
/// @file
-/// This file contains the declarations for the subclasses of Constant,
+/// This file contains the declarations for the subclasses of Constant,
/// which represent the different flavors of constant values that live in LLVM.
-/// Note that Constants are immutable (once created they never change) and are
+/// Note that Constants are immutable (once created they never change) and are
/// fully shared by structural equivalence. This means that two structurally
/// equivalent constants will always have the same address. Constant's are
/// created on demand as needed and never deleted: thus clients don't have to
@@ -21,11 +21,11 @@
#ifndef LLVM_CONSTANTS_H
#define LLVM_CONSTANTS_H
-#include "llvm/Constant.h"
-#include "llvm/OperandTraits.h"
-#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/OperandTraits.h"
namespace llvm {
@@ -44,13 +44,13 @@ template<class ConstantClass, class TypeClass>
struct ConvertConstantType;
//===----------------------------------------------------------------------===//
-/// This is the shared class of boolean and integer constants. This class
+/// This is the shared class of boolean and integer constants. This class
/// represents both boolean and integral constants.
/// @brief Class for constant integers.
class ConstantInt : public Constant {
virtual void anchor();
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ ConstantInt(const ConstantInt &) LLVM_DELETED_FUNCTION;
ConstantInt(IntegerType *Ty, const APInt& V);
APInt Val;
protected:
@@ -63,11 +63,11 @@ public:
static ConstantInt *getFalse(LLVMContext &Context);
static Constant *getTrue(Type *Ty);
static Constant *getFalse(Type *Ty);
-
+
/// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value.
static Constant *get(Type *Ty, uint64_t V, bool isSigned = false);
-
+
/// Return a ConstantInt with the specified integer value for the specified
/// type. If the type is wider than 64 bits, the value will be zero-extended
/// to fit the type, unless isSigned is true, in which case the value will
@@ -84,27 +84,27 @@ public:
/// @brief Get a ConstantInt for a specific signed value.
static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
static Constant *getSigned(Type *Ty, int64_t V);
-
+
/// Return a ConstantInt with the specified value and an implied Type. The
/// type is the integer type that corresponds to the bit width of the value.
static ConstantInt *get(LLVMContext &Context, const APInt &V);
/// Return a ConstantInt constructed from the string strStart with the given
- /// radix.
+ /// radix.
static ConstantInt *get(IntegerType *Ty, StringRef Str,
uint8_t radix);
-
+
/// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value.
static Constant *get(Type* Ty, const APInt& V);
-
+
/// Return the constant as an APInt value reference. This allows clients to
/// obtain a copy of the value, with all its precision in tact.
/// @brief Return the constant's value.
inline const APInt &getValue() const {
return Val;
}
-
+
/// getBitWidth - Return the bitwidth of this constant.
unsigned getBitWidth() const { return Val.getBitWidth(); }
@@ -126,8 +126,8 @@ public:
return Val.getSExtValue();
}
- /// A helper method that can be used to determine if the constant contained
- /// within is equal to a constant. This only works for very small values,
+ /// A helper method that can be used to determine if the constant contained
+ /// within is equal to a constant. This only works for very small values,
/// because this is all that can be represented with all types.
/// @brief Determine if this constant's value is same as an unsigned char.
bool equalsInt(uint64_t V) const {
@@ -141,11 +141,11 @@ public:
return reinterpret_cast<IntegerType*>(Value::getType());
}
- /// This static method returns true if the type Ty is big enough to
- /// represent the value V. This can be used to avoid having the get method
+ /// This static method returns true if the type Ty is big enough to
+ /// represent the value V. This can be used to avoid having the get method
/// assert when V is larger than Ty can represent. Note that there are two
/// versions of this method, one for unsigned and one for signed integers.
- /// Although ConstantInt canonicalizes everything to an unsigned integer,
+ /// Although ConstantInt canonicalizes everything to an unsigned integer,
/// the signed version avoids callers having to convert a signed quantity
/// to the appropriate unsigned type before calling the method.
/// @returns true if V is a valid value for type Ty
@@ -162,7 +162,7 @@ public:
return Val == 0;
}
- /// This is just a convenience method to make client code smaller for a
+ /// This is just a convenience method to make client code smaller for a
/// common case. It also correctly performs the comparison without the
/// potential for an assertion from getZExtValue().
/// @brief Determine if the value is one.
@@ -174,17 +174,17 @@ public:
/// to true.
/// @returns true iff this constant's bits are all set to true.
/// @brief Determine if the value is all ones.
- bool isMinusOne() const {
+ bool isMinusOne() const {
return Val.isAllOnesValue();
}
/// This function will return true iff this constant represents the largest
/// value that may be represented by the constant's type.
- /// @returns true iff this is the largest value that may be represented
+ /// @returns true iff this is the largest value that may be represented
/// by this type.
/// @brief Determine if the value is maximal.
bool isMaxValue(bool isSigned) const {
- if (isSigned)
+ if (isSigned)
return Val.isMaxSignedValue();
else
return Val.isMaxValue();
@@ -192,11 +192,11 @@ public:
/// This function will return true iff this constant represents the smallest
/// value that may be represented by this constant's type.
- /// @returns true if this is the smallest value that may be represented by
+ /// @returns true if this is the smallest value that may be represented by
/// this type.
/// @brief Determine if the value is minimal.
bool isMinValue(bool isSigned) const {
- if (isSigned)
+ if (isSigned)
return Val.isMinSignedValue();
else
return Val.isMinValue();
@@ -221,7 +221,6 @@ public:
}
/// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const ConstantInt *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantIntVal;
}
@@ -234,8 +233,8 @@ public:
class ConstantFP : public Constant {
APFloat Val;
virtual void anchor();
- void *operator new(size_t, unsigned);// DO NOT IMPLEMENT
- ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ ConstantFP(const ConstantFP &) LLVM_DELETED_FUNCTION;
friend class LLVMContextImpl;
protected:
ConstantFP(Type *Ty, const APFloat& V);
@@ -249,7 +248,7 @@ public:
/// method returns the negative zero constant for floating point or vector
/// floating point types; for all other types, it returns the null value.
static Constant *getZeroValueForNegation(Type *Ty);
-
+
/// get() - This returns a ConstantFP, or a vector containing a splat of a
/// ConstantFP, for the specified value in the specified type. This should
/// only be used for simple constant values like 2.0/1.0 etc, that are
@@ -259,7 +258,7 @@ public:
static ConstantFP *get(LLVMContext &Context, const APFloat &V);
static ConstantFP *getNegativeZero(Type* Ty);
static ConstantFP *getInfinity(Type *Ty, bool Negative = false);
-
+
/// isValueValidForType - return true if Ty is big enough to represent V.
static bool isValueValidForType(Type *Ty, const APFloat &V);
inline const APFloat &getValueAPF() const { return Val; }
@@ -283,15 +282,11 @@ public:
bool isExactlyValue(double V) const {
bool ignored;
- // convert is not supported on this type
- if (&Val.getSemantics() == &APFloat::PPCDoubleDouble)
- return false;
APFloat FV(V);
FV.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &ignored);
return isExactlyValue(FV);
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ConstantFP *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantFPVal;
}
@@ -301,8 +296,8 @@ public:
/// ConstantAggregateZero - All zero aggregate value
///
class ConstantAggregateZero : public Constant {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ ConstantAggregateZero(const ConstantAggregateZero &) LLVM_DELETED_FUNCTION;
protected:
explicit ConstantAggregateZero(Type *ty)
: Constant(ty, ConstantAggregateZeroVal, 0, 0) {}
@@ -313,7 +308,7 @@ protected:
}
public:
static ConstantAggregateZero *get(Type *Ty);
-
+
virtual void destroyConstant();
/// getSequentialElement - If this CAZ has array or vector type, return a zero
@@ -334,7 +329,6 @@ public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
- static bool classof(const ConstantAggregateZero *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantAggregateZeroVal;
}
@@ -346,13 +340,13 @@ public:
///
class ConstantArray : public Constant {
friend struct ConstantArrayCreator<ConstantArray, ArrayType>;
- ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT
+ ConstantArray(const ConstantArray &) LLVM_DELETED_FUNCTION;
protected:
ConstantArray(ArrayType *T, ArrayRef<Constant *> Val);
public:
// ConstantArray accessors
static Constant *get(ArrayType *T, ArrayRef<Constant*> V);
-
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -367,7 +361,6 @@ public:
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ConstantArray *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantArrayVal;
}
@@ -385,7 +378,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant)
//
class ConstantStruct : public Constant {
friend struct ConstantArrayCreator<ConstantStruct, StructType>;
- ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT
+ ConstantStruct(const ConstantStruct &) LLVM_DELETED_FUNCTION;
protected:
ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
public:
@@ -399,7 +392,7 @@ public:
static Constant *getAnon(ArrayRef<Constant*> V, bool Packed = false) {
return get(getTypeForElements(V, Packed), V);
}
- static Constant *getAnon(LLVMContext &Ctx,
+ static Constant *getAnon(LLVMContext &Ctx,
ArrayRef<Constant*> V, bool Packed = false) {
return get(getTypeForElements(Ctx, V, Packed), V);
}
@@ -412,7 +405,7 @@ public:
static StructType *getTypeForElements(LLVMContext &Ctx,
ArrayRef<Constant*> V,
bool Packed = false);
-
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -426,7 +419,6 @@ public:
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ConstantStruct *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantStructVal;
}
@@ -445,17 +437,17 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant)
///
class ConstantVector : public Constant {
friend struct ConstantArrayCreator<ConstantVector, VectorType>;
- ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT
+ ConstantVector(const ConstantVector &) LLVM_DELETED_FUNCTION;
protected:
ConstantVector(VectorType *T, ArrayRef<Constant *> Val);
public:
// ConstantVector accessors
static Constant *get(ArrayRef<Constant*> V);
-
+
/// getSplat - Return a ConstantVector with the specified constant in each
/// element.
static Constant *getSplat(unsigned NumElts, Constant *Elt);
-
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -474,7 +466,6 @@ public:
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ConstantVector *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantVectorVal;
}
@@ -491,8 +482,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant)
/// ConstantPointerNull - a constant pointer value that points to null
///
class ConstantPointerNull : public Constant {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- ConstantPointerNull(const ConstantPointerNull &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION;
protected:
explicit ConstantPointerNull(PointerType *T)
: Constant(reinterpret_cast<Type*>(T),
@@ -517,12 +508,11 @@ public:
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ConstantPointerNull *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantPointerNullVal;
}
};
-
+
//===----------------------------------------------------------------------===//
/// ConstantDataSequential - A vector or array constant whose element type is a
/// simple 1/2/4/8-byte integer or float/double, and whose elements are just
@@ -537,19 +527,19 @@ class ConstantDataSequential : public Constant {
/// DataElements - A pointer to the bytes underlying this constant (which is
/// owned by the uniquing StringMap).
const char *DataElements;
-
+
/// Next - This forms a link list of ConstantDataSequential nodes that have
/// the same value but different type. For example, 0,0,0,1 could be a 4
/// element array of i8, or a 1-element array of i32. They'll both end up in
/// the same StringMap bucket, linked up.
ConstantDataSequential *Next;
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- ConstantDataSequential(const ConstantDataSequential &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ ConstantDataSequential(const ConstantDataSequential &) LLVM_DELETED_FUNCTION;
protected:
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
: Constant(ty, VT, 0, 0), DataElements(Data), Next(0) {}
~ConstantDataSequential() { delete Next; }
-
+
static Constant *getImpl(StringRef Bytes, Type *Ty);
protected:
@@ -558,13 +548,13 @@ protected:
return User::operator new(s, 0);
}
public:
-
+
/// isElementTypeCompatible - Return true if a ConstantDataSequential can be
/// formed with a vector or array of the specified element type.
/// ConstantDataArray only works with normal float and int types that are
/// stored densely in memory, not with things like i42 or x86_f80.
static bool isElementTypeCompatible(const Type *Ty);
-
+
/// getElementAsInteger - If this is a sequential container of integers (of
/// any size), return the specified element in the low bits of a uint64_t.
uint64_t getElementAsInteger(unsigned i) const;
@@ -576,26 +566,26 @@ public:
/// getElementAsFloat - If this is an sequential container of floats, return
/// the specified element as a float.
float getElementAsFloat(unsigned i) const;
-
+
/// getElementAsDouble - If this is an sequential container of doubles, return
/// the specified element as a double.
double getElementAsDouble(unsigned i) const;
-
+
/// getElementAsConstant - Return a Constant for a specified index's element.
/// Note that this has to compute a new constant to return, so it isn't as
/// efficient as getElementAsInteger/Float/Double.
Constant *getElementAsConstant(unsigned i) const;
-
+
/// getType - Specialize the getType() method to always return a
/// SequentialType, which reduces the amount of casting needed in parts of the
/// compiler.
inline SequentialType *getType() const {
return reinterpret_cast<SequentialType*>(Value::getType());
}
-
+
/// getElementType - Return the element type of the array/vector.
Type *getElementType() const;
-
+
/// getNumElements - Return the number of elements in the array or vector.
unsigned getNumElements() const;
@@ -604,14 +594,14 @@ public:
/// byte.
uint64_t getElementByteSize() const;
-
+
/// isString - This method returns true if this is an array of i8.
bool isString() const;
-
+
/// isCString - This method returns true if the array "isString", ends with a
/// nul byte, and does not contains any other nul bytes.
bool isCString() const;
-
+
/// getAsString - If this array is isString(), then this method returns the
/// array as a StringRef. Otherwise, it asserts out.
///
@@ -619,7 +609,7 @@ public:
assert(isString() && "Not a string");
return getRawDataValues();
}
-
+
/// getAsCString - If this array is isCString(), then this method returns the
/// array (without the trailing null byte) as a StringRef. Otherwise, it
/// asserts out.
@@ -629,17 +619,16 @@ public:
StringRef Str = getAsString();
return Str.substr(0, Str.size()-1);
}
-
+
/// getRawDataValues - Return the raw, underlying, bytes of this data. Note
/// that this is an extremely tricky thing to work with, as it exposes the
/// host endianness of the data elements.
StringRef getRawDataValues() const;
-
+
virtual void destroyConstant();
-
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
- static bool classof(const ConstantDataSequential *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantDataArrayVal ||
V->getValueID() == ConstantDataVectorVal;
@@ -655,8 +644,8 @@ private:
/// operands because it stores all of the elements of the constant as densely
/// packed data, instead of as Value*'s.
class ConstantDataArray : public ConstantDataSequential {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- ConstantDataArray(const ConstantDataArray &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ ConstantDataArray(const ConstantDataArray &) LLVM_DELETED_FUNCTION;
virtual void anchor();
friend class ConstantDataSequential;
explicit ConstantDataArray(Type *ty, const char *Data)
@@ -667,7 +656,7 @@ protected:
return User::operator new(s, 0);
}
public:
-
+
/// get() constructors - Return a constant with array type with an element
/// count and element type matching the ArrayRef passed in. Note that this
/// can return a ConstantAggregateZero object.
@@ -677,7 +666,7 @@ public:
static Constant *get(LLVMContext &Context, ArrayRef<uint64_t> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
-
+
/// getString - This method constructs a CDS and initializes it with a text
/// string. The default behavior (AddNull==true) causes a null terminator to
/// be placed at the end of the array (increasing the length of the string by
@@ -692,15 +681,14 @@ public:
inline ArrayType *getType() const {
return reinterpret_cast<ArrayType*>(Value::getType());
}
-
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
- static bool classof(const ConstantDataArray *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantDataArrayVal;
}
};
-
+
//===----------------------------------------------------------------------===//
/// ConstantDataVector - A vector constant whose element type is a simple
/// 1/2/4/8-byte integer or float/double, and whose elements are just simple
@@ -708,8 +696,8 @@ public:
/// operands because it stores all of the elements of the constant as densely
/// packed data, instead of as Value*'s.
class ConstantDataVector : public ConstantDataSequential {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- ConstantDataVector(const ConstantDataVector &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ ConstantDataVector(const ConstantDataVector &) LLVM_DELETED_FUNCTION;
virtual void anchor();
friend class ConstantDataSequential;
explicit ConstantDataVector(Type *ty, const char *Data)
@@ -720,7 +708,7 @@ protected:
return User::operator new(s, 0);
}
public:
-
+
/// get() constructors - Return a constant with vector type with an element
/// count and element type matching the ArrayRef passed in. Note that this
/// can return a ConstantAggregateZero object.
@@ -730,7 +718,7 @@ public:
static Constant *get(LLVMContext &Context, ArrayRef<uint64_t> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
-
+
/// getSplat - Return a ConstantVector with the specified constant in each
/// element. The specified constant has to be a of a compatible type (i8/i16/
/// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
@@ -739,17 +727,16 @@ public:
/// getSplatValue - If this is a splat constant, meaning that all of the
/// elements have the same value, return that value. Otherwise return NULL.
Constant *getSplatValue() const;
-
+
/// getType - Specialize the getType() method to always return a VectorType,
/// which reduces the amount of casting needed in parts of the compiler.
///
inline VectorType *getType() const {
return reinterpret_cast<VectorType*>(Value::getType());
}
-
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
- static bool classof(const ConstantDataVector *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == ConstantDataVectorVal;
}
@@ -760,28 +747,27 @@ public:
/// BlockAddress - The address of a basic block.
///
class BlockAddress : public Constant {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void *operator new(size_t s) { return User::operator new(s, 2); }
BlockAddress(Function *F, BasicBlock *BB);
public:
/// get - Return a BlockAddress for the specified function and basic block.
static BlockAddress *get(Function *F, BasicBlock *BB);
-
+
/// get - Return a BlockAddress for the specified basic block. The basic
/// block must be embedded into a function.
static BlockAddress *get(BasicBlock *BB);
-
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
-
+
Function *getFunction() const { return (Function*)Op<0>().get(); }
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
-
+
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
-
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const BlockAddress *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == BlockAddressVal;
}
@@ -793,7 +779,7 @@ struct OperandTraits<BlockAddress> :
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value)
-
+
//===----------------------------------------------------------------------===//
/// ConstantExpr - a constant value that is initialized with an expression using
@@ -823,14 +809,14 @@ public:
/// getAlignOf constant expr - computes the alignment of a type in a target
/// independent way (Note: the return type is an i64).
static Constant *getAlignOf(Type *Ty);
-
+
/// getSizeOf constant expr - computes the (alloc) size of a type (in
/// address-units, not bits) in a target independent way (Note: the return
/// type is an i64).
///
static Constant *getSizeOf(Type *Ty);
- /// getOffsetOf constant expr - computes the offset of a struct field in a
+ /// getOffsetOf constant expr - computes the offset of a struct field in a
/// target independent way (Note: the return type is an i64).
///
static Constant *getOffsetOf(StructType *STy, unsigned FieldNo);
@@ -839,7 +825,7 @@ public:
/// which supports any aggregate type, and any Constant index.
///
static Constant *getOffsetOf(Type *Ty, Constant *FieldNo);
-
+
static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false);
static Constant *getFNeg(Constant *C);
static Constant *getNot(Constant *C);
@@ -945,7 +931,7 @@ public:
Type *Ty ///< The type to zext or bitcast C to
);
- // @brief Create a SExt or BitCast cast constant expression
+ // @brief Create a SExt or BitCast cast constant expression
static Constant *getSExtOrBitCast(
Constant *C, ///< The constant to sext or bitcast
Type *Ty ///< The type to sext or bitcast C to
@@ -965,14 +951,14 @@ public:
/// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
static Constant *getIntegerCast(
- Constant *C, ///< The integer constant to be casted
+ Constant *C, ///< The integer constant to be casted
Type *Ty, ///< The integer type to cast to
bool isSigned ///< Whether C should be treated as signed or not
);
/// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
static Constant *getFPCast(
- Constant *C, ///< The integer constant to be casted
+ Constant *C, ///< The integer constant to be casted
Type *Ty ///< The integer type to cast to
);
@@ -1076,7 +1062,7 @@ public:
/// getWithOperandReplaced - Return a constant expression identical to this
/// one, but with the specified operand set to the specified value.
Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const;
-
+
/// getWithOperands - This returns the current constant expression with the
/// operands replaced with the specified values. The specified array must
/// have the same number of operands as our current one.
@@ -1090,15 +1076,23 @@ public:
/// current one.
Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const;
+ /// getAsInstruction - Returns an Instruction which implements the same operation
+ /// as this ConstantExpr. The instruction is not linked to any basic block.
+ ///
+ /// A better approach to this could be to have a constructor for Instruction
+ /// which would take a ConstantExpr parameter, but that would have spread
+ /// implementation details of ConstantExpr outside of Constants.cpp, which
+ /// would make it harder to remove ConstantExprs altogether.
+ Instruction *getAsInstruction();
+
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ConstantExpr *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == ConstantExprVal;
}
-
+
private:
// Shadow Value::setValueSubclassData with a private forwarding method so that
// subclasses cannot accidentally use it.
@@ -1125,8 +1119,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
/// LangRef.html#undefvalues for details.
///
class UndefValue : public Constant {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- UndefValue(const UndefValue &); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ UndefValue(const UndefValue &) LLVM_DELETED_FUNCTION;
protected:
explicit UndefValue(Type *T) : Constant(T, UndefValueVal, 0, 0) {}
protected:
@@ -1143,11 +1137,11 @@ public:
/// getSequentialElement - If this Undef has array or vector type, return a
/// undef with the right element type.
UndefValue *getSequentialElement() const;
-
+
/// getStructElement - If this undef has struct type, return a undef with the
/// right element type for the specified element.
UndefValue *getStructElement(unsigned Elt) const;
-
+
/// getElementValue - Return an undef of the right value for the specified GEP
/// index.
UndefValue *getElementValue(Constant *C) const;
@@ -1159,7 +1153,6 @@ public:
virtual void destroyConstant();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const UndefValue *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == UndefValueVal;
}
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/IR/DataLayout.h
index 4f94ab7..cc02017 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/IR/DataLayout.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/TargetData.h - Data size & alignment info ---*- C++ -*-===//
+//===--------- llvm/DataLayout.h - Data size & alignment info ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines target properties related to datatype size/offset/alignment
+// This file defines layout properties related to datatype size/offset/alignment
// information. It uses lazy annotations to cache information about how
// structure types are laid out and used.
//
@@ -17,11 +17,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_TARGETDATA_H
-#define LLVM_TARGET_TARGETDATA_H
+#ifndef LLVM_DATALAYOUT_H
+#define LLVM_DATALAYOUT_H
-#include "llvm/Pass.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Pass.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -36,8 +37,9 @@ class LLVMContext;
template<typename T>
class ArrayRef;
-/// Enum used to categorize the alignment types stored by TargetAlignElem
+/// Enum used to categorize the alignment types stored by LayoutAlignElem
enum AlignTypeEnum {
+ INVALID_ALIGN = 0, ///< An invalid alignment
INTEGER_ALIGN = 'i', ///< Integer type alignment
VECTOR_ALIGN = 'v', ///< Vector type alignment
FLOAT_ALIGN = 'f', ///< Floating point type alignment
@@ -45,38 +47,55 @@ enum AlignTypeEnum {
STACK_ALIGN = 's' ///< Stack objects alignment
};
-/// Target alignment element.
+/// Layout alignment element.
+///
+/// Stores the alignment data associated with a given alignment type (integer,
+/// vector, float) and type bit width.
+///
+/// @note The unusual order of elements in the structure attempts to reduce
+/// padding and make the structure slightly more cache friendly.
+struct LayoutAlignElem {
+ unsigned AlignType : 8; ///< Alignment type (AlignTypeEnum)
+ unsigned TypeBitWidth : 24; ///< Type bit width
+ unsigned ABIAlign : 16; ///< ABI alignment for this type/bitw
+ unsigned PrefAlign : 16; ///< Pref. alignment for this type/bitw
+
+ /// Initializer
+ static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width);
+ /// Equality predicate
+ bool operator==(const LayoutAlignElem &rhs) const;
+};
+
+/// Layout pointer alignment element.
///
-/// Stores the alignment data associated with a given alignment type (pointer,
-/// integer, vector, float) and type bit width.
+/// Stores the alignment data associated with a given pointer and address space.
///
/// @note The unusual order of elements in the structure attempts to reduce
/// padding and make the structure slightly more cache friendly.
-struct TargetAlignElem {
- AlignTypeEnum AlignType : 8; ///< Alignment type (AlignTypeEnum)
+struct PointerAlignElem {
unsigned ABIAlign; ///< ABI alignment for this type/bitw
unsigned PrefAlign; ///< Pref. alignment for this type/bitw
uint32_t TypeBitWidth; ///< Type bit width
+ uint32_t AddressSpace; ///< Address space for the pointer type
/// Initializer
- static TargetAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
+ static PointerAlignElem get(uint32_t addr_space, unsigned abi_align,
unsigned pref_align, uint32_t bit_width);
/// Equality predicate
- bool operator==(const TargetAlignElem &rhs) const;
+ bool operator==(const PointerAlignElem &rhs) const;
};
-/// TargetData - This class holds a parsed version of the target data layout
+
+/// DataLayout - This class holds a parsed version of the target data layout
/// string in a module and provides methods for querying it. The target data
/// layout string is specified *by the target* - a frontend generating LLVM IR
/// is required to generate the right target data for the target being codegen'd
/// to. If some measure of portability is desired, an empty string may be
/// specified in the module.
-class TargetData : public ImmutablePass {
+class DataLayout : public ImmutablePass {
private:
bool LittleEndian; ///< Defaults to false
- unsigned PointerMemSize; ///< Pointer size in bytes
- unsigned PointerABIAlign; ///< Pointer ABI alignment
- unsigned PointerPrefAlign; ///< Pointer preferred alignment
unsigned StackNaturalAlign; ///< Stack natural alignment
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
@@ -85,13 +104,18 @@ private:
///
/// @sa init().
/// @note Could support multiple size pointer alignments, e.g., 32-bit
- /// pointers vs. 64-bit pointers by extending TargetAlignment, but for now,
+ /// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now,
/// we don't.
- SmallVector<TargetAlignElem, 16> Alignments;
+ SmallVector<LayoutAlignElem, 16> Alignments;
+ DenseMap<unsigned, PointerAlignElem> Pointers;
/// InvalidAlignmentElem - This member is a signal that a requested alignment
/// type and bit width were not found in the SmallVector.
- static const TargetAlignElem InvalidAlignmentElem;
+ static const LayoutAlignElem InvalidAlignmentElem;
+
+ /// InvalidPointerElem - This member is a signal that a requested pointer
+ /// type and bit width were not found in the DenseSet.
+ static const PointerAlignElem InvalidPointerElem;
// The StructType -> StructLayout map.
mutable void *LayoutMap;
@@ -101,63 +125,71 @@ private:
unsigned pref_align, uint32_t bit_width);
unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
bool ABIAlign, Type *Ty) const;
+
+ //! Set/initialize pointer alignments
+ void setPointerAlignment(uint32_t addr_space, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width);
+
//! Internal helper method that returns requested alignment for type.
unsigned getAlignment(Type *Ty, bool abi_or_pref) const;
/// Valid alignment predicate.
///
- /// Predicate that tests a TargetAlignElem reference returned by get() against
+ /// Predicate that tests a LayoutAlignElem reference returned by get() against
/// InvalidAlignmentElem.
- bool validAlignment(const TargetAlignElem &align) const {
+ bool validAlignment(const LayoutAlignElem &align) const {
return &align != &InvalidAlignmentElem;
}
- /// Initialise a TargetData object with default values, ensure that the
- /// target data pass is registered.
- void init();
+ /// Valid pointer predicate.
+ ///
+ /// Predicate that tests a PointerAlignElem reference returned by get() against
+ /// InvalidPointerElem.
+ bool validPointer(const PointerAlignElem &align) const {
+ return &align != &InvalidPointerElem;
+ }
+
+ /// Parses a target data specification string. Assert if the string is
+ /// malformed.
+ void parseSpecifier(StringRef LayoutDescription);
public:
/// Default ctor.
///
/// @note This has to exist, because this is a pass, but it should never be
/// used.
- TargetData();
+ DataLayout();
- /// Constructs a TargetData from a specification string. See init().
- explicit TargetData(StringRef TargetDescription)
+ /// Constructs a DataLayout from a specification string. See init().
+ explicit DataLayout(StringRef LayoutDescription)
: ImmutablePass(ID) {
- std::string errMsg = parseSpecifier(TargetDescription, this);
- assert(errMsg == "" && "Invalid target data layout string.");
- (void)errMsg;
+ init(LayoutDescription);
}
- /// Parses a target data specification string. Returns an error message
- /// if the string is malformed, or the empty string on success. Optionally
- /// initialises a TargetData object if passed a non-null pointer.
- static std::string parseSpecifier(StringRef TargetDescription, TargetData* td = 0);
-
/// Initialize target data from properties stored in the module.
- explicit TargetData(const Module *M);
+ explicit DataLayout(const Module *M);
- TargetData(const TargetData &TD) :
+ DataLayout(const DataLayout &TD) :
ImmutablePass(ID),
LittleEndian(TD.isLittleEndian()),
- PointerMemSize(TD.PointerMemSize),
- PointerABIAlign(TD.PointerABIAlign),
- PointerPrefAlign(TD.PointerPrefAlign),
LegalIntWidths(TD.LegalIntWidths),
Alignments(TD.Alignments),
+ Pointers(TD.Pointers),
LayoutMap(0)
{ }
- ~TargetData(); // Not virtual, do not subclass this class
+ ~DataLayout(); // Not virtual, do not subclass this class
+
+ /// Parse a data layout string (with fallback to default values). Ensure that
+ /// the data layout pass is registered.
+ void init(StringRef LayoutDescription);
- /// Target endianness...
+ /// Layout endianness...
bool isLittleEndian() const { return LittleEndian; }
bool isBigEndian() const { return !LittleEndian; }
/// getStringRepresentation - Return the string representation of the
- /// TargetData. This representation is in the same format accepted by the
+ /// DataLayout. This representation is in the same format accepted by the
/// string constructor above.
std::string getStringRepresentation() const;
@@ -195,15 +227,42 @@ public:
return false;
}
- /// Target pointer alignment
- unsigned getPointerABIAlignment() const { return PointerABIAlign; }
+ /// Layout pointer alignment
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerABIAlignment(unsigned AS = 0) const {
+ DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
+ if (val == Pointers.end()) {
+ val = Pointers.find(0);
+ }
+ return val->second.ABIAlign;
+ }
/// Return target's alignment for stack-based pointers
- unsigned getPointerPrefAlignment() const { return PointerPrefAlign; }
- /// Target pointer size
- unsigned getPointerSize() const { return PointerMemSize; }
- /// Target pointer size, in bits
- unsigned getPointerSizeInBits() const { return 8*PointerMemSize; }
-
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerPrefAlignment(unsigned AS = 0) const {
+ DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
+ if (val == Pointers.end()) {
+ val = Pointers.find(0);
+ }
+ return val->second.PrefAlign;
+ }
+ /// Layout pointer size
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerSize(unsigned AS = 0) const {
+ DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
+ if (val == Pointers.end()) {
+ val = Pointers.find(0);
+ }
+ return val->second.TypeBitWidth;
+ }
+ /// Layout pointer size, in bits
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerSizeInBits(unsigned AS = 0) const {
+ return getPointerSize(AS) * 8;
+ }
/// Size examples:
///
/// Type SizeInBits StoreSizeInBits AllocSizeInBits[*]
@@ -223,6 +282,7 @@ public:
/// getTypeSizeInBits - Return the number of bits necessary to hold the
/// specified type. For example, returns 36 for i36 and 80 for x86_fp80.
+ /// The type passed must have a size (Type::isSized() must return true).
uint64_t getTypeSizeInBits(Type* Ty) const;
/// getTypeStoreSize - Return the maximum number of bytes that may be
@@ -279,10 +339,14 @@ public:
///
unsigned getPreferredTypeAlignmentShift(Type *Ty) const;
- /// getIntPtrType - Return an unsigned integer type that is the same size or
- /// greater to the host pointer size.
- ///
- IntegerType *getIntPtrType(LLVMContext &C) const;
+ /// getIntPtrType - Return an integer type with size at least as big as that
+ /// of a pointer in the given address space.
+ IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const;
+
+ /// getIntPtrType - Return an integer (vector of integer) type with size at
+ /// least as big as that of a pointer of the given pointer (vector of pointer)
+ /// type.
+ Type *getIntPtrType(Type *) const;
/// getIndexedOffset - return the offset from the beginning of the type for
/// the specified indices. This is used to implement getelementptr.
@@ -318,7 +382,7 @@ public:
};
/// StructLayout - used to lazily calculate structure layout information for a
-/// target machine, based on the TargetData structure.
+/// target machine, based on the DataLayout structure.
///
class StructLayout {
uint64_t StructSize;
@@ -354,8 +418,8 @@ public:
}
private:
- friend class TargetData; // Only TargetData can create this class
- StructLayout(StructType *ST, const TargetData &TD);
+ friend class DataLayout; // Only DataLayout can create this class
+ StructLayout(StructType *ST, const DataLayout &TD);
};
} // End llvm namespace
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h
index da5ad27..5a941520 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/IR/DerivedTypes.h
@@ -18,7 +18,8 @@
#ifndef LLVM_DERIVED_TYPES_H
#define LLVM_DERIVED_TYPES_H
-#include "llvm/Type.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -84,7 +85,6 @@ public:
bool isPowerOf2ByteWidth() const;
// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const IntegerType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == IntegerTyID;
}
@@ -94,8 +94,8 @@ public:
/// FunctionType - Class to represent function types
///
class FunctionType : public Type {
- FunctionType(const FunctionType &); // Do not implement
- const FunctionType &operator=(const FunctionType &); // Do not implement
+ FunctionType(const FunctionType &) LLVM_DELETED_FUNCTION;
+ const FunctionType &operator=(const FunctionType &) LLVM_DELETED_FUNCTION;
FunctionType(Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
public:
@@ -133,7 +133,6 @@ public:
unsigned getNumParams() const { return NumContainedTys - 1; }
// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const FunctionType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == FunctionTyID;
}
@@ -156,7 +155,6 @@ public:
bool indexValid(unsigned Idx) const;
// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const CompositeType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID ||
@@ -183,12 +181,12 @@ public:
/// Independent of what kind of struct you have, the body of a struct type are
/// laid out in memory consequtively with the elements directly one after the
/// other (if the struct is packed) or (if not packed) with padding between the
-/// elements as defined by TargetData (which is required to match what the code
+/// elements as defined by DataLayout (which is required to match what the code
/// generator for a target expects).
///
class StructType : public CompositeType {
- StructType(const StructType &); // Do not implement
- const StructType &operator=(const StructType &); // Do not implement
+ StructType(const StructType &) LLVM_DELETED_FUNCTION;
+ const StructType &operator=(const StructType &) LLVM_DELETED_FUNCTION;
StructType(LLVMContext &C)
: CompositeType(C, StructTyID), SymbolTableEntry(0) {}
enum {
@@ -292,7 +290,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const StructType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == StructTyID;
}
@@ -308,8 +305,8 @@ public:
///
class SequentialType : public CompositeType {
Type *ContainedType; ///< Storage for the single contained type.
- SequentialType(const SequentialType &); // Do not implement!
- const SequentialType &operator=(const SequentialType &); // Do not implement!
+ SequentialType(const SequentialType &) LLVM_DELETED_FUNCTION;
+ const SequentialType &operator=(const SequentialType &) LLVM_DELETED_FUNCTION;
protected:
SequentialType(TypeID TID, Type *ElType)
@@ -322,7 +319,6 @@ public:
Type *getElementType() const { return ContainedTys[0]; }
// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const SequentialType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == PointerTyID ||
@@ -336,8 +332,8 @@ public:
class ArrayType : public SequentialType {
uint64_t NumElements;
- ArrayType(const ArrayType &); // Do not implement
- const ArrayType &operator=(const ArrayType &); // Do not implement
+ ArrayType(const ArrayType &) LLVM_DELETED_FUNCTION;
+ const ArrayType &operator=(const ArrayType &) LLVM_DELETED_FUNCTION;
ArrayType(Type *ElType, uint64_t NumEl);
public:
/// ArrayType::get - This static method is the primary way to construct an
@@ -352,7 +348,6 @@ public:
uint64_t getNumElements() const { return NumElements; }
// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const ArrayType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID;
}
@@ -363,8 +358,8 @@ public:
class VectorType : public SequentialType {
unsigned NumElements;
- VectorType(const VectorType &); // Do not implement
- const VectorType &operator=(const VectorType &); // Do not implement
+ VectorType(const VectorType &) LLVM_DELETED_FUNCTION;
+ const VectorType &operator=(const VectorType &) LLVM_DELETED_FUNCTION;
VectorType(Type *ElType, unsigned NumEl);
public:
/// VectorType::get - This static method is the primary way to construct an
@@ -419,7 +414,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VectorType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == VectorTyID;
}
@@ -429,8 +423,8 @@ public:
/// PointerType - Class to represent pointers.
///
class PointerType : public SequentialType {
- PointerType(const PointerType &); // Do not implement
- const PointerType &operator=(const PointerType &); // Do not implement
+ PointerType(const PointerType &) LLVM_DELETED_FUNCTION;
+ const PointerType &operator=(const PointerType &) LLVM_DELETED_FUNCTION;
explicit PointerType(Type *ElType, unsigned AddrSpace);
public:
/// PointerType::get - This constructs a pointer to an object of the specified
@@ -451,7 +445,6 @@ public:
inline unsigned getAddressSpace() const { return getSubclassData(); }
// Implement support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const PointerType *) { return true; }
static inline bool classof(const Type *T) {
return T->getTypeID() == PointerTyID;
}
diff --git a/include/llvm/Function.h b/include/llvm/IR/Function.h
index fdd90d1..1762b2c 100644
--- a/include/llvm/Function.h
+++ b/include/llvm/IR/Function.h
@@ -18,11 +18,11 @@
#ifndef LLVM_FUNCTION_H
#define LLVM_FUNCTION_H
-#include "llvm/GlobalValue.h"
-#include "llvm/CallingConv.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/Argument.h"
-#include "llvm/Attributes.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -85,11 +85,11 @@ private:
BasicBlockListType BasicBlocks; ///< The basic blocks
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
- AttrListPtr AttributeList; ///< Parameter attributes
+ AttributeSet AttributeList; ///< Parameter attributes
// HasLazyArguments is stored in Value::SubclassData.
/*bool HasLazyArguments;*/
-
+
// The Calling Convention is stored in Value::SubclassData.
/*CallingConv::ID CallingConvention;*/
@@ -109,9 +109,9 @@ private:
BuildLazyArguments();
}
void BuildLazyArguments() const;
-
- Function(const Function&); // DO NOT IMPLEMENT
- void operator=(const Function&); // DO NOT IMPLEMENT
+
+ Function(const Function&) LLVM_DELETED_FUNCTION;
+ void operator=(const Function&) LLVM_DELETED_FUNCTION;
/// Function ctor - If the (optional) Module argument is specified, the
/// function is automatically inserted into the end of the function list for
@@ -131,7 +131,7 @@ public:
Type *getReturnType() const; // Return the type of the ret val
FunctionType *getFunctionType() const; // Return the FunctionType for me
- /// getContext - Return a pointer to the LLVMContext associated with this
+ /// getContext - Return a pointer to the LLVMContext associated with this
/// function, or NULL if this function is not bound to a context yet.
LLVMContext &getContext() const;
@@ -147,7 +147,7 @@ public:
/// defined in llvm/Intrinsics.h.
///
unsigned getIntrinsicID() const LLVM_READONLY;
- bool isIntrinsic() const { return getIntrinsicID() != 0; }
+ bool isIntrinsic() const { return getName().startswith("llvm."); }
/// getCallingConv()/setCallingConv(CC) - These method get and set the
/// calling convention of this function. The enum values for the known
@@ -159,32 +159,26 @@ public:
setValueSubclassData((getSubclassDataFromValue() & 1) |
(static_cast<unsigned>(CC) << 1));
}
-
+
/// getAttributes - Return the attribute list for this Function.
///
- const AttrListPtr &getAttributes() const { return AttributeList; }
+ const AttributeSet &getAttributes() const { return AttributeList; }
/// setAttributes - Set the attribute list for this Function.
///
- void setAttributes(const AttrListPtr &attrs) { AttributeList = attrs; }
-
- /// hasFnAttr - Return true if this function has the given attribute.
- bool hasFnAttr(Attributes N) const {
- // Function Attributes are stored at ~0 index
- return AttributeList.paramHasAttr(~0U, N);
- }
+ void setAttributes(const AttributeSet &attrs) { AttributeList = attrs; }
/// addFnAttr - Add function attributes to this function.
///
- void addFnAttr(Attributes N) {
- // Function Attributes are stored at ~0 index
- addAttribute(~0U, N);
+ void addFnAttr(Attribute::AttrKind N) {
+ // Function Attribute are stored at ~0 index
+ addAttribute(AttributeSet::FunctionIndex, Attribute::get(getContext(), N));
}
/// removeFnAttr - Remove function attributes from this function.
///
- void removeFnAttr(Attributes N) {
- // Function Attributes are stored at ~0 index
+ void removeFnAttr(Attribute N) {
+ // Function Attribute are stored at ~0 index
removeAttribute(~0U, N);
}
@@ -195,16 +189,11 @@ public:
void setGC(const char *Str);
void clearGC();
- /// @brief Determine whether the function has the given attribute.
- bool paramHasAttr(unsigned i, Attributes attr) const {
- return AttributeList.paramHasAttr(i, attr);
- }
-
/// addAttribute - adds the attribute to the list of attributes.
- void addAttribute(unsigned i, Attributes attr);
-
+ void addAttribute(unsigned i, Attribute attr);
+
/// removeAttribute - removes the attribute from the list of attributes.
- void removeAttribute(unsigned i, Attributes attr);
+ void removeAttribute(unsigned i, Attribute attr);
/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
@@ -213,50 +202,58 @@ public:
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
- return hasFnAttr(Attribute::ReadNone);
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::ReadNone);
}
- void setDoesNotAccessMemory(bool DoesNotAccessMemory = true) {
- if (DoesNotAccessMemory) addFnAttr(Attribute::ReadNone);
- else removeFnAttr(Attribute::ReadNone);
+ void setDoesNotAccessMemory() {
+ addFnAttr(Attribute::ReadNone);
}
/// @brief Determine if the function does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
+ return doesNotAccessMemory() ||
+ AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::ReadOnly);
}
- void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
- if (OnlyReadsMemory) addFnAttr(Attribute::ReadOnly);
- else removeFnAttr(Attribute::ReadOnly | Attribute::ReadNone);
+ void setOnlyReadsMemory() {
+ addFnAttr(Attribute::ReadOnly);
}
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
- return hasFnAttr(Attribute::NoReturn);
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoReturn);
}
- void setDoesNotReturn(bool DoesNotReturn = true) {
- if (DoesNotReturn) addFnAttr(Attribute::NoReturn);
- else removeFnAttr(Attribute::NoReturn);
+ void setDoesNotReturn() {
+ addFnAttr(Attribute::NoReturn);
}
/// @brief Determine if the function cannot unwind.
bool doesNotThrow() const {
- return hasFnAttr(Attribute::NoUnwind);
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoUnwind);
+ }
+ void setDoesNotThrow() {
+ addFnAttr(Attribute::NoUnwind);
+ }
+
+ /// @brief Determine if the call cannot be duplicated.
+ bool cannotDuplicate() const {
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoDuplicate);
}
- void setDoesNotThrow(bool DoesNotThrow = true) {
- if (DoesNotThrow) addFnAttr(Attribute::NoUnwind);
- else removeFnAttr(Attribute::NoUnwind);
+ void setCannotDuplicate() {
+ addFnAttr(Attribute::NoDuplicate);
}
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
- return hasFnAttr(Attribute::UWTable);
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::UWTable);
}
- void setHasUWTable(bool HasUWTable = true) {
- if (HasUWTable)
- addFnAttr(Attribute::UWTable);
- else
- removeFnAttr(Attribute::UWTable);
+ void setHasUWTable() {
+ addFnAttr(Attribute::UWTable);
}
/// @brief True if this function needs an unwind table.
@@ -264,30 +261,28 @@ public:
return hasUWTable() || !doesNotThrow();
}
- /// @brief Determine if the function returns a structure through first
+ /// @brief Determine if the function returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
- return paramHasAttr(1, Attribute::StructRet);
+ return AttributeList.hasAttribute(1, Attribute::StructRet);
}
/// @brief Determine if the parameter does not alias other parameters.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotAlias(unsigned n) const {
- return paramHasAttr(n, Attribute::NoAlias);
+ return AttributeList.hasAttribute(n, Attribute::NoAlias);
}
- void setDoesNotAlias(unsigned n, bool DoesNotAlias = true) {
- if (DoesNotAlias) addAttribute(n, Attribute::NoAlias);
- else removeAttribute(n, Attribute::NoAlias);
+ void setDoesNotAlias(unsigned n) {
+ addAttribute(n, Attribute::get(getContext(), Attribute::NoAlias));
}
/// @brief Determine if the parameter can be captured.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotCapture(unsigned n) const {
- return paramHasAttr(n, Attribute::NoCapture);
+ return AttributeList.hasAttribute(n, Attribute::NoCapture);
}
- void setDoesNotCapture(unsigned n, bool DoesNotCapture = true) {
- if (DoesNotCapture) addAttribute(n, Attribute::NoCapture);
- else removeAttribute(n, Attribute::NoCapture);
+ void setDoesNotCapture(unsigned n) {
+ addAttribute(n, Attribute::get(getContext(), Attribute::NoCapture));
}
/// copyAttributesFrom - copy all additional attributes (those not needed to
@@ -400,7 +395,6 @@ public:
void viewCFGOnly() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Function *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal;
}
diff --git a/include/llvm/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index 164d976..03c1648 100644
--- a/include/llvm/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -15,10 +15,10 @@
#ifndef LLVM_GLOBAL_ALIAS_H
#define LLVM_GLOBAL_ALIAS_H
-#include "llvm/GlobalValue.h"
-#include "llvm/OperandTraits.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/OperandTraits.h"
namespace llvm {
@@ -28,8 +28,8 @@ template<typename ValueSubClass, typename ItemParentClass>
class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
friend class SymbolTableListTraits<GlobalAlias, Module>;
- void operator=(const GlobalAlias &); // Do not implement
- GlobalAlias(const GlobalAlias &); // Do not implement
+ void operator=(const GlobalAlias &) LLVM_DELETED_FUNCTION;
+ GlobalAlias(const GlobalAlias &) LLVM_DELETED_FUNCTION;
void setParent(Module *parent);
@@ -76,7 +76,6 @@ public:
const GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true) const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const GlobalAlias *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::GlobalAliasVal;
}
diff --git a/include/llvm/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index 391b830..246e00b 100644
--- a/include/llvm/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -18,7 +18,7 @@
#ifndef LLVM_GLOBALVALUE_H
#define LLVM_GLOBALVALUE_H
-#include "llvm/Constant.h"
+#include "llvm/IR/Constant.h"
namespace llvm {
@@ -26,7 +26,7 @@ class PointerType;
class Module;
class GlobalValue : public Constant {
- GlobalValue(const GlobalValue &); // do not implement
+ GlobalValue(const GlobalValue &) LLVM_DELETED_FUNCTION;
public:
/// @brief An enumeration for the kinds of linkage for global values.
enum LinkageTypes {
@@ -287,7 +287,6 @@ public:
inline const Module *getParent() const { return Parent; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const GlobalValue *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
V->getValueID() == Value::GlobalVariableVal ||
diff --git a/include/llvm/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
index 99b7a73..5c42d76 100644
--- a/include/llvm/GlobalVariable.h
+++ b/include/llvm/IR/GlobalVariable.h
@@ -20,10 +20,10 @@
#ifndef LLVM_GLOBAL_VARIABLE_H
#define LLVM_GLOBAL_VARIABLE_H
-#include "llvm/GlobalValue.h"
-#include "llvm/OperandTraits.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/OperandTraits.h"
namespace llvm {
@@ -34,9 +34,9 @@ template<typename ValueSubClass, typename ItemParentClass>
class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
friend class SymbolTableListTraits<GlobalVariable, Module>;
- void *operator new(size_t, unsigned); // Do not implement
- void operator=(const GlobalVariable &); // Do not implement
- GlobalVariable(const GlobalVariable &); // Do not implement
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void operator=(const GlobalVariable &) LLVM_DELETED_FUNCTION;
+ GlobalVariable(const GlobalVariable &) LLVM_DELETED_FUNCTION;
void setParent(Module *parent);
@@ -174,7 +174,6 @@ public:
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const GlobalVariable *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::GlobalVariableVal;
}
diff --git a/include/llvm/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index d5b6f47..27f990e 100644
--- a/include/llvm/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -15,12 +15,14 @@
#ifndef LLVM_IRBUILDER_H
#define LLVM_IRBUILDER_H
-#include "llvm/Instructions.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/LLVMContext.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Operator.h"
#include "llvm/Support/ConstantFolder.h"
namespace llvm {
@@ -237,7 +239,7 @@ public:
return Type::getInt16Ty(Context);
}
- /// getInt32Ty - Fetch the type resepresenting a 32-bit integer.
+ /// getInt32Ty - Fetch the type representing a 32-bit integer.
IntegerType *getInt32Ty() {
return Type::getInt32Ty(Context);
}
@@ -266,6 +268,10 @@ public:
return Type::getInt8PtrTy(Context, AddrSpace);
}
+ IntegerType* getIntPtrTy(DataLayout *DL, unsigned AddrSpace = 0) {
+ return DL->getIntPtrType(Context, AddrSpace);
+ }
+
//===--------------------------------------------------------------------===//
// Intrinsic creation methods
//===--------------------------------------------------------------------===//
@@ -285,12 +291,15 @@ public:
/// If the pointers aren't i8*, they will be converted. If a TBAA tag is
/// specified, it will be added to the instruction.
CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0) {
- return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
+ bool isVolatile = false, MDNode *TBAATag = 0,
+ MDNode *TBAAStructTag = 0) {
+ return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag,
+ TBAAStructTag);
}
CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0);
+ bool isVolatile = false, MDNode *TBAATag = 0,
+ MDNode *TBAAStructTag = 0);
/// CreateMemMove - Create and insert a memmove between the specified
/// pointers. If the pointers aren't i8*, they will be converted. If a TBAA
@@ -321,7 +330,10 @@ private:
///
/// Note that the builder does not expose the full generality of LLVM
/// instructions. For access to extra instruction properties, use the mutators
-/// (e.g. setVolatile) on the instructions after they have been created.
+/// (e.g. setVolatile) on the instructions after they have been
+/// created. Convenience state exists to specify fast-math flags and fp-math
+/// tags.
+///
/// The first template argument handles whether or not to preserve names in the
/// final instruction output. This defaults to on. The second template argument
/// specifies a class to use for creating constants. This defaults to creating
@@ -333,36 +345,40 @@ template<bool preserveNames = true, typename T = ConstantFolder,
class IRBuilder : public IRBuilderBase, public Inserter {
T Folder;
MDNode *DefaultFPMathTag;
+ FastMathFlags FMF;
public:
IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(),
MDNode *FPMathTag = 0)
- : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) {
+ : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag),
+ FMF() {
}
- explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C),
- Folder(), DefaultFPMathTag(FPMathTag) {
+ explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0)
+ : IRBuilderBase(C), Folder(), DefaultFPMathTag(FPMathTag), FMF() {
}
explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0)
: IRBuilderBase(TheBB->getContext()), Folder(F),
- DefaultFPMathTag(FPMathTag) {
+ DefaultFPMathTag(FPMathTag), FMF() {
SetInsertPoint(TheBB);
}
explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0)
: IRBuilderBase(TheBB->getContext()), Folder(),
- DefaultFPMathTag(FPMathTag) {
+ DefaultFPMathTag(FPMathTag), FMF() {
SetInsertPoint(TheBB);
}
explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0)
- : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
+ : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag),
+ FMF() {
SetInsertPoint(IP);
SetCurrentDebugLocation(IP->getDebugLoc());
}
explicit IRBuilder(Use &U, MDNode *FPMathTag = 0)
- : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
+ : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag),
+ FMF() {
SetInsertPoint(U);
SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
}
@@ -370,13 +386,13 @@ public:
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F,
MDNode *FPMathTag = 0)
: IRBuilderBase(TheBB->getContext()), Folder(F),
- DefaultFPMathTag(FPMathTag) {
+ DefaultFPMathTag(FPMathTag), FMF() {
SetInsertPoint(TheBB, IP);
}
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0)
: IRBuilderBase(TheBB->getContext()), Folder(),
- DefaultFPMathTag(FPMathTag) {
+ DefaultFPMathTag(FPMathTag), FMF() {
SetInsertPoint(TheBB, IP);
}
@@ -386,9 +402,18 @@ public:
/// getDefaultFPMathTag - Get the floating point math metadata being used.
MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; }
+ /// Get the flags to be applied to created floating point ops
+ FastMathFlags getFastMathFlags() const { return FMF; }
+
+ /// Clear the fast-math flags.
+ void clearFastMathFlags() { FMF.clear(); }
+
/// SetDefaultFPMathTag - Set the floating point math metadata to be used.
void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; }
+ /// Set the fast-math flags to be used with generated fp-math operators
+ void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
+
/// isNamePreserving - Return true if this builder is configured to actually
/// add the requested names to IR created through it.
bool isNamePreserving() const { return preserveNames; }
@@ -527,11 +552,14 @@ private:
return BO;
}
- Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const {
+ Instruction *AddFPMathAttributes(Instruction *I,
+ MDNode *FPMathTag,
+ FastMathFlags FMF) const {
if (!FPMathTag)
FPMathTag = DefaultFPMathTag;
if (FPMathTag)
I->setMetadata(LLVMContext::MD_fpmath, FPMathTag);
+ I->setFastMathFlags(FMF);
return I;
}
public:
@@ -554,8 +582,8 @@ public:
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFAdd(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS),
- FPMathTag), Name);
+ return Insert(AddFPMathAttributes(BinaryOperator::CreateFAdd(LHS, RHS),
+ FPMathTag, FMF), Name);
}
Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "",
bool HasNUW = false, bool HasNSW = false) {
@@ -576,8 +604,8 @@ public:
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFSub(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS),
- FPMathTag), Name);
+ return Insert(AddFPMathAttributes(BinaryOperator::CreateFSub(LHS, RHS),
+ FPMathTag, FMF), Name);
}
Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "",
bool HasNUW = false, bool HasNSW = false) {
@@ -598,8 +626,8 @@ public:
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFMul(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS),
- FPMathTag), Name);
+ return Insert(AddFPMathAttributes(BinaryOperator::CreateFMul(LHS, RHS),
+ FPMathTag, FMF), Name);
}
Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
bool isExact = false) {
@@ -630,8 +658,8 @@ public:
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFDiv(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS),
- FPMathTag), Name);
+ return Insert(AddFPMathAttributes(BinaryOperator::CreateFDiv(LHS, RHS),
+ FPMathTag, FMF), Name);
}
Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
@@ -650,8 +678,8 @@ public:
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFRem(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS),
- FPMathTag), Name);
+ return Insert(AddFPMathAttributes(BinaryOperator::CreateFRem(LHS, RHS),
+ FPMathTag, FMF), Name);
}
Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "",
@@ -780,7 +808,8 @@ public:
Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) {
if (Constant *VC = dyn_cast<Constant>(V))
return Insert(Folder.CreateFNeg(VC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), Name);
+ return Insert(AddFPMathAttributes(BinaryOperator::CreateFNeg(V),
+ FPMathTag, FMF), Name);
}
Value *CreateNot(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
@@ -810,6 +839,31 @@ public:
StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
return Insert(new StoreInst(Val, Ptr, isVolatile));
}
+ // Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' correctly,
+ // instead of converting the string to 'bool' for the isVolatile parameter.
+ LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) {
+ LoadInst *LI = CreateLoad(Ptr, Name);
+ LI->setAlignment(Align);
+ return LI;
+ }
+ LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align,
+ const Twine &Name = "") {
+ LoadInst *LI = CreateLoad(Ptr, Name);
+ LI->setAlignment(Align);
+ return LI;
+ }
+ LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile,
+ const Twine &Name = "") {
+ LoadInst *LI = CreateLoad(Ptr, isVolatile, Name);
+ LI->setAlignment(Align);
+ return LI;
+ }
+ StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align,
+ bool isVolatile = false) {
+ StoreInst *SI = CreateStore(Val, Ptr, isVolatile);
+ SI->setAlignment(Align);
+ return SI;
+ }
FenceInst *CreateFence(AtomicOrdering Ordering,
SynchronizationScope SynchScope = CrossThread) {
return Insert(new FenceInst(Context, Ordering, SynchScope));
@@ -970,6 +1024,30 @@ public:
Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") {
return CreateCast(Instruction::SExt, V, DestTy, Name);
}
+ /// CreateZExtOrTrunc - Create a ZExt or Trunc from the integer value V to
+ /// DestTy. Return the value untouched if the type of V is already DestTy.
+ Value *CreateZExtOrTrunc(Value *V, IntegerType *DestTy,
+ const Twine &Name = "") {
+ assert(isa<IntegerType>(V->getType()) && "Can only zero extend integers!");
+ IntegerType *IntTy = cast<IntegerType>(V->getType());
+ if (IntTy->getBitWidth() < DestTy->getBitWidth())
+ return CreateZExt(V, DestTy, Name);
+ if (IntTy->getBitWidth() > DestTy->getBitWidth())
+ return CreateTrunc(V, DestTy, Name);
+ return V;
+ }
+ /// CreateSExtOrTrunc - Create a SExt or Trunc from the integer value V to
+ /// DestTy. Return the value untouched if the type of V is already DestTy.
+ Value *CreateSExtOrTrunc(Value *V, IntegerType *DestTy,
+ const Twine &Name = "") {
+ assert(isa<IntegerType>(V->getType()) && "Can only sign extend integers!");
+ IntegerType *IntTy = cast<IntegerType>(V->getType());
+ if (IntTy->getBitWidth() < DestTy->getBitWidth())
+ return CreateSExt(V, DestTy, Name);
+ if (IntTy->getBitWidth() > DestTy->getBitWidth())
+ return CreateTrunc(V, DestTy, Name);
+ return V;
+ }
Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){
return CreateCast(Instruction::FPToUI, V, DestTy, Name);
}
@@ -1052,7 +1130,7 @@ public:
private:
// Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile time
// error, instead of converting the string to bool for the isSigned parameter.
- Value *CreateIntCast(Value *, Type *, const char *); // DO NOT IMPLEMENT
+ Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION;
public:
Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") {
if (V->getType() == DestTy)
@@ -1254,20 +1332,20 @@ public:
LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses,
const Twine &Name = "") {
- return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name));
+ return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses), Name);
}
//===--------------------------------------------------------------------===//
// Utility creation methods
//===--------------------------------------------------------------------===//
- /// CreateIsNull - Return an i1 value testing if \arg Arg is null.
+ /// CreateIsNull - Return an i1 value testing if \p Arg is null.
Value *CreateIsNull(Value *Arg, const Twine &Name = "") {
return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
Name);
}
- /// CreateIsNotNull - Return an i1 value testing if \arg Arg is not null.
+ /// CreateIsNotNull - Return an i1 value testing if \p Arg is not null.
Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") {
return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
Name);
@@ -1289,6 +1367,22 @@ public:
ConstantExpr::getSizeOf(ArgType->getElementType()),
Name);
}
+
+ /// CreateVectorSplat - Return a vector value that contains \arg V broadcasted
+ /// to \p NumElts elements.
+ Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") {
+ assert(NumElts > 0 && "Cannot splat to an empty vector!");
+
+ // First insert it into an undef vector so we can shuffle it.
+ Type *I32Ty = getInt32Ty();
+ Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts));
+ V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0),
+ Name + ".splatinsert");
+
+ // Shuffle the value across the desired number of elements.
+ Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts));
+ return CreateShuffleVector(V, Undef, Zeros, Name + ".splat");
+ }
};
}
diff --git a/include/llvm/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index a0aecfd..15d4fb0 100644
--- a/include/llvm/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -16,8 +16,8 @@
#ifndef LLVM_INLINEASM_H
#define LLVM_INLINEASM_H
-#include "llvm/Value.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Value.h"
#include <vector>
namespace llvm {
@@ -44,8 +44,8 @@ private:
friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&,
PointerType, InlineAsm, false>;
- InlineAsm(const InlineAsm &); // do not implement
- void operator=(const InlineAsm&); // do not implement
+ InlineAsm(const InlineAsm &) LLVM_DELETED_FUNCTION;
+ void operator=(const InlineAsm&) LLVM_DELETED_FUNCTION;
std::string AsmString, Constraints;
bool HasSideEffects;
@@ -189,7 +189,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const InlineAsm *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::InlineAsmVal;
}
@@ -215,6 +214,8 @@ public:
Extra_HasSideEffects = 1,
Extra_IsAlignStack = 2,
Extra_AsmDialect = 4,
+ Extra_MayLoad = 8,
+ Extra_MayStore = 16,
// Inline asm operands map to multiple SDNode / MachineInstr operands.
// The first operand is an immediate describing the asm operand, the low
diff --git a/include/llvm/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index 6291a6d..66bf8dd 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -16,10 +16,10 @@
#ifndef LLVM_INSTRUCTION_TYPES_H
#define LLVM_INSTRUCTION_TYPES_H
-#include "llvm/Instruction.h"
-#include "llvm/OperandTraits.h"
-#include "llvm/DerivedTypes.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/OperandTraits.h"
namespace llvm {
@@ -73,7 +73,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const TerminatorInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->isTerminator();
}
@@ -88,7 +87,7 @@ public:
//===----------------------------------------------------------------------===//
class UnaryInstruction : public Instruction {
- void *operator new(size_t, unsigned); // Do not implement
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
protected:
UnaryInstruction(Type *Ty, unsigned iType, Value *V,
@@ -113,7 +112,6 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const UnaryInstruction *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Alloca ||
I->getOpcode() == Instruction::Load ||
@@ -138,14 +136,14 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
//===----------------------------------------------------------------------===//
class BinaryOperator : public Instruction {
- void *operator new(size_t, unsigned); // Do not implement
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
protected:
void init(BinaryOps iType);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, Instruction *InsertBefore);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, BasicBlock *InsertAtEnd);
- virtual BinaryOperator *clone_impl() const;
+ virtual BinaryOperator *clone_impl() const LLVM_OVERRIDE;
public:
// allocate space for exactly two operands
void *operator new(size_t s) {
@@ -179,19 +177,19 @@ public:
const Twine &Name = "") {\
return Create(Instruction::OPC, V1, V2, Name);\
}
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
#define HANDLE_BINARY_INST(N, OPC, CLASS) \
static BinaryOperator *Create##OPC(Value *V1, Value *V2, \
const Twine &Name, BasicBlock *BB) {\
return Create(Instruction::OPC, V1, V2, Name, BB);\
}
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
#define HANDLE_BINARY_INST(N, OPC, CLASS) \
static BinaryOperator *Create##OPC(Value *V1, Value *V2, \
const Twine &Name, Instruction *I) {\
return Create(Instruction::OPC, V1, V2, Name, I);\
}
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
const Twine &Name = "") {
@@ -361,7 +359,6 @@ public:
bool isExact() const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const BinaryOperator *) { return true; }
static inline bool classof(const Instruction *I) {
return I->isBinaryOp();
}
@@ -388,7 +385,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
/// if (isa<CastInst>(Instr)) { ... }
/// @brief Base class of casting instructions.
class CastInst : public UnaryInstruction {
- virtual void anchor();
+ virtual void anchor() LLVM_OVERRIDE;
protected:
/// @brief Constructor with insert-before-instruction semantics for subclasses
CastInst(Type *Ty, unsigned iType, Value *S,
@@ -563,7 +560,7 @@ public:
/// IntPtrTy argument is used to make accurate determinations for casts
/// involving Integer and Pointer types. They are no-op casts if the integer
/// is the same size as the pointer. However, pointer size varies with
- /// platform. Generally, the result of TargetData::getIntPtrType() should be
+ /// platform. Generally, the result of DataLayout::getIntPtrType() should be
/// passed in. If that's not available, use Type::Int64Ty, which will make
/// the isNoopCast call conservative.
/// @brief Determine if the described cast is a no-op cast.
@@ -591,7 +588,9 @@ public:
Type *SrcTy, ///< SrcTy of 1st cast
Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
Type *DstTy, ///< DstTy of 2nd cast
- Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
+ Type *SrcIntPtrTy, ///< Integer type corresponding to Ptr SrcTy, or null
+ Type *MidIntPtrTy, ///< Integer type corresponding to Ptr MidTy, or null
+ Type *DstIntPtrTy ///< Integer type corresponding to Ptr DstTy, or null
);
/// @brief Return the opcode of this CastInst
@@ -611,7 +610,6 @@ public:
static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy);
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const CastInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->isCast();
}
@@ -627,8 +625,8 @@ public:
/// This class is the base class for the comparison instructions.
/// @brief Abstract base class of comparison instructions.
class CmpInst : public Instruction {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- CmpInst(); // do not implement
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ CmpInst() LLVM_DELETED_FUNCTION;
protected:
CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
Value *LHS, Value *RHS, const Twine &Name = "",
@@ -638,7 +636,7 @@ protected:
Value *LHS, Value *RHS, const Twine &Name,
BasicBlock *InsertAtEnd);
- virtual void Anchor() const; // Out of line virtual method.
+ virtual void anchor() LLVM_OVERRIDE; // Out of line virtual method.
public:
/// This enumeration lists the possible predicates for CmpInst subclasses.
/// Values in the range 0-31 are reserved for FCmpInst, while values in the
@@ -816,7 +814,6 @@ public:
static bool isFalseWhenEqual(unsigned short predicate);
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const CmpInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ICmp ||
I->getOpcode() == Instruction::FCmp;
diff --git a/include/llvm/Instruction.def b/include/llvm/IR/Instruction.def
index e59a052..e59a052 100644
--- a/include/llvm/Instruction.def
+++ b/include/llvm/IR/Instruction.def
diff --git a/include/llvm/Instruction.h b/include/llvm/IR/Instruction.h
index 5512dcc..2731bfb 100644
--- a/include/llvm/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -15,12 +15,13 @@
#ifndef LLVM_INSTRUCTION_H
#define LLVM_INSTRUCTION_H
-#include "llvm/User.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/User.h"
#include "llvm/Support/DebugLoc.h"
namespace llvm {
+class FastMathFlags;
class LLVMContext;
class MDNode;
@@ -28,12 +29,12 @@ template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
class Instruction : public User, public ilist_node<Instruction> {
- void operator=(const Instruction &); // Do not implement
- Instruction(const Instruction &); // Do not implement
+ void operator=(const Instruction &) LLVM_DELETED_FUNCTION;
+ Instruction(const Instruction &) LLVM_DELETED_FUNCTION;
BasicBlock *Parent;
DebugLoc DbgLoc; // 'dbg' Metadata cache.
-
+
enum {
/// HasMetadataBit - This is a bit stored in the SubClassData field which
/// indicates whether this instruction has metadata attached to it or not.
@@ -42,12 +43,12 @@ class Instruction : public User, public ilist_node<Instruction> {
public:
// Out of line virtual method, so the vtable, etc has a home.
~Instruction();
-
+
/// use_back - Specialize the methods defined in Value, as we know that an
/// instruction can only be used by other instructions.
Instruction *use_back() { return cast<Instruction>(*use_begin());}
const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
-
+
inline const BasicBlock *getParent() const { return Parent; }
inline BasicBlock *getParent() { return Parent; }
@@ -77,16 +78,16 @@ public:
//===--------------------------------------------------------------------===//
// Subclass classification.
//===--------------------------------------------------------------------===//
-
+
/// getOpcode() returns a member of one of the enums like Instruction::Add.
unsigned getOpcode() const { return getValueID() - InstructionVal; }
-
+
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
bool isTerminator() const { return isTerminator(getOpcode()); }
bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
bool isShift() { return isShift(getOpcode()); }
bool isCast() const { return isCast(getOpcode()); }
-
+
static const char* getOpcodeName(unsigned OpCode);
static inline bool isTerminator(unsigned OpCode) {
@@ -121,33 +122,33 @@ public:
//===--------------------------------------------------------------------===//
// Metadata manipulation.
//===--------------------------------------------------------------------===//
-
+
/// hasMetadata() - Return true if this instruction has any metadata attached
/// to it.
bool hasMetadata() const {
return !DbgLoc.isUnknown() || hasMetadataHashEntry();
}
-
+
/// hasMetadataOtherThanDebugLoc - Return true if this instruction has
/// metadata attached to it other than a debug location.
bool hasMetadataOtherThanDebugLoc() const {
return hasMetadataHashEntry();
}
-
+
/// getMetadata - Get the metadata of given kind attached to this Instruction.
/// If the metadata is not found then return null.
MDNode *getMetadata(unsigned KindID) const {
if (!hasMetadata()) return 0;
return getMetadataImpl(KindID);
}
-
+
/// getMetadata - Get the metadata of given kind attached to this Instruction.
/// If the metadata is not found then return null.
MDNode *getMetadata(StringRef Kind) const {
if (!hasMetadata()) return 0;
return getMetadataImpl(Kind);
}
-
+
/// getAllMetadata - Get all metadata attached to this Instruction. The first
/// element of each pair returned is the KindID, the second element is the
/// metadata value. This list is returned sorted by the KindID.
@@ -155,7 +156,7 @@ public:
if (hasMetadata())
getAllMetadataImpl(MDs);
}
-
+
/// getAllMetadataOtherThanDebugLoc - This does the same thing as
/// getAllMetadata, except that it filters out the debug location.
void getAllMetadataOtherThanDebugLoc(SmallVectorImpl<std::pair<unsigned,
@@ -163,7 +164,7 @@ public:
if (hasMetadataOtherThanDebugLoc())
getAllMetadataOtherThanDebugLocImpl(MDs);
}
-
+
/// setMetadata - Set the metadata of the specified kind to the specified
/// node. This updates/replaces metadata if already present, or removes it if
/// Node is null.
@@ -172,17 +173,70 @@ public:
/// setDebugLoc - Set the debug location information for this instruction.
void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
-
+
/// getDebugLoc - Return the debug location for this node as a DebugLoc.
const DebugLoc &getDebugLoc() const { return DbgLoc; }
-
+
+ /// Set or clear the unsafe-algebra flag on this instruction, which must be an
+ /// operator which supports this flag. See LangRef.html for the meaning of
+ /// this flag.
+ void setHasUnsafeAlgebra(bool B);
+
+ /// Set or clear the no-nans flag on this instruction, which must be an
+ /// operator which supports this flag. See LangRef.html for the meaning of
+ /// this flag.
+ void setHasNoNaNs(bool B);
+
+ /// Set or clear the no-infs flag on this instruction, which must be an
+ /// operator which supports this flag. See LangRef.html for the meaning of
+ /// this flag.
+ void setHasNoInfs(bool B);
+
+ /// Set or clear the no-signed-zeros flag on this instruction, which must be
+ /// an operator which supports this flag. See LangRef.html for the meaning of
+ /// this flag.
+ void setHasNoSignedZeros(bool B);
+
+ /// Set or clear the allow-reciprocal flag on this instruction, which must be
+ /// an operator which supports this flag. See LangRef.html for the meaning of
+ /// this flag.
+ void setHasAllowReciprocal(bool B);
+
+ /// Convenience function for setting all the fast-math flags on this
+ /// instruction, which must be an operator which supports these flags. See
+ /// LangRef.html for the meaning of these flats.
+ void setFastMathFlags(FastMathFlags FMF);
+
+ /// Determine whether the unsafe-algebra flag is set.
+ bool hasUnsafeAlgebra() const;
+
+ /// Determine whether the no-NaNs flag is set.
+ bool hasNoNaNs() const;
+
+ /// Determine whether the no-infs flag is set.
+ bool hasNoInfs() const;
+
+ /// Determine whether the no-signed-zeros flag is set.
+ bool hasNoSignedZeros() const;
+
+ /// Determine whether the allow-reciprocal flag is set.
+ bool hasAllowReciprocal() const;
+
+ /// Convenience function for getting all the fast-math flags, which must be an
+ /// operator which supports these flags. See LangRef.html for the meaning of
+ /// these flats.
+ FastMathFlags getFastMathFlags() const;
+
+ /// Copy I's fast-math flags
+ void copyFastMathFlags(const Instruction *I);
+
private:
/// hasMetadataHashEntry - Return true if we have an entry in the on-the-side
/// metadata hash.
bool hasMetadataHashEntry() const {
return (getSubclassDataFromValue() & HasMetadataBit) != 0;
}
-
+
// These are all implemented in Metadata.cpp.
MDNode *getMetadataImpl(unsigned KindID) const;
MDNode *getMetadataImpl(StringRef Kind) const;
@@ -194,15 +248,15 @@ public:
//===--------------------------------------------------------------------===//
// Predicates and helper methods.
//===--------------------------------------------------------------------===//
-
-
+
+
/// isAssociative - Return true if the instruction is associative:
///
/// Associative operators satisfy: x op (y op z) === (x op y) op z
///
/// In LLVM, the Add, Mul, And, Or, and Xor operators are associative.
///
- bool isAssociative() const { return isAssociative(getOpcode()); }
+ bool isAssociative() const;
static bool isAssociative(unsigned op);
/// isCommutative - Return true if the instruction is commutative:
@@ -271,12 +325,12 @@ public:
/// * The instruction has no name
///
Instruction *clone() const;
-
+
/// isIdenticalTo - Return true if the specified instruction is exactly
/// identical to the current one. This means that all operands match and any
/// extra information (e.g. load is volatile) agree.
bool isIdenticalTo(const Instruction *I) const;
-
+
/// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it
/// ignores the SubclassOptionalData flags, which specify conditions
/// under which the instruction's result is undefined.
@@ -291,7 +345,7 @@ public:
/// as equivalent.
CompareUsingScalarTypes = 1<<1
};
-
+
/// This function determines if the specified instruction executes the same
/// operation as the current one. This means that the opcodes, type, operand
/// types and any other factors affecting the operation must be the same. This
@@ -301,16 +355,15 @@ public:
/// the current one.
/// @brief Determine if one instruction is the same operation as another.
bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const;
-
+
/// isUsedOutsideOfBlock - Return true if there are any uses of this
/// instruction in blocks other than the specified block. Note that PHI nodes
/// are considered to evaluate their operands in the corresponding predecessor
/// block.
bool isUsedOutsideOfBlock(const BasicBlock *BB) const;
-
-
+
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() >= Value::InstructionVal;
}
@@ -322,35 +375,35 @@ public:
#define FIRST_TERM_INST(N) TermOpsBegin = N,
#define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N,
#define LAST_TERM_INST(N) TermOpsEnd = N+1
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
};
enum BinaryOps {
#define FIRST_BINARY_INST(N) BinaryOpsBegin = N,
#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
#define LAST_BINARY_INST(N) BinaryOpsEnd = N+1
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
};
enum MemoryOps {
#define FIRST_MEMORY_INST(N) MemoryOpsBegin = N,
#define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N,
#define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
};
enum CastOps {
#define FIRST_CAST_INST(N) CastOpsBegin = N,
#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N,
#define LAST_CAST_INST(N) CastOpsEnd = N+1
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
};
enum OtherOps {
#define FIRST_OTHER_INST(N) OtherOpsBegin = N,
#define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N,
#define LAST_OTHER_INST(N) OtherOpsEnd = N+1
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
};
private:
// Shadow Value::setValueSubclassData with a private forwarding method so that
@@ -361,34 +414,34 @@ private:
unsigned short getSubclassDataFromValue() const {
return Value::getSubclassDataFromValue();
}
-
+
void setHasMetadataHashEntry(bool V) {
setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
(V ? HasMetadataBit : 0));
}
-
+
friend class SymbolTableListTraits<Instruction, BasicBlock>;
void setParent(BasicBlock *P);
protected:
// Instruction subclasses can stick up to 15 bits of stuff into the
// SubclassData field of instruction with these members.
-
+
// Verify that only the low 15 bits are used.
void setInstructionSubclassData(unsigned short D) {
assert((D & HasMetadataBit) == 0 && "Out of range value put into field");
setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D);
}
-
+
unsigned getSubclassDataFromInstruction() const {
return getSubclassDataFromValue() & ~HasMetadataBit;
}
-
+
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
Instruction *InsertBefore = 0);
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd);
virtual Instruction *clone_impl() const = 0;
-
+
};
// Instruction* is only 4-byte aligned.
@@ -402,7 +455,7 @@ public:
}
enum { NumLowBitsAvailable = 2 };
};
-
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Instructions.h b/include/llvm/IR/Instructions.h
index f5187e6..bb4ea55 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -16,22 +16,23 @@
#ifndef LLVM_INSTRUCTIONS_H
#define LLVM_INSTRUCTIONS_H
-#include "llvm/InstrTypes.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Attributes.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Support/IntegersSubset.h"
-#include "llvm/Support/IntegersSubsetMapping.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/IntegersSubset.h"
+#include "llvm/Support/IntegersSubsetMapping.h"
#include <iterator>
namespace llvm {
+class APInt;
class ConstantInt;
class ConstantRange;
-class APInt;
+class DataLayout;
class LLVMContext;
enum AtomicOrdering {
@@ -112,7 +113,6 @@ public:
bool isStaticAlloca() const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const AllocaInst *) { return true; }
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Alloca);
}
@@ -226,13 +226,13 @@ public:
const Value *getPointerOperand() const { return getOperand(0); }
static unsigned getPointerOperandIndex() { return 0U; }
+ /// \brief Returns the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
- return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ return getPointerOperand()->getType()->getPointerAddressSpace();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const LoadInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Load;
}
@@ -255,7 +255,7 @@ private:
/// StoreInst - an instruction for storing to memory
///
class StoreInst : public Instruction {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void AssertOK();
protected:
virtual StoreInst *clone_impl() const;
@@ -349,12 +349,12 @@ public:
const Value *getPointerOperand() const { return getOperand(1); }
static unsigned getPointerOperandIndex() { return 1U; }
+ /// \brief Returns the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
- return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ return getPointerOperand()->getType()->getPointerAddressSpace();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const StoreInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Store;
}
@@ -382,7 +382,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
/// FenceInst - an instruction for ordering other memory operations
///
class FenceInst : public Instruction {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope);
protected:
virtual FenceInst *clone_impl() const;
@@ -426,7 +426,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const FenceInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Fence;
}
@@ -450,7 +449,7 @@ private:
/// there. Returns the value that was loaded.
///
class AtomicCmpXchgInst : public Instruction {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void Init(Value *Ptr, Value *Cmp, Value *NewVal,
AtomicOrdering Ordering, SynchronizationScope SynchScope);
protected:
@@ -521,12 +520,12 @@ public:
Value *getNewValOperand() { return getOperand(2); }
const Value *getNewValOperand() const { return getOperand(2); }
+ /// \brief Returns the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
- return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ return getPointerOperand()->getType()->getPointerAddressSpace();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const AtomicCmpXchgInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::AtomicCmpXchg;
}
@@ -557,7 +556,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value)
/// the old value.
///
class AtomicRMWInst : public Instruction {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
protected:
virtual AtomicRMWInst *clone_impl() const;
public:
@@ -665,12 +664,12 @@ public:
Value *getValOperand() { return getOperand(1); }
const Value *getValOperand() const { return getOperand(1); }
+ /// \brief Returns the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
- return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ return getPointerOperand()->getType()->getPointerAddressSpace();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const AtomicRMWInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::AtomicRMW;
}
@@ -768,6 +767,13 @@ public:
return reinterpret_cast<PointerType*>(Instruction::getType());
}
+ /// \brief Returns the address space of this instruction's pointer type.
+ unsigned getAddressSpace() const {
+ // Note that this is always the same as the pointer operand's address space
+ // and that is cheaper to compute, so cheat here.
+ return getPointerAddressSpace();
+ }
+
/// getIndexedType - Returns the type of the element that would be loaded with
/// a load instruction with the specified parameters.
///
@@ -778,10 +784,6 @@ public:
static Type *getIndexedType(Type *Ptr, ArrayRef<Constant *> IdxList);
static Type *getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList);
- /// getIndexedType - Returns the address space used by the GEP pointer.
- ///
- static unsigned getAddressSpace(Value *Ptr);
-
inline op_iterator idx_begin() { return op_begin()+1; }
inline const_op_iterator idx_begin() const { return op_begin()+1; }
inline op_iterator idx_end() { return op_end(); }
@@ -797,22 +799,23 @@ public:
return 0U; // get index for modifying correct operand.
}
- unsigned getPointerAddressSpace() const {
- return cast<PointerType>(getType())->getAddressSpace();
- }
-
/// getPointerOperandType - Method to return the pointer operand as a
/// PointerType.
Type *getPointerOperandType() const {
return getPointerOperand()->getType();
}
+ /// \brief Returns the address space of the pointer operand.
+ unsigned getPointerAddressSpace() const {
+ return getPointerOperandType()->getPointerAddressSpace();
+ }
+
/// GetGEPReturnType - Returns the pointer type returned by the GEP
/// instruction, which may be a vector of pointers.
static Type *getGEPReturnType(Value *Ptr, ArrayRef<Value *> IdxList) {
Type *PtrTy = PointerType::get(checkGEPType(
getIndexedType(Ptr->getType(), IdxList)),
- getAddressSpace(Ptr));
+ Ptr->getType()->getPointerAddressSpace());
// Vector GEP
if (Ptr->getType()->isVectorTy()) {
unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements();
@@ -848,8 +851,17 @@ public:
/// isInBounds - Determine whether the GEP has the inbounds flag.
bool isInBounds() const;
+ /// \brief Accumulate the constant address offset of this GEP if possible.
+ ///
+ /// This routine accepts an APInt into which it will accumulate the constant
+ /// offset of this GEP if the GEP is in fact constant. If the GEP is not
+ /// all-constant, it returns false and the value of the offset APInt is
+ /// undefined (it is *not* preserved!). The APInt passed into this routine
+ /// must be at least as wide as the IntPtr type for the address space of
+ /// the base GEP pointer.
+ bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const GetElementPtrInst *) { return true; }
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::GetElementPtr);
}
@@ -897,13 +909,13 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
/// This instruction compares its operands according to the predicate given
/// to the constructor. It only operates on integers or pointers. The operands
/// must be identical types.
-/// @brief Represent an integer comparison operator.
+/// \brief Represent an integer comparison operator.
class ICmpInst: public CmpInst {
protected:
- /// @brief Clone an identical ICmpInst
+ /// \brief Clone an identical ICmpInst
virtual ICmpInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics.
+ /// \brief Constructor with insert-before-instruction semantics.
ICmpInst(
Instruction *InsertBefore, ///< Where to insert
Predicate pred, ///< The predicate to use for the comparison
@@ -924,7 +936,7 @@ public:
"Invalid operand types for ICmp instruction");
}
- /// @brief Constructor with insert-at-end semantics.
+ /// \brief Constructor with insert-at-end semantics.
ICmpInst(
BasicBlock &InsertAtEnd, ///< Block to insert into.
Predicate pred, ///< The predicate to use for the comparison
@@ -945,7 +957,7 @@ public:
"Invalid operand types for ICmp instruction");
}
- /// @brief Constructor with no-insertion semantics
+ /// \brief Constructor with no-insertion semantics
ICmpInst(
Predicate pred, ///< The predicate to use for the comparison
Value *LHS, ///< The left-hand-side of the expression
@@ -967,25 +979,25 @@ public:
/// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
/// @returns the predicate that would be the result if the operand were
/// regarded as signed.
- /// @brief Return the signed version of the predicate
+ /// \brief Return the signed version of the predicate
Predicate getSignedPredicate() const {
return getSignedPredicate(getPredicate());
}
/// This is a static version that you can use without an instruction.
- /// @brief Return the signed version of the predicate.
+ /// \brief Return the signed version of the predicate.
static Predicate getSignedPredicate(Predicate pred);
/// For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
/// @returns the predicate that would be the result if the operand were
/// regarded as unsigned.
- /// @brief Return the unsigned version of the predicate
+ /// \brief Return the unsigned version of the predicate
Predicate getUnsignedPredicate() const {
return getUnsignedPredicate(getPredicate());
}
/// This is a static version that you can use without an instruction.
- /// @brief Return the unsigned version of the predicate.
+ /// \brief Return the unsigned version of the predicate.
static Predicate getUnsignedPredicate(Predicate pred);
/// isEquality - Return true if this predicate is either EQ or NE. This also
@@ -1001,7 +1013,7 @@ public:
}
/// @returns true if the predicate of this ICmpInst is commutative
- /// @brief Determine if this relation is commutative.
+ /// \brief Determine if this relation is commutative.
bool isCommutative() const { return isEquality(); }
/// isRelational - Return true if the predicate is relational (not EQ or NE).
@@ -1017,21 +1029,20 @@ public:
}
/// Initialize a set of values that all satisfy the predicate with C.
- /// @brief Make a ConstantRange for a relation with a constant value.
+ /// \brief Make a ConstantRange for a relation with a constant value.
static ConstantRange makeConstantRange(Predicate pred, const APInt &C);
/// Exchange the two operands to this instruction in such a way that it does
/// not modify the semantics of the instruction. The predicate value may be
/// changed to retain the same result if the predicate is order dependent
/// (e.g. ult).
- /// @brief Swap operands and adjust predicate.
+ /// \brief Swap operands and adjust predicate.
void swapOperands() {
setPredicate(getSwappedPredicate());
Op<0>().swap(Op<1>());
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ICmpInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ICmp;
}
@@ -1048,13 +1059,13 @@ public:
/// This instruction compares its operands according to the predicate given
/// to the constructor. It only operates on floating point values or packed
/// vectors of floating point values. The operands must be identical types.
-/// @brief Represents a floating point comparison operator.
+/// \brief Represents a floating point comparison operator.
class FCmpInst: public CmpInst {
protected:
- /// @brief Clone an identical FCmpInst
+ /// \brief Clone an identical FCmpInst
virtual FCmpInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics.
+ /// \brief Constructor with insert-before-instruction semantics.
FCmpInst(
Instruction *InsertBefore, ///< Where to insert
Predicate pred, ///< The predicate to use for the comparison
@@ -1073,7 +1084,7 @@ public:
"Invalid operand types for FCmp instruction");
}
- /// @brief Constructor with insert-at-end semantics.
+ /// \brief Constructor with insert-at-end semantics.
FCmpInst(
BasicBlock &InsertAtEnd, ///< Block to insert into.
Predicate pred, ///< The predicate to use for the comparison
@@ -1092,7 +1103,7 @@ public:
"Invalid operand types for FCmp instruction");
}
- /// @brief Constructor with no-insertion semantics
+ /// \brief Constructor with no-insertion semantics
FCmpInst(
Predicate pred, ///< The predicate to use for the comparison
Value *LHS, ///< The left-hand-side of the expression
@@ -1110,14 +1121,14 @@ public:
}
/// @returns true if the predicate of this instruction is EQ or NE.
- /// @brief Determine if this is an equality predicate.
+ /// \brief Determine if this is an equality predicate.
bool isEquality() const {
return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE ||
getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE;
}
/// @returns true if the predicate of this instruction is commutative.
- /// @brief Determine if this is a commutative predicate.
+ /// \brief Determine if this is a commutative predicate.
bool isCommutative() const {
return isEquality() ||
getPredicate() == FCMP_FALSE ||
@@ -1127,21 +1138,20 @@ public:
}
/// @returns true if the predicate is relational (not EQ or NE).
- /// @brief Determine if this a relational predicate.
+ /// \brief Determine if this a relational predicate.
bool isRelational() const { return !isEquality(); }
/// Exchange the two operands to this instruction in such a way that it does
/// not modify the semantics of the instruction. The predicate value may be
/// changed to retain the same result if the predicate is order dependent
/// (e.g. ult).
- /// @brief Swap operands and adjust predicate.
+ /// \brief Swap operands and adjust predicate.
void swapOperands() {
setPredicate(getSwappedPredicate());
Op<0>().swap(Op<1>());
}
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const FCmpInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::FCmp;
}
@@ -1157,18 +1167,18 @@ public:
/// hold the calling convention of the call.
///
class CallInst : public Instruction {
- AttrListPtr AttributeList; ///< parameter attributes for call
+ AttributeSet AttributeList; ///< parameter attributes for call
CallInst(const CallInst &CI);
void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr);
void init(Value *Func, const Twine &NameStr);
/// Construct a CallInst given a range of arguments.
- /// @brief Construct a CallInst from a range of arguments
+ /// \brief Construct a CallInst from a range of arguments
inline CallInst(Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore);
/// Construct a CallInst given a range of arguments.
- /// @brief Construct a CallInst from a range of arguments
+ /// \brief Construct a CallInst from a range of arguments
inline CallInst(Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd);
@@ -1255,87 +1265,92 @@ public:
/// getAttributes - Return the parameter attributes for this call.
///
- const AttrListPtr &getAttributes() const { return AttributeList; }
+ const AttributeSet &getAttributes() const { return AttributeList; }
/// setAttributes - Set the parameter attributes for this call.
///
- void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; }
+ void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; }
/// addAttribute - adds the attribute to the list of attributes.
- void addAttribute(unsigned i, Attributes attr);
+ void addAttribute(unsigned i, Attribute attr);
/// removeAttribute - removes the attribute from the list of attributes.
- void removeAttribute(unsigned i, Attributes attr);
+ void removeAttribute(unsigned i, Attribute attr);
- /// \brief Return true if this call has the given attribute.
- bool hasFnAttr(Attributes N) const {
- return paramHasAttr(~0, N);
- }
+ /// \brief Determine whether this call has the given attribute.
+ bool hasFnAttr(Attribute::AttrKind A) const;
- /// @brief Determine whether the call or the callee has the given attribute.
- bool paramHasAttr(unsigned i, Attributes attr) const;
+ /// \brief Determine whether the call or the callee has the given attributes.
+ bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
- /// @brief Extract the alignment for a call or parameter (0=unknown).
+ /// \brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
return AttributeList.getParamAlignment(i);
}
- /// @brief Return true if the call should not be inlined.
+ /// \brief Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
- void setIsNoInline(bool Value = true) {
- if (Value) addAttribute(~0, Attribute::NoInline);
- else removeAttribute(~0, Attribute::NoInline);
+ void setIsNoInline() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::NoInline));
}
- /// @brief Return true if the call can return twice
+ /// \brief Return true if the call can return twice
bool canReturnTwice() const {
return hasFnAttr(Attribute::ReturnsTwice);
}
- void setCanReturnTwice(bool Value = true) {
- if (Value) addAttribute(~0, Attribute::ReturnsTwice);
- else removeAttribute(~0, Attribute::ReturnsTwice);
+ void setCanReturnTwice() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::ReturnsTwice));
}
- /// @brief Determine if the call does not access memory.
+ /// \brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
return hasFnAttr(Attribute::ReadNone);
}
- void setDoesNotAccessMemory(bool NotAccessMemory = true) {
- if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
- else removeAttribute(~0, Attribute::ReadNone);
+ void setDoesNotAccessMemory() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::ReadNone));
}
- /// @brief Determine if the call does not access or only reads memory.
+ /// \brief Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
}
- void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
- if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
- else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
+ void setOnlyReadsMemory() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::ReadOnly));
}
- /// @brief Determine if the call cannot return.
+ /// \brief Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
- void setDoesNotReturn(bool DoesNotReturn = true) {
- if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
- else removeAttribute(~0, Attribute::NoReturn);
+ void setDoesNotReturn() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::NoReturn));
}
- /// @brief Determine if the call cannot unwind.
+ /// \brief Determine if the call cannot unwind.
bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
- void setDoesNotThrow(bool DoesNotThrow = true) {
- if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
- else removeAttribute(~0, Attribute::NoUnwind);
+ void setDoesNotThrow() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::NoUnwind));
+ }
+
+ /// \brief Determine if the call cannot be duplicated.
+ bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); }
+ void setCannotDuplicate() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::NoDuplicate));
}
- /// @brief Determine if the call returns a structure through first
+ /// \brief Determine if the call returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
// Be friendly and also check the callee.
return paramHasAttr(1, Attribute::StructRet);
}
- /// @brief Determine if any call argument is an aggregate passed by value.
+ /// \brief Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
return AttributeList.hasAttrSomewhere(Attribute::ByVal);
}
@@ -1363,7 +1378,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const CallInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Call;
}
@@ -1469,7 +1483,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SelectInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Select;
}
@@ -1512,7 +1525,6 @@ public:
static unsigned getPointerOperandIndex() { return 0U; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const VAArgInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == VAArg;
}
@@ -1566,7 +1578,6 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ExtractElementInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ExtractElement;
}
@@ -1625,7 +1636,6 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const InsertElementInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::InsertElement;
}
@@ -1706,7 +1716,6 @@ public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ShuffleVectorInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ShuffleVector;
}
@@ -1802,7 +1811,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ExtractValueInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ExtractValue;
}
@@ -1839,7 +1847,7 @@ ExtractValueInst::ExtractValueInst(Value *Agg,
class InsertValueInst : public Instruction {
SmallVector<unsigned, 4> Indices;
- void *operator new(size_t, unsigned); // Do not implement
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
InsertValueInst(const InsertValueInst &IVI);
void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
const Twine &NameStr);
@@ -1924,7 +1932,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const InsertValueInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::InsertValue;
}
@@ -1970,7 +1977,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
// scientist's overactive imagination.
//
class PHINode : public Instruction {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
/// ReservedSpace - The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
@@ -2141,7 +2148,6 @@ public:
Value *hasConstantValue() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const PHINode *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::PHI;
}
@@ -2178,7 +2184,7 @@ class LandingPadInst : public Instruction {
public:
enum ClauseType { Catch, Filter };
private:
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
// Allocate space for exactly zero operands.
void *operator new(size_t s) {
return User::operator new(s, 0);
@@ -2249,7 +2255,6 @@ public:
void reserveClauses(unsigned Size) { growOperands(Size); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const LandingPadInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::LandingPad;
}
@@ -2318,7 +2323,6 @@ public:
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ReturnInst *) { return true; }
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Ret);
}
@@ -2418,7 +2422,6 @@ public:
void swapSuccessors();
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const BranchInst *) { return true; }
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Br);
}
@@ -2445,7 +2448,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
/// SwitchInst - Multiway switch
///
class SwitchInst : public TerminatorInst {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
unsigned ReservedSpace;
// Operands format:
// Operand[0] = Value to switch on
@@ -2613,7 +2616,7 @@ public:
}
/// addCase - Add an entry to the switch instruction...
- /// @Deprecated
+ /// @deprecated
/// Note:
/// This action invalidates case_end(). Old case_end() iterator will
/// point to the added case.
@@ -2699,7 +2702,7 @@ public:
}
/// Resolves case value for current case.
- /// @Deprecated
+ /// @deprecated
ConstantIntTy *getCaseValue() {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
IntegersSubsetRef CaseRanges = *SubsetIt;
@@ -2803,7 +2806,7 @@ public:
CaseIt(const ParentTy& Src) : ParentTy(Src) {}
/// Sets the new value for current case.
- /// @Deprecated.
+ /// @deprecated.
void setValue(ConstantInt *V) {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
IntegersSubsetToBB Mapping;
@@ -2829,7 +2832,6 @@ public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SwitchInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Switch;
}
@@ -2857,7 +2859,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
/// IndirectBrInst - Indirect Branch Instruction.
///
class IndirectBrInst : public TerminatorInst {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
unsigned ReservedSpace;
// Operand[0] = Value to switch on
// Operand[1] = Default basic block destination
@@ -2928,7 +2930,6 @@ public:
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IndirectBrInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::IndirectBr;
}
@@ -2956,21 +2957,21 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
/// calling convention of the call.
///
class InvokeInst : public TerminatorInst {
- AttrListPtr AttributeList;
+ AttributeSet AttributeList;
InvokeInst(const InvokeInst &BI);
void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, const Twine &NameStr);
/// Construct an InvokeInst given a range of arguments.
///
- /// @brief Construct an InvokeInst from a range of arguments
+ /// \brief Construct an InvokeInst from a range of arguments
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, Instruction *InsertBefore);
/// Construct an InvokeInst given a range of arguments.
///
- /// @brief Construct an InvokeInst from a range of arguments
+ /// \brief Construct an InvokeInst from a range of arguments
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd);
@@ -3017,78 +3018,76 @@ public:
/// getAttributes - Return the parameter attributes for this invoke.
///
- const AttrListPtr &getAttributes() const { return AttributeList; }
+ const AttributeSet &getAttributes() const { return AttributeList; }
/// setAttributes - Set the parameter attributes for this invoke.
///
- void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; }
+ void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; }
/// addAttribute - adds the attribute to the list of attributes.
- void addAttribute(unsigned i, Attributes attr);
+ void addAttribute(unsigned i, Attribute attr);
/// removeAttribute - removes the attribute from the list of attributes.
- void removeAttribute(unsigned i, Attributes attr);
+ void removeAttribute(unsigned i, Attribute attr);
- /// \brief Return true if this call has the given attribute.
- bool hasFnAttr(Attributes N) const {
- return paramHasAttr(~0, N);
- }
+ /// \brief Determine whether this call has the NoAlias attribute.
+ bool hasFnAttr(Attribute::AttrKind A) const;
- /// @brief Determine whether the call or the callee has the given attribute.
- bool paramHasAttr(unsigned i, Attributes attr) const;
+ /// \brief Determine whether the call or the callee has the given attributes.
+ bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
- /// @brief Extract the alignment for a call or parameter (0=unknown).
+ /// \brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
return AttributeList.getParamAlignment(i);
}
- /// @brief Return true if the call should not be inlined.
+ /// \brief Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
- void setIsNoInline(bool Value = true) {
- if (Value) addAttribute(~0, Attribute::NoInline);
- else removeAttribute(~0, Attribute::NoInline);
+ void setIsNoInline() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::NoInline));
}
- /// @brief Determine if the call does not access memory.
+ /// \brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
return hasFnAttr(Attribute::ReadNone);
}
- void setDoesNotAccessMemory(bool NotAccessMemory = true) {
- if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
- else removeAttribute(~0, Attribute::ReadNone);
+ void setDoesNotAccessMemory() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::ReadNone));
}
- /// @brief Determine if the call does not access or only reads memory.
+ /// \brief Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
}
- void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
- if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
- else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
+ void setOnlyReadsMemory() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::ReadOnly));
}
- /// @brief Determine if the call cannot return.
+ /// \brief Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
- void setDoesNotReturn(bool DoesNotReturn = true) {
- if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
- else removeAttribute(~0, Attribute::NoReturn);
+ void setDoesNotReturn() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::NoReturn));
}
- /// @brief Determine if the call cannot unwind.
+ /// \brief Determine if the call cannot unwind.
bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
- void setDoesNotThrow(bool DoesNotThrow = true) {
- if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
- else removeAttribute(~0, Attribute::NoUnwind);
+ void setDoesNotThrow() {
+ addAttribute(AttributeSet::FunctionIndex,
+ Attribute::get(getContext(), Attribute::NoUnwind));
}
- /// @brief Determine if the call returns a structure through first
+ /// \brief Determine if the call returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
// Be friendly and also check the callee.
return paramHasAttr(1, Attribute::StructRet);
}
- /// @brief Determine if any call argument is an aggregate passed by value.
+ /// \brief Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
return AttributeList.hasAttrSomewhere(Attribute::ByVal);
}
@@ -3141,7 +3140,6 @@ public:
unsigned getNumSuccessors() const { return 2; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const InvokeInst *) { return true; }
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Invoke);
}
@@ -3221,7 +3219,6 @@ public:
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ResumeInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Resume;
}
@@ -3251,7 +3248,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
/// end of the block cannot be reached.
///
class UnreachableInst : public TerminatorInst {
- void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
protected:
virtual UnreachableInst *clone_impl() const;
@@ -3266,7 +3263,6 @@ public:
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const UnreachableInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Unreachable;
}
@@ -3283,14 +3279,14 @@ private:
// TruncInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a truncation of integer types.
+/// \brief This class represents a truncation of integer types.
class TruncInst : public CastInst {
protected:
- /// @brief Clone an identical TruncInst
+ /// \brief Clone an identical TruncInst
virtual TruncInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
TruncInst(
Value *S, ///< The value to be truncated
Type *Ty, ///< The (smaller) type to truncate to
@@ -3298,7 +3294,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
TruncInst(
Value *S, ///< The value to be truncated
Type *Ty, ///< The (smaller) type to truncate to
@@ -3306,8 +3302,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const TruncInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Trunc;
}
@@ -3320,14 +3315,14 @@ public:
// ZExtInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents zero extension of integer types.
+/// \brief This class represents zero extension of integer types.
class ZExtInst : public CastInst {
protected:
- /// @brief Clone an identical ZExtInst
+ /// \brief Clone an identical ZExtInst
virtual ZExtInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
ZExtInst(
Value *S, ///< The value to be zero extended
Type *Ty, ///< The type to zero extend to
@@ -3335,7 +3330,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end semantics.
+ /// \brief Constructor with insert-at-end semantics.
ZExtInst(
Value *S, ///< The value to be zero extended
Type *Ty, ///< The type to zero extend to
@@ -3343,8 +3338,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const ZExtInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == ZExt;
}
@@ -3357,14 +3351,14 @@ public:
// SExtInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a sign extension of integer types.
+/// \brief This class represents a sign extension of integer types.
class SExtInst : public CastInst {
protected:
- /// @brief Clone an identical SExtInst
+ /// \brief Clone an identical SExtInst
virtual SExtInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
SExtInst(
Value *S, ///< The value to be sign extended
Type *Ty, ///< The type to sign extend to
@@ -3372,7 +3366,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
SExtInst(
Value *S, ///< The value to be sign extended
Type *Ty, ///< The type to sign extend to
@@ -3380,8 +3374,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SExtInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == SExt;
}
@@ -3394,14 +3387,14 @@ public:
// FPTruncInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a truncation of floating point types.
+/// \brief This class represents a truncation of floating point types.
class FPTruncInst : public CastInst {
protected:
- /// @brief Clone an identical FPTruncInst
+ /// \brief Clone an identical FPTruncInst
virtual FPTruncInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
FPTruncInst(
Value *S, ///< The value to be truncated
Type *Ty, ///< The type to truncate to
@@ -3409,7 +3402,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
FPTruncInst(
Value *S, ///< The value to be truncated
Type *Ty, ///< The type to truncate to
@@ -3417,8 +3410,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const FPTruncInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == FPTrunc;
}
@@ -3431,14 +3423,14 @@ public:
// FPExtInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents an extension of floating point types.
+/// \brief This class represents an extension of floating point types.
class FPExtInst : public CastInst {
protected:
- /// @brief Clone an identical FPExtInst
+ /// \brief Clone an identical FPExtInst
virtual FPExtInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
FPExtInst(
Value *S, ///< The value to be extended
Type *Ty, ///< The type to extend to
@@ -3446,7 +3438,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
FPExtInst(
Value *S, ///< The value to be extended
Type *Ty, ///< The type to extend to
@@ -3454,8 +3446,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const FPExtInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == FPExt;
}
@@ -3468,14 +3459,14 @@ public:
// UIToFPInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a cast unsigned integer to floating point.
+/// \brief This class represents a cast unsigned integer to floating point.
class UIToFPInst : public CastInst {
protected:
- /// @brief Clone an identical UIToFPInst
+ /// \brief Clone an identical UIToFPInst
virtual UIToFPInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
UIToFPInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3483,7 +3474,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
UIToFPInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3491,8 +3482,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const UIToFPInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == UIToFP;
}
@@ -3505,14 +3495,14 @@ public:
// SIToFPInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a cast from signed integer to floating point.
+/// \brief This class represents a cast from signed integer to floating point.
class SIToFPInst : public CastInst {
protected:
- /// @brief Clone an identical SIToFPInst
+ /// \brief Clone an identical SIToFPInst
virtual SIToFPInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
SIToFPInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3520,7 +3510,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
SIToFPInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3528,8 +3518,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SIToFPInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == SIToFP;
}
@@ -3542,14 +3531,14 @@ public:
// FPToUIInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a cast from floating point to unsigned integer
+/// \brief This class represents a cast from floating point to unsigned integer
class FPToUIInst : public CastInst {
protected:
- /// @brief Clone an identical FPToUIInst
+ /// \brief Clone an identical FPToUIInst
virtual FPToUIInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
FPToUIInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3557,7 +3546,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
FPToUIInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3565,8 +3554,7 @@ public:
BasicBlock *InsertAtEnd ///< Where to insert the new instruction
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const FPToUIInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == FPToUI;
}
@@ -3579,14 +3567,14 @@ public:
// FPToSIInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a cast from floating point to signed integer.
+/// \brief This class represents a cast from floating point to signed integer.
class FPToSIInst : public CastInst {
protected:
- /// @brief Clone an identical FPToSIInst
+ /// \brief Clone an identical FPToSIInst
virtual FPToSIInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
FPToSIInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3594,7 +3582,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
FPToSIInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3602,8 +3590,7 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const FPToSIInst *) { return true; }
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == FPToSI;
}
@@ -3616,10 +3603,10 @@ public:
// IntToPtrInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a cast from an integer to a pointer.
+/// \brief This class represents a cast from an integer to a pointer.
class IntToPtrInst : public CastInst {
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
IntToPtrInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3627,7 +3614,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
IntToPtrInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3635,11 +3622,15 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
- /// @brief Clone an identical IntToPtrInst
+ /// \brief Clone an identical IntToPtrInst
virtual IntToPtrInst *clone_impl() const;
+ /// \brief Returns the address space of this instruction's pointer type.
+ unsigned getAddressSpace() const {
+ return getType()->getPointerAddressSpace();
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntToPtrInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == IntToPtr;
}
@@ -3652,14 +3643,14 @@ public:
// PtrToIntInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a cast from a pointer to an integer
+/// \brief This class represents a cast from a pointer to an integer
class PtrToIntInst : public CastInst {
protected:
- /// @brief Clone an identical PtrToIntInst
+ /// \brief Clone an identical PtrToIntInst
virtual PtrToIntInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
PtrToIntInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3667,7 +3658,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
PtrToIntInst(
Value *S, ///< The value to be converted
Type *Ty, ///< The type to convert to
@@ -3675,8 +3666,19 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
+ /// \brief Gets the pointer operand.
+ Value *getPointerOperand() { return getOperand(0); }
+ /// \brief Gets the pointer operand.
+ const Value *getPointerOperand() const { return getOperand(0); }
+ /// \brief Gets the operand index of the pointer operand.
+ static unsigned getPointerOperandIndex() { return 0U; }
+
+ /// \brief Returns the address space of the pointer operand.
+ unsigned getPointerAddressSpace() const {
+ return getPointerOperand()->getType()->getPointerAddressSpace();
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const PtrToIntInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == PtrToInt;
}
@@ -3689,14 +3691,14 @@ public:
// BitCastInst Class
//===----------------------------------------------------------------------===//
-/// @brief This class represents a no-op cast from one type to another.
+/// \brief This class represents a no-op cast from one type to another.
class BitCastInst : public CastInst {
protected:
- /// @brief Clone an identical BitCastInst
+ /// \brief Clone an identical BitCastInst
virtual BitCastInst *clone_impl() const;
public:
- /// @brief Constructor with insert-before-instruction semantics
+ /// \brief Constructor with insert-before-instruction semantics
BitCastInst(
Value *S, ///< The value to be casted
Type *Ty, ///< The type to casted to
@@ -3704,7 +3706,7 @@ public:
Instruction *InsertBefore = 0 ///< Where to insert the new instruction
);
- /// @brief Constructor with insert-at-end-of-block semantics
+ /// \brief Constructor with insert-at-end-of-block semantics
BitCastInst(
Value *S, ///< The value to be casted
Type *Ty, ///< The type to casted to
@@ -3713,7 +3715,6 @@ public:
);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const BitCastInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == BitCast;
}
diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index 1cebdd2..a8dfcbd 100644
--- a/include/llvm/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -24,19 +24,19 @@
#ifndef LLVM_INTRINSICINST_H
#define LLVM_INTRINSICINST_H
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
namespace llvm {
/// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic
/// functions. This allows the standard isa/dyncast/cast functionality to
/// work with calls to intrinsic functions.
class IntrinsicInst : public CallInst {
- IntrinsicInst(); // DO NOT IMPLEMENT
- IntrinsicInst(const IntrinsicInst&); // DO NOT IMPLEMENT
- void operator=(const IntrinsicInst&); // DO NOT IMPLEMENT
+ IntrinsicInst() LLVM_DELETED_FUNCTION;
+ IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION;
+ void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION;
public:
/// getIntrinsicID - Return the intrinsic ID of this intrinsic.
///
@@ -45,24 +45,22 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const IntrinsicInst *) { return true; }
static inline bool classof(const CallInst *I) {
if (const Function *CF = I->getCalledFunction())
- return CF->getIntrinsicID() != 0;
+ return CF->isIntrinsic();
return false;
}
static inline bool classof(const Value *V) {
return isa<CallInst>(V) && classof(cast<CallInst>(V));
}
};
-
+
/// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
///
class DbgInfoIntrinsic : public IntrinsicInst {
public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const DbgInfoIntrinsic *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::dbg_declare:
@@ -86,7 +84,6 @@ namespace llvm {
MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1)); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const DbgDeclareInst *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::dbg_declare;
}
@@ -108,7 +105,6 @@ namespace llvm {
MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2)); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const DbgValueInst *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::dbg_value;
}
@@ -175,7 +171,6 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MemIntrinsic *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memcpy:
@@ -205,7 +200,6 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MemSetInst *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memset;
}
@@ -238,7 +232,6 @@ namespace llvm {
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MemTransferInst *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memcpy ||
I->getIntrinsicID() == Intrinsic::memmove;
@@ -254,7 +247,6 @@ namespace llvm {
class MemCpyInst : public MemTransferInst {
public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MemCpyInst *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memcpy;
}
@@ -268,7 +260,6 @@ namespace llvm {
class MemMoveInst : public MemTransferInst {
public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MemMoveInst *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memmove;
}
@@ -277,6 +268,49 @@ namespace llvm {
}
};
+ /// VAStartInst - This represents the llvm.va_start intrinsic.
+ ///
+ class VAStartInst : public IntrinsicInst {
+ public:
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::vastart;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
+ };
+
+ /// VAEndInst - This represents the llvm.va_end intrinsic.
+ ///
+ class VAEndInst : public IntrinsicInst {
+ public:
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::vaend;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
+ };
+
+ /// VACopyInst - This represents the llvm.va_copy intrinsic.
+ ///
+ class VACopyInst : public IntrinsicInst {
+ public:
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::vacopy;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); }
+ Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); }
+ };
+
}
#endif
diff --git a/include/llvm/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index c350388..1e20fd7 100644
--- a/include/llvm/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -26,7 +26,7 @@ class FunctionType;
class Function;
class LLVMContext;
class Module;
-class AttrListPtr;
+class AttributeSet;
/// Intrinsic Namespace - This namespace contains an enum with a value for
/// every intrinsic/builtin function known by LLVM. These enum values are
@@ -38,7 +38,7 @@ namespace Intrinsic {
// Get the intrinsic enums generated from Intrinsics.td
#define GET_INTRINSIC_ENUM_VALUES
-#include "llvm/Intrinsics.gen"
+#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_ENUM_VALUES
, num_intrinsics
};
@@ -50,7 +50,7 @@ namespace Intrinsic {
/// Intrinsic::getType(ID) - Return the function type for an intrinsic.
///
FunctionType *getType(LLVMContext &Context, ID id,
- ArrayRef<Type*> Tys = ArrayRef<Type*>());
+ ArrayRef<Type*> Tys = ArrayRef<Type*>());
/// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be
/// overloaded.
@@ -58,7 +58,7 @@ namespace Intrinsic {
/// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic.
///
- AttrListPtr getAttributes(ID id);
+ AttributeSet getAttributes(LLVMContext &C, ID id);
/// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
/// declaration for an intrinsic, and return it.
diff --git a/include/llvm/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index d1a0fee..e9fbba9 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -121,15 +121,27 @@ def llvm_metadata_ty : LLVMType<MetadataVT>; // !{...}
def llvm_x86mmx_ty : LLVMType<x86mmx>;
def llvm_ptrx86mmx_ty : LLVMPointerType<llvm_x86mmx_ty>; // <1 x i64>*
+def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1
+def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1
+def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1
+def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1
+def llvm_v32i1_ty : LLVMType<v32i1>; // 32 x i1
+def llvm_v64i1_ty : LLVMType<v64i1>; // 64 x i1
def llvm_v2i8_ty : LLVMType<v2i8>; // 2 x i8
def llvm_v4i8_ty : LLVMType<v4i8>; // 4 x i8
def llvm_v8i8_ty : LLVMType<v8i8>; // 8 x i8
def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8
def llvm_v32i8_ty : LLVMType<v32i8>; // 32 x i8
+def llvm_v64i8_ty : LLVMType<v64i8>; // 64 x i8
+
+def llvm_v1i16_ty : LLVMType<v1i16>; // 1 x i16
def llvm_v2i16_ty : LLVMType<v2i16>; // 2 x i16
def llvm_v4i16_ty : LLVMType<v4i16>; // 4 x i16
def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16
def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16
+def llvm_v32i16_ty : LLVMType<v32i16>; // 32 x i16
+
+def llvm_v1i32_ty : LLVMType<v1i32>; // 1 x i32
def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32
def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32
def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32
@@ -143,8 +155,10 @@ def llvm_v16i64_ty : LLVMType<v16i64>; // 16 x i64
def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float
def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float
def llvm_v8f32_ty : LLVMType<v8f32>; // 8 x float
+def llvm_v16f32_ty : LLVMType<v16f32>; // 16 x float
def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double
def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double
+def llvm_v8f64_ty : LLVMType<v8f64>; // 8 x double
def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
@@ -265,6 +279,10 @@ let Properties = [IntrReadMem] in {
def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_ceil : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_trunc : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
}
let Properties = [IntrNoMem] in {
@@ -279,9 +297,9 @@ let Properties = [IntrNoMem] in {
// NOTE: these are internal interfaces.
def int_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
-def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>;
+def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>;
-def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>;
+def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
// Internal interface for object size checking
def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty],
@@ -339,7 +357,7 @@ let Properties = [IntrNoMem] in {
}
def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>;
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
-def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>;
+def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>;
//===---------------- Generic Variable Attribute Intrinsics----------------===//
//
@@ -455,11 +473,11 @@ def int_convertuu : Intrinsic<[llvm_anyint_ty],
// Target-specific intrinsics
//===----------------------------------------------------------------------===//
-include "llvm/IntrinsicsPowerPC.td"
-include "llvm/IntrinsicsX86.td"
-include "llvm/IntrinsicsARM.td"
-include "llvm/IntrinsicsCellSPU.td"
-include "llvm/IntrinsicsXCore.td"
-include "llvm/IntrinsicsHexagon.td"
-include "llvm/IntrinsicsNVVM.td"
-include "llvm/IntrinsicsMips.td"
+include "llvm/IR/IntrinsicsPowerPC.td"
+include "llvm/IR/IntrinsicsX86.td"
+include "llvm/IR/IntrinsicsARM.td"
+include "llvm/IR/IntrinsicsXCore.td"
+include "llvm/IR/IntrinsicsHexagon.td"
+include "llvm/IR/IntrinsicsNVVM.td"
+include "llvm/IR/IntrinsicsMips.td"
+include "llvm/IR/IntrinsicsR600.td"
diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td
new file mode 100644
index 0000000..93b1ae1
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsARM.td
@@ -0,0 +1,429 @@
+//===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the ARM-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+
+//===----------------------------------------------------------------------===//
+// TLS
+
+let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
+
+def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">,
+ Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Saturating Arithmentic
+
+def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Load and Store exclusive doubleword
+
+def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+ llvm_ptr_ty], [IntrReadWriteArgMem]>;
+def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty],
+ [IntrReadArgMem]>;
+
+//===----------------------------------------------------------------------===//
+// VFP
+
+def int_arm_get_fpscr : GCCBuiltin<"__builtin_arm_get_fpscr">,
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+def int_arm_set_fpscr : GCCBuiltin<"__builtin_arm_set_fpscr">,
+ Intrinsic<[], [llvm_i32_ty], []>;
+def int_arm_vcvtr : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
+ [IntrNoMem]>;
+def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
+ [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Coprocessor
+
+// Move to coprocessor
+def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+
+// Move from coprocessor
+def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty], []>;
+
+// Coprocessor data processing
+def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+
+// Move from two registers to coprocessor
+def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Advanced SIMD (NEON)
+
+// The following classes do not correspond directly to GCC builtins.
+class Neon_1Arg_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+class Neon_1Arg_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMExtendedElementVectorType<0>], [IntrNoMem]>;
+class Neon_2Arg_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+class Neon_2Arg_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMExtendedElementVectorType<0>,
+ LLVMExtendedElementVectorType<0>],
+ [IntrNoMem]>;
+class Neon_2Arg_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMTruncatedElementVectorType<0>,
+ LLVMTruncatedElementVectorType<0>],
+ [IntrNoMem]>;
+class Neon_3Arg_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+class Neon_3Arg_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMTruncatedElementVectorType<0>,
+ LLVMTruncatedElementVectorType<0>],
+ [IntrNoMem]>;
+class Neon_CvtFxToFP_Intrinsic
+ : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
+class Neon_CvtFPToFx_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
+
+// The table operands for VTBL and VTBX consist of 1 to 4 v8i8 vectors.
+// Besides the table, VTBL has one other v8i8 argument and VTBX has two.
+// Overall, the classes range from 2 to 6 v8i8 arguments.
+class Neon_Tbl2Arg_Intrinsic
+ : Intrinsic<[llvm_v8i8_ty],
+ [llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
+class Neon_Tbl3Arg_Intrinsic
+ : Intrinsic<[llvm_v8i8_ty],
+ [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
+class Neon_Tbl4Arg_Intrinsic
+ : Intrinsic<[llvm_v8i8_ty],
+ [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty],
+ [IntrNoMem]>;
+class Neon_Tbl5Arg_Intrinsic
+ : Intrinsic<[llvm_v8i8_ty],
+ [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+class Neon_Tbl6Arg_Intrinsic
+ : Intrinsic<[llvm_v8i8_ty],
+ [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
+
+// Arithmetic ops
+
+let Properties = [IntrNoMem, Commutative] in {
+
+ // Vector Add.
+ def int_arm_neon_vhadds : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vhaddu : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vrhadds : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vrhaddu : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vqadds : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vqaddu : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vaddhn : Neon_2Arg_Narrow_Intrinsic;
+ def int_arm_neon_vraddhn : Neon_2Arg_Narrow_Intrinsic;
+
+ // Vector Multiply.
+ def int_arm_neon_vmulp : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic;
+ def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic;
+ def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic;
+ def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic;
+
+ // Vector Multiply and Accumulate/Subtract.
+ def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic;
+ def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic;
+
+ // Vector Maximum.
+ def int_arm_neon_vmaxs : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vmaxu : Neon_2Arg_Intrinsic;
+
+ // Vector Minimum.
+ def int_arm_neon_vmins : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vminu : Neon_2Arg_Intrinsic;
+
+ // Vector Reciprocal Step.
+ def int_arm_neon_vrecps : Neon_2Arg_Intrinsic;
+
+ // Vector Reciprocal Square Root Step.
+ def int_arm_neon_vrsqrts : Neon_2Arg_Intrinsic;
+}
+
+// Vector Subtract.
+def int_arm_neon_vhsubs : Neon_2Arg_Intrinsic;
+def int_arm_neon_vhsubu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqsubs : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqsubu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vsubhn : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vrsubhn : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Absolute Compare.
+def int_arm_neon_vacged : Intrinsic<[llvm_v2i32_ty],
+ [llvm_v2f32_ty, llvm_v2f32_ty],
+ [IntrNoMem]>;
+def int_arm_neon_vacgeq : Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+def int_arm_neon_vacgtd : Intrinsic<[llvm_v2i32_ty],
+ [llvm_v2f32_ty, llvm_v2f32_ty],
+ [IntrNoMem]>;
+def int_arm_neon_vacgtq : Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+
+// Vector Absolute Differences.
+def int_arm_neon_vabds : Neon_2Arg_Intrinsic;
+def int_arm_neon_vabdu : Neon_2Arg_Intrinsic;
+
+// Vector Pairwise Add.
+def int_arm_neon_vpadd : Neon_2Arg_Intrinsic;
+
+// Vector Pairwise Add Long.
+// Note: This is different than the other "long" NEON intrinsics because
+// the result vector has half as many elements as the source vector.
+// The source and destination vector types must be specified separately.
+def int_arm_neon_vpaddls : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_arm_neon_vpaddlu : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty],
+ [IntrNoMem]>;
+
+// Vector Pairwise Add and Accumulate Long.
+// Note: This is similar to vpaddl but the destination vector also appears
+// as the first argument.
+def int_arm_neon_vpadals : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_arm_neon_vpadalu : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty],
+ [IntrNoMem]>;
+
+// Vector Pairwise Maximum and Minimum.
+def int_arm_neon_vpmaxs : Neon_2Arg_Intrinsic;
+def int_arm_neon_vpmaxu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vpmins : Neon_2Arg_Intrinsic;
+def int_arm_neon_vpminu : Neon_2Arg_Intrinsic;
+
+// Vector Shifts:
+//
+// The various saturating and rounding vector shift operations need to be
+// represented by intrinsics in LLVM, and even the basic VSHL variable shift
+// operation cannot be safely translated to LLVM's shift operators. VSHL can
+// be used for both left and right shifts, or even combinations of the two,
+// depending on the signs of the shift amounts. It also has well-defined
+// behavior for shift amounts that LLVM leaves undefined. Only basic shifts
+// by constants can be represented with LLVM's shift operators.
+//
+// The shift counts for these intrinsics are always vectors, even for constant
+// shifts, where the constant is replicated. For consistency with VSHL (and
+// other variable shift instructions), left shifts have positive shift counts
+// and right shifts have negative shift counts. This convention is also used
+// for constant right shift intrinsics, and to help preserve sanity, the
+// intrinsic names use "shift" instead of either "shl" or "shr". Where
+// applicable, signed and unsigned versions of the intrinsics are
+// distinguished with "s" and "u" suffixes. A few NEON shift instructions,
+// such as VQSHLU, take signed operands but produce unsigned results; these
+// use a "su" suffix.
+
+// Vector Shift.
+def int_arm_neon_vshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vshiftu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vshiftls : Neon_2Arg_Long_Intrinsic;
+def int_arm_neon_vshiftlu : Neon_2Arg_Long_Intrinsic;
+def int_arm_neon_vshiftn : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Rounding Shift.
+def int_arm_neon_vrshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vrshiftu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vrshiftn : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Saturating Shift.
+def int_arm_neon_vqshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqshiftu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqshiftsu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqshiftns : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqshiftnu : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqshiftnsu : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Saturating Rounding Shift.
+def int_arm_neon_vqrshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqrshiftu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqrshiftns : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqrshiftnu : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqrshiftnsu : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Shift and Insert.
+def int_arm_neon_vshiftins : Neon_3Arg_Intrinsic;
+
+// Vector Absolute Value and Saturating Absolute Value.
+def int_arm_neon_vabs : Neon_1Arg_Intrinsic;
+def int_arm_neon_vqabs : Neon_1Arg_Intrinsic;
+
+// Vector Saturating Negate.
+def int_arm_neon_vqneg : Neon_1Arg_Intrinsic;
+
+// Vector Count Leading Sign/Zero Bits.
+def int_arm_neon_vcls : Neon_1Arg_Intrinsic;
+def int_arm_neon_vclz : Neon_1Arg_Intrinsic;
+
+// Vector Count One Bits.
+def int_arm_neon_vcnt : Neon_1Arg_Intrinsic;
+
+// Vector Reciprocal Estimate.
+def int_arm_neon_vrecpe : Neon_1Arg_Intrinsic;
+
+// Vector Reciprocal Square Root Estimate.
+def int_arm_neon_vrsqrte : Neon_1Arg_Intrinsic;
+
+// Vector Conversions Between Floating-point and Fixed-point.
+def int_arm_neon_vcvtfp2fxs : Neon_CvtFPToFx_Intrinsic;
+def int_arm_neon_vcvtfp2fxu : Neon_CvtFPToFx_Intrinsic;
+def int_arm_neon_vcvtfxs2fp : Neon_CvtFxToFP_Intrinsic;
+def int_arm_neon_vcvtfxu2fp : Neon_CvtFxToFP_Intrinsic;
+
+// Vector Conversions Between Half-Precision and Single-Precision.
+def int_arm_neon_vcvtfp2hf
+ : Intrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_arm_neon_vcvthf2fp
+ : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
+
+// Narrowing Saturating Vector Moves.
+def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic;
+def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic;
+def int_arm_neon_vqmovnsu : Neon_1Arg_Narrow_Intrinsic;
+
+// Vector Table Lookup.
+// The first 1-4 arguments are the table.
+def int_arm_neon_vtbl1 : Neon_Tbl2Arg_Intrinsic;
+def int_arm_neon_vtbl2 : Neon_Tbl3Arg_Intrinsic;
+def int_arm_neon_vtbl3 : Neon_Tbl4Arg_Intrinsic;
+def int_arm_neon_vtbl4 : Neon_Tbl5Arg_Intrinsic;
+
+// Vector Table Extension.
+// Some elements of the destination vector may not be updated, so the original
+// value of that vector is passed as the first argument. The next 1-4
+// arguments after that are the table.
+def int_arm_neon_vtbx1 : Neon_Tbl3Arg_Intrinsic;
+def int_arm_neon_vtbx2 : Neon_Tbl4Arg_Intrinsic;
+def int_arm_neon_vtbx3 : Neon_Tbl5Arg_Intrinsic;
+def int_arm_neon_vtbx4 : Neon_Tbl6Arg_Intrinsic;
+
+// De-interleaving vector loads from N-element structures.
+// Source operands are the address and alignment.
+def int_arm_neon_vld1 : Intrinsic<[llvm_anyvector_ty],
+ [llvm_ptr_ty, llvm_i32_ty],
+ [IntrReadArgMem]>;
+def int_arm_neon_vld2 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+ [llvm_ptr_ty, llvm_i32_ty],
+ [IntrReadArgMem]>;
+def int_arm_neon_vld3 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>],
+ [llvm_ptr_ty, llvm_i32_ty],
+ [IntrReadArgMem]>;
+def int_arm_neon_vld4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>],
+ [llvm_ptr_ty, llvm_i32_ty],
+ [IntrReadArgMem]>;
+
+// Vector load N-element structure to one lane.
+// Source operands are: the address, the N input vectors (since only one
+// lane is assigned), the lane number, and the alignment.
+def int_arm_neon_vld2lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+ [llvm_ptr_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, llvm_i32_ty,
+ llvm_i32_ty], [IntrReadArgMem]>;
+def int_arm_neon_vld3lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>],
+ [llvm_ptr_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrReadArgMem]>;
+def int_arm_neon_vld4lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>],
+ [llvm_ptr_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>, llvm_i32_ty,
+ llvm_i32_ty], [IntrReadArgMem]>;
+
+// Interleaving vector stores from N-element structures.
+// Source operands are: the address, the N vectors, and the alignment.
+def int_arm_neon_vst1 : Intrinsic<[],
+ [llvm_ptr_ty, llvm_anyvector_ty,
+ llvm_i32_ty], [IntrReadWriteArgMem]>;
+def int_arm_neon_vst2 : Intrinsic<[],
+ [llvm_ptr_ty, llvm_anyvector_ty,
+ LLVMMatchType<0>, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+def int_arm_neon_vst3 : Intrinsic<[],
+ [llvm_ptr_ty, llvm_anyvector_ty,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i32_ty], [IntrReadWriteArgMem]>;
+def int_arm_neon_vst4 : Intrinsic<[],
+ [llvm_ptr_ty, llvm_anyvector_ty,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+// Vector store N-element structure from one lane.
+// Source operands are: the address, the N vectors, the lane number, and
+// the alignment.
+def int_arm_neon_vst2lane : Intrinsic<[],
+ [llvm_ptr_ty, llvm_anyvector_ty,
+ LLVMMatchType<0>, llvm_i32_ty,
+ llvm_i32_ty], [IntrReadWriteArgMem]>;
+def int_arm_neon_vst3lane : Intrinsic<[],
+ [llvm_ptr_ty, llvm_anyvector_ty,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+def int_arm_neon_vst4lane : Intrinsic<[],
+ [llvm_ptr_ty, llvm_anyvector_ty,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>, llvm_i32_ty,
+ llvm_i32_ty], [IntrReadWriteArgMem]>;
+
+// Vector bitwise select.
+def int_arm_neon_vbsl : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+} // end TargetPrefix
diff --git a/include/llvm/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td
index 8a88729..8a88729 100644
--- a/include/llvm/IntrinsicsHexagon.td
+++ b/include/llvm/IR/IntrinsicsHexagon.td
diff --git a/include/llvm/IntrinsicsMips.td b/include/llvm/IR/IntrinsicsMips.td
index e40e162..e40e162 100644
--- a/include/llvm/IntrinsicsMips.td
+++ b/include/llvm/IR/IntrinsicsMips.td
diff --git a/include/llvm/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td
index 1853c99..1853c99 100644
--- a/include/llvm/IntrinsicsNVVM.td
+++ b/include/llvm/IR/IntrinsicsNVVM.td
diff --git a/include/llvm/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
index da85bfb..cde39cc 100644
--- a/include/llvm/IntrinsicsPowerPC.td
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -22,7 +22,8 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_dcbf : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>;
- def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>;
diff --git a/include/llvm/IR/IntrinsicsR600.td b/include/llvm/IR/IntrinsicsR600.td
new file mode 100644
index 0000000..ecb5668
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsR600.td
@@ -0,0 +1,36 @@
+//===- IntrinsicsR600.td - Defines R600 intrinsics ---------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the R600-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "r600" in {
+
+class R600ReadPreloadRegisterIntrinsic<string name>
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<name>;
+
+multiclass R600ReadPreloadRegisterIntrinsic_xyz<string prefix> {
+ def _x : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_x")>;
+ def _y : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_y")>;
+ def _z : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_z")>;
+}
+
+defm int_r600_read_global_size : R600ReadPreloadRegisterIntrinsic_xyz <
+ "__builtin_r600_read_global_size">;
+defm int_r600_read_local_size : R600ReadPreloadRegisterIntrinsic_xyz <
+ "__builtin_r600_read_local_size">;
+defm int_r600_read_ngroups : R600ReadPreloadRegisterIntrinsic_xyz <
+ "__builtin_r600_read_ngroups">;
+defm int_r600_read_tgid : R600ReadPreloadRegisterIntrinsic_xyz <
+ "__builtin_r600_read_tgid">;
+defm int_r600_read_tidig : R600ReadPreloadRegisterIntrinsic_xyz <
+ "__builtin_r600_read_tidig">;
+} // End TargetPrefix = "r600"
diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 5ff0856..d2463c0 100644
--- a/include/llvm/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -2559,3 +2559,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_rdrand_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>;
def int_x86_rdrand_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>;
}
+
+//===----------------------------------------------------------------------===//
+// RTM intrinsics. Transactional Memory support.
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_xbegin : GCCBuiltin<"__builtin_ia32_xbegin">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+ def int_x86_xend : GCCBuiltin<"__builtin_ia32_xend">,
+ Intrinsic<[], [], []>;
+ def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">,
+ Intrinsic<[], [llvm_i8_ty], [IntrNoReturn]>;
+}
diff --git a/include/llvm/IntrinsicsXCore.td b/include/llvm/IR/IntrinsicsXCore.td
index a481313..a481313 100644
--- a/include/llvm/IntrinsicsXCore.td
+++ b/include/llvm/IR/IntrinsicsXCore.td
diff --git a/include/llvm/LLVMContext.h b/include/llvm/IR/LLVMContext.h
index a8306a9..58fb39f 100644
--- a/include/llvm/LLVMContext.h
+++ b/include/llvm/IR/LLVMContext.h
@@ -15,6 +15,8 @@
#ifndef LLVM_LLVMCONTEXT_H
#define LLVM_LLVMCONTEXT_H
+#include "llvm/Support/Compiler.h"
+
namespace llvm {
class LLVMContextImpl;
@@ -43,7 +45,8 @@ public:
MD_tbaa = 1, // "tbaa"
MD_prof = 2, // "prof"
MD_fpmath = 3, // "fpmath"
- MD_range = 4 // "range"
+ MD_range = 4, // "range"
+ MD_tbaa_struct = 5 // "tbaa.struct"
};
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
@@ -55,27 +58,39 @@ public:
void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
- typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
- unsigned LocCookie);
+ typedef void (*DiagHandlerTy)(const SMDiagnostic&, void *Context,
+ unsigned LocCookie);
- /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
- /// when problems with inline asm are detected by the backend. The first
- /// argument is a function pointer and the second is a context pointer that
- /// gets passed into the DiagHandler.
+ /// setDiagnosticHandler - This method sets a handler that is invoked
+ /// when problems are detected by the backend. The first argument is a
+ /// function pointer and the second is a context pointer that gets passed
+ /// into the DiagHandler.
///
/// LLVMContext doesn't take ownership or interpret either of these
/// pointers.
- void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
- void *DiagContext = 0);
+ void setDiagnosticHandler(DiagHandlerTy DiagHandler, void *DiagContext = 0);
- /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
- /// setInlineAsmDiagnosticHandler.
- InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const;
+ /// getDiagnosticHandler - Return the diagnostic handler set by
+ /// setDiagnosticHandler.
+ DiagHandlerTy getDiagnosticHandler() const;
- /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
- /// setInlineAsmDiagnosticHandler.
- void *getInlineAsmDiagnosticContext() const;
+ /// getDiagnosticContext - Return the diagnostic context set by
+ /// setDiagnosticHandler.
+ void *getDiagnosticContext() const;
+ /// FIXME: Temporary copies of the old names; to be removed as soon as
+ /// clang switches to the new ones.
+ typedef DiagHandlerTy InlineAsmDiagHandlerTy;
+ void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
+ void *DiagContext = 0) {
+ setDiagnosticHandler(DiagHandler, DiagContext);
+ }
+ InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const {
+ return getDiagnosticHandler();
+ }
+ void *getInlineAsmDiagnosticContext() const {
+ return getDiagnosticContext();
+ }
/// emitError - Emit an error message to the currently installed error handler
/// with optional location information. This function returns, so code should
@@ -86,10 +101,15 @@ public:
void emitError(const Instruction *I, const Twine &ErrorStr);
void emitError(const Twine &ErrorStr);
+ /// emitWarning - This is similar to emitError but it emits a warning instead
+ /// of an error.
+ void emitWarning(unsigned LocCookie, const Twine &ErrorStr);
+ void emitWarning(const Instruction *I, const Twine &ErrorStr);
+ void emitWarning(const Twine &ErrorStr);
+
private:
- // DO NOT IMPLEMENT
- LLVMContext(LLVMContext&);
- void operator=(LLVMContext&);
+ LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
+ void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
/// addModule - Register a module as being instantiated in this context. If
/// the context is deleted, the module will be deleted as well.
diff --git a/include/llvm/MDBuilder.h b/include/llvm/IR/MDBuilder.h
index 2aa48b0..d3ca644 100644
--- a/include/llvm/MDBuilder.h
+++ b/include/llvm/IR/MDBuilder.h
@@ -15,11 +15,11 @@
#ifndef LLVM_MDBUILDER_H
#define LLVM_MDBUILDER_H
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
namespace llvm {
@@ -134,6 +134,27 @@ namespace llvm {
}
}
+ struct TBAAStructField {
+ uint64_t Offset;
+ uint64_t Size;
+ MDNode *TBAA;
+ TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) :
+ Offset(Offset), Size(Size), TBAA(TBAA) {}
+ };
+
+ /// \brief Return metadata for a tbaa.struct node with the given
+ /// struct field descriptions.
+ MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
+ SmallVector<Value *, 4> Vals(Fields.size() * 3);
+ Type *Int64 = IntegerType::get(Context, 64);
+ for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
+ Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset);
+ Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size);
+ Vals[i * 3 + 2] = Fields[i].TBAA;
+ }
+ return MDNode::get(Context, Vals);
+ }
+
};
} // end namespace llvm
diff --git a/include/llvm/Metadata.h b/include/llvm/IR/Metadata.h
index b40549b..402abb3 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -16,10 +16,10 @@
#ifndef LLVM_METADATA_H
#define LLVM_METADATA_H
-#include "llvm/Value.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/Value.h"
namespace llvm {
class Constant;
@@ -37,7 +37,7 @@ template<typename ValueSubClass, typename ItemParentClass>
/// MDString is always unnamed.
class MDString : public Value {
virtual void anchor();
- MDString(const MDString &); // DO NOT IMPLEMENT
+ MDString(const MDString &) LLVM_DELETED_FUNCTION;
explicit MDString(LLVMContext &C);
public:
@@ -59,7 +59,6 @@ public:
iterator end() const { return getName().end(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MDString *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == MDStringVal;
}
@@ -71,8 +70,8 @@ class MDNodeOperand;
//===----------------------------------------------------------------------===//
/// MDNode - a tuple of other values.
class MDNode : public Value, public FoldingSetNode {
- MDNode(const MDNode &); // DO NOT IMPLEMENT
- void operator=(const MDNode &); // DO NOT IMPLEMENT
+ MDNode(const MDNode &) LLVM_DELETED_FUNCTION;
+ void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
friend class MDNodeOperand;
friend class LLVMContextImpl;
friend struct FoldingSetTrait<MDNode>;
@@ -161,7 +160,6 @@ public:
void Profile(FoldingSetNodeID &ID) const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MDNode *) { return true; }
static bool classof(const Value *V) {
return V->getValueID() == MDNodeVal;
}
@@ -195,7 +193,7 @@ class NamedMDNode : public ilist_node<NamedMDNode> {
friend struct ilist_traits<NamedMDNode>;
friend class LLVMContextImpl;
friend class Module;
- NamedMDNode(const NamedMDNode &); // DO NOT IMPLEMENT
+ NamedMDNode(const NamedMDNode &) LLVM_DELETED_FUNCTION;
std::string Name;
Module *Parent;
diff --git a/include/llvm/Module.h b/include/llvm/IR/Module.h
index e6303ac..4e1ca43 100644
--- a/include/llvm/Module.h
+++ b/include/llvm/IR/Module.h
@@ -15,13 +15,12 @@
#ifndef LLVM_MODULE_H
#define LLVM_MODULE_H
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/GlobalAlias.h"
-#include "llvm/Metadata.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalAlias.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/Support/DataTypes.h"
-#include <vector>
namespace llvm {
@@ -122,9 +121,6 @@ public:
/// The type for the list of named metadata.
typedef ilist<NamedMDNode> NamedMDListType;
- /// The type for the list of dependent libraries.
- typedef std::vector<std::string> LibraryListType;
-
/// The Global Variable iterator.
typedef GlobalListType::iterator global_iterator;
/// The Global Variable constant iterator.
@@ -144,8 +140,6 @@ public:
typedef NamedMDListType::iterator named_metadata_iterator;
/// The named metadata constant interators.
typedef NamedMDListType::const_iterator const_named_metadata_iterator;
- /// The Library list iterator.
- typedef LibraryListType::const_iterator lib_iterator;
/// An enumeration for describing the endianess of the target machine.
enum Endianness { AnyEndianness, LittleEndian, BigEndian };
@@ -195,7 +189,6 @@ private:
GlobalListType GlobalList; ///< The Global Variables in the module
FunctionListType FunctionList; ///< The Functions in the module
AliasListType AliasList; ///< The Aliases in the module
- LibraryListType LibraryList; ///< The Libraries needed by the module
NamedMDListType NamedMDList; ///< The named metadata in the module
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
ValueSymbolTable *ValSymTab; ///< Symbol table for values
@@ -319,7 +312,7 @@ public:
/// 4. Finally, the function exists but has the wrong prototype: return the
/// function with a constantexpr cast to the right prototype.
Constant *getOrInsertFunction(StringRef Name, FunctionType *T,
- AttrListPtr AttributeList);
+ AttributeSet AttributeList);
Constant *getOrInsertFunction(StringRef Name, FunctionType *T);
@@ -331,7 +324,7 @@ public:
/// null terminated list of function arguments, which makes it easier for
/// clients to use.
Constant *getOrInsertFunction(StringRef Name,
- AttrListPtr AttributeList,
+ AttributeSet AttributeList,
Type *RetTy, ...) END_WITH_NULL;
/// getOrInsertFunction - Same as above, but without the attributes.
@@ -340,7 +333,7 @@ public:
Constant *getOrInsertTargetIntrinsic(StringRef Name,
FunctionType *Ty,
- AttrListPtr AttributeList);
+ AttributeSet AttributeList);
/// getFunction - Look up the specified function in the module symbol table.
/// If it does not exist, return null.
@@ -527,23 +520,6 @@ public:
bool empty() const { return FunctionList.empty(); }
/// @}
-/// @name Dependent Library Iteration
-/// @{
-
- /// @brief Get a constant iterator to beginning of dependent library list.
- inline lib_iterator lib_begin() const { return LibraryList.begin(); }
- /// @brief Get a constant iterator to end of dependent library list.
- inline lib_iterator lib_end() const { return LibraryList.end(); }
- /// @brief Returns the number of items in the list of libraries.
- inline size_t lib_size() const { return LibraryList.size(); }
- /// @brief Add a library to the list of dependent libraries
- void addLibrary(StringRef Lib);
- /// @brief Remove a library from the list of dependent libraries
- void removeLibrary(StringRef Lib);
- /// @brief Get all the libraries
- inline const LibraryListType& getLibraries() const { return LibraryList; }
-
-/// @}
/// @name Alias Iteration
/// @{
diff --git a/include/llvm/OperandTraits.h b/include/llvm/IR/OperandTraits.h
index 3d8dc32..60c8b09 100644
--- a/include/llvm/OperandTraits.h
+++ b/include/llvm/IR/OperandTraits.h
@@ -15,7 +15,7 @@
#ifndef LLVM_OPERAND_TRAITS_H
#define LLVM_OPERAND_TRAITS_H
-#include "llvm/User.h"
+#include "llvm/IR/User.h"
namespace llvm {
diff --git a/include/llvm/Operator.h b/include/llvm/IR/Operator.h
index 1e86980..577b41a 100644
--- a/include/llvm/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -15,9 +15,12 @@
#ifndef LLVM_OPERATOR_H
#define LLVM_OPERATOR_H
-#include "llvm/Constants.h"
-#include "llvm/Instruction.h"
-#include "llvm/Type.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
namespace llvm {
@@ -32,9 +35,14 @@ class Operator : public User {
private:
// Do not implement any of these. The Operator class is intended to be used
// as a utility, and is never itself instantiated.
- void *operator new(size_t, unsigned);
- void *operator new(size_t s);
- Operator();
+ void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t s) LLVM_DELETED_FUNCTION;
+ Operator() LLVM_DELETED_FUNCTION;
+
+protected:
+ // NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delete
+ // an overridden method that's not deleted in the base class. Cannot leave
+ // this unimplemented because that leads to an ODR-violation.
~Operator();
public:
@@ -57,7 +65,6 @@ public:
return Instruction::UserOp1;
}
- static inline bool classof(const Operator *) { return true; }
static inline bool classof(const Instruction *) { return true; }
static inline bool classof(const ConstantExpr *) { return true; }
static inline bool classof(const Value *V) {
@@ -77,8 +84,6 @@ public:
};
private:
- ~OverflowingBinaryOperator(); // do not implement
-
friend class BinaryOperator;
friend class ConstantExpr;
void setHasNoUnsignedWrap(bool B) {
@@ -103,7 +108,6 @@ public:
return (SubclassOptionalData & NoSignedWrap) != 0;
}
- static inline bool classof(const OverflowingBinaryOperator *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Add ||
I->getOpcode() == Instruction::Sub ||
@@ -129,23 +133,21 @@ public:
enum {
IsExact = (1 << 0)
};
-
-private:
- ~PossiblyExactOperator(); // do not implement
+private:
friend class BinaryOperator;
friend class ConstantExpr;
void setIsExact(bool B) {
SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
}
-
+
public:
/// isExact - Test whether this division is known to be exact, with
/// zero remainder.
bool isExact() const {
return SubclassOptionalData & IsExact;
}
-
+
static bool isPossiblyExactOpcode(unsigned OpC) {
return OpC == Instruction::SDiv ||
OpC == Instruction::UDiv ||
@@ -164,20 +166,139 @@ public:
}
};
+/// Convenience struct for specifying and reasoning about fast-math flags.
+class FastMathFlags {
+private:
+ friend class FPMathOperator;
+ unsigned Flags;
+ FastMathFlags(unsigned F) : Flags(F) { }
+
+public:
+ enum {
+ UnsafeAlgebra = (1 << 0),
+ NoNaNs = (1 << 1),
+ NoInfs = (1 << 2),
+ NoSignedZeros = (1 << 3),
+ AllowReciprocal = (1 << 4)
+ };
+
+ FastMathFlags() : Flags(0)
+ { }
+
+ /// Whether any flag is set
+ bool any() { return Flags != 0; }
+
+ /// Set all the flags to false
+ void clear() { Flags = 0; }
+
+ /// Flag queries
+ bool noNaNs() { return 0 != (Flags & NoNaNs); }
+ bool noInfs() { return 0 != (Flags & NoInfs); }
+ bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); }
+ bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); }
+ bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); }
+
+ /// Flag setters
+ void setNoNaNs() { Flags |= NoNaNs; }
+ void setNoInfs() { Flags |= NoInfs; }
+ void setNoSignedZeros() { Flags |= NoSignedZeros; }
+ void setAllowReciprocal() { Flags |= AllowReciprocal; }
+ void setUnsafeAlgebra() {
+ Flags |= UnsafeAlgebra;
+ setNoNaNs();
+ setNoInfs();
+ setNoSignedZeros();
+ setAllowReciprocal();
+ }
+};
+
+
/// FPMathOperator - Utility class for floating point operations which can have
/// information about relaxed accuracy requirements attached to them.
class FPMathOperator : public Operator {
private:
- ~FPMathOperator(); // do not implement
+ friend class Instruction;
+
+ void setHasUnsafeAlgebra(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) |
+ (B * FastMathFlags::UnsafeAlgebra);
+
+ // Unsafe algebra implies all the others
+ if (B) {
+ setHasNoNaNs(true);
+ setHasNoInfs(true);
+ setHasNoSignedZeros(true);
+ setHasAllowReciprocal(true);
+ }
+ }
+ void setHasNoNaNs(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
+ (B * FastMathFlags::NoNaNs);
+ }
+ void setHasNoInfs(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~FastMathFlags::NoInfs) |
+ (B * FastMathFlags::NoInfs);
+ }
+ void setHasNoSignedZeros(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
+ (B * FastMathFlags::NoSignedZeros);
+ }
+ void setHasAllowReciprocal(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
+ (B * FastMathFlags::AllowReciprocal);
+ }
+
+ /// Convenience function for setting all the fast-math flags
+ void setFastMathFlags(FastMathFlags FMF) {
+ SubclassOptionalData |= FMF.Flags;
+ }
public:
+ /// Test whether this operation is permitted to be
+ /// algebraically transformed, aka the 'A' fast-math property.
+ bool hasUnsafeAlgebra() const {
+ return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0;
+ }
+
+ /// Test whether this operation's arguments and results are to be
+ /// treated as non-NaN, aka the 'N' fast-math property.
+ bool hasNoNaNs() const {
+ return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
+ }
+
+ /// Test whether this operation's arguments and results are to be
+ /// treated as NoN-Inf, aka the 'I' fast-math property.
+ bool hasNoInfs() const {
+ return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
+ }
+
+ /// Test whether this operation can treat the sign of zero
+ /// as insignificant, aka the 'S' fast-math property.
+ bool hasNoSignedZeros() const {
+ return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
+ }
+
+ /// Test whether this operation is permitted to use
+ /// reciprocal instead of division, aka the 'R' fast-math property.
+ bool hasAllowReciprocal() const {
+ return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
+ }
+
+ /// Convenience function for getting all the fast-math flags
+ FastMathFlags getFastMathFlags() const {
+ return FastMathFlags(SubclassOptionalData);
+ }
/// \brief Get the maximum error permitted by this operation in ULPs. An
/// accuracy of 0.0 means that the operation should be performed with the
/// default precision.
float getFPAccuracy() const;
- static inline bool classof(const FPMathOperator *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getType()->isFPOrFPVectorTy();
}
@@ -186,16 +307,12 @@ public:
}
};
-
+
/// ConcreteOperator - A helper template for defining operators for individual
/// opcodes.
template<typename SuperClass, unsigned Opc>
class ConcreteOperator : public SuperClass {
- ~ConcreteOperator(); // DO NOT IMPLEMENT
public:
- static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
- return true;
- }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Opc;
}
@@ -210,45 +327,35 @@ public:
class AddOperator
: public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
- ~AddOperator(); // DO NOT IMPLEMENT
};
class SubOperator
: public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
- ~SubOperator(); // DO NOT IMPLEMENT
};
class MulOperator
: public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
- ~MulOperator(); // DO NOT IMPLEMENT
};
class ShlOperator
: public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
- ~ShlOperator(); // DO NOT IMPLEMENT
};
-
+
class SDivOperator
: public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
- ~SDivOperator(); // DO NOT IMPLEMENT
};
class UDivOperator
: public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
- ~UDivOperator(); // DO NOT IMPLEMENT
};
class AShrOperator
: public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
- ~AShrOperator(); // DO NOT IMPLEMENT
};
class LShrOperator
: public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
- ~LShrOperator(); // DO NOT IMPLEMENT
};
-
-
-
+
+
+
class GEPOperator
: public ConcreteOperator<Operator, Instruction::GetElementPtr> {
- ~GEPOperator(); // DO NOT IMPLEMENT
-
enum {
IsInBounds = (1 << 0)
};
@@ -288,6 +395,12 @@ public:
return getPointerOperand()->getType();
}
+ /// getPointerAddressSpace - Method to return the address space of the
+ /// pointer operand.
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperandType())->getAddressSpace();
+ }
+
unsigned getNumIndices() const { // Note: always non-negative
return getNumOperands() - 1;
}
@@ -319,6 +432,45 @@ public:
}
return true;
}
+
+ /// \brief Accumulate the constant address offset of this GEP if possible.
+ ///
+ /// This routine accepts an APInt into which it will accumulate the constant
+ /// offset of this GEP if the GEP is in fact constant. If the GEP is not
+ /// all-constant, it returns false and the value of the offset APInt is
+ /// undefined (it is *not* preserved!). The APInt passed into this routine
+ /// must be at least as wide as the IntPtr type for the address space of
+ /// the base GEP pointer.
+ bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const {
+ assert(Offset.getBitWidth() ==
+ DL.getPointerSizeInBits(getPointerAddressSpace()) &&
+ "The offset must have exactly as many bits as our pointer.");
+
+ for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
+ GTI != GTE; ++GTI) {
+ ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
+ if (!OpC)
+ return false;
+ if (OpC->isZero())
+ continue;
+
+ // Handle a struct index, which adds its field offset to the pointer.
+ if (StructType *STy = dyn_cast<StructType>(*GTI)) {
+ unsigned ElementIdx = OpC->getZExtValue();
+ const StructLayout *SL = DL.getStructLayout(STy);
+ Offset += APInt(Offset.getBitWidth(),
+ SL->getElementOffset(ElementIdx));
+ continue;
+ }
+
+ // For array or vector indices, scale the index by the size of the type.
+ APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth());
+ Offset += Index * APInt(Offset.getBitWidth(),
+ DL.getTypeAllocSize(GTI.getIndexedType()));
+ }
+ return true;
+ }
+
};
} // End llvm namespace
diff --git a/include/llvm/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h
index ec5c88f..ec5c88f 100644
--- a/include/llvm/SymbolTableListTraits.h
+++ b/include/llvm/IR/SymbolTableListTraits.h
diff --git a/include/llvm/Type.h b/include/llvm/IR/Type.h
index 185258d..def4575 100644
--- a/include/llvm/Type.h
+++ b/include/llvm/IR/Type.h
@@ -153,7 +153,7 @@ public:
/// isPPC_FP128Ty - Return true if this is powerpc long double.
bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; }
- /// isFloatingPointTy - Return true if this is one of the five floating point
+ /// isFloatingPointTy - Return true if this is one of the six floating point
/// types
bool isFloatingPointTy() const {
return getTypeID() == HalfTyID || getTypeID() == FloatTyID ||
@@ -167,7 +167,7 @@ public:
/// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP.
///
- bool isFPOrFPVectorTy() const;
+ bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); }
/// isLabelTy - Return true if this is 'label'.
bool isLabelTy() const { return getTypeID() == LabelTyID; }
@@ -185,7 +185,7 @@ public:
/// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
/// integer types.
///
- bool isIntOrIntVectorTy() const;
+ bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); }
/// isFunctionTy - True if this is an instance of FunctionType.
///
@@ -203,6 +203,11 @@ public:
///
bool isPointerTy() const { return getTypeID() == PointerTyID; }
+ /// isPtrOrPtrVectorTy - Return true if this is a pointer type or a vector of
+ /// pointer types.
+ ///
+ bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); }
+
/// isVectorTy - True if this is an instance of VectorType.
///
bool isVectorTy() const { return getTypeID() == VectorTyID; }
@@ -252,7 +257,7 @@ public:
/// isSized - Return true if it makes sense to take the size of this type. To
/// get the actual size for a particular target, it is reasonable to use the
- /// TargetData subsystem to do this.
+ /// DataLayout subsystem to do this.
///
bool isSized() const {
// If it's a primitive, it is always sized.
@@ -276,7 +281,7 @@ public:
///
/// Note that this may not reflect the size of memory allocated for an
/// instance of the type or the number of bytes that are written when an
- /// instance of the type is stored to memory. The TargetData class provides
+ /// instance of the type is stored to memory. The DataLayout class provides
/// additional query functions to provide this information.
///
unsigned getPrimitiveSizeInBits() const;
@@ -293,6 +298,7 @@ public:
/// getScalarType - If this is a vector type, return the element type,
/// otherwise return 'this'.
+ const Type *getScalarType() const;
Type *getScalarType();
//===--------------------------------------------------------------------===//
@@ -340,8 +346,10 @@ public:
unsigned getVectorNumElements() const;
Type *getVectorElementType() const { return getSequentialElementType(); }
- unsigned getPointerAddressSpace() const;
Type *getPointerElementType() const { return getSequentialElementType(); }
+
+ /// \brief Get the address space of this pointer or pointer vector type.
+ unsigned getPointerAddressSpace() const;
//===--------------------------------------------------------------------===//
// Static members exported by the Type class itself. Useful for getting
@@ -389,9 +397,6 @@ public:
static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0);
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Type *) { return true; }
-
/// getPointerTo - Return a pointer to the current type. This is equivalent
/// to PointerType::get(Foo, AddrSpace).
PointerType *getPointerTo(unsigned AddrSpace = 0);
diff --git a/include/llvm/TypeBuilder.h b/include/llvm/IR/TypeBuilder.h
index 0b56479..83ca2a3 100644
--- a/include/llvm/TypeBuilder.h
+++ b/include/llvm/IR/TypeBuilder.h
@@ -15,8 +15,8 @@
#ifndef LLVM_TYPEBUILDER_H
#define LLVM_TYPEBUILDER_H
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
#include <limits.h>
namespace llvm {
diff --git a/include/llvm/TypeFinder.h b/include/llvm/IR/TypeFinder.h
index 5d80705..cea66a4 100644
--- a/include/llvm/TypeFinder.h
+++ b/include/llvm/IR/TypeFinder.h
@@ -1,4 +1,4 @@
-//===-- llvm/TypeFinder.h - Class for finding used struct types -*- C++ -*-===//
+//===-- llvm/IR/TypeFinder.h - Class to find used struct types --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TYPEFINDER_H
-#define LLVM_TYPEFINDER_H
+#ifndef LLVM_IR_TYPEFINDER_H
+#define LLVM_IR_TYPEFINDER_H
#include "llvm/ADT/DenseSet.h"
#include <vector>
diff --git a/include/llvm/Use.h b/include/llvm/IR/Use.h
index a496325..8080445 100644
--- a/include/llvm/Use.h
+++ b/include/llvm/IR/Use.h
@@ -26,6 +26,7 @@
#define LLVM_USE_H
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
#include <cstddef>
#include <iterator>
@@ -66,7 +67,7 @@ public:
private:
/// Copy ctor - do not implement
- Use(const Use &U);
+ Use(const Use &U) LLVM_DELETED_FUNCTION;
/// Destructor - Only for zap()
~Use() {
diff --git a/include/llvm/User.h b/include/llvm/IR/User.h
index 5d5460c..843d20b 100644
--- a/include/llvm/User.h
+++ b/include/llvm/IR/User.h
@@ -19,8 +19,8 @@
#ifndef LLVM_USER_H
#define LLVM_USER_H
+#include "llvm/IR/Value.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Value.h"
namespace llvm {
@@ -31,8 +31,8 @@ template <class>
struct OperandTraits;
class User : public Value {
- User(const User &); // Do not implement
- void *operator new(size_t); // Do not implement
+ User(const User &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t) LLVM_DELETED_FUNCTION;
template <unsigned>
friend struct HungoffOperandTraits;
virtual void anchor();
@@ -104,7 +104,7 @@ public:
assert(i < NumOperands && "getOperandUse() out of range!");
return OperandList[i];
}
-
+
unsigned getNumOperands() const { return NumOperands; }
// ---------------------------------------------------------------------------
@@ -118,6 +118,45 @@ public:
inline op_iterator op_end() { return OperandList+NumOperands; }
inline const_op_iterator op_end() const { return OperandList+NumOperands; }
+ /// Convenience iterator for directly iterating over the Values in the
+ /// OperandList
+ class value_op_iterator : public std::iterator<std::forward_iterator_tag,
+ Value*> {
+ op_iterator OI;
+ public:
+ explicit value_op_iterator(Use *U) : OI(U) {}
+
+ bool operator==(const value_op_iterator &x) const {
+ return OI == x.OI;
+ }
+ bool operator!=(const value_op_iterator &x) const {
+ return !operator==(x);
+ }
+
+ /// Iterator traversal: forward iteration only
+ value_op_iterator &operator++() { // Preincrement
+ ++OI;
+ return *this;
+ }
+ value_op_iterator operator++(int) { // Postincrement
+ value_op_iterator tmp = *this; ++*this; return tmp;
+ }
+
+ /// Retrieve a pointer to the current Value.
+ Value *operator*() const {
+ return *OI;
+ }
+
+ Value *operator->() const { return operator*(); }
+ };
+
+ inline value_op_iterator value_op_begin() {
+ return value_op_iterator(op_begin());
+ }
+ inline value_op_iterator value_op_end() {
+ return value_op_iterator(op_end());
+ }
+
// dropAllReferences() - This function is in charge of "letting go" of all
// objects that this User refers to. This allows one to
// 'delete' a whole class at a time, even though there may be circular
@@ -137,7 +176,6 @@ public:
void replaceUsesOfWith(Value *From, Value *To);
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const User *) { return true; }
static inline bool classof(const Value *V) {
return isa<Instruction>(V) || isa<Constant>(V);
}
diff --git a/include/llvm/Value.h b/include/llvm/IR/Value.h
index a82ac45..85fdfe3 100644
--- a/include/llvm/Value.h
+++ b/include/llvm/IR/Value.h
@@ -14,8 +14,9 @@
#ifndef LLVM_VALUE_H
#define LLVM_VALUE_H
-#include "llvm/Use.h"
+#include "llvm/IR/Use.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -80,8 +81,8 @@ private:
friend class ValueHandleBase;
ValueName *Name;
- void operator=(const Value &); // Do not implement
- Value(const Value &); // Do not implement
+ void operator=(const Value &) LLVM_DELETED_FUNCTION;
+ Value(const Value &) LLVM_DELETED_FUNCTION;
protected:
/// printCustom - Value subclasses can override this to implement custom
@@ -120,7 +121,7 @@ public:
/// setName() - Change the name of the value, choosing a new unique name if
/// the provided name is taken.
///
- /// \arg Name - The new name; or "" if the value's name should be removed.
+ /// \param Name The new name; or "" if the value's name should be removed.
void setName(const Twine &Name);
@@ -256,11 +257,6 @@ public:
/// hasValueHandle - Return true if there is a value handle associated with
/// this value.
bool hasValueHandle() const { return HasValueHandle; }
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *) {
- return true; // Values are always values.
- }
/// stripPointerCasts - This method strips off any unneeded pointer casts and
/// all-zero GEPs from the specified value, returning the original uncasted
diff --git a/include/llvm/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h
index 1738cc4..3ea095b 100644
--- a/include/llvm/ValueSymbolTable.h
+++ b/include/llvm/IR/ValueSymbolTable.h
@@ -14,8 +14,8 @@
#ifndef LLVM_VALUE_SYMBOL_TABLE_H
#define LLVM_VALUE_SYMBOL_TABLE_H
-#include "llvm/Value.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/Value.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index bede4eb..79037f7 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -66,8 +66,10 @@ void initializeAliasDebuggerPass(PassRegistry&);
void initializeAliasSetPrinterPass(PassRegistry&);
void initializeAlwaysInlinerPass(PassRegistry&);
void initializeArgPromotionPass(PassRegistry&);
+void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&);
void initializeBasicCallGraphPass(PassRegistry&);
+void initializeBasicTTIPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyInfoPass(PassRegistry&);
void initializeBlockPlacementPass(PassRegistry&);
@@ -87,6 +89,7 @@ void initializeCodePlacementOptPass(PassRegistry&);
void initializeConstantMergePass(PassRegistry&);
void initializeConstantPropagationPass(PassRegistry&);
void initializeMachineCopyPropagationPass(PassRegistry&);
+void initializeCostModelAnalysisPass(PassRegistry&);
void initializeCorrelatedValuePropagationPass(PassRegistry&);
void initializeDAEPass(PassRegistry&);
void initializeDAHPass(PassRegistry&);
@@ -94,6 +97,7 @@ void initializeDCEPass(PassRegistry&);
void initializeDSEPass(PassRegistry&);
void initializeDeadInstEliminationPass(PassRegistry&);
void initializeDeadMachineInstructionElimPass(PassRegistry&);
+void initializeDependenceAnalysisPass(PassRegistry&);
void initializeDomOnlyPrinterPass(PassRegistry&);
void initializeDomOnlyViewerPass(PassRegistry&);
void initializeDomPrinterPass(PassRegistry&);
@@ -107,6 +111,8 @@ void initializeExpandPostRAPass(PassRegistry&);
void initializePathProfilerPass(PassRegistry&);
void initializeGCOVProfilerPass(PassRegistry&);
void initializeAddressSanitizerPass(PassRegistry&);
+void initializeAddressSanitizerModulePass(PassRegistry&);
+void initializeMemorySanitizerPass(PassRegistry&);
void initializeThreadSanitizerPass(PassRegistry&);
void initializeEarlyCSEPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&);
@@ -145,7 +151,6 @@ void initializeProfileMetadataLoaderPassPass(PassRegistry&);
void initializePathProfileLoaderPassPass(PassRegistry&);
void initializeLocalStackSlotPassPass(PassRegistry&);
void initializeLoopDeletionPass(PassRegistry&);
-void initializeLoopDependenceAnalysisPass(PassRegistry&);
void initializeLoopExtractorPass(PassRegistry&);
void initializeLoopInfoPass(PassRegistry&);
void initializeLoopInstSimplifyPass(PassRegistry&);
@@ -167,9 +172,9 @@ void initializeMachineBlockPlacementStatsPass(PassRegistry&);
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
void initializeMachineCSEPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&);
+void initializeMachinePostDominatorTreePass(PassRegistry&);
void initializeMachineLICMPass(PassRegistry&);
void initializeMachineLoopInfoPass(PassRegistry&);
-void initializeMachineLoopRangesPass(PassRegistry&);
void initializeMachineModuleInfoPass(PassRegistry&);
void initializeMachineSchedulerPass(PassRegistry&);
void initializeMachineSinkingPass(PassRegistry&);
@@ -178,6 +183,7 @@ void initializeMachineVerifierPassPass(PassRegistry&);
void initializeMemCpyOptPass(PassRegistry&);
void initializeMemDepPrinterPass(PassRegistry&);
void initializeMemoryDependenceAnalysisPass(PassRegistry&);
+void initializeMetaRenamerPass(PassRegistry&);
void initializeMergeFunctionsPass(PassRegistry&);
void initializeModuleDebugInfoPrinterPass(PassRegistry&);
void initializeNoAAPass(PassRegistry&);
@@ -220,6 +226,7 @@ void initializeRegionOnlyViewerPass(PassRegistry&);
void initializeRegionPrinterPass(PassRegistry&);
void initializeRegionViewerPass(PassRegistry&);
void initializeSCCPPass(PassRegistry&);
+void initializeSROAPass(PassRegistry&);
void initializeSROA_DTPass(PassRegistry&);
void initializeSROA_SSAUpPass(PassRegistry&);
void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
@@ -243,7 +250,9 @@ void initializeStrongPHIEliminationPass(PassRegistry&);
void initializeTailCallElimPass(PassRegistry&);
void initializeTailDuplicatePassPass(PassRegistry&);
void initializeTargetPassConfigPass(PassRegistry&);
-void initializeTargetDataPass(PassRegistry&);
+void initializeDataLayoutPass(PassRegistry&);
+void initializeTargetTransformInfoAnalysisGroup(PassRegistry&);
+void initializeNoTTIPass(PassRegistry&);
void initializeTargetLibraryInfoPass(PassRegistry&);
void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
@@ -256,6 +265,7 @@ void initializeVirtRegRewriterPass(PassRegistry&);
void initializeInstSimplifierPass(PassRegistry&);
void initializeUnpackMachineBundlesPass(PassRegistry&);
void initializeFinalizeMachineBundlesPass(PassRegistry&);
+void initializeLoopVectorizePass(PassRegistry&);
void initializeBBVectorizePass(PassRegistry&);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
}
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/InstVisitor.h
index 109b3cf..2911703 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/InstVisitor.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*-===//
+//===- llvm/InstVisitor.h - Instruction visitor templates -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,14 +8,14 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_INSTVISITOR_H
-#define LLVM_SUPPORT_INSTVISITOR_H
+#ifndef LLVM_INSTVISITOR_H
+#define LLVM_INSTVISITOR_H
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Module.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
@@ -25,7 +25,7 @@ namespace llvm {
// types now...
//
#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
#define DELEGATE(CLASS_TO_VISIT) \
return static_cast<SubClass*>(this)-> \
@@ -123,7 +123,7 @@ public:
case Instruction::OPCODE: return \
static_cast<SubClass*>(this)-> \
visit##OPCODE(static_cast<CLASS&>(I));
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
}
}
@@ -158,7 +158,7 @@ public:
else \
DELEGATE(CLASS); \
}
-#include "llvm/Instruction.def"
+#include "llvm/IR/Instruction.def"
// Specific Instruction type classes... note that all of the casts are
// necessary because we use the instruction classes as opaque types...
@@ -209,6 +209,9 @@ public:
RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); }
RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); }
RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitVAStartInst(VAStartInst &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitVACopyInst(VACopyInst &I) { DELEGATE(IntrinsicInst); }
RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); }
// Call and Invoke are slightly different as they delegate first through
@@ -262,6 +265,9 @@ private:
case Intrinsic::memcpy: DELEGATE(MemCpyInst);
case Intrinsic::memmove: DELEGATE(MemMoveInst);
case Intrinsic::memset: DELEGATE(MemSetInst);
+ case Intrinsic::vastart: DELEGATE(VAStartInst);
+ case Intrinsic::vaend: DELEGATE(VAEndInst);
+ case Intrinsic::vacopy: DELEGATE(VACopyInst);
case Intrinsic::not_intrinsic: break;
}
}
diff --git a/include/llvm/IntrinsicsARM.td b/include/llvm/IntrinsicsARM.td
deleted file mode 100644
index fa8034e..0000000
--- a/include/llvm/IntrinsicsARM.td
+++ /dev/null
@@ -1,442 +0,0 @@
-//===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines all of the ARM-specific intrinsics.
-//
-//===----------------------------------------------------------------------===//
-
-
-//===----------------------------------------------------------------------===//
-// TLS
-
-let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
- def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">,
- Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
-}
-
-//===----------------------------------------------------------------------===//
-// Saturating Arithmentic
-
-let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
- def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, Commutative]>;
- def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
-}
-
-//===----------------------------------------------------------------------===//
-// Load and Store exclusive doubleword
-
-let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
- def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
- llvm_ptr_ty], [IntrReadWriteArgMem]>;
- def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty],
- [IntrReadArgMem]>;
-}
-
-//===----------------------------------------------------------------------===//
-// VFP
-
-let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
- def int_arm_get_fpscr : GCCBuiltin<"__builtin_arm_get_fpscr">,
- Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
- def int_arm_set_fpscr : GCCBuiltin<"__builtin_arm_set_fpscr">,
- Intrinsic<[], [llvm_i32_ty], []>;
- def int_arm_vcvtr : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
- [IntrNoMem]>;
- def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
- [IntrNoMem]>;
-}
-
-//===----------------------------------------------------------------------===//
-// Coprocessor
-
-let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
- // Move to coprocessor
- def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
- def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
-
- // Move from coprocessor
- def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], []>;
- def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], []>;
-
- // Coprocessor data processing
- def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
- def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
-
- // Move from two registers to coprocessor
- def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], []>;
- def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], []>;
-}
-
-//===----------------------------------------------------------------------===//
-// Advanced SIMD (NEON)
-
-let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
-
- // The following classes do not correspond directly to GCC builtins.
- class Neon_1Arg_Intrinsic
- : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
- class Neon_1Arg_Narrow_Intrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMExtendedElementVectorType<0>], [IntrNoMem]>;
- class Neon_2Arg_Intrinsic
- : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
- class Neon_2Arg_Narrow_Intrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMExtendedElementVectorType<0>,
- LLVMExtendedElementVectorType<0>],
- [IntrNoMem]>;
- class Neon_2Arg_Long_Intrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMTruncatedElementVectorType<0>,
- LLVMTruncatedElementVectorType<0>],
- [IntrNoMem]>;
- class Neon_3Arg_Intrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
- class Neon_3Arg_Long_Intrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>,
- LLVMTruncatedElementVectorType<0>,
- LLVMTruncatedElementVectorType<0>],
- [IntrNoMem]>;
- class Neon_CvtFxToFP_Intrinsic
- : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
- class Neon_CvtFPToFx_Intrinsic
- : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
-
- // The table operands for VTBL and VTBX consist of 1 to 4 v8i8 vectors.
- // Besides the table, VTBL has one other v8i8 argument and VTBX has two.
- // Overall, the classes range from 2 to 6 v8i8 arguments.
- class Neon_Tbl2Arg_Intrinsic
- : Intrinsic<[llvm_v8i8_ty],
- [llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
- class Neon_Tbl3Arg_Intrinsic
- : Intrinsic<[llvm_v8i8_ty],
- [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
- class Neon_Tbl4Arg_Intrinsic
- : Intrinsic<[llvm_v8i8_ty],
- [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty],
- [IntrNoMem]>;
- class Neon_Tbl5Arg_Intrinsic
- : Intrinsic<[llvm_v8i8_ty],
- [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty,
- llvm_v8i8_ty], [IntrNoMem]>;
- class Neon_Tbl6Arg_Intrinsic
- : Intrinsic<[llvm_v8i8_ty],
- [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty,
- llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
-}
-
-// Arithmetic ops
-
-let Properties = [IntrNoMem, Commutative] in {
-
- // Vector Add.
- def int_arm_neon_vhadds : Neon_2Arg_Intrinsic;
- def int_arm_neon_vhaddu : Neon_2Arg_Intrinsic;
- def int_arm_neon_vrhadds : Neon_2Arg_Intrinsic;
- def int_arm_neon_vrhaddu : Neon_2Arg_Intrinsic;
- def int_arm_neon_vqadds : Neon_2Arg_Intrinsic;
- def int_arm_neon_vqaddu : Neon_2Arg_Intrinsic;
- def int_arm_neon_vaddhn : Neon_2Arg_Narrow_Intrinsic;
- def int_arm_neon_vraddhn : Neon_2Arg_Narrow_Intrinsic;
-
- // Vector Multiply.
- def int_arm_neon_vmulp : Neon_2Arg_Intrinsic;
- def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic;
- def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic;
- def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic;
- def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic;
- def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic;
- def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic;
-
- // Vector Multiply and Accumulate/Subtract.
- def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic;
- def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic;
-
- // Vector Maximum.
- def int_arm_neon_vmaxs : Neon_2Arg_Intrinsic;
- def int_arm_neon_vmaxu : Neon_2Arg_Intrinsic;
-
- // Vector Minimum.
- def int_arm_neon_vmins : Neon_2Arg_Intrinsic;
- def int_arm_neon_vminu : Neon_2Arg_Intrinsic;
-
- // Vector Reciprocal Step.
- def int_arm_neon_vrecps : Neon_2Arg_Intrinsic;
-
- // Vector Reciprocal Square Root Step.
- def int_arm_neon_vrsqrts : Neon_2Arg_Intrinsic;
-}
-
-// Vector Subtract.
-def int_arm_neon_vhsubs : Neon_2Arg_Intrinsic;
-def int_arm_neon_vhsubu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vqsubs : Neon_2Arg_Intrinsic;
-def int_arm_neon_vqsubu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vsubhn : Neon_2Arg_Narrow_Intrinsic;
-def int_arm_neon_vrsubhn : Neon_2Arg_Narrow_Intrinsic;
-
-// Vector Absolute Compare.
-let TargetPrefix = "arm" in {
- def int_arm_neon_vacged : Intrinsic<[llvm_v2i32_ty],
- [llvm_v2f32_ty, llvm_v2f32_ty],
- [IntrNoMem]>;
- def int_arm_neon_vacgeq : Intrinsic<[llvm_v4i32_ty],
- [llvm_v4f32_ty, llvm_v4f32_ty],
- [IntrNoMem]>;
- def int_arm_neon_vacgtd : Intrinsic<[llvm_v2i32_ty],
- [llvm_v2f32_ty, llvm_v2f32_ty],
- [IntrNoMem]>;
- def int_arm_neon_vacgtq : Intrinsic<[llvm_v4i32_ty],
- [llvm_v4f32_ty, llvm_v4f32_ty],
- [IntrNoMem]>;
-}
-
-// Vector Absolute Differences.
-def int_arm_neon_vabds : Neon_2Arg_Intrinsic;
-def int_arm_neon_vabdu : Neon_2Arg_Intrinsic;
-
-// Vector Pairwise Add.
-def int_arm_neon_vpadd : Neon_2Arg_Intrinsic;
-
-// Vector Pairwise Add Long.
-// Note: This is different than the other "long" NEON intrinsics because
-// the result vector has half as many elements as the source vector.
-// The source and destination vector types must be specified separately.
-let TargetPrefix = "arm" in {
- def int_arm_neon_vpaddls : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty],
- [IntrNoMem]>;
- def int_arm_neon_vpaddlu : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty],
- [IntrNoMem]>;
-}
-
-// Vector Pairwise Add and Accumulate Long.
-// Note: This is similar to vpaddl but the destination vector also appears
-// as the first argument.
-let TargetPrefix = "arm" in {
- def int_arm_neon_vpadals : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty],
- [IntrNoMem]>;
- def int_arm_neon_vpadalu : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty],
- [IntrNoMem]>;
-}
-
-// Vector Pairwise Maximum and Minimum.
-def int_arm_neon_vpmaxs : Neon_2Arg_Intrinsic;
-def int_arm_neon_vpmaxu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vpmins : Neon_2Arg_Intrinsic;
-def int_arm_neon_vpminu : Neon_2Arg_Intrinsic;
-
-// Vector Shifts:
-//
-// The various saturating and rounding vector shift operations need to be
-// represented by intrinsics in LLVM, and even the basic VSHL variable shift
-// operation cannot be safely translated to LLVM's shift operators. VSHL can
-// be used for both left and right shifts, or even combinations of the two,
-// depending on the signs of the shift amounts. It also has well-defined
-// behavior for shift amounts that LLVM leaves undefined. Only basic shifts
-// by constants can be represented with LLVM's shift operators.
-//
-// The shift counts for these intrinsics are always vectors, even for constant
-// shifts, where the constant is replicated. For consistency with VSHL (and
-// other variable shift instructions), left shifts have positive shift counts
-// and right shifts have negative shift counts. This convention is also used
-// for constant right shift intrinsics, and to help preserve sanity, the
-// intrinsic names use "shift" instead of either "shl" or "shr". Where
-// applicable, signed and unsigned versions of the intrinsics are
-// distinguished with "s" and "u" suffixes. A few NEON shift instructions,
-// such as VQSHLU, take signed operands but produce unsigned results; these
-// use a "su" suffix.
-
-// Vector Shift.
-def int_arm_neon_vshifts : Neon_2Arg_Intrinsic;
-def int_arm_neon_vshiftu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vshiftls : Neon_2Arg_Long_Intrinsic;
-def int_arm_neon_vshiftlu : Neon_2Arg_Long_Intrinsic;
-def int_arm_neon_vshiftn : Neon_2Arg_Narrow_Intrinsic;
-
-// Vector Rounding Shift.
-def int_arm_neon_vrshifts : Neon_2Arg_Intrinsic;
-def int_arm_neon_vrshiftu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vrshiftn : Neon_2Arg_Narrow_Intrinsic;
-
-// Vector Saturating Shift.
-def int_arm_neon_vqshifts : Neon_2Arg_Intrinsic;
-def int_arm_neon_vqshiftu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vqshiftsu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vqshiftns : Neon_2Arg_Narrow_Intrinsic;
-def int_arm_neon_vqshiftnu : Neon_2Arg_Narrow_Intrinsic;
-def int_arm_neon_vqshiftnsu : Neon_2Arg_Narrow_Intrinsic;
-
-// Vector Saturating Rounding Shift.
-def int_arm_neon_vqrshifts : Neon_2Arg_Intrinsic;
-def int_arm_neon_vqrshiftu : Neon_2Arg_Intrinsic;
-def int_arm_neon_vqrshiftns : Neon_2Arg_Narrow_Intrinsic;
-def int_arm_neon_vqrshiftnu : Neon_2Arg_Narrow_Intrinsic;
-def int_arm_neon_vqrshiftnsu : Neon_2Arg_Narrow_Intrinsic;
-
-// Vector Shift and Insert.
-def int_arm_neon_vshiftins : Neon_3Arg_Intrinsic;
-
-// Vector Absolute Value and Saturating Absolute Value.
-def int_arm_neon_vabs : Neon_1Arg_Intrinsic;
-def int_arm_neon_vqabs : Neon_1Arg_Intrinsic;
-
-// Vector Saturating Negate.
-def int_arm_neon_vqneg : Neon_1Arg_Intrinsic;
-
-// Vector Count Leading Sign/Zero Bits.
-def int_arm_neon_vcls : Neon_1Arg_Intrinsic;
-def int_arm_neon_vclz : Neon_1Arg_Intrinsic;
-
-// Vector Count One Bits.
-def int_arm_neon_vcnt : Neon_1Arg_Intrinsic;
-
-// Vector Reciprocal Estimate.
-def int_arm_neon_vrecpe : Neon_1Arg_Intrinsic;
-
-// Vector Reciprocal Square Root Estimate.
-def int_arm_neon_vrsqrte : Neon_1Arg_Intrinsic;
-
-// Vector Conversions Between Floating-point and Fixed-point.
-def int_arm_neon_vcvtfp2fxs : Neon_CvtFPToFx_Intrinsic;
-def int_arm_neon_vcvtfp2fxu : Neon_CvtFPToFx_Intrinsic;
-def int_arm_neon_vcvtfxs2fp : Neon_CvtFxToFP_Intrinsic;
-def int_arm_neon_vcvtfxu2fp : Neon_CvtFxToFP_Intrinsic;
-
-// Vector Conversions Between Half-Precision and Single-Precision.
-def int_arm_neon_vcvtfp2hf
- : Intrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
-def int_arm_neon_vcvthf2fp
- : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
-
-// Narrowing Saturating Vector Moves.
-def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic;
-def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic;
-def int_arm_neon_vqmovnsu : Neon_1Arg_Narrow_Intrinsic;
-
-// Vector Table Lookup.
-// The first 1-4 arguments are the table.
-def int_arm_neon_vtbl1 : Neon_Tbl2Arg_Intrinsic;
-def int_arm_neon_vtbl2 : Neon_Tbl3Arg_Intrinsic;
-def int_arm_neon_vtbl3 : Neon_Tbl4Arg_Intrinsic;
-def int_arm_neon_vtbl4 : Neon_Tbl5Arg_Intrinsic;
-
-// Vector Table Extension.
-// Some elements of the destination vector may not be updated, so the original
-// value of that vector is passed as the first argument. The next 1-4
-// arguments after that are the table.
-def int_arm_neon_vtbx1 : Neon_Tbl3Arg_Intrinsic;
-def int_arm_neon_vtbx2 : Neon_Tbl4Arg_Intrinsic;
-def int_arm_neon_vtbx3 : Neon_Tbl5Arg_Intrinsic;
-def int_arm_neon_vtbx4 : Neon_Tbl6Arg_Intrinsic;
-
-let TargetPrefix = "arm" in {
-
- // De-interleaving vector loads from N-element structures.
- // Source operands are the address and alignment.
- def int_arm_neon_vld1 : Intrinsic<[llvm_anyvector_ty],
- [llvm_ptr_ty, llvm_i32_ty],
- [IntrReadArgMem]>;
- def int_arm_neon_vld2 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
- [llvm_ptr_ty, llvm_i32_ty],
- [IntrReadArgMem]>;
- def int_arm_neon_vld3 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
- LLVMMatchType<0>],
- [llvm_ptr_ty, llvm_i32_ty],
- [IntrReadArgMem]>;
- def int_arm_neon_vld4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
- LLVMMatchType<0>, LLVMMatchType<0>],
- [llvm_ptr_ty, llvm_i32_ty],
- [IntrReadArgMem]>;
-
- // Vector load N-element structure to one lane.
- // Source operands are: the address, the N input vectors (since only one
- // lane is assigned), the lane number, and the alignment.
- def int_arm_neon_vld2lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
- [llvm_ptr_ty, LLVMMatchType<0>,
- LLVMMatchType<0>, llvm_i32_ty,
- llvm_i32_ty], [IntrReadArgMem]>;
- def int_arm_neon_vld3lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
- LLVMMatchType<0>],
- [llvm_ptr_ty, LLVMMatchType<0>,
- LLVMMatchType<0>, LLVMMatchType<0>,
- llvm_i32_ty, llvm_i32_ty],
- [IntrReadArgMem]>;
- def int_arm_neon_vld4lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
- LLVMMatchType<0>, LLVMMatchType<0>],
- [llvm_ptr_ty, LLVMMatchType<0>,
- LLVMMatchType<0>, LLVMMatchType<0>,
- LLVMMatchType<0>, llvm_i32_ty,
- llvm_i32_ty], [IntrReadArgMem]>;
-
- // Interleaving vector stores from N-element structures.
- // Source operands are: the address, the N vectors, and the alignment.
- def int_arm_neon_vst1 : Intrinsic<[],
- [llvm_ptr_ty, llvm_anyvector_ty,
- llvm_i32_ty], [IntrReadWriteArgMem]>;
- def int_arm_neon_vst2 : Intrinsic<[],
- [llvm_ptr_ty, llvm_anyvector_ty,
- LLVMMatchType<0>, llvm_i32_ty],
- [IntrReadWriteArgMem]>;
- def int_arm_neon_vst3 : Intrinsic<[],
- [llvm_ptr_ty, llvm_anyvector_ty,
- LLVMMatchType<0>, LLVMMatchType<0>,
- llvm_i32_ty], [IntrReadWriteArgMem]>;
- def int_arm_neon_vst4 : Intrinsic<[],
- [llvm_ptr_ty, llvm_anyvector_ty,
- LLVMMatchType<0>, LLVMMatchType<0>,
- LLVMMatchType<0>, llvm_i32_ty],
- [IntrReadWriteArgMem]>;
-
- // Vector store N-element structure from one lane.
- // Source operands are: the address, the N vectors, the lane number, and
- // the alignment.
- def int_arm_neon_vst2lane : Intrinsic<[],
- [llvm_ptr_ty, llvm_anyvector_ty,
- LLVMMatchType<0>, llvm_i32_ty,
- llvm_i32_ty], [IntrReadWriteArgMem]>;
- def int_arm_neon_vst3lane : Intrinsic<[],
- [llvm_ptr_ty, llvm_anyvector_ty,
- LLVMMatchType<0>, LLVMMatchType<0>,
- llvm_i32_ty, llvm_i32_ty],
- [IntrReadWriteArgMem]>;
- def int_arm_neon_vst4lane : Intrinsic<[],
- [llvm_ptr_ty, llvm_anyvector_ty,
- LLVMMatchType<0>, LLVMMatchType<0>,
- LLVMMatchType<0>, llvm_i32_ty,
- llvm_i32_ty], [IntrReadWriteArgMem]>;
-}
diff --git a/include/llvm/IntrinsicsCellSPU.td b/include/llvm/IntrinsicsCellSPU.td
deleted file mode 100644
index 1e311bb..0000000
--- a/include/llvm/IntrinsicsCellSPU.td
+++ /dev/null
@@ -1,242 +0,0 @@
-//==- IntrinsicsCellSPU.td - Cell SDK intrinsics -*- tablegen -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// Department at The Aerospace Corporation and is distributed under the
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Cell SPU Instructions:
-//===----------------------------------------------------------------------===//
-// TODO Items (not urgent today, but would be nice, low priority)
-//
-// ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by
-// concatenating the byte argument b as "bbbb". Could recognize this bit pattern
-// in 16-bit and 32-bit constants and reduce instruction count.
-//===----------------------------------------------------------------------===//
-
-// 7-bit integer type, used as an immediate:
-def cell_i7_ty: LLVMType<i8>;
-def cell_i8_ty: LLVMType<i8>;
-
-// Keep this here until it's actually supported:
-def llvm_i128_ty : LLVMType<i128>;
-
-class v16i8_u7imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, cell_i7_ty],
- [IntrNoMem]>;
-
-class v16i8_u8imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
-class v16i8_s10imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
-class v16i8_u16imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
-class v16i8_rr<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
-
-class v8i16_s10imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
-class v8i16_u16imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
-class v8i16_rr<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
-
-class v4i32_rr<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
-
-class v4i32_u7imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, cell_i7_ty],
- [IntrNoMem]>;
-
-class v4i32_s10imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
-class v4i32_u16imm<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
-class v4f32_rr<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
- [IntrNoMem]>;
-
-class v4f32_rrr<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
- [IntrNoMem]>;
-
-class v2f64_rr<string builtin_suffix> :
- GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
- [IntrNoMem]>;
-
-// All Cell SPU intrinsics start with "llvm.spu.".
-let TargetPrefix = "spu" in {
- def int_spu_si_fsmbi : v8i16_u16imm<"fsmbi">;
- def int_spu_si_ah : v8i16_rr<"ah">;
- def int_spu_si_ahi : v8i16_s10imm<"ahi">;
- def int_spu_si_a : v4i32_rr<"a">;
- def int_spu_si_ai : v4i32_s10imm<"ai">;
- def int_spu_si_sfh : v8i16_rr<"sfh">;
- def int_spu_si_sfhi : v8i16_s10imm<"sfhi">;
- def int_spu_si_sf : v4i32_rr<"sf">;
- def int_spu_si_sfi : v4i32_s10imm<"sfi">;
- def int_spu_si_addx : v4i32_rr<"addx">;
- def int_spu_si_cg : v4i32_rr<"cg">;
- def int_spu_si_cgx : v4i32_rr<"cgx">;
- def int_spu_si_sfx : v4i32_rr<"sfx">;
- def int_spu_si_bg : v4i32_rr<"bg">;
- def int_spu_si_bgx : v4i32_rr<"bgx">;
- def int_spu_si_mpy : // This is special:
- GCCBuiltin<"__builtin_si_mpy">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyu : // This is special:
- GCCBuiltin<"__builtin_si_mpyu">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyi : // This is special:
- GCCBuiltin<"__builtin_si_mpyi">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyui : // This is special:
- GCCBuiltin<"__builtin_si_mpyui">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpya : // This is special:
- GCCBuiltin<"__builtin_si_mpya">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyh : // This is special:
- GCCBuiltin<"__builtin_si_mpyh">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpys : // This is special:
- GCCBuiltin<"__builtin_si_mpys">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyhh : // This is special:
- GCCBuiltin<"__builtin_si_mpyhh">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyhha : // This is special:
- GCCBuiltin<"__builtin_si_mpyhha">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyhhu : // This is special:
- GCCBuiltin<"__builtin_si_mpyhhu">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
- def int_spu_si_mpyhhau : // This is special:
- GCCBuiltin<"__builtin_si_mpyhhau">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem]>;
-
- def int_spu_si_shli: v4i32_u7imm<"shli">;
-
- def int_spu_si_shlqbi:
- GCCBuiltin<!strconcat("__builtin_si_", "shlqbi")>,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem]>;
-
- def int_spu_si_shlqbii: v16i8_u7imm<"shlqbii">;
- def int_spu_si_shlqby:
- GCCBuiltin<!strconcat("__builtin_si_", "shlqby")>,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_spu_si_shlqbyi: v16i8_u7imm<"shlqbyi">;
-
- def int_spu_si_ceq: v4i32_rr<"ceq">;
- def int_spu_si_ceqi: v4i32_s10imm<"ceqi">;
- def int_spu_si_ceqb: v16i8_rr<"ceqb">;
- def int_spu_si_ceqbi: v16i8_u8imm<"ceqbi">;
- def int_spu_si_ceqh: v8i16_rr<"ceqh">;
- def int_spu_si_ceqhi: v8i16_s10imm<"ceqhi">;
- def int_spu_si_cgt: v4i32_rr<"cgt">;
- def int_spu_si_cgti: v4i32_s10imm<"cgti">;
- def int_spu_si_cgtb: v16i8_rr<"cgtb">;
- def int_spu_si_cgtbi: v16i8_u8imm<"cgtbi">;
- def int_spu_si_cgth: v8i16_rr<"cgth">;
- def int_spu_si_cgthi: v8i16_s10imm<"cgthi">;
- def int_spu_si_clgtb: v16i8_rr<"clgtb">;
- def int_spu_si_clgtbi: v16i8_u8imm<"clgtbi">;
- def int_spu_si_clgth: v8i16_rr<"clgth">;
- def int_spu_si_clgthi: v8i16_s10imm<"clgthi">;
- def int_spu_si_clgt: v4i32_rr<"clgt">;
- def int_spu_si_clgti: v4i32_s10imm<"clgti">;
-
- def int_spu_si_and: v4i32_rr<"and">;
- def int_spu_si_andbi: v16i8_u8imm<"andbi">;
- def int_spu_si_andc: v4i32_rr<"andc">;
- def int_spu_si_andhi: v8i16_s10imm<"andhi">;
- def int_spu_si_andi: v4i32_s10imm<"andi">;
-
- def int_spu_si_or: v4i32_rr<"or">;
- def int_spu_si_orbi: v16i8_u8imm<"orbi">;
- def int_spu_si_orc: v4i32_rr<"orc">;
- def int_spu_si_orhi: v8i16_s10imm<"orhi">;
- def int_spu_si_ori: v4i32_s10imm<"ori">;
-
- def int_spu_si_xor: v4i32_rr<"xor">;
- def int_spu_si_xorbi: v16i8_u8imm<"xorbi">;
- def int_spu_si_xorhi: v8i16_s10imm<"xorhi">;
- def int_spu_si_xori: v4i32_s10imm<"xori">;
-
- def int_spu_si_nor: v4i32_rr<"nor">;
- def int_spu_si_nand: v4i32_rr<"nand">;
-
- def int_spu_si_fa: v4f32_rr<"fa">;
- def int_spu_si_fs: v4f32_rr<"fs">;
- def int_spu_si_fm: v4f32_rr<"fm">;
-
- def int_spu_si_fceq: v4f32_rr<"fceq">;
- def int_spu_si_fcmeq: v4f32_rr<"fcmeq">;
- def int_spu_si_fcgt: v4f32_rr<"fcgt">;
- def int_spu_si_fcmgt: v4f32_rr<"fcmgt">;
-
- def int_spu_si_fma: v4f32_rrr<"fma">;
- def int_spu_si_fnms: v4f32_rrr<"fnms">;
- def int_spu_si_fms: v4f32_rrr<"fms">;
-
- def int_spu_si_dfa: v2f64_rr<"dfa">;
- def int_spu_si_dfs: v2f64_rr<"dfs">;
- def int_spu_si_dfm: v2f64_rr<"dfm">;
-
-//def int_spu_si_dfceq: v2f64_rr<"dfceq">;
-//def int_spu_si_dfcmeq: v2f64_rr<"dfcmeq">;
-//def int_spu_si_dfcgt: v2f64_rr<"dfcgt">;
-//def int_spu_si_dfcmgt: v2f64_rr<"dfcmgt">;
-
- def int_spu_si_dfnma: v2f64_rr<"dfnma">;
- def int_spu_si_dfma: v2f64_rr<"dfma">;
- def int_spu_si_dfnms: v2f64_rr<"dfnms">;
- def int_spu_si_dfms: v2f64_rr<"dfms">;
-}
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index fe4c92a..d29775a 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -19,20 +19,20 @@
#include "llvm/Analysis/DomPrinter.h"
#include "llvm/Analysis/FindUsedTypes.h"
#include "llvm/Analysis/IntervalPartition.h"
+#include "llvm/Analysis/Lint.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/RegionPrinter.h"
#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/Lint.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/Function.h"
-#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/IR/Function.h"
#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Vectorize.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
+#include "llvm/Transforms/Vectorize.h"
#include <cstdlib>
namespace {
@@ -60,10 +60,12 @@ namespace {
(void) llvm::createCFGSimplificationPass();
(void) llvm::createConstantMergePass();
(void) llvm::createConstantPropagationPass();
+ (void) llvm::createCostModelAnalysisPass();
(void) llvm::createDeadArgEliminationPass();
(void) llvm::createDeadCodeEliminationPass();
(void) llvm::createDeadInstEliminationPass();
(void) llvm::createDeadStoreEliminationPass();
+ (void) llvm::createDependenceAnalysisPass();
(void) llvm::createDomOnlyPrinterPass();
(void) llvm::createDomPrinterPass();
(void) llvm::createDomOnlyViewerPass();
@@ -81,11 +83,10 @@ namespace {
(void) llvm::createIPSCCPPass();
(void) llvm::createIndVarSimplifyPass();
(void) llvm::createInstructionCombiningPass();
- (void) llvm::createInternalizePass(false);
+ (void) llvm::createInternalizePass();
(void) llvm::createLCSSAPass();
(void) llvm::createLICMPass();
(void) llvm::createLazyValueInfoPass();
- (void) llvm::createLoopDependenceAnalysisPass();
(void) llvm::createLoopExtractorPass();
(void) llvm::createLoopSimplifyPass();
(void) llvm::createLoopStrengthReducePass();
@@ -141,6 +142,7 @@ namespace {
(void) llvm::createLoopDeletionPass();
(void) llvm::createPostDomTree();
(void) llvm::createInstructionNamerPass();
+ (void) llvm::createMetaRenamerPass();
(void) llvm::createFunctionAttrsPass();
(void) llvm::createMergeFunctionsPass();
(void) llvm::createPrintModulePass(0);
@@ -154,6 +156,7 @@ namespace {
(void) llvm::createCorrelatedValuePropagationPass();
(void) llvm::createMemDepPrinter();
(void) llvm::createInstructionSimplifierPass();
+ (void) llvm::createLoopVectorizePass();
(void) llvm::createBBVectorizePass();
(void)new llvm::IntervalPartition();
diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllVMCore.h
index 83684c0..6039a63 100644
--- a/include/llvm/LinkAllVMCore.h
+++ b/include/llvm/LinkAllVMCore.h
@@ -16,13 +16,15 @@
#ifndef LLVM_LINKALLVMCORE_H
#define LLVM_LINKALLVMCORE_H
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/Instructions.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/InlineAsm.h"
#include "llvm/Analysis/Verifier.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Path.h"
@@ -30,8 +32,6 @@
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TimeValue.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/MathExtras.h"
#include <cstdlib>
namespace {
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h
deleted file mode 100644
index 5b02467..0000000
--- a/include/llvm/MC/EDInstInfo.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef EDINSTINFO_H
-#define EDINSTINFO_H
-
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
-
-#define EDIS_MAX_OPERANDS 13
-#define EDIS_MAX_SYNTAXES 2
-
-struct EDInstInfo {
- uint8_t instructionType;
- uint8_t numOperands;
- uint8_t operandTypes[EDIS_MAX_OPERANDS];
- uint8_t operandFlags[EDIS_MAX_OPERANDS];
- const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS];
-};
-
-} // namespace llvm
-
-#endif
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index 1c45090..9a6b703 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -22,7 +22,7 @@ class MCELFObjectTargetWriter;
struct MCFixupKindInfo;
class MCFragment;
class MCInst;
-class MCInstFragment;
+class MCRelaxableFragment;
class MCObjectWriter;
class MCSection;
class MCValue;
@@ -36,10 +36,14 @@ protected: // Can only create subclasses.
MCAsmBackend();
unsigned HasReliableSymbolDifference : 1;
+ unsigned HasDataInCodeSupport : 1;
public:
virtual ~MCAsmBackend();
+ /// lifetime management
+ virtual void reset() { }
+
/// createObjectWriter - Create a new MCObjectWriter instance for use by the
/// assembler backend to emit the final object file.
virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
@@ -65,6 +69,12 @@ public:
return HasReliableSymbolDifference;
}
+ /// hasDataInCodeSupport - Check whether this target implements data-in-code
+ /// markers. If not, data region directives will be ignored.
+ bool hasDataInCodeSupport() const {
+ return HasDataInCodeSupport;
+ }
+
/// doesSectionRequireSymbols - Check whether the given section requires that
/// all symbols (even temporaries) have symbol table entries.
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
@@ -99,7 +109,7 @@ public:
/// @}
- /// applyFixup - Apply the \arg Value for given \arg Fixup into the provided
+ /// applyFixup - Apply the \p Value for given \p Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
@@ -120,15 +130,15 @@ public:
/// fixup requires the associated instruction to be relaxed.
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value,
- const MCInstFragment *DF,
+ const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const = 0;
/// RelaxInstruction - Relax the instruction in the given fragment to the next
/// wider instruction.
///
- /// \param Inst - The instruction to relax, which may be the same as the
+ /// \param Inst The instruction to relax, which may be the same as the
/// output.
- /// \parm Res [output] - On return, the relaxed instruction.
+ /// \param [out] Res On return, the relaxed instruction.
virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
/// @}
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 97aad71..38cf060 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -16,8 +16,8 @@
#ifndef LLVM_TARGET_ASM_INFO_H
#define LLVM_TARGET_ASM_INFO_H
-#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MachineLocation.h"
#include <cassert>
#include <vector>
@@ -102,6 +102,9 @@ namespace llvm {
/// LabelSuffix - This is appended to emitted labels.
const char *LabelSuffix; // Defaults to ":"
+ /// LabelSuffix - This is appended to emitted labels.
+ const char *DebugLabelSuffix; // Defaults to ":"
+
/// GlobalPrefix - If this is set to a non-empty string, it is prepended
/// onto all global symbols. This is often used for "_" or ".".
const char *GlobalPrefix; // Defaults to ""
@@ -426,6 +429,11 @@ namespace llvm {
const char *getLabelSuffix() const {
return LabelSuffix;
}
+
+ const char *getDebugLabelSuffix() const {
+ return DebugLabelSuffix;
+ }
+
const char *getGlobalPrefix() const {
return GlobalPrefix;
}
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index cf79216..8cb4601 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -21,10 +21,10 @@ class MCSymbolData;
/// Encapsulates the layout of an assembly file at a particular point in time.
///
-/// Assembly may requiring compute multiple layouts for a particular assembly
+/// Assembly may require computing multiple layouts for a particular assembly
/// file as part of the relaxation process. This class encapsulates the layout
/// at a single point in time in such a way that it is always possible to
-/// efficiently compute the exact addresses of any symbol in the assembly file,
+/// efficiently compute the exact address of any symbol in the assembly file,
/// even during the relaxation process.
class MCAsmLayout {
public:
@@ -39,14 +39,20 @@ private:
/// The last fragment which was laid out, or 0 if nothing has been laid
/// out. Fragments are always laid out in order, so all fragments with a
- /// lower ordinal will be up to date.
- mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment;
+ /// lower ordinal will be valid.
+ mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment;
/// \brief Make sure that the layout for the given fragment is valid, lazily
/// computing it if necessary.
- void EnsureValid(const MCFragment *F) const;
+ void ensureValid(const MCFragment *F) const;
- bool isFragmentUpToDate(const MCFragment *F) const;
+ /// \brief Is the layout for this fragment valid?
+ bool isFragmentValid(const MCFragment *F) const;
+
+ /// \brief Compute the amount of padding required before this fragment to
+ /// obey bundling restrictions.
+ uint64_t computeBundlePadding(const MCFragment *F,
+ uint64_t FOffset, uint64_t FSize);
public:
MCAsmLayout(MCAssembler &_Assembler);
@@ -54,14 +60,14 @@ public:
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
- /// \brief Invalidate all following fragments because a fragment has been
- /// resized. The fragments size should have already been updated.
- void Invalidate(MCFragment *F);
+ /// \brief Invalidate the fragments after F because it has been resized.
+ /// The fragment's size should have already been updated.
+ void invalidateFragmentsAfter(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous
/// fragment has already been laid out correctly, and the parent section has
/// been initialized.
- void LayoutFragment(MCFragment *Fragment);
+ void layoutFragment(MCFragment *Fragment);
/// @name Section Access (in layout order)
/// @{
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 1858349..40766b4 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -10,13 +10,13 @@
#ifndef LLVM_MC_MCASSEMBLER_H
#define LLVM_MC_MCASSEMBLER_H
-#include "llvm/MC/MCFixup.h"
-#include "llvm/MC/MCInst.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
@@ -53,7 +53,7 @@ public:
FT_Align,
FT_Data,
FT_Fill,
- FT_Inst,
+ FT_Relaxable,
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
@@ -107,44 +107,107 @@ public:
unsigned getLayoutOrder() const { return LayoutOrder; }
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
- static bool classof(const MCFragment *O) { return true; }
+ /// \brief Does this fragment have instructions emitted into it? By default
+ /// this is false, but specific fragment types may set it to true.
+ virtual bool hasInstructions() const { return false; }
+
+ /// \brief Should this fragment be placed at the end of an aligned bundle?
+ virtual bool alignToBundleEnd() const { return false; }
+
+ /// \brief Get the padding size that must be inserted before this fragment.
+ /// Used for bundling. By default, no padding is inserted.
+ /// Note that padding size is restricted to 8 bits. This is an optimization
+ /// to reduce the amount of space used for each fragment. In practice, larger
+ /// padding should never be required.
+ virtual uint8_t getBundlePadding() const {
+ return 0;
+ }
+
+ /// \brief Set the padding size for this fragment. By default it's a no-op,
+ /// and only some fragments have a meaningful implementation.
+ virtual void setBundlePadding(uint8_t N) {
+ }
void dump();
};
-class MCDataFragment : public MCFragment {
+class MCEncodedFragment : public MCFragment {
virtual void anchor();
- SmallString<32> Contents;
-
- /// Fixups - The list of fixups in this fragment.
- std::vector<MCFixup> Fixups;
+ uint8_t BundlePadding;
public:
- typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
- typedef std::vector<MCFixup>::iterator fixup_iterator;
+ MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+ : MCFragment(FType, SD), BundlePadding(0)
+ {
+ }
+ virtual ~MCEncodedFragment();
-public:
- MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
+ typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
+ typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
- /// @name Accessors
- /// @{
+ virtual SmallVectorImpl<char> &getContents() = 0;
+ virtual const SmallVectorImpl<char> &getContents() const = 0;
- SmallString<32> &getContents() { return Contents; }
- const SmallString<32> &getContents() const { return Contents; }
+ virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
+ virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
- /// @}
- /// @name Fixup Access
- /// @{
+ virtual fixup_iterator fixup_begin() = 0;
+ virtual const_fixup_iterator fixup_begin() const = 0;
+ virtual fixup_iterator fixup_end() = 0;
+ virtual const_fixup_iterator fixup_end() const = 0;
+
+ virtual uint8_t getBundlePadding() const {
+ return BundlePadding;
+ }
- void addFixup(MCFixup Fixup) {
- // Enforce invariant that fixups are in offset order.
- assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) &&
- "Fixups must be added in order!");
- Fixups.push_back(Fixup);
+ virtual void setBundlePadding(uint8_t N) {
+ BundlePadding = N;
}
- std::vector<MCFixup> &getFixups() { return Fixups; }
- const std::vector<MCFixup> &getFixups() const { return Fixups; }
+ static bool classof(const MCFragment *F) {
+ MCFragment::FragmentType Kind = F->getKind();
+ return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
+ }
+};
+
+/// Fragment for data and encoded instructions.
+///
+class MCDataFragment : public MCEncodedFragment {
+ virtual void anchor();
+
+ /// \brief Does this fragment contain encoded instructions anywhere in it?
+ bool HasInstructions;
+
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
+
+ SmallVector<char, 32> Contents;
+
+ /// Fixups - The list of fixups in this fragment.
+ SmallVector<MCFixup, 4> Fixups;
+public:
+ MCDataFragment(MCSectionData *SD = 0)
+ : MCEncodedFragment(FT_Data, SD),
+ HasInstructions(false), AlignToBundleEnd(false)
+ {
+ }
+
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+
+ SmallVectorImpl<MCFixup> &getFixups() {
+ return Fixups;
+ }
+
+ const SmallVectorImpl<MCFixup> &getFixups() const {
+ return Fixups;
+ }
+
+ virtual bool hasInstructions() const { return HasInstructions; }
+ virtual void setHasInstructions(bool V) { HasInstructions = V; }
+
+ virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
fixup_iterator fixup_begin() { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
@@ -152,61 +215,46 @@ public:
fixup_iterator fixup_end() {return Fixups.end();}
const_fixup_iterator fixup_end() const {return Fixups.end();}
- size_t fixup_size() const { return Fixups.size(); }
-
- /// @}
-
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Data;
}
- static bool classof(const MCDataFragment *) { return true; }
};
-// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as
-// it is almost entirely a duplicate of MCDataFragment. If we decide to stick
-// with this approach (as opposed to making MCInstFragment a very light weight
-// object with just the MCInst and a code size, then we should just change
-// MCDataFragment to have an optional MCInst at its end.
-class MCInstFragment : public MCFragment {
+/// A relaxable fragment holds on to its MCInst, since it may need to be
+/// relaxed during the assembler layout and relaxation stage.
+///
+class MCRelaxableFragment : public MCEncodedFragment {
virtual void anchor();
/// Inst - The instruction this is a fragment for.
MCInst Inst;
- /// Code - Binary data for the currently encoded instruction.
- SmallString<8> Code;
+ /// Contents - Binary data for the currently encoded instruction.
+ SmallVector<char, 8> Contents;
/// Fixups - The list of fixups in this fragment.
SmallVector<MCFixup, 1> Fixups;
public:
- typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
- typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
-
-public:
- MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0)
- : MCFragment(FT_Inst, SD), Inst(_Inst) {
+ MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
+ : MCEncodedFragment(FT_Relaxable, SD), Inst(_Inst) {
}
- /// @name Accessors
- /// @{
-
- SmallVectorImpl<char> &getCode() { return Code; }
- const SmallVectorImpl<char> &getCode() const { return Code; }
-
- unsigned getInstSize() const { return Code.size(); }
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
- MCInst &getInst() { return Inst; }
const MCInst &getInst() const { return Inst; }
-
void setInst(const MCInst& Value) { Inst = Value; }
- /// @}
- /// @name Fixup Access
- /// @{
+ SmallVectorImpl<MCFixup> &getFixups() {
+ return Fixups;
+ }
- SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
- const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
+ const SmallVectorImpl<MCFixup> &getFixups() const {
+ return Fixups;
+ }
+
+ virtual bool hasInstructions() const { return true; }
fixup_iterator fixup_begin() { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
@@ -214,14 +262,9 @@ public:
fixup_iterator fixup_end() {return Fixups.end();}
const_fixup_iterator fixup_end() const {return Fixups.end();}
- size_t fixup_size() const { return Fixups.size(); }
-
- /// @}
-
static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Inst;
+ return F->getKind() == MCFragment::FT_Relaxable;
}
- static bool classof(const MCInstFragment *) { return true; }
};
class MCAlignFragment : public MCFragment {
@@ -233,7 +276,7 @@ class MCAlignFragment : public MCFragment {
/// Value - Value to use for filling padding bytes.
int64_t Value;
- /// ValueSize - The size of the integer (in bytes) of \arg Value.
+ /// ValueSize - The size of the integer (in bytes) of \p Value.
unsigned ValueSize;
/// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
@@ -271,7 +314,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Align;
}
- static bool classof(const MCAlignFragment *) { return true; }
};
class MCFillFragment : public MCFragment {
@@ -280,7 +322,7 @@ class MCFillFragment : public MCFragment {
/// Value - Value to use for filling bytes.
int64_t Value;
- /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if
+ /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
/// this is a virtual fill fragment.
unsigned ValueSize;
@@ -310,7 +352,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Fill;
}
- static bool classof(const MCFillFragment *) { return true; }
};
class MCOrgFragment : public MCFragment {
@@ -339,7 +380,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Org;
}
- static bool classof(const MCOrgFragment *) { return true; }
};
class MCLEBFragment : public MCFragment {
@@ -372,7 +412,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_LEB;
}
- static bool classof(const MCLEBFragment *) { return true; }
};
class MCDwarfLineAddrFragment : public MCFragment {
@@ -409,7 +448,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Dwarf;
}
- static bool classof(const MCDwarfLineAddrFragment *) { return true; }
};
class MCDwarfCallFrameFragment : public MCFragment {
@@ -439,7 +477,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_DwarfFrame;
}
- static bool classof(const MCDwarfCallFrameFragment *) { return true; }
};
// FIXME: Should this be a separate class, or just merged into MCSection? Since
@@ -448,8 +485,8 @@ public:
class MCSectionData : public ilist_node<MCSectionData> {
friend class MCAsmLayout;
- MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT
- void operator=(const MCSectionData&); // DO NOT IMPLEMENT
+ MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
+ void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
public:
typedef iplist<MCFragment> FragmentListType;
@@ -460,6 +497,12 @@ public:
typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
typedef FragmentListType::reverse_iterator reverse_iterator;
+ /// \brief Express the state of bundle locked groups while emitting code.
+ enum BundleLockStateType {
+ NotBundleLocked,
+ BundleLocked,
+ BundleLockedAlignToEnd
+ };
private:
FragmentListType Fragments;
const MCSection *Section;
@@ -473,6 +516,13 @@ private:
/// Alignment - The maximum alignment seen in this section.
unsigned Alignment;
+ /// \brief Keeping track of bundle-locked state.
+ BundleLockStateType BundleLockState;
+
+ /// \brief We've seen a bundle_lock directive but not its first instruction
+ /// yet.
+ bool BundleGroupBeforeFirstInst;
+
/// @name Assembler Backend Data
/// @{
//
@@ -525,6 +575,26 @@ public:
bool empty() const { return Fragments.empty(); }
+ bool isBundleLocked() const {
+ return BundleLockState != NotBundleLocked;
+ }
+
+ BundleLockStateType getBundleLockState() const {
+ return BundleLockState;
+ }
+
+ void setBundleLockState(BundleLockStateType NewState) {
+ BundleLockState = NewState;
+ }
+
+ bool isBundleGroupBeforeFirstInst() const {
+ return BundleGroupBeforeFirstInst;
+ }
+
+ void setBundleGroupBeforeFirstInst(bool IsFirst) {
+ BundleGroupBeforeFirstInst = IsFirst;
+ }
+
void dump();
/// @}
@@ -691,8 +761,8 @@ public:
typedef std::vector<DataRegionData>::iterator data_region_iterator;
private:
- MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT
- void operator=(const MCAssembler&); // DO NOT IMPLEMENT
+ MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
+ void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
MCContext &Context;
@@ -730,6 +800,11 @@ private:
// refactoring too.
SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+ /// \brief The bundle alignment size currently set in the assembler.
+ ///
+ /// By default it's 0, which means bundling is disabled.
+ unsigned BundleAlignSize;
+
unsigned RelaxAll : 1;
unsigned NoExecStack : 1;
unsigned SubsectionsViaSymbols : 1;
@@ -746,7 +821,7 @@ private:
/// \param Value [out] On return, the value of the fixup as currently laid
/// out.
/// \return Whether the fixup value was fully resolved. This is true if the
- /// \arg Value result is fixed, otherwise the value may change due to
+ /// \p Value result is fixed, otherwise the value may change due to
/// relocation.
bool evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
@@ -754,20 +829,22 @@ private:
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
- bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF,
+ bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const;
/// Check whether the given fragment needs relaxation.
- bool fragmentNeedsRelaxation(const MCInstFragment *IF,
+ bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
const MCAsmLayout &Layout) const;
- /// layoutOnce - Perform one layout iteration and return true if any offsets
+ /// \brief Perform one layout iteration and return true if any offsets
/// were adjusted.
bool layoutOnce(MCAsmLayout &Layout);
+ /// \brief Perform one layout iteration of the given section and return true
+ /// if any offsets were adjusted.
bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
- bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
+ bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
@@ -783,7 +860,7 @@ private:
public:
/// Compute the effective fragment size assuming it is laid out at the given
- /// \arg SectionAddress and \arg FragmentOffset.
+ /// \p SectionAddress and \p FragmentOffset.
uint64_t computeFragmentSize(const MCAsmLayout &Layout,
const MCFragment &F) const;
@@ -812,7 +889,7 @@ public:
public:
/// Construct a new assembler instance.
///
- /// \arg OS - The stream to output to.
+ /// \param OS The stream to output to.
//
// FIXME: How are we going to parameterize this? Two obvious options are stay
// concrete and require clients to pass in a target like object. The other
@@ -823,6 +900,10 @@ public:
raw_ostream &OS);
~MCAssembler();
+ /// Reuse an assembler instance
+ ///
+ void reset();
+
MCContext &getContext() const { return Context; }
MCAsmBackend &getBackend() const { return Backend; }
@@ -834,7 +915,7 @@ public:
void setWriter(MCObjectWriter &ObjectWriter);
/// Finish - Do final processing and write the object to the output stream.
- /// \arg Writer is used for custom object writer (as the MCJIT does),
+ /// \p Writer is used for custom object writer (as the MCJIT does),
/// if not specified it is automatically created from backend.
void Finish();
@@ -852,6 +933,20 @@ public:
bool getNoExecStack() const { return NoExecStack; }
void setNoExecStack(bool Value) { NoExecStack = Value; }
+ bool isBundlingEnabled() const {
+ return BundleAlignSize != 0;
+ }
+
+ unsigned getBundleAlignSize() const {
+ return BundleAlignSize;
+ }
+
+ void setBundleAlignSize(unsigned Size) {
+ assert((Size == 0 || !(Size & (Size - 1))) &&
+ "Expect a power-of-two bundle align size");
+ BundleAlignSize = Size;
+ }
+
/// @name Section List Access
/// @{
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index 4f7d103..9bfa08e 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -29,8 +29,11 @@ protected: // Can only create subclasses.
public:
virtual ~MCCodeEmitter();
- /// EncodeInstruction - Encode the given \arg Inst to bytes on the output
- /// stream \arg OS.
+ /// Lifetime management
+ virtual void reset() { }
+
+ /// EncodeInstruction - Encode the given \p Inst to bytes on the output
+ /// stream \p OS.
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const = 0;
};
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 23652f0..e92d3b9 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -10,10 +10,10 @@
#ifndef LLVM_MC_MCCONTEXT_H
#define LLVM_MC_MCCONTEXT_H
-#include "llvm/MC/SectionKind.h"
-#include "llvm/MC/MCDwarf.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
@@ -94,6 +94,12 @@ namespace llvm {
/// .secure_log_reset appearing between them.
bool SecureLogUsed;
+ /// The compilation directory to use for DW_AT_comp_dir.
+ std::string CompilationDir;
+
+ /// The main file name if passed in explicitly.
+ std::string MainFileName;
+
/// The dwarf file and directory tables from the dwarf .file directive.
std::vector<MCDwarfFile *> MCDwarfFiles;
std::vector<StringRef> MCDwarfDirs;
@@ -137,11 +143,15 @@ namespace llvm {
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
+ /// Do automatic reset in destructor
+ bool AutoReset;
+
MCSymbol *CreateSymbol(StringRef Name);
public:
explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
- const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0);
+ const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
+ bool DoAutoReset = true);
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
@@ -154,6 +164,15 @@ namespace llvm {
void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+ /// @name Module Lifetime Management
+ /// @{
+
+ /// reset - return object to right after construction state to prepare
+ /// to process a new module
+ void reset();
+
+ /// @}
+
/// @name Symbol Management
/// @{
@@ -183,6 +202,7 @@ namespace llvm {
/// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const;
+ MCSymbol *LookupSymbol(const Twine &Name) const;
/// getSymbols - Get a reference for the symbol table for clients that
/// want to, for example, iterate over all symbols. 'const' because we
@@ -234,6 +254,24 @@ namespace llvm {
/// @name Dwarf Management
/// @{
+ /// \brief Get the compilation directory for DW_AT_comp_dir
+ /// This can be overridden by clients which want to control the reported
+ /// compilation directory and have it be something other than the current
+ /// working directory.
+ const std::string &getCompilationDir() const { return CompilationDir; }
+
+ /// \brief Set the compilation directory for DW_AT_comp_dir
+ /// Override the default (CWD) compilation directory.
+ void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
+
+ /// \brief Get the main file name for use in error messages and debug
+ /// info. This can be set to ensure we've got the correct file name
+ /// after preprocessing or for -save-temps.
+ const std::string &getMainFileName() const { return MainFileName; }
+
+ /// \brief Set the main file name and override the default.
+ void setMainFileName(StringRef S) { MainFileName = S.str(); }
+
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
unsigned FileNumber);
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index 53a9ce0..1b6beb2 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -9,8 +9,8 @@
#ifndef MCDISASSEMBLER_H
#define MCDISASSEMBLER_H
-#include "llvm/Support/DataTypes.h"
#include "llvm-c/Disassembler.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -20,8 +20,6 @@ class MemoryObject;
class raw_ostream;
class MCContext;
-struct EDInstInfo;
-
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory region
/// and provides an array of assembly instructions.
class MCDisassembler {
@@ -84,14 +82,6 @@ public:
raw_ostream &vStream,
raw_ostream &cStream) const = 0;
- /// getEDInfo - Returns the enhanced instruction information corresponding to
- /// the disassembler.
- ///
- /// @return - An array of instruction information, with one entry for
- /// each MCInst opcode this disassembler returns.
- /// NULL if there is no info for this target.
- virtual const EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; }
-
private:
//
// Hooks for symbolic disassembly via the public 'C' interface.
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 9e09ddf..3160b61 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -16,10 +16,9 @@
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MachineLocation.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/raw_ostream.h"
#include <vector>
namespace llvm {
@@ -59,7 +58,7 @@ namespace llvm {
unsigned getDirIndex() const { return DirIndex; }
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
@@ -178,8 +177,8 @@ namespace llvm {
class MCLineSection {
private:
- MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT
- void operator=(const MCLineSection&); // DO NOT IMPLEMENT
+ MCLineSection(const MCLineSection&) LLVM_DELETED_FUNCTION;
+ void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION;
public:
// Constructor to create an MCLineSection with an empty MCLineEntries
@@ -266,42 +265,115 @@ namespace llvm {
class MCCFIInstruction {
public:
- enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape,
- Restore};
+ enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset,
+ OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset,
+ OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined,
+ OpRegister };
private:
OpType Operation;
MCSymbol *Label;
- // Move to & from location.
- MachineLocation Destination;
- MachineLocation Source;
+ unsigned Register;
+ union {
+ int Offset;
+ unsigned Register2;
+ };
std::vector<char> Values;
+
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) :
+ Operation(Op), Label(L), Register(R), Offset(O),
+ Values(V.begin(), V.end()) {
+ assert(Op != OpRegister);
+ }
+
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) :
+ Operation(Op), Label(L), Register(R1), Register2(R2) {
+ assert(Op == OpRegister);
+ }
+
public:
- MCCFIInstruction(OpType Op, MCSymbol *L)
- : Operation(Op), Label(L) {
- assert(Op == RememberState || Op == RestoreState);
+ static MCCFIInstruction
+ createOffset(MCSymbol *L, unsigned Register, int Offset) {
+ return MCCFIInstruction(OpOffset, L, Register, Offset, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
- : Operation(Op), Label(L), Destination(Register) {
- assert(Op == SameValue || Op == Restore);
+
+ static MCCFIInstruction
+ createDefCfaRegister(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
}
- MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
- const MachineLocation &S)
- : Operation(Move), Label(L), Destination(D), Source(S) {
+
+ static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
+ return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
- const MachineLocation &S)
- : Operation(Op), Label(L), Destination(D), Source(S) {
- assert(Op == RelMove);
+
+ static MCCFIInstruction
+ createDefCfa(MCSymbol *L, unsigned Register, int Offset) {
+ return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals)
- : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) {
- assert(Op == Escape);
+
+ static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpUndefined, L, Register, 0, "");
+ }
+
+ static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpRestore, L, Register, 0, "");
+ }
+
+ static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpSameValue, L, Register, 0, "");
+ }
+
+ static MCCFIInstruction createRestoreState(MCSymbol *L) {
+ return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
}
+
+ static MCCFIInstruction createRememberState(MCSymbol *L) {
+ return MCCFIInstruction(OpRememberState, L, 0, 0, "");
+ }
+
+ static MCCFIInstruction
+ createRelOffset(MCSymbol *L, unsigned Register, int Offset) {
+ return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
+ }
+
+ static MCCFIInstruction
+ createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
+ return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
+ }
+
+ static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
+ return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
+ }
+
+ static MCCFIInstruction
+ createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) {
+ return MCCFIInstruction(OpRegister, L, Register1, Register2);
+ }
+
OpType getOperation() const { return Operation; }
MCSymbol *getLabel() const { return Label; }
- const MachineLocation &getDestination() const { return Destination; }
- const MachineLocation &getSource() const { return Source; }
+
+ unsigned getRegister() const {
+ assert(Operation == OpDefCfa || Operation == OpOffset ||
+ Operation == OpRestore || Operation == OpUndefined ||
+ Operation == OpSameValue || Operation == OpDefCfaRegister ||
+ Operation == OpRelOffset || Operation == OpRegister);
+ return Register;
+ }
+
+ unsigned getRegister2() const {
+ assert(Operation == OpRegister);
+ return Register2;
+ }
+
+ int getOffset() const {
+ assert(Operation == OpDefCfa || Operation == OpOffset ||
+ Operation == OpRelOffset || Operation == OpDefCfaOffset ||
+ Operation == OpAdjustCfaOffset);
+ return Offset;
+ }
+
const StringRef getValues() const {
+ assert(Operation == OpEscape);
return StringRef(&Values[0], Values.size());
}
};
diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h
new file mode 100644
index 0000000..e08f1e6
--- /dev/null
+++ b/include/llvm/MC/MCELF.h
@@ -0,0 +1,35 @@
+//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some support functions used by the ELF Streamer and
+// ObjectWriter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELF_H
+#define LLVM_MC_MCELF_H
+
+#include "llvm/MC/MCExpr.h"
+
+namespace llvm {
+class MCSymbolData;
+
+class MCELF {
+ public:
+ static void SetBinding(MCSymbolData &SD, unsigned Binding);
+ static unsigned GetBinding(const MCSymbolData &SD);
+ static void SetType(MCSymbolData &SD, unsigned Type);
+ static unsigned GetType(const MCSymbolData &SD);
+ static void SetVisibility(MCSymbolData &SD, unsigned Visibility);
+ static unsigned GetVisibility(MCSymbolData &SD);
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index abbe188..38cdc72 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -85,6 +85,9 @@ public:
const MCFragment &F,
const MCFixup &Fixup,
bool IsPCRel) const;
+ virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsPCRel) const;
virtual void adjustFixupOffset(const MCFixup &Fixup,
uint64_t &RelocOffset);
@@ -93,9 +96,9 @@ public:
/// @name Accessors
/// @{
- uint8_t getOSABI() { return OSABI; }
- uint16_t getEMachine() { return EMachine; }
- bool hasRelocationAddend() { return HasRelocationAddend; }
+ uint8_t getOSABI() const { return OSABI; }
+ uint16_t getEMachine() const { return EMachine; }
+ bool hasRelocationAddend() const { return HasRelocationAddend; }
bool is64Bit() const { return Is64Bit; }
bool isN64() const { return IsN64; }
/// @}
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
new file mode 100644
index 0000000..ab20ee8
--- /dev/null
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -0,0 +1,113 @@
+//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFSTREAMER_H
+#define LLVM_MC_MCELFSTREAMER_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+class MCAsmBackend;
+class MCAssembler;
+class MCCodeEmitter;
+class MCExpr;
+class MCInst;
+class MCSymbol;
+class MCSymbolData;
+class raw_ostream;
+
+class MCELFStreamer : public MCObjectStreamer {
+public:
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter)
+ : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter,
+ MCAssembler *Assembler)
+ : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {}
+
+ virtual ~MCELFStreamer();
+
+ /// @name MCStreamer Interface
+ /// @{
+
+ virtual void InitSections();
+ virtual void ChangeSection(const MCSection *Section);
+ virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitThumbFunc(MCSymbol *Func);
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
+ virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment);
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass);
+ virtual void EmitCOFFSymbolType(int Type);
+ virtual void EndCOFFSymbolDef();
+
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment);
+
+ virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+ uint64_t Size = 0, unsigned ByteAlignment = 0);
+ virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace);
+
+ virtual void EmitFileDirective(StringRef Filename);
+
+ virtual void EmitTCEntry(const MCSymbol &S);
+
+ virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
+
+ virtual void FinishImpl();
+ /// @}
+
+private:
+ virtual void EmitInstToFragment(const MCInst &Inst);
+ virtual void EmitInstToData(const MCInst &Inst);
+
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
+ virtual void EmitBundleLock(bool AlignToEnd);
+ virtual void EmitBundleUnlock();
+
+ void fixSymbolsInTLSFixups(const MCExpr *expr);
+
+ struct LocalCommon {
+ MCSymbolData *SD;
+ uint64_t Size;
+ unsigned ByteAlignment;
+ };
+
+ std::vector<LocalCommon> LocalCommons;
+
+ SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+
+
+ void SetSection(StringRef Section, unsigned Type, unsigned Flags,
+ SectionKind Kind);
+ void SetSectionData();
+ void SetSectionText();
+ void SetSectionBss();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index f36db3c..475981f 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -99,8 +99,6 @@ public:
const MCSection *FindAssociatedSection() const;
/// @}
-
- static bool classof(const MCExpr *) { return true; }
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
@@ -132,7 +130,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Constant;
}
- static bool classof(const MCConstantExpr *) { return true; }
};
/// MCSymbolRefExpr - Represent a reference to a symbol from inside an
@@ -163,6 +160,7 @@ public:
VK_TLVP, // Mach-O thread local variable relocation
VK_SECREL,
// FIXME: We'd really like to use the generic Kinds listed above for these.
+ VK_ARM_NONE,
VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT
VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
VK_ARM_GOT,
@@ -170,15 +168,30 @@ public:
VK_ARM_TPOFF,
VK_ARM_GOTTPOFF,
VK_ARM_TARGET1,
+ VK_ARM_TARGET2,
+ VK_ARM_PREL31,
VK_PPC_TOC, // TOC base
VK_PPC_TOC_ENTRY, // TOC entry
VK_PPC_DARWIN_HA16, // ha16(symbol)
VK_PPC_DARWIN_LO16, // lo16(symbol)
VK_PPC_GAS_HA16, // symbol@ha
- VK_PPC_GAS_LO16, // symbol@l
+ VK_PPC_GAS_LO16, // symbol@l
VK_PPC_TPREL16_HA, // symbol@tprel@ha
VK_PPC_TPREL16_LO, // symbol@tprel@l
+ VK_PPC_DTPREL16_HA, // symbol@dtprel@ha
+ VK_PPC_DTPREL16_LO, // symbol@dtprel@l
+ VK_PPC_TOC16_HA, // symbol@toc@ha
+ VK_PPC_TOC16_LO, // symbol@toc@l
+ VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha
+ VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l
+ VK_PPC_TLS, // symbol@tls
+ VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha
+ VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l
+ VK_PPC_TLSGD, // symbol@tlsgd
+ VK_PPC_GOT_TLSLD16_HA, // symbol@got@tlsld@ha
+ VK_PPC_GOT_TLSLD16_LO, // symbol@got@tlsld@l
+ VK_PPC_TLSLD, // symbol@tlsld
VK_Mips_GPREL,
VK_Mips_GOT_CALL,
@@ -199,7 +212,11 @@ public:
VK_Mips_GOT_PAGE,
VK_Mips_GOT_OFST,
VK_Mips_HIGHER,
- VK_Mips_HIGHEST
+ VK_Mips_HIGHEST,
+ VK_Mips_GOT_HI16,
+ VK_Mips_GOT_LO16,
+ VK_Mips_CALL_HI16,
+ VK_Mips_CALL_LO16
};
private:
@@ -248,7 +265,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::SymbolRef;
}
- static bool classof(const MCSymbolRefExpr *) { return true; }
};
/// MCUnaryExpr - Unary assembler expressions.
@@ -302,7 +318,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Unary;
}
- static bool classof(const MCUnaryExpr *) { return true; }
};
/// MCBinaryExpr - Binary assembler expressions.
@@ -437,7 +452,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Binary;
}
- static bool classof(const MCBinaryExpr *) { return true; }
};
/// MCTargetExpr - This is an extension point for target-specific MCExpr
@@ -446,7 +460,7 @@ public:
/// NOTE: All subclasses are required to have trivial destructors because
/// MCExprs are bump pointer allocated and not destructed.
class MCTargetExpr : public MCExpr {
- virtual void Anchor();
+ virtual void anchor();
protected:
MCTargetExpr() : MCExpr(Target) {}
virtual ~MCTargetExpr() {}
@@ -461,7 +475,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
- static bool classof(const MCTargetExpr *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
index 397a37d..e91c6a2 100644
--- a/include/llvm/MC/MCInst.h
+++ b/include/llvm/MC/MCInst.h
@@ -182,7 +182,7 @@ public:
void dump() const;
/// \brief Dump the MCInst as prettily as possible using the additional MC
- /// structures, if given. Operators are separated by the \arg Separator
+ /// structures, if given. Operators are separated by the \p Separator
/// string.
void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0,
const MCInstPrinter *Printer = 0,
diff --git a/include/llvm/MC/MCInstBuilder.h b/include/llvm/MC/MCInstBuilder.h
new file mode 100644
index 0000000..c5acb26
--- /dev/null
+++ b/include/llvm/MC/MCInstBuilder.h
@@ -0,0 +1,68 @@
+//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MCInstBuilder class for convenient creation of
+// MCInsts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTBUILDER_H
+#define LLVM_MC_MCINSTBUILDER_H
+
+#include "llvm/MC/MCInst.h"
+
+namespace llvm {
+
+class MCInstBuilder {
+ MCInst Inst;
+
+public:
+ /// \brief Create a new MCInstBuilder for an MCInst with a specific opcode.
+ MCInstBuilder(unsigned Opcode) {
+ Inst.setOpcode(Opcode);
+ }
+
+ /// \brief Add a new register operand.
+ MCInstBuilder &addReg(unsigned Reg) {
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return *this;
+ }
+
+ /// \brief Add a new integer immediate operand.
+ MCInstBuilder &addImm(int64_t Val) {
+ Inst.addOperand(MCOperand::CreateImm(Val));
+ return *this;
+ }
+
+ /// \brief Add a new floating point immediate operand.
+ MCInstBuilder &addFPImm(double Val) {
+ Inst.addOperand(MCOperand::CreateFPImm(Val));
+ return *this;
+ }
+
+ /// \brief Add a new MCExpr operand.
+ MCInstBuilder &addExpr(const MCExpr *Val) {
+ Inst.addOperand(MCOperand::CreateExpr(Val));
+ return *this;
+ }
+
+ /// \brief Add a new MCInst operand.
+ MCInstBuilder &addInst(const MCInst *Val) {
+ Inst.addOperand(MCOperand::CreateInst(Val));
+ return *this;
+ }
+
+ operator MCInst&() {
+ return Inst;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index 3c4f28b..a18cbd9 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -10,6 +10,9 @@
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Format.h"
+
namespace llvm {
class MCInst;
class raw_ostream;
@@ -33,12 +36,19 @@ protected:
/// The current set of available features.
unsigned AvailableFeatures;
+ /// True if we are printing marked up assembly.
+ bool UseMarkup;
+
+ /// True if we are printing immediates as hex.
+ bool PrintImmHex;
+
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
- : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0) {}
+ : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0),
+ UseMarkup(0), PrintImmHex(0) {}
virtual ~MCInstPrinter();
@@ -59,6 +69,19 @@ public:
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+
+ bool getUseMarkup() const { return UseMarkup; }
+ void setUseMarkup(bool Value) { UseMarkup = Value; }
+
+ /// Utility functions to make adding mark ups simpler.
+ StringRef markup(StringRef s) const;
+ StringRef markup(StringRef a, StringRef b) const;
+
+ bool getPrintImmHex() const { return PrintImmHex; }
+ void setPrintImmHex(bool Value) { PrintImmHex = Value; }
+
+ /// Utility function to print immediates in decimal or hex.
+ format_object1<int64_t> formatImm(const int64_t Value) const;
};
} // namespace llvm
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index dbf16d8..9b5415a 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -1,4 +1,4 @@
-//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
+//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,6 +15,8 @@
#ifndef LLVM_MC_MCINSTRDESC_H
#define LLVM_MC_MCINSTRDESC_H
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -144,7 +146,7 @@ public:
const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
- /// getOperandConstraint - Returns the value of the specific constraint if
+ /// \brief Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set.
int getOperandConstraint(unsigned OpNum,
MCOI::OperandConstraint Constraint) const {
@@ -156,12 +158,12 @@ public:
return -1;
}
- /// getOpcode - Return the opcode number for this descriptor.
+ /// \brief Return the opcode number for this descriptor.
unsigned getOpcode() const {
return Opcode;
}
- /// getNumOperands - Return the number of declared MachineOperands for this
+ /// \brief Return the number of declared MachineOperands for this
/// MachineInstruction. Note that variadic (isVariadic() returns true)
/// instructions may have additional operands at the end of the list, and note
/// that the machine instruction may include implicit register def/uses as
@@ -170,7 +172,7 @@ public:
return NumOperands;
}
- /// getNumDefs - Return the number of MachineOperands that are register
+ /// \brief Return the number of MachineOperands that are register
/// definitions. Register definitions always occur at the start of the
/// machine operand list. This is the number of "outs" in the .td file,
/// and does not include implicit defs.
@@ -178,11 +180,10 @@ public:
return NumDefs;
}
- /// getFlags - Return flags of this instruction.
- ///
+ /// \brief Return flags of this instruction.
unsigned getFlags() const { return Flags; }
- /// isVariadic - Return true if this instruction can have a variable number of
+ /// \brief Return true if this instruction can have a variable number of
/// operands. In this case, the variable operands will be after the normal
/// operands but before the implicit definitions and uses (if any are
/// present).
@@ -190,35 +191,37 @@ public:
return Flags & (1 << MCID::Variadic);
}
- /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
+ /// \brief Set if this instruction has an optional definition, e.g.
/// ARM instructions which can set condition code if 's' bit is set.
bool hasOptionalDef() const {
return Flags & (1 << MCID::HasOptionalDef);
}
- /// isPseudo - Return true if this is a pseudo instruction that doesn't
+ /// \brief Return true if this is a pseudo instruction that doesn't
/// correspond to a real machine instruction.
///
bool isPseudo() const {
return Flags & (1 << MCID::Pseudo);
}
+ /// \brief Return true if the instruction is a return.
bool isReturn() const {
return Flags & (1 << MCID::Return);
}
+ /// \brief Return true if the instruction is a call.
bool isCall() const {
return Flags & (1 << MCID::Call);
}
- /// isBarrier - Returns true if the specified instruction stops control flow
+ /// \brief Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
bool isBarrier() const {
return Flags & (1 << MCID::Barrier);
}
- /// isTerminator - Returns true if this instruction part of the terminator for
+ /// \brief Returns true if this instruction part of the terminator for
/// a basic block. Typically this is things like return and branch
/// instructions.
///
@@ -228,7 +231,7 @@ public:
return Flags & (1 << MCID::Terminator);
}
- /// isBranch - Returns true if this is a conditional, unconditional, or
+ /// \brief Returns true if this is a conditional, unconditional, or
/// indirect branch. Predicates below can be used to discriminate between
/// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
/// get more information.
@@ -236,13 +239,13 @@ public:
return Flags & (1 << MCID::Branch);
}
- /// isIndirectBranch - Return true if this is an indirect branch, such as a
+ /// \brief Return true if this is an indirect branch, such as a
/// branch through a register.
bool isIndirectBranch() const {
return Flags & (1 << MCID::IndirectBranch);
}
- /// isConditionalBranch - Return true if this is a branch which may fall
+ /// \brief Return true if this is a branch which may fall
/// through to the next instruction or may transfer control flow to some other
/// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
/// information about this branch.
@@ -250,7 +253,7 @@ public:
return isBranch() & !isBarrier() & !isIndirectBranch();
}
- /// isUnconditionalBranch - Return true if this is a branch which always
+ /// \brief Return true if this is a branch which always
/// transfers control flow to some other block. The
/// TargetInstrInfo::AnalyzeBranch method can be used to get more information
/// about this branch.
@@ -258,38 +261,47 @@ public:
return isBranch() & isBarrier() & !isIndirectBranch();
}
- // isPredicable - Return true if this instruction has a predicate operand that
- // controls execution. It may be set to 'always', or may be set to other
- /// values. There are various methods in TargetInstrInfo that can be used to
+ /// \brief Return true if this is a branch or an instruction which directly
+ /// writes to the program counter. Considered 'may' affect rather than
+ /// 'does' affect as things like predication are not taken into account.
+ bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const {
+ if (isBranch() || isCall() || isReturn() || isIndirectBranch())
+ return true;
+ unsigned PC = RI.getProgramCounter();
+ if (PC == 0) return false;
+ return hasDefOfPhysReg(MI, PC, RI);
+ }
+
+ /// \brief Return true if this instruction has a predicate operand
+ /// that controls execution. It may be set to 'always', or may be set to other
+ /// values. There are various methods in TargetInstrInfo that can be used to
/// control and modify the predicate in this instruction.
bool isPredicable() const {
return Flags & (1 << MCID::Predicable);
}
- /// isCompare - Return true if this instruction is a comparison.
+ /// \brief Return true if this instruction is a comparison.
bool isCompare() const {
return Flags & (1 << MCID::Compare);
}
- /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// \brief Return true if this instruction is a move immediate
/// (including conditional moves) instruction.
bool isMoveImmediate() const {
return Flags & (1 << MCID::MoveImm);
}
- /// isBitcast - Return true if this instruction is a bitcast instruction.
- ///
+ /// \brief Return true if this instruction is a bitcast instruction.
bool isBitcast() const {
return Flags & (1 << MCID::Bitcast);
}
- /// isSelect - Return true if this is a select instruction.
- ///
+ /// \brief Return true if this is a select instruction.
bool isSelect() const {
return Flags & (1 << MCID::Select);
}
- /// isNotDuplicable - Return true if this instruction cannot be safely
+ /// \brief Return true if this instruction cannot be safely
/// duplicated. For example, if the instruction has a unique labels attached
/// to it, duplicating it would cause multiple definition errors.
bool isNotDuplicable() const {
@@ -318,7 +330,7 @@ public:
// Side Effect Analysis
//===--------------------------------------------------------------------===//
- /// mayLoad - Return true if this instruction could possibly read memory.
+ /// \brief Return true if this instruction could possibly read memory.
/// Instructions with this flag set are not necessarily simple load
/// instructions, they may load a value and modify it, for example.
bool mayLoad() const {
@@ -326,7 +338,7 @@ public:
}
- /// mayStore - Return true if this instruction could possibly modify memory.
+ /// \brief Return true if this instruction could possibly modify memory.
/// Instructions with this flag set are not necessarily simple store
/// instructions, they may store a modified value based on their operands, or
/// may not actually modify anything, for example.
@@ -459,8 +471,7 @@ public:
return ImplicitUses;
}
- /// getNumImplicitUses - Return the number of implicit uses this instruction
- /// has.
+ /// \brief Return the number of implicit uses this instruction has.
unsigned getNumImplicitUses() const {
if (ImplicitUses == 0) return 0;
unsigned i = 0;
@@ -482,8 +493,7 @@ public:
return ImplicitDefs;
}
- /// getNumImplicitDefs - Return the number of implicit defs this instruction
- /// has.
+ /// \brief Return the number of implicit defs this instruct has.
unsigned getNumImplicitDefs() const {
if (ImplicitDefs == 0) return 0;
unsigned i = 0;
@@ -491,7 +501,7 @@ public:
return i;
}
- /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
+ /// \brief Return true if this instruction implicitly
/// uses the specified physical register.
bool hasImplicitUseOfPhysReg(unsigned Reg) const {
if (const uint16_t *ImpUses = ImplicitUses)
@@ -500,31 +510,43 @@ public:
return false;
}
- /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
+ /// \brief Return true if this instruction implicitly
/// defines the specified physical register.
- bool hasImplicitDefOfPhysReg(unsigned Reg) const {
+ bool hasImplicitDefOfPhysReg(unsigned Reg,
+ const MCRegisterInfo *MRI = 0) const {
if (const uint16_t *ImpDefs = ImplicitDefs)
for (; *ImpDefs; ++ImpDefs)
- if (*ImpDefs == Reg) return true;
+ if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
+ return true;
return false;
}
- /// getSchedClass - Return the scheduling class for this instruction. The
+ /// \brief Return true if this instruction defines the specified physical
+ /// register, either explicitly or implicitly.
+ bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
+ const MCRegisterInfo &RI) const {
+ for (int i = 0, e = NumDefs; i != e; ++i)
+ if (MI.getOperand(i).isReg() &&
+ RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
+ return true;
+ return hasImplicitDefOfPhysReg(Reg, &RI);
+ }
+
+ /// \brief Return the scheduling class for this instruction. The
/// scheduling class is an index into the InstrItineraryData table. This
/// returns zero if there is no known scheduling information for the
/// instruction.
- ///
unsigned getSchedClass() const {
return SchedClass;
}
- /// getSize - Return the number of bytes in the encoding of this instruction,
+ /// \brief Return the number of bytes in the encoding of this instruction,
/// or zero if the encoding size cannot be known from the opcode.
unsigned getSize() const {
return Size;
}
- /// findFirstPredOperandIdx() - Find the index of the first operand in the
+ /// \brief Find the index of the first operand in the
/// operand list that is used to represent the predicate. It returns -1 if
/// none is found.
int findFirstPredOperandIdx() const {
diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h
index c72aabd..f531de8 100644
--- a/include/llvm/MC/MCLabel.h
+++ b/include/llvm/MC/MCLabel.h
@@ -42,7 +42,7 @@ namespace llvm {
/// Label.
unsigned incInstance() { return ++Instance; }
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 949d907..3cd278e 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -45,6 +45,13 @@ protected:
public:
virtual ~MCMachObjectTargetWriter();
+ /// @name Lifetime Management
+ /// @{
+
+ virtual void reset() {};
+
+ /// @}
+
/// @name Accessors
/// @{
@@ -111,6 +118,13 @@ public:
: MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
}
+ /// @name Lifetime management Methods
+ /// @{
+
+ virtual void reset();
+
+ /// @}
+
/// @name Utility Methods
/// @{
@@ -153,8 +167,8 @@ public:
/// WriteSegmentLoadCommand - Write a segment load command.
///
- /// \arg NumSections - The number of sections in this segment.
- /// \arg SectionDataSize - The total size of the sections.
+ /// \param NumSections The number of sections in this segment.
+ /// \param SectionDataSize The total size of the sections.
void WriteSegmentLoadCommand(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
@@ -223,8 +237,6 @@ public:
/// ComputeSymbolTable - Compute the symbol table data
///
/// \param StringTable [out] - The string table data.
- /// \param StringIndexMap [out] - Map from symbol names to offsets in the
- /// string table.
void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
@@ -233,6 +245,8 @@ public:
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
+ void markAbsoluteVariableSymbols(MCAssembler &Asm,
+ const MCAsmLayout &Layout);
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index 74e2263..c8444fd 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -84,14 +84,6 @@ protected:
/// this is the section to emit them into.
const MCSection *CompactUnwindSection;
- /// DwarfAccelNamesSection, DwarfAccelObjCSection
- /// If we use the DWARF accelerated hash tables then we want toe emit these
- /// sections.
- const MCSection *DwarfAccelNamesSection;
- const MCSection *DwarfAccelObjCSection;
- const MCSection *DwarfAccelNamespaceSection;
- const MCSection *DwarfAccelTypesSection;
-
// Dwarf sections for debug info. If a target supports debug info, these must
// be set.
const MCSection *DwarfAbbrevSection;
@@ -106,6 +98,24 @@ protected:
const MCSection *DwarfRangesSection;
const MCSection *DwarfMacroInfoSection;
+ // DWARF5 Experimental Debug Info Sections
+ /// DwarfAccelNamesSection, DwarfAccelObjCSection,
+ /// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
+ /// If we use the DWARF accelerated hash tables then we want to emit these
+ /// sections.
+ const MCSection *DwarfAccelNamesSection;
+ const MCSection *DwarfAccelObjCSection;
+ const MCSection *DwarfAccelNamespaceSection;
+ const MCSection *DwarfAccelTypesSection;
+
+ /// These are used for the Fission separate debug information files.
+ const MCSection *DwarfInfoDWOSection;
+ const MCSection *DwarfAbbrevDWOSection;
+ const MCSection *DwarfStrDWOSection;
+ const MCSection *DwarfLineDWOSection;
+ const MCSection *DwarfLocDWOSection;
+ const MCSection *DwarfStrOffDWOSection;
+
// Extra TLS Variable Data section. If the target needs to put additional
// information for a TLS variable, it'll go here.
const MCSection *TLSExtraDataSection;
@@ -194,18 +204,6 @@ public:
const MCSection *getCompactUnwindSection() const{
return CompactUnwindSection;
}
- const MCSection *getDwarfAccelNamesSection() const {
- return DwarfAccelNamesSection;
- }
- const MCSection *getDwarfAccelObjCSection() const {
- return DwarfAccelObjCSection;
- }
- const MCSection *getDwarfAccelNamespaceSection() const {
- return DwarfAccelNamespaceSection;
- }
- const MCSection *getDwarfAccelTypesSection() const {
- return DwarfAccelTypesSection;
- }
const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
@@ -221,6 +219,39 @@ public:
const MCSection *getDwarfMacroInfoSection() const {
return DwarfMacroInfoSection;
}
+
+ // DWARF5 Experimental Debug Info Sections
+ const MCSection *getDwarfAccelNamesSection() const {
+ return DwarfAccelNamesSection;
+ }
+ const MCSection *getDwarfAccelObjCSection() const {
+ return DwarfAccelObjCSection;
+ }
+ const MCSection *getDwarfAccelNamespaceSection() const {
+ return DwarfAccelNamespaceSection;
+ }
+ const MCSection *getDwarfAccelTypesSection() const {
+ return DwarfAccelTypesSection;
+ }
+ const MCSection *getDwarfInfoDWOSection() const {
+ return DwarfInfoDWOSection;
+ }
+ const MCSection *getDwarfAbbrevDWOSection() const {
+ return DwarfAbbrevDWOSection;
+ }
+ const MCSection *getDwarfStrDWOSection() const {
+ return DwarfStrDWOSection;
+ }
+ const MCSection *getDwarfLineDWOSection() const {
+ return DwarfLineDWOSection;
+ }
+ const MCSection *getDwarfLocDWOSection() const {
+ return DwarfLocDWOSection;
+ }
+ const MCSection *getDwarfStrOffDWOSection() const {
+ return DwarfStrOffDWOSection;
+ }
+
const MCSection *getTLSExtraDataSection() const {
return TLSExtraDataSection;
}
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index b59b76c..0ece092 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -45,6 +45,11 @@ protected:
MCAssembler *_Assembler);
~MCObjectStreamer();
+public:
+ /// state management
+ virtual void reset();
+
+protected:
MCSectionData *getCurrentSectionData() const {
return CurSectionData;
}
@@ -64,6 +69,8 @@ public:
/// @{
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+ virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
unsigned AddrSpace);
virtual void EmitULEB128Value(const MCExpr *Value);
@@ -71,7 +78,21 @@ public:
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
virtual void ChangeSection(const MCSection *Section);
virtual void EmitInstruction(const MCInst &Inst);
+
+ /// \brief Emit an instruction to a special fragment, because this instruction
+ /// can change its size during relaxation.
virtual void EmitInstToFragment(const MCInst &Inst);
+
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
+ virtual void EmitBundleLock(bool AlignToEnd);
+ virtual void EmitBundleUnlock();
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitValueToAlignment(unsigned ByteAlignment,
+ int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0);
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0);
virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
@@ -81,6 +102,8 @@ public:
const MCSymbol *Label);
virtual void EmitGPRel32Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace);
virtual void FinishImpl();
/// @}
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 14fe75f..9d5c1a7 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -10,9 +10,9 @@
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
namespace llvm {
@@ -51,6 +51,9 @@ protected: // Can only create subclasses.
public:
virtual ~MCObjectWriter();
+ /// lifetime management
+ virtual void reset() { }
+
bool isLittleEndian() const { return IsLittleEndian; }
raw_ostream &getStream() { return OS; }
@@ -173,7 +176,13 @@ public:
OS << StringRef(Zeros, N % 16);
}
+ void WriteBytes(SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
+ WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
+ }
+
void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
+ // TODO: this version may need to go away once all fragment contents are
+ // converted to SmallVector<char, N>
assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
"data size greater than fill size, unexpected large write will occur");
OS << Str;
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index ca163c5..37a69e2 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -34,12 +34,10 @@ public:
// Real values.
Real,
- // Register values (stored in IntVal). Only used by MCTargetAsmLexer.
- Register,
-
// No-value.
EndOfStatement,
Colon,
+ Space,
Plus, Minus, Tilde,
Slash, // '/'
BackSlash, // '\'
@@ -103,13 +101,6 @@ public:
assert(Kind == Integer && "This token isn't an integer!");
return IntVal;
}
-
- /// getRegVal - Get the register number for the current token, which should
- /// be a register.
- unsigned getRegVal() const {
- assert(Kind == Register && "This token isn't a register!");
- return static_cast<unsigned>(IntVal);
- }
};
/// MCAsmLexer - Generic assembler lexer interface, for use by target specific
@@ -126,6 +117,7 @@ class MCAsmLexer {
void operator=(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses.
const char *TokStart;
+ bool SkipSpace;
MCAsmLexer();
@@ -170,11 +162,14 @@ public:
/// getKind - Get the kind of current token.
AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
- /// is - Check if the current token has kind \arg K.
+ /// is - Check if the current token has kind \p K.
bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
- /// isNot - Check if the current token has kind \arg K.
+ /// isNot - Check if the current token has kind \p K.
bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
+
+ /// setSkipSpace - Set whether spaces should be ignored by the lexer
+ void setSkipSpace(bool val) { SkipSpace = val; }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index c673a79..b9490fa 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -10,8 +10,8 @@
#ifndef LLVM_MC_MCASMPARSER_H
#define LLVM_MC_MCASMPARSER_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class AsmToken;
@@ -20,6 +20,9 @@ class MCAsmLexer;
class MCAsmParserExtension;
class MCContext;
class MCExpr;
+class MCInstPrinter;
+class MCInstrInfo;
+class MCParsedAsmOperand;
class MCStreamer;
class MCTargetAsmParser;
class SMLoc;
@@ -28,6 +31,16 @@ class SourceMgr;
class StringRef;
class Twine;
+/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
+class MCAsmParserSemaCallback {
+public:
+ virtual ~MCAsmParserSemaCallback();
+ virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc,
+ unsigned &Size) = 0;
+ virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
+ unsigned &Offset) = 0;
+};
+
/// MCAsmParser - Generic assembler parser interface, for use by target specific
/// assembly parsers.
class MCAsmParser {
@@ -73,15 +86,26 @@ public:
/// Run - Run the parser on the input source buffer.
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
- /// Warning - Emit a warning at the location \arg L, with the message \arg
- /// Msg.
+ virtual void setParsingInlineAsm(bool V) = 0;
+ virtual bool isParsingInlineAsm() = 0;
+
+ /// ParseMSInlineAsm - Parse ms-style inline assembly.
+ virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
+ unsigned &NumOutputs, unsigned &NumInputs,
+ SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
+ SmallVectorImpl<std::string> &Constraints,
+ SmallVectorImpl<std::string> &Clobbers,
+ const MCInstrInfo *MII,
+ const MCInstPrinter *IP,
+ MCAsmParserSemaCallback &SI) = 0;
+
+ /// Warning - Emit a warning at the location \p L, with the message \p Msg.
///
/// \return The return value is true, if warnings are fatal.
virtual bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0;
- /// Error - Emit an error at the location \arg L, with the message \arg
- /// Msg.
+ /// Error - Emit an error at the location \p L, with the message \p Msg.
///
/// \return The return value is always true, as an idiomatic convenience to
/// clients.
@@ -100,7 +124,7 @@ public:
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
- /// and set \arg Res to the identifier contents.
+ /// and set \p Res to the identifier contents.
virtual bool ParseIdentifier(StringRef &Res) = 0;
/// \brief Parse up to the end of statement and return the contents from the
diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 59593a8..84b33b5 100644
--- a/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -10,8 +10,8 @@
#ifndef LLVM_MC_MCASMPARSEREXTENSION_H
#define LLVM_MC_MCASMPARSEREXTENSION_H
-#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
@@ -43,8 +43,8 @@ protected:
public:
virtual ~MCAsmParserExtension();
- /// \brief Initialize the extension for parsing using the given \arg
- /// Parser. The extension should use the AsmParser interfaces to register its
+ /// \brief Initialize the extension for parsing using the given \p Parser.
+ /// The extension should use the AsmParser interfaces to register its
/// parsing routines.
virtual void Initialize(MCAsmParser &Parser);
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 2556e5f..60e7887 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -19,15 +19,69 @@ class raw_ostream;
/// base class is used by target-independent clients and is the interface
/// between parsing an asm instruction and recognizing it.
class MCParsedAsmOperand {
+ /// MCOperandNum - The corresponding MCInst operand number. Only valid when
+ /// parsing MS-style inline assembly.
+ unsigned MCOperandNum;
+
+ /// Constraint - The constraint on this operand. Only valid when parsing
+ /// MS-style inline assembly.
+ std::string Constraint;
+
public:
MCParsedAsmOperand() {}
virtual ~MCParsedAsmOperand() {}
+ void setConstraint(StringRef C) { Constraint = C.str(); }
+ StringRef getConstraint() { return Constraint; }
+
+ void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; }
+ unsigned getMCOperandNum() { return MCOperandNum; }
+
+ unsigned getNameLen() {
+ assert (getStartLoc().isValid() && "Invalid StartLoc!");
+ assert (getEndLoc().isValid() && "Invalid EndLoc!");
+ return getEndLoc().getPointer() - getStartLoc().getPointer();
+ }
+
+ StringRef getName() {
+ return StringRef(getStartLoc().getPointer(), getNameLen());
+ }
+
+ /// isToken - Is this a token operand?
+ virtual bool isToken() const = 0;
+ /// isImm - Is this an immediate operand?
+ virtual bool isImm() const = 0;
+ /// isReg - Is this a register operand?
+ virtual bool isReg() const = 0;
+ virtual unsigned getReg() const = 0;
+
+ /// isMem - Is this a memory operand?
+ virtual bool isMem() const = 0;
+ virtual unsigned getMemSize() const { return 0; }
+
/// getStartLoc - Get the location of the first token of this operand.
virtual SMLoc getStartLoc() const = 0;
/// getEndLoc - Get the location of the last token of this operand.
virtual SMLoc getEndLoc() const = 0;
+ /// needAsmRewrite - AsmRewrites happen in both the target-independent and
+ /// target-dependent parsers. The target-independent parser calls this
+ /// function to determine if the target-dependent parser has already taken
+ /// care of the rewrites. Only valid when parsing MS-style inline assembly.
+ virtual bool needAsmRewrite() const { return true; }
+
+ /// isOffsetOf - Do we need to emit code to get the offset of the variable,
+ /// rather then the value of the variable? Only valid when parsing MS-style
+ /// inline assembly.
+ virtual bool isOffsetOf() const { return false; }
+
+ /// getOffsetOfLoc - Get the location of the offset operator.
+ virtual SMLoc getOffsetOfLoc() const { return SMLoc(); }
+
+ /// needSizeDirective - Do we need to emit a sizing directive for this
+ /// operand? Only valid when parsing MS-style inline assembly.
+ virtual bool needSizeDirective() const { return false; }
+
/// print - Print a debug representation of the operand to the given stream.
virtual void print(raw_ostream &OS) const = 0;
/// dump - Print to the debug stream.
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index 46a9d71..f5b4ddd 100644
--- a/include/llvm/MC/MCRegisterInfo.h
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -22,11 +22,15 @@
namespace llvm {
+/// An unsigned integer type large enough to represent all physical registers,
+/// but not necessarily virtual registers.
+typedef uint16_t MCPhysReg;
+
/// MCRegisterClass - Base class of TargetRegisterClass.
class MCRegisterClass {
public:
- typedef const uint16_t* iterator;
- typedef const uint16_t* const_iterator;
+ typedef const MCPhysReg* iterator;
+ typedef const MCPhysReg* const_iterator;
const char *Name;
const iterator RegsBegin;
@@ -148,11 +152,12 @@ private:
const MCRegisterDesc *Desc; // Pointer to the descriptor array
unsigned NumRegs; // Number of entries in the array
unsigned RAReg; // Return address register
+ unsigned PCReg; // Program counter register
const MCRegisterClass *Classes; // Pointer to the regclass array
unsigned NumClasses; // Number of entries in the array
unsigned NumRegUnits; // Number of regunits.
const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table.
- const uint16_t *DiffLists; // Pointer to the difflists array
+ const MCPhysReg *DiffLists; // Pointer to the difflists array
const char *RegStrings; // Pointer to the string table.
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
// array.
@@ -177,7 +182,7 @@ public:
/// defined below.
class DiffListIterator {
uint16_t Val;
- const uint16_t *List;
+ const MCPhysReg *List;
protected:
/// Create an invalid iterator. Call init() to point to something useful.
@@ -186,7 +191,7 @@ public:
/// init - Point the iterator to InitVal, decoding subsequent values from
/// DiffList. The iterator will initially point to InitVal, sub-classes are
/// responsible for skipping the seed value if it is not part of the list.
- void init(uint16_t InitVal, const uint16_t *DiffList) {
+ void init(MCPhysReg InitVal, const MCPhysReg *DiffList) {
Val = InitVal;
List = DiffList;
}
@@ -196,7 +201,7 @@ public:
/// is the caller's responsibility (by checking for a 0 return value).
unsigned advance() {
assert(isValid() && "Cannot move off the end of the list.");
- uint16_t D = *List++;
+ MCPhysReg D = *List++;
Val += D;
return D;
}
@@ -225,13 +230,14 @@ public:
friend class MCRegUnitIterator;
friend class MCRegUnitRootIterator;
- /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
+ /// \brief Initialize MCRegisterInfo, called by TableGen
/// auto-generated routines. *DO NOT USE*.
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
+ unsigned PC,
const MCRegisterClass *C, unsigned NC,
const uint16_t (*RURoots)[2],
unsigned NRU,
- const uint16_t *DL,
+ const MCPhysReg *DL,
const char *Strings,
const uint16_t *SubIndices,
unsigned NumIndices,
@@ -239,6 +245,7 @@ public:
Desc = D;
NumRegs = NR;
RAReg = RA;
+ PCReg = PC;
Classes = C;
DiffLists = DL;
RegStrings = Strings;
@@ -250,7 +257,7 @@ public:
RegEncodingTable = RET;
}
- /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf
+ /// \brief Used to initialize LLVM register to Dwarf
/// register number mapping. Called by TableGen auto-generated routines.
/// *DO NOT USE*.
void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size,
@@ -264,7 +271,7 @@ public:
}
}
- /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM
+ /// \brief Used to initialize Dwarf register to LLVM
/// register number mapping. Called by TableGen auto-generated routines.
/// *DO NOT USE*.
void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size,
@@ -287,70 +294,80 @@ public:
L2SEHRegs[LLVMReg] = SEHReg;
}
- /// getRARegister - This method should return the register where the return
+ /// \brief This method should return the register where the return
/// address can be found.
unsigned getRARegister() const {
return RAReg;
}
+ /// Return the register which is the program counter.
+ unsigned getProgramCounter() const {
+ return PCReg;
+ }
+
const MCRegisterDesc &operator[](unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to access record for invalid register number!");
return Desc[RegNo];
}
- /// Provide a get method, equivalent to [], but more useful if we have a
+ /// \brief Provide a get method, equivalent to [], but more useful with a
/// pointer to this object.
- ///
const MCRegisterDesc &get(unsigned RegNo) const {
return operator[](RegNo);
}
- /// getSubReg - Returns the physical register number of sub-register "Index"
+ /// \brief Returns the physical register number of sub-register "Index"
/// for physical register RegNo. Return zero if the sub-register does not
/// exist.
unsigned getSubReg(unsigned Reg, unsigned Idx) const;
- /// getMatchingSuperReg - Return a super-register of the specified register
+ /// \brief Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
const MCRegisterClass *RC) const;
- /// getSubRegIndex - For a given register pair, return the sub-register index
+ /// \brief For a given register pair, return the sub-register index
/// if the second register is a sub-register of the first. Return zero
/// otherwise.
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;
- /// getName - Return the human-readable symbolic target-specific name for the
+ /// \brief Return the human-readable symbolic target-specific name for the
/// specified physical register.
const char *getName(unsigned RegNo) const {
return RegStrings + get(RegNo).Name;
}
- /// getNumRegs - Return the number of registers this target has (useful for
+ /// \brief Return the number of registers this target has (useful for
/// sizing arrays holding per register information)
unsigned getNumRegs() const {
return NumRegs;
}
- /// getNumRegUnits - Return the number of (native) register units in the
+ /// \brief Return the number of sub-register indices
+ /// understood by the target. Index 0 is reserved for the no-op sub-register,
+ /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers.
+ unsigned getNumSubRegIndices() const {
+ return NumSubRegIndices;
+ }
+
+ /// \brief Return the number of (native) register units in the
/// target. Register units are numbered from 0 to getNumRegUnits() - 1. They
/// can be accessed through MCRegUnitIterator defined below.
unsigned getNumRegUnits() const {
return NumRegUnits;
}
- /// getDwarfRegNum - Map a target register to an equivalent dwarf register
+ /// \brief Map a target register to an equivalent dwarf register
/// number. Returns -1 if there is no equivalent value. The second
/// parameter allows targets to use different numberings for EH info and
/// debugging info.
int getDwarfRegNum(unsigned RegNum, bool isEH) const;
- /// getLLVMRegNum - Map a dwarf register back to a target register.
- ///
+ /// \brief Map a dwarf register back to a target register.
int getLLVMRegNum(unsigned RegNum, bool isEH) const;
- /// getSEHRegNum - Map a target register to an equivalent SEH register
+ /// \brief Map a target register to an equivalent SEH register
/// number. Returns LLVM register number if there is no equivalent value.
int getSEHRegNum(unsigned RegNum) const;
@@ -361,20 +378,39 @@ public:
return (unsigned)(regclass_end()-regclass_begin());
}
- /// getRegClass - Returns the register class associated with the enumeration
+ /// \brief Returns the register class associated with the enumeration
/// value. See class MCOperandInfo.
- const MCRegisterClass getRegClass(unsigned i) const {
+ const MCRegisterClass& getRegClass(unsigned i) const {
assert(i < getNumRegClasses() && "Register Class ID out of range");
return Classes[i];
}
- /// getEncodingValue - Returns the encoding for RegNo
+ /// \brief Returns the encoding for RegNo
uint16_t getEncodingValue(unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to get encoding for invalid register number!");
return RegEncodingTable[RegNo];
}
+ /// \brief Returns true if RegB is a sub-register of RegA.
+ bool isSubRegister(unsigned RegA, unsigned RegB) const {
+ return isSuperRegister(RegB, RegA);
+ }
+
+ /// \brief Returns true if RegB is a super-register of RegA.
+ bool isSuperRegister(unsigned RegA, unsigned RegB) const;
+
+ /// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA.
+ bool isSubRegisterEq(unsigned RegA, unsigned RegB) const {
+ return isSuperRegisterEq(RegB, RegA);
+ }
+
+ /// \brief Returns true if RegB is a super-register of RegA or if
+ /// RegB == RegA.
+ bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const {
+ return RegA == RegB || isSuperRegister(RegA, RegB);
+ }
+
};
//===----------------------------------------------------------------------===//
@@ -415,6 +451,15 @@ public:
}
};
+// Definition for isSuperRegister. Put it down here since it needs the
+// iterator defined above in addition to the MCRegisterInfo class itself.
+inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{
+ for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
+ if (*I == RegB)
+ return true;
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Register Units
//===----------------------------------------------------------------------===//
@@ -434,6 +479,7 @@ public:
/// MCRegUnitIterator - Create an iterator that traverses the register units
/// in Reg.
MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
+ assert(Reg && "Null register has no regunits");
// Decode the RegUnits MCRegisterDesc field.
unsigned RU = MCRI->get(Reg).RegUnits;
unsigned Scale = RU & 15;
@@ -473,17 +519,17 @@ public:
Reg1 = MCRI->RegUnitRoots[RegUnit][1];
}
- /// Dereference to get the current root register.
+ /// \brief Dereference to get the current root register.
unsigned operator*() const {
return Reg0;
}
- /// isValid - Check if the iterator is at the end of the list.
+ /// \brief Check if the iterator is at the end of the list.
bool isValid() const {
return Reg0;
}
- /// Preincrement to move to the next root register.
+ /// \brief Preincrement to move to the next root register.
void operator++() {
assert(isValid() && "Cannot move off the end of the list.");
Reg0 = Reg1;
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
index 3b1cdf1..0c71ee5 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -16,17 +16,111 @@
#define LLVM_MC_MCSCHEDMODEL_H
#include "llvm/Support/DataTypes.h"
+#include <cassert>
namespace llvm {
struct InstrItinerary;
+/// Define a kind of processor resource that will be modeled by the scheduler.
+struct MCProcResourceDesc {
+#ifndef NDEBUG
+ const char *Name;
+#endif
+ unsigned NumUnits; // Number of resource of this kind
+ unsigned SuperIdx; // Index of the resources kind that contains this kind.
+
+ // Buffered resources may be consumed at some indeterminate cycle after
+ // dispatch (e.g. for instructions that may issue out-of-order). Unbuffered
+ // resources always consume their resource some fixed number of cycles after
+ // dispatch (e.g. for instruction interlocking that may stall the pipeline).
+ bool IsBuffered;
+
+ bool operator==(const MCProcResourceDesc &Other) const {
+ return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx
+ && IsBuffered == Other.IsBuffered;
+ }
+};
+
+/// Identify one of the processor resource kinds consumed by a particular
+/// scheduling class for the specified number of cycles.
+struct MCWriteProcResEntry {
+ unsigned ProcResourceIdx;
+ unsigned Cycles;
+
+ bool operator==(const MCWriteProcResEntry &Other) const {
+ return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles;
+ }
+};
+
+/// Specify the latency in cpu cycles for a particular scheduling class and def
+/// index. -1 indicates an invalid latency. Heuristics would typically consider
+/// an instruction with invalid latency to have infinite latency. Also identify
+/// the WriteResources of this def. When the operand expands to a sequence of
+/// writes, this ID is the last write in the sequence.
+struct MCWriteLatencyEntry {
+ int Cycles;
+ unsigned WriteResourceID;
+
+ bool operator==(const MCWriteLatencyEntry &Other) const {
+ return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID;
+ }
+};
+
+/// Specify the number of cycles allowed after instruction issue before a
+/// particular use operand reads its registers. This effectively reduces the
+/// write's latency. Here we allow negative cycles for corner cases where
+/// latency increases. This rule only applies when the entry's WriteResource
+/// matches the write's WriteResource.
+///
+/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by
+/// WriteResourceIdx.
+struct MCReadAdvanceEntry {
+ unsigned UseIdx;
+ unsigned WriteResourceID;
+ int Cycles;
+
+ bool operator==(const MCReadAdvanceEntry &Other) const {
+ return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID
+ && Cycles == Other.Cycles;
+ }
+};
+
+/// Summarize the scheduling resources required for an instruction of a
+/// particular scheduling class.
+///
+/// Defined as an aggregate struct for creating tables with initializer lists.
+struct MCSchedClassDesc {
+ static const unsigned short InvalidNumMicroOps = UINT16_MAX;
+ static const unsigned short VariantNumMicroOps = UINT16_MAX - 1;
+
+#ifndef NDEBUG
+ const char* Name;
+#endif
+ unsigned short NumMicroOps;
+ bool BeginGroup;
+ bool EndGroup;
+ unsigned WriteProcResIdx; // First index into WriteProcResTable.
+ unsigned NumWriteProcResEntries;
+ unsigned WriteLatencyIdx; // First index into WriteLatencyTable.
+ unsigned NumWriteLatencyEntries;
+ unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable.
+ unsigned NumReadAdvanceEntries;
+
+ bool isValid() const {
+ return NumMicroOps != InvalidNumMicroOps;
+ }
+ bool isVariant() const {
+ return NumMicroOps == VariantNumMicroOps;
+ }
+};
+
/// Machine model for scheduling, bundling, and heuristics.
///
/// The machine model directly provides basic information about the
/// microarchitecture to the scheduler in the form of properties. It also
-/// optionally refers to scheduler resources tables and itinerary
-/// tables. Scheduler resources tables model the latency and cost for each
+/// optionally refers to scheduler resource tables and itinerary
+/// tables. Scheduler resource tables model the latency and cost for each
/// instruction type. Itinerary tables are an independant mechanism that
/// provides a detailed reservation table describing each cycle of instruction
/// execution. Subtargets may define any or all of the above categories of data
@@ -84,8 +178,11 @@ public:
static const unsigned DefaultMispredictPenalty = 10;
private:
- // TODO: Add a reference to proc resource types and sched resource tables.
-
+ unsigned ProcID;
+ const MCProcResourceDesc *ProcResourceTable;
+ const MCSchedClassDesc *SchedClassTable;
+ unsigned NumProcResourceKinds;
+ unsigned NumSchedClasses;
// Instruction itinerary tables used by InstrItineraryData.
friend class InstrItineraryData;
const InstrItinerary *InstrItineraries;
@@ -100,13 +197,45 @@ public:
LoadLatency(DefaultLoadLatency),
HighLatency(DefaultHighLatency),
MispredictPenalty(DefaultMispredictPenalty),
- InstrItineraries(0) {}
+ ProcID(0), ProcResourceTable(0), SchedClassTable(0),
+ NumProcResourceKinds(0), NumSchedClasses(0),
+ InstrItineraries(0) {
+ (void)NumProcResourceKinds;
+ (void)NumSchedClasses;
+ }
// Table-gen driven ctor.
MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp,
+ unsigned pi, const MCProcResourceDesc *pr,
+ const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,
const InstrItinerary *ii):
IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl),
- MispredictPenalty(mp), InstrItineraries(ii){}
+ MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
+ SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),
+ InstrItineraries(ii) {}
+
+ unsigned getProcessorID() const { return ProcID; }
+
+ /// Does this machine model include instruction-level scheduling.
+ bool hasInstrSchedModel() const { return SchedClassTable; }
+
+ unsigned getNumProcResourceKinds() const {
+ return NumProcResourceKinds;
+ }
+
+ const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const {
+ assert(hasInstrSchedModel() && "No scheduling machine model");
+
+ assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx");
+ return &ProcResourceTable[ProcResourceIdx];
+ }
+
+ const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const {
+ assert(hasInstrSchedModel() && "No scheduling machine model");
+
+ assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx");
+ return &SchedClassTable[SchedClassIdx];
+ }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index f90ad6a..5d6cac2 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -14,6 +14,7 @@
#ifndef LLVM_MC_MCSECTION_H
#define LLVM_MC_MCSECTION_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Compiler.h"
@@ -50,6 +51,11 @@ namespace llvm {
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const = 0;
+ // Convenience routines to get label names for the beginning/end of a
+ // section.
+ virtual std::string getLabelBeginName() const = 0;
+ virtual std::string getLabelEndName() const = 0;
+
/// isBaseAddressKnownZero - Return true if we know that this section will
/// get a base address of zero. In cases where we know that this is true we
/// can emit section offsets as direct references to avoid a subtraction
@@ -65,8 +71,6 @@ namespace llvm {
/// isVirtualSection - Check whether this section is "virtual", that is
/// has no actual object file contents.
virtual bool isVirtualSection() const = 0;
-
- static bool classof(const MCSection *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 7eacde5..07c4714 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -14,9 +14,9 @@
#ifndef LLVM_MC_MCSECTIONCOFF_H
#define LLVM_MC_MCSECTIONCOFF_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
#include "llvm/Support/COFF.h"
-#include "llvm/ADT/StringRef.h"
namespace llvm {
@@ -50,6 +50,12 @@ namespace llvm {
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
+ virtual std::string getLabelBeginName() const {
+ return SectionName.str() + "_begin";
+ }
+ virtual std::string getLabelEndName() const {
+ return SectionName.str() + "_end";
+ }
unsigned getCharacteristics() const { return Characteristics; }
int getSelection () const { return Selection; }
@@ -61,7 +67,6 @@ namespace llvm {
static bool classof(const MCSection *S) {
return S->getVariant() == SV_COFF;
}
- static bool classof(const MCSectionCOFF *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 7321ca8..4b8b849 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -14,9 +14,11 @@
#ifndef LLVM_MC_MCSECTIONELF_H
#define LLVM_MC_MCSECTIONELF_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -57,6 +59,11 @@ public:
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
+ virtual std::string getLabelBeginName() const {
+ return SectionName.str() + "_begin"; }
+ virtual std::string getLabelEndName() const {
+ return SectionName.str() + "_end";
+ }
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
unsigned getEntrySize() const { return EntrySize; }
@@ -76,7 +83,6 @@ public:
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
}
- static bool classof(const MCSectionELF *) { return true; }
// Return the entry size for sections with fixed-width data.
static unsigned DetermineEntrySize(SectionKind Kind);
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index 15eb4f4..898f571 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -14,8 +14,8 @@
#ifndef LLVM_MC_MCSECTIONMACHO_H
#define LLVM_MC_MCSECTIONMACHO_H
-#include "llvm/MC/MCSection.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCSection.h"
namespace llvm {
@@ -145,6 +145,14 @@ public:
return StringRef(SectionName);
}
+ virtual std::string getLabelBeginName() const {
+ return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
+ }
+
+ virtual std::string getLabelEndName() const {
+ return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
+ }
+
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
@@ -174,7 +182,6 @@ public:
static bool classof(const MCSection *S) {
return S->getVariant() == SV_MachO;
}
- static bool classof(const MCSectionMachO *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 91593b9..05a33c5 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -14,12 +14,12 @@
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCWin64EH.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCAsmBackend;
@@ -55,6 +55,7 @@ namespace llvm {
std::vector<MCDwarfFrameInfo> FrameInfos;
MCDwarfFrameInfo *getCurrentFrameInfo();
+ MCSymbol *EmitCFICommon();
void EnsureValidFrame();
std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos;
@@ -69,6 +70,8 @@ namespace llvm {
SmallVector<std::pair<const MCSection *,
const MCSection *>, 4> SectionStack;
+ bool AutoInitSections;
+
protected:
MCStreamer(MCContext &Ctx);
@@ -89,6 +92,10 @@ namespace llvm {
public:
virtual ~MCStreamer();
+ /// State management
+ ///
+ virtual void reset();
+
MCContext &getContext() const { return Context; }
unsigned getNumFrameInfos() {
@@ -213,6 +220,17 @@ namespace llvm {
SectionStack.back().first = Section;
}
+ /// Initialize the streamer.
+ void InitStreamer() {
+ if (AutoInitSections)
+ InitSections();
+ }
+
+ /// Tell this MCStreamer to call InitSections upon initialization.
+ void setAutoInitSections(bool AutoInitSections) {
+ this->AutoInitSections = AutoInitSections;
+ }
+
/// InitSections - Create the default sections and set the initial one.
virtual void InitSections() = 0;
@@ -226,6 +244,8 @@ namespace llvm {
/// used in an assignment.
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
@@ -342,7 +362,7 @@ namespace llvm {
/// @name Generating Data
/// @{
- /// EmitBytes - Emit the bytes in \arg Data into the output.
+ /// EmitBytes - Emit the bytes in \p Data into the output.
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
@@ -417,7 +437,6 @@ namespace llvm {
EmitFill(NumBytes, 0, AddrSpace);
}
-
/// EmitValueToAlignment - Emit some number of copies of @p Value until
/// the byte alignment @p ByteAlignment is reached.
///
@@ -515,6 +534,8 @@ namespace llvm {
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
virtual void EmitCFIEscape(StringRef Values);
virtual void EmitCFISignalFrame();
+ virtual void EmitCFIUndefined(int64_t Register);
+ virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
virtual void EmitWin64EHEndProc();
@@ -535,6 +556,20 @@ namespace llvm {
/// section.
virtual void EmitInstruction(const MCInst &Inst) = 0;
+ /// \brief Set the bundle alignment mode from now on in the section.
+ /// The argument is the power of 2 to which the alignment is set. The
+ /// value 0 means turn the bundle alignment off.
+ virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0;
+
+ /// \brief The following instructions are a bundle-locked group.
+ ///
+ /// \param AlignToEnd - If true, the bundle-locked group will be aligned to
+ /// the end of a bundle.
+ virtual void EmitBundleLock(bool AlignToEnd) = 0;
+
+ /// \brief Ends a bundle-locked group.
+ virtual void EmitBundleUnlock() = 0;
+
/// EmitRawText - If this file is backed by a assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate. By default this aborts.
@@ -554,6 +589,11 @@ namespace llvm {
virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
+ /// PPC-related methods.
+ /// FIXME: Eventually replace it with some "target MC streamer" and move
+ /// these methods there.
+ virtual void EmitTCEntry(const MCSymbol &S);
+
/// FinishImpl - Streamer specific finalization.
virtual void FinishImpl() = 0;
/// Finish - Finish emission of machine code.
@@ -573,11 +613,11 @@ namespace llvm {
/// InstPrint.
///
/// \param CE - If given, a code emitter to use to show the instruction
- /// encoding inline with the assembly. This method takes ownership of \arg CE.
+ /// encoding inline with the assembly. This method takes ownership of \p CE.
///
/// \param TAB - If given, a target asm backend to use to show the fixup
/// information in conjunction with encoding information. This method takes
- /// ownership of \arg TAB.
+ /// ownership of \p TAB.
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
@@ -594,7 +634,7 @@ namespace llvm {
/// createMachOStreamer - Create a machine code streamer which will generate
/// Mach-O format object files.
///
- /// Takes ownership of \arg TAB and \arg CE.
+ /// Takes ownership of \p TAB and \p CE.
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
bool RelaxAll = false);
@@ -602,7 +642,7 @@ namespace llvm {
/// createWinCOFFStreamer - Create a machine code streamer which will
/// generate Microsoft COFF format object files.
///
- /// Takes ownership of \arg TAB and \arg CE.
+ /// Takes ownership of \p TAB and \p CE.
MCStreamer *createWinCOFFStreamer(MCContext &Ctx,
MCAsmBackend &TAB,
MCCodeEmitter &CE, raw_ostream &OS,
@@ -617,7 +657,7 @@ namespace llvm {
/// createPureStreamer - Create a machine code streamer which will generate
/// "pure" MC object files, for use with MC-JIT and testing tools.
///
- /// Takes ownership of \arg TAB and \arg CE.
+ /// Takes ownership of \p TAB and \p CE.
MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE);
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index 6c96f49..346fb2d 100644
--- a/include/llvm/MC/MCSubtargetInfo.h
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -14,8 +14,8 @@
#ifndef LLVM_MC_MCSUBTARGET_H
#define LLVM_MC_MCSUBTARGET_H
-#include "llvm/MC/SubtargetFeature.h"
#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/SubtargetFeature.h"
#include <string>
namespace llvm {
@@ -30,7 +30,14 @@ class MCSubtargetInfo {
std::string TargetTriple; // Target triple
const SubtargetFeatureKV *ProcFeatures; // Processor feature list
const SubtargetFeatureKV *ProcDesc; // Processor descriptions
- const SubtargetInfoKV *ProcSchedModel; // Scheduler machine model
+
+ // Scheduler machine model
+ const SubtargetInfoKV *ProcSchedModels;
+ const MCWriteProcResEntry *WriteProcResTable;
+ const MCWriteLatencyEntry *WriteLatencyTable;
+ const MCReadAdvanceEntry *ReadAdvanceTable;
+ const MCSchedModel *CPUSchedModel;
+
const InstrStage *Stages; // Instruction itinerary stages
const unsigned *OperandCycles; // Itinerary operand cycles
const unsigned *ForwardingPaths; // Forwarding paths
@@ -43,6 +50,9 @@ public:
const SubtargetFeatureKV *PF,
const SubtargetFeatureKV *PD,
const SubtargetInfoKV *ProcSched,
+ const MCWriteProcResEntry *WPR,
+ const MCWriteLatencyEntry *WL,
+ const MCReadAdvanceEntry *RA,
const InstrStage *IS,
const unsigned *OC, const unsigned *FP,
unsigned NF, unsigned NP);
@@ -58,9 +68,9 @@ public:
return FeatureBits;
}
- /// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with
- /// feature string), recompute and return feature bits.
- uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS);
+ /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
+ /// feature string). Recompute feature bits and scheduling model.
+ void InitMCProcessorInfo(StringRef CPU, StringRef FS);
/// ToggleFeature - Toggle a feature and returns the re-computed feature
/// bits. This version does not change the implied bits.
@@ -74,9 +84,54 @@ public:
///
const MCSchedModel *getSchedModelForCPU(StringRef CPU) const;
+ /// getSchedModel - Get the machine model for this subtarget's CPU.
+ ///
+ const MCSchedModel *getSchedModel() const { return CPUSchedModel; }
+
+ /// Return an iterator at the first process resource consumed by the given
+ /// scheduling class.
+ const MCWriteProcResEntry *getWriteProcResBegin(
+ const MCSchedClassDesc *SC) const {
+ return &WriteProcResTable[SC->WriteProcResIdx];
+ }
+ const MCWriteProcResEntry *getWriteProcResEnd(
+ const MCSchedClassDesc *SC) const {
+ return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
+ }
+
+ const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
+ unsigned DefIdx) const {
+ assert(DefIdx < SC->NumWriteLatencyEntries &&
+ "MachineModel does not specify a WriteResource for DefIdx");
+
+ return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
+ }
+
+ int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
+ unsigned WriteResID) const {
+ // TODO: The number of read advance entries in a class can be significant
+ // (~50). Consider compressing the WriteID into a dense ID of those that are
+ // used by ReadAdvance and representing them as a bitset.
+ for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
+ *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
+ if (I->UseIdx < UseIdx)
+ continue;
+ if (I->UseIdx > UseIdx)
+ break;
+ // Find the first WriteResIdx match, which has the highest cycle count.
+ if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
+ return I->Cycles;
+ }
+ }
+ return 0;
+ }
+
/// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
///
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
+
+ /// Initialize an InstrItineraryData instance.
+ void initInstrItins(InstrItineraryData &InstrItins) const;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index 4c9e7f5..fe92755 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -113,7 +113,7 @@ namespace llvm {
return *Section;
}
- /// setSection - Mark the symbol as defined in the section \arg S.
+ /// setSection - Mark the symbol as defined in the section \p S.
void setSection(const MCSection &S) { Section = &S; }
/// setUndefined - Mark the symbol as undefined.
@@ -133,7 +133,7 @@ namespace llvm {
return Value != 0;
}
- /// getValue() - Get the value for variable symbols.
+ /// getVariableValue() - Get the value for variable symbols.
const MCExpr *getVariableValue() const {
assert(isVariable() && "Invalid accessor!");
IsUsed = true;
@@ -149,7 +149,7 @@ namespace llvm {
/// @}
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h
deleted file mode 100644
index d09fe04..0000000
--- a/include/llvm/MC/MCTargetAsmLexer.h
+++ /dev/null
@@ -1,89 +0,0 @@
-//===-- llvm/MC/MCTargetAsmLexer.h - Target Assembly Lexer ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCTARGETASMLEXER_H
-#define LLVM_MC_MCTARGETASMLEXER_H
-
-#include "llvm/MC/MCParser/MCAsmLexer.h"
-
-namespace llvm {
-class Target;
-
-/// MCTargetAsmLexer - Generic interface to target specific assembly lexers.
-class MCTargetAsmLexer {
- /// The current token
- AsmToken CurTok;
-
- /// The location and description of the current error
- SMLoc ErrLoc;
- std::string Err;
-
- MCTargetAsmLexer(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION;
- void operator=(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION;
-protected: // Can only create subclasses.
- MCTargetAsmLexer(const Target &);
-
- virtual AsmToken LexToken() = 0;
-
- void SetError(const SMLoc &errLoc, const std::string &err) {
- ErrLoc = errLoc;
- Err = err;
- }
-
- /// TheTarget - The Target that this machine was created for.
- const Target &TheTarget;
- MCAsmLexer *Lexer;
-
-public:
- virtual ~MCTargetAsmLexer();
-
- const Target &getTarget() const { return TheTarget; }
-
- /// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg L.
- void InstallLexer(MCAsmLexer &L) {
- Lexer = &L;
- }
-
- MCAsmLexer *getLexer() {
- return Lexer;
- }
-
- /// Lex - Consume the next token from the input stream and return it.
- const AsmToken &Lex() {
- return CurTok = LexToken();
- }
-
- /// getTok - Get the current (last) lexed token.
- const AsmToken &getTok() {
- return CurTok;
- }
-
- /// getErrLoc - Get the current error location
- const SMLoc &getErrLoc() {
- return ErrLoc;
- }
-
- /// getErr - Get the current error string
- const std::string &getErr() {
- return Err;
- }
-
- /// getKind - Get the kind of current token.
- AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
-
- /// is - Check if the current token has kind \arg K.
- bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
-
- /// isNot - Check if the current token has kind \arg K.
- bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 709c2d2..483a80b 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -21,6 +21,39 @@ class MCParsedAsmOperand;
class MCInst;
template <typename T> class SmallVectorImpl;
+enum AsmRewriteKind {
+ AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
+ // E.g., [eax].foo.bar -> [eax].8
+ AOK_Emit, // Rewrite _emit as .byte.
+ AOK_Imm, // Rewrite as $$N.
+ AOK_ImmPrefix, // Add $$ before a parsed Imm.
+ AOK_Input, // Rewrite in terms of $N.
+ AOK_Output, // Rewrite in terms of $N.
+ AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr).
+ AOK_Skip // Skip emission (e.g., offset/type operators).
+};
+
+struct AsmRewrite {
+ AsmRewriteKind Kind;
+ SMLoc Loc;
+ unsigned Len;
+ unsigned Val;
+public:
+ AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0)
+ : Kind(kind), Loc(loc), Len(len), Val(val) {}
+};
+
+struct ParseInstructionInfo {
+
+ SmallVectorImpl<AsmRewrite> *AsmRewrites;
+
+ ParseInstructionInfo() : AsmRewrites(0) {}
+ ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
+ : AsmRewrites(rewrites) {}
+
+ ~ParseInstructionInfo() {}
+};
+
/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
class MCTargetAsmParser : public MCAsmParserExtension {
public:
@@ -41,12 +74,26 @@ protected: // Can only create subclasses.
/// AvailableFeatures - The current set of available features.
unsigned AvailableFeatures;
+ /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
+ bool ParsingInlineAsm;
+
+ /// SemaCallback - The Sema callback implementation. Must be set when parsing
+ /// ms-style inline assembly.
+ MCAsmParserSemaCallback *SemaCallback;
+
public:
virtual ~MCTargetAsmParser();
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+ bool isParsingInlineAsm () { return ParsingInlineAsm; }
+ void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
+
+ void setSemaCallback(MCAsmParserSemaCallback *Callback) {
+ SemaCallback = Callback;
+ }
+
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
@@ -63,7 +110,8 @@ public:
/// \param Operands [out] - The list of parsed operands, this returns
/// ownership of them to the caller.
/// \return True on failure.
- virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
+ virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
+ SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
/// ParseDirective - Parse a target specific assembler directive
@@ -78,21 +126,9 @@ public:
/// \param DirectiveID - the identifier token of the directive.
virtual bool ParseDirective(AsmToken DirectiveID) = 0;
- /// MatchInstruction - Recognize a series of operands of a parsed instruction
- /// as an actual MCInst. This returns false on success and returns true on
- /// failure to match.
- ///
- /// On failure, the target parser is responsible for emitting a diagnostic
- /// explaining the match failure.
- virtual bool
- MatchInstruction(SMLoc IDLoc, unsigned &Kind,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- SmallVectorImpl<MCInst> &MCInsts,
- unsigned &OrigErrorInfo,
- bool matchingInlineAsm = false) {
- OrigErrorInfo = ~0x0;
- return true;
- }
+ /// mnemonicIsValid - This returns true if this is a valid mnemonic and false
+ /// otherwise.
+ virtual bool mnemonicIsValid(StringRef Mnemonic) = 0;
/// MatchAndEmitInstruction - Recognize a series of operands of a parsed
/// instruction as an actual MCInst and emit it to the specified MCStreamer.
@@ -101,9 +137,10 @@ public:
/// On failure, the target parser is responsible for emitting a diagnostic
/// explaining the match failure.
virtual bool
- MatchAndEmitInstruction(SMLoc IDLoc,
+ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- MCStreamer &Out) = 0;
+ MCStreamer &Out, unsigned &ErrorInfo,
+ bool MatchingInlineAsm) = 0;
/// checkTargetMatchPredicate - Validate the instruction match against
/// any complex target predicates not expressible via match classes.
@@ -111,10 +148,8 @@ public:
return Match_Success;
}
- virtual unsigned getMCInstOperandNum(unsigned Kind, MCInst &Inst,
- const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- unsigned OperandNum,
- unsigned &NumMCOperands) = 0;
+ virtual void convertToMapAndConstraints(unsigned Kind,
+ const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index 8352ed1..a4e7301 100644
--- a/include/llvm/MC/MCValue.h
+++ b/include/llvm/MC/MCValue.h
@@ -14,8 +14,8 @@
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -46,7 +46,7 @@ public:
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
/// dump - Print the value to stderr.
diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h
index 7a0b1ff..11df574 100644
--- a/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -11,6 +11,9 @@
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
namespace llvm {
+ class MCObjectWriter;
+ class raw_ostream;
+
class MCWinCOFFObjectTargetWriter {
const unsigned Machine;
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index 87c5fd3..37ae03b 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -18,9 +18,9 @@
#ifndef LLVM_MC_SUBTARGETFEATURE_H
#define LLVM_MC_SUBTARGETFEATURE_H
-#include <vector>
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
+#include <vector>
namespace llvm {
class raw_ostream;
@@ -95,10 +95,6 @@ public:
const SubtargetFeatureKV *FeatureTable,
size_t FeatureTableSize);
- /// Get scheduling itinerary of a CPU.
- const void *getItinerary(const StringRef CPU,
- const SubtargetInfoKV *Table, size_t TableSize);
-
/// Print feature string.
void print(raw_ostream &OS) const;
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 358b27a..8046efd 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -14,8 +14,8 @@
#ifndef LLVM_OBJECT_ARCHIVE_H
#define LLVM_OBJECT_ARCHIVE_H
-#include "llvm/Object/Binary.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -122,6 +122,16 @@ public:
Archive(MemoryBuffer *source, error_code &ec);
+ enum Kind {
+ K_GNU,
+ K_BSD,
+ K_COFF
+ };
+
+ Kind kind() const {
+ return Format;
+ }
+
child_iterator begin_children(bool skip_internal = true) const;
child_iterator end_children() const;
@@ -129,14 +139,17 @@ public:
symbol_iterator end_symbols() const;
// Cast methods.
- static inline bool classof(Archive const *v) { return true; }
static inline bool classof(Binary const *v) {
return v->isArchive();
}
+ // check if a symbol is in the archive
+ child_iterator findSym(StringRef name) const;
+
private:
child_iterator SymbolTable;
child_iterator StringTable;
+ Kind Format;
};
}
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index befe812..d555de3 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -26,8 +26,8 @@ namespace object {
class Binary {
private:
- Binary(); // = delete
- Binary(const Binary &other); // = delete
+ Binary() LLVM_DELETED_FUNCTION;
+ Binary(const Binary &other) LLVM_DELETED_FUNCTION;
unsigned int TypeID;
@@ -64,7 +64,6 @@ public:
// Cast methods.
unsigned int getType() const { return TypeID; }
- static inline bool classof(const Binary *v) { return true; }
// Convenience methods
bool isObject() const {
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index 967420e..6f42d76 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -116,6 +116,7 @@ protected:
virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
virtual error_code getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const;
+ virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
@@ -128,6 +129,7 @@ protected:
virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
bool &Res) const;
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
@@ -197,7 +199,6 @@ public:
static inline bool classof(const Binary *v) {
return v->isCOFF();
}
- static inline bool classof(const COFFObjectFile *v) { return true; }
};
}
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 9c4afed..aa26d17 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -14,11 +14,11 @@
#ifndef LLVM_OBJECT_ELF_H
#define LLVM_OBJECT_ELF_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
@@ -35,6 +35,14 @@
namespace llvm {
namespace object {
+using support::endianness;
+
+template<typename T, int max_align>
+struct MaximumAlignment {
+ enum {value = AlignOf<T>::Alignment > max_align ? max_align
+ : AlignOf<T>::Alignment};
+};
+
// Subclasses of ELFObjectFile may need this for template instantiation
inline std::pair<unsigned char, unsigned char>
getElfArchType(MemoryBuffer *Object) {
@@ -45,69 +53,78 @@ getElfArchType(MemoryBuffer *Object) {
}
// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
-template<support::endianness target_endianness>
+template<endianness target_endianness, std::size_t max_alignment>
struct ELFDataTypeTypedefHelperCommon {
typedef support::detail::packed_endian_specific_integral
- <uint16_t, target_endianness, support::aligned> Elf_Half;
+ <uint16_t, target_endianness,
+ MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half;
typedef support::detail::packed_endian_specific_integral
- <uint32_t, target_endianness, support::aligned> Elf_Word;
+ <uint32_t, target_endianness,
+ MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word;
typedef support::detail::packed_endian_specific_integral
- <int32_t, target_endianness, support::aligned> Elf_Sword;
+ <int32_t, target_endianness,
+ MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword;
typedef support::detail::packed_endian_specific_integral
- <uint64_t, target_endianness, support::aligned> Elf_Xword;
+ <uint64_t, target_endianness,
+ MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword;
typedef support::detail::packed_endian_specific_integral
- <int64_t, target_endianness, support::aligned> Elf_Sxword;
+ <int64_t, target_endianness,
+ MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
};
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct ELFDataTypeTypedefHelper;
/// ELF 32bit types.
-template<support::endianness target_endianness>
-struct ELFDataTypeTypedefHelper<target_endianness, false>
- : ELFDataTypeTypedefHelperCommon<target_endianness> {
+template<endianness target_endianness, std::size_t max_alignment>
+struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, false>
+ : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment> {
typedef uint32_t value_type;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness, support::aligned> Elf_Addr;
+ <value_type, target_endianness,
+ MaximumAlignment<value_type, max_alignment>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness, support::aligned> Elf_Off;
+ <value_type, target_endianness,
+ MaximumAlignment<value_type, max_alignment>::value> Elf_Off;
};
/// ELF 64bit types.
-template<support::endianness target_endianness>
-struct ELFDataTypeTypedefHelper<target_endianness, true>
- : ELFDataTypeTypedefHelperCommon<target_endianness>{
+template<endianness target_endianness, std::size_t max_alignment>
+struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, true>
+ : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment>{
typedef uint64_t value_type;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness, support::aligned> Elf_Addr;
+ <value_type, target_endianness,
+ MaximumAlignment<value_type, max_alignment>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness, support::aligned> Elf_Off;
+ <value_type, target_endianness,
+ MaximumAlignment<value_type, max_alignment>::value> Elf_Off;
};
// I really don't like doing this, but the alternative is copypasta.
-#define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \
-typedef typename \
- ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \
-typedef typename \
- ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \
-typedef typename \
- ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \
-typedef typename \
- ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \
-typedef typename \
- ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \
-typedef typename \
- ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \
-typedef typename \
- ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword;
+#define LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits) \
+typedef typename ELFDataTypeTypedefHelper \
+ <target_endianness, max_alignment, is64Bits>::Elf_Addr Elf_Addr; \
+typedef typename ELFDataTypeTypedefHelper \
+ <target_endianness, max_alignment, is64Bits>::Elf_Off Elf_Off; \
+typedef typename ELFDataTypeTypedefHelper \
+ <target_endianness, max_alignment, is64Bits>::Elf_Half Elf_Half; \
+typedef typename ELFDataTypeTypedefHelper \
+ <target_endianness, max_alignment, is64Bits>::Elf_Word Elf_Word; \
+typedef typename ELFDataTypeTypedefHelper \
+ <target_endianness, max_alignment, is64Bits>::Elf_Sword Elf_Sword; \
+typedef typename ELFDataTypeTypedefHelper \
+ <target_endianness, max_alignment, is64Bits>::Elf_Xword Elf_Xword; \
+typedef typename ELFDataTypeTypedefHelper \
+ <target_endianness, max_alignment, is64Bits>::Elf_Sxword Elf_Sxword;
// Section header.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Shdr_Base;
-template<support::endianness target_endianness>
-struct Elf_Shdr_Base<target_endianness, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Shdr_Base<target_endianness, max_alignment, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Word sh_flags; // Section flags (SHF_*)
@@ -120,9 +137,9 @@ struct Elf_Shdr_Base<target_endianness, false> {
Elf_Word sh_entsize; // Size of records contained within the section
};
-template<support::endianness target_endianness>
-struct Elf_Shdr_Base<target_endianness, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Shdr_Base<target_endianness, max_alignment, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Xword sh_flags; // Section flags (SHF_*)
@@ -135,10 +152,11 @@ struct Elf_Shdr_Base<target_endianness, true> {
Elf_Xword sh_entsize; // Size of records contained within the section
};
-template<support::endianness target_endianness, bool is64Bits>
-struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> {
- using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize;
- using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size;
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+struct Elf_Shdr_Impl
+ : Elf_Shdr_Base<target_endianness, max_alignment, is64Bits> {
+ using Elf_Shdr_Base<target_endianness, max_alignment, is64Bits>::sh_entsize;
+ using Elf_Shdr_Base<target_endianness, max_alignment, is64Bits>::sh_size;
/// @brief Get the number of entities this section contains if it has any.
unsigned getEntityCount() const {
@@ -148,12 +166,14 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> {
}
};
-template<support::endianness target_endianness, bool is64Bits>
+template< endianness target_endianness
+ , std::size_t max_alignment
+ , bool is64Bits>
struct Elf_Sym_Base;
-template<support::endianness target_endianness>
-struct Elf_Sym_Base<target_endianness, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Sym_Base<target_endianness, max_alignment, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
Elf_Word st_name; // Symbol name (index into string table)
Elf_Addr st_value; // Value or address associated with the symbol
Elf_Word st_size; // Size of the symbol
@@ -162,9 +182,9 @@ struct Elf_Sym_Base<target_endianness, false> {
Elf_Half st_shndx; // Which section (header table index) it's defined in
};
-template<support::endianness target_endianness>
-struct Elf_Sym_Base<target_endianness, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Sym_Base<target_endianness, max_alignment, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
Elf_Word st_name; // Symbol name (index into string table)
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
@@ -173,9 +193,10 @@ struct Elf_Sym_Base<target_endianness, true> {
Elf_Xword st_size; // Size of the symbol
};
-template<support::endianness target_endianness, bool is64Bits>
-struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> {
- using Elf_Sym_Base<target_endianness, is64Bits>::st_info;
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+struct Elf_Sym_Impl
+ : Elf_Sym_Base<target_endianness, max_alignment, is64Bits> {
+ using Elf_Sym_Base<target_endianness, max_alignment, is64Bits>::st_info;
// These accessors and mutators correspond to the ELF32_ST_BIND,
// ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
@@ -190,21 +211,22 @@ struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> {
/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
/// (.gnu.version). This structure is identical for ELF32 and ELF64.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Versym_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
};
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Verdaux_Impl;
/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Verdef_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
- typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux;
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ typedef
+ Elf_Verdaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdaux;
Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
Elf_Half vd_ndx; // Version index, used in .gnu.version entries
@@ -221,18 +243,18 @@ struct Elf_Verdef_Impl {
/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Verdaux_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
Elf_Word vda_name; // Version name (offset in string table)
Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
};
/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Verneed_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
Elf_Half vn_cnt; // Number of associated Vernaux entries
Elf_Word vn_file; // Library name (string table offset)
@@ -242,9 +264,9 @@ struct Elf_Verneed_Impl {
/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Vernaux_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
Elf_Word vna_hash; // Hash of dependency name
Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
Elf_Half vna_other; // Version index, used in .gnu.version entries
@@ -254,12 +276,12 @@ struct Elf_Vernaux_Impl {
/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
/// table section (.dynamic) look like.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Dyn_Base;
-template<support::endianness target_endianness>
-struct Elf_Dyn_Base<target_endianness, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Dyn_Base<target_endianness, max_alignment, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
Elf_Sword d_tag;
union {
Elf_Word d_val;
@@ -267,9 +289,9 @@ struct Elf_Dyn_Base<target_endianness, false> {
} d_un;
};
-template<support::endianness target_endianness>
-struct Elf_Dyn_Base<target_endianness, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Dyn_Base<target_endianness, max_alignment, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
Elf_Sxword d_tag;
union {
Elf_Xword d_val;
@@ -278,24 +300,24 @@ struct Elf_Dyn_Base<target_endianness, true> {
};
/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters.
-template<support::endianness target_endianness, bool is64Bits>
-struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, is64Bits> {
- using Elf_Dyn_Base<target_endianness, is64Bits>::d_tag;
- using Elf_Dyn_Base<target_endianness, is64Bits>::d_un;
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, max_alignment, is64Bits> {
+ using Elf_Dyn_Base<target_endianness, max_alignment, is64Bits>::d_tag;
+ using Elf_Dyn_Base<target_endianness, max_alignment, is64Bits>::d_un;
int64_t getTag() const { return d_tag; }
uint64_t getVal() const { return d_un.d_val; }
uint64_t getPtr() const { return d_un.ptr; }
};
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
class ELFObjectFile;
// DynRefImpl: Reference to an entry in the dynamic table
// This is an ELF-specific interface.
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
class DynRefImpl {
- typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn;
- typedef ELFObjectFile<target_endianness, is64Bits> OwningType;
+ typedef Elf_Dyn_Impl<target_endianness, max_alignment, is64Bits> Elf_Dyn;
+ typedef ELFObjectFile<target_endianness, max_alignment, is64Bits> OwningType;
DataRefImpl DynPimpl;
const OwningType *OwningObject;
@@ -317,66 +339,72 @@ public:
};
// Elf_Rel: Elf Relocation
-template<support::endianness target_endianness, bool is64Bits, bool isRela>
+template< endianness target_endianness
+ , std::size_t max_alignment
+ , bool is64Bits
+ , bool isRela>
struct Elf_Rel_Base;
-template<support::endianness target_endianness>
-struct Elf_Rel_Base<target_endianness, false, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Rel_Base<target_endianness, max_alignment, false, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
};
-template<support::endianness target_endianness>
-struct Elf_Rel_Base<target_endianness, true, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Rel_Base<target_endianness, max_alignment, true, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Xword r_info; // Symbol table index and type of relocation to apply
};
-template<support::endianness target_endianness>
-struct Elf_Rel_Base<target_endianness, false, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Rel_Base<target_endianness, max_alignment, false, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
Elf_Sword r_addend; // Compute value for relocatable field by adding this
};
-template<support::endianness target_endianness>
-struct Elf_Rel_Base<target_endianness, true, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Rel_Base<target_endianness, max_alignment, true, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Xword r_info; // Symbol table index and type of relocation to apply
Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
};
-template<support::endianness target_endianness, bool is64Bits, bool isRela>
+template< endianness target_endianness
+ , std::size_t max_alignment
+ , bool is64Bits
+ , bool isRela>
struct Elf_Rel_Impl;
-template<support::endianness target_endianness, bool isRela>
-struct Elf_Rel_Impl<target_endianness, true, isRela>
- : Elf_Rel_Base<target_endianness, true, isRela> {
- using Elf_Rel_Base<target_endianness, true, isRela>::r_info;
- LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+template<endianness target_endianness, std::size_t max_alignment, bool isRela>
+struct Elf_Rel_Impl<target_endianness, max_alignment, true, isRela>
+ : Elf_Rel_Base<target_endianness, max_alignment, true, isRela> {
+ using Elf_Rel_Base<target_endianness, max_alignment, true, isRela>::r_info;
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
- uint64_t getSymbol() const { return (r_info >> 32); }
- unsigned char getType() const {
- return (unsigned char) (r_info & 0xffffffffL);
+ uint32_t getSymbol() const { return (uint32_t) (r_info >> 32); }
+ uint32_t getType() const {
+ return (uint32_t) (r_info & 0xffffffffL);
}
- void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); }
- void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
- void setSymbolAndType(uint64_t s, unsigned char t) {
- r_info = (s << 32) + (t&0xffffffffL);
+ void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
+ void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(uint32_t s, uint32_t t) {
+ r_info = ((uint64_t)s << 32) + (t&0xffffffffL);
}
};
-template<support::endianness target_endianness, bool isRela>
-struct Elf_Rel_Impl<target_endianness, false, isRela>
- : Elf_Rel_Base<target_endianness, false, isRela> {
- using Elf_Rel_Base<target_endianness, false, isRela>::r_info;
- LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+template<endianness target_endianness, std::size_t max_alignment, bool isRela>
+struct Elf_Rel_Impl<target_endianness, max_alignment, false, isRela>
+ : Elf_Rel_Base<target_endianness, max_alignment, false, isRela> {
+ using Elf_Rel_Base<target_endianness, max_alignment, false, isRela>::r_info;
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
// These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
// and ELF32_R_INFO macros defined in the ELF specification:
@@ -389,9 +417,9 @@ struct Elf_Rel_Impl<target_endianness, false, isRela>
}
};
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
struct Elf_Ehdr_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
Elf_Half e_type; // Type of file (see ET_*)
Elf_Half e_machine; // Required architecture for this file (see EM_*)
@@ -414,22 +442,59 @@ struct Elf_Ehdr_Impl {
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
};
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+struct Elf_Phdr_Impl;
+
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Phdr_Impl<target_endianness, max_alignment, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+ Elf_Word p_type; // Type of segment
+ Elf_Off p_offset; // FileOffset where segment is located, in bytes
+ Elf_Addr p_vaddr; // Virtual Address of beginning of segment
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Word p_flags; // Segment flags
+ Elf_Word p_align; // Segment alignment constraint
+};
+
+template<endianness target_endianness, std::size_t max_alignment>
+struct Elf_Phdr_Impl<target_endianness, max_alignment, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+ Elf_Word p_type; // Type of segment
+ Elf_Word p_flags; // Segment flags
+ Elf_Off p_offset; // FileOffset where segment is located, in bytes
+ Elf_Addr p_vaddr; // Virtual Address of beginning of segment
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Xword p_align; // Segment alignment constraint
+};
+
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
class ELFObjectFile : public ObjectFile {
- LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
-
- typedef Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr;
- typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
- typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
- typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn;
- typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel;
- typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela;
- typedef Elf_Verdef_Impl<target_endianness, is64Bits> Elf_Verdef;
- typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux;
- typedef Elf_Verneed_Impl<target_endianness, is64Bits> Elf_Verneed;
- typedef Elf_Vernaux_Impl<target_endianness, is64Bits> Elf_Vernaux;
- typedef Elf_Versym_Impl<target_endianness, is64Bits> Elf_Versym;
- typedef DynRefImpl<target_endianness, is64Bits> DynRef;
+ LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+
+ typedef Elf_Ehdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Ehdr;
+ typedef Elf_Shdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Shdr;
+ typedef Elf_Sym_Impl<target_endianness, max_alignment, is64Bits> Elf_Sym;
+ typedef Elf_Dyn_Impl<target_endianness, max_alignment, is64Bits> Elf_Dyn;
+ typedef Elf_Phdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Phdr;
+ typedef
+ Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, false> Elf_Rel;
+ typedef
+ Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, true> Elf_Rela;
+ typedef
+ Elf_Verdef_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdef;
+ typedef
+ Elf_Verdaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdaux;
+ typedef
+ Elf_Verneed_Impl<target_endianness, max_alignment, is64Bits> Elf_Verneed;
+ typedef
+ Elf_Vernaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Vernaux;
+ typedef
+ Elf_Versym_Impl<target_endianness, max_alignment, is64Bits> Elf_Versym;
+ typedef DynRefImpl<target_endianness, max_alignment, is64Bits> DynRef;
typedef content_iterator<DynRef> dyn_iterator;
protected:
@@ -464,6 +529,59 @@ private:
// This is set the first time getLoadName is called.
mutable const char *dt_soname;
+public:
+ /// \brief Iterate over constant sized entities.
+ template<class EntT>
+ class ELFEntityIterator {
+ public:
+ typedef void difference_type;
+ typedef EntT value_type;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef value_type &reference;
+ typedef value_type *pointer;
+
+ /// \brief Default construct iterator.
+ ELFEntityIterator() : EntitySize(0), Current(0) {}
+ ELFEntityIterator(uint64_t EntSize, const char *Start)
+ : EntitySize(EntSize)
+ , Current(Start) {}
+
+ reference operator *() {
+ assert(Current && "Attempted to dereference an invalid iterator!");
+ return *reinterpret_cast<pointer>(Current);
+ }
+
+ pointer operator ->() {
+ assert(Current && "Attempted to dereference an invalid iterator!");
+ return reinterpret_cast<pointer>(Current);
+ }
+
+ bool operator ==(const ELFEntityIterator &Other) {
+ return Current == Other.Current;
+ }
+
+ bool operator !=(const ELFEntityIterator &Other) {
+ return !(*this == Other);
+ }
+
+ ELFEntityIterator &operator ++() {
+ assert(Current && "Attempted to increment an invalid iterator!");
+ Current += EntitySize;
+ return *this;
+ }
+
+ ELFEntityIterator operator ++(int) {
+ ELFEntityIterator Tmp = *this;
+ ++*this;
+ return Tmp;
+ }
+
+ private:
+ const uint64_t EntitySize;
+ const char *Current;
+ };
+
+private:
// Records for each version index the corresponding Verdef or Vernaux entry.
// This is filled the first time LoadVersionMap() is called.
class VersionMapEntry : public PointerIntPair<const void*, 1> {
@@ -529,6 +647,7 @@ public:
const Elf_Dyn *getDyn(DataRefImpl DynData) const;
error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
bool &IsDefault) const;
+ uint64_t getSymbolIndex(const Elf_Sym *sym) const;
protected:
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
@@ -540,8 +659,9 @@ protected:
virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
virtual error_code getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const;
+ virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
- friend class DynRefImpl<target_endianness, is64Bits>;
+ friend class DynRefImpl<target_endianness, max_alignment, is64Bits>;
virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const;
virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
@@ -560,6 +680,7 @@ protected:
bool &Res) const;
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
bool &Result) const;
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
@@ -599,6 +720,44 @@ public:
virtual dyn_iterator begin_dynamic_table() const;
virtual dyn_iterator end_dynamic_table() const;
+ typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
+ typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
+
+ Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const {
+ return Elf_Rela_Iter(sec->sh_entsize,
+ (const char *)(base() + sec->sh_offset));
+ }
+
+ Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const {
+ return Elf_Rela_Iter(sec->sh_entsize, (const char *)
+ (base() + sec->sh_offset + sec->sh_size));
+ }
+
+ Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const {
+ return Elf_Rel_Iter(sec->sh_entsize,
+ (const char *)(base() + sec->sh_offset));
+ }
+
+ Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const {
+ return Elf_Rel_Iter(sec->sh_entsize, (const char *)
+ (base() + sec->sh_offset + sec->sh_size));
+ }
+
+ /// \brief Iterate over program header table.
+ typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter;
+
+ Elf_Phdr_Iter begin_program_headers() const {
+ return Elf_Phdr_Iter(Header->e_phentsize,
+ (const char*)base() + Header->e_phoff);
+ }
+
+ Elf_Phdr_Iter end_program_headers() const {
+ return Elf_Phdr_Iter(Header->e_phentsize,
+ (const char*)base() +
+ Header->e_phoff +
+ (Header->e_phnum * Header->e_phentsize));
+ }
+
virtual uint8_t getBytesInAddress() const;
virtual StringRef getFileFormatName() const;
virtual StringRef getObjectType() const { return "ELF"; }
@@ -613,6 +772,7 @@ public:
const Elf_Shdr *getSection(const Elf_Sym *symb) const;
const Elf_Shdr *getElfSection(section_iterator &It) const;
const Elf_Sym *getElfSymbol(symbol_iterator &It) const;
+ const Elf_Sym *getElfSymbol(uint32_t index) const;
// Methods for type inquiry through isa, cast, and dyn_cast
bool isDyldType() const { return isDyldELFObject; }
@@ -620,13 +780,12 @@ public:
return v->getType() == getELFType(target_endianness == support::little,
is64Bits);
}
- static inline bool classof(const ELFObjectFile *v) { return true; }
};
// Iterate through the version definitions, and place each Elf_Verdef
// in the VersionMap according to its index.
-template<support::endianness target_endianness, bool is64Bits>
-void ELFObjectFile<target_endianness, is64Bits>::
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
LoadVersionDefs(const Elf_Shdr *sec) const {
unsigned vd_size = sec->sh_size; // Size of section in bytes
unsigned vd_count = sec->sh_info; // Number of Verdef entries
@@ -651,8 +810,8 @@ void ELFObjectFile<target_endianness, is64Bits>::
// Iterate through the versions needed section, and place each Elf_Vernaux
// in the VersionMap according to its index.
-template<support::endianness target_endianness, bool is64Bits>
-void ELFObjectFile<target_endianness, is64Bits>::
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
LoadVersionNeeds(const Elf_Shdr *sec) const {
unsigned vn_size = sec->sh_size; // Size of section in bytes
unsigned vn_count = sec->sh_info; // Number of Verneed entries
@@ -684,8 +843,9 @@ void ELFObjectFile<target_endianness, is64Bits>::
}
}
-template<support::endianness target_endianness, bool is64Bits>
-void ELFObjectFile<target_endianness, is64Bits>::LoadVersionMap() const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+void ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::LoadVersionMap() const {
// If there is no dynamic symtab or version table, there is nothing to do.
if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL)
return;
@@ -706,8 +866,8 @@ void ELFObjectFile<target_endianness, is64Bits>::LoadVersionMap() const {
LoadVersionNeeds(dot_gnu_version_r_sec);
}
-template<support::endianness target_endianness, bool is64Bits>
-void ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+void ELFObjectFile<target_endianness, max_alignment, is64Bits>
::validateSymbol(DataRefImpl Symb) const {
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
@@ -725,8 +885,8 @@ void ELFObjectFile<target_endianness, is64Bits>
report_fatal_error("Symb must point to a valid symbol!");
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolNext(DataRefImpl Symb,
SymbolRef &Result) const {
validateSymbol(Symb);
@@ -753,8 +913,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolName(DataRefImpl Symb,
StringRef &Result) const {
validateSymbol(Symb);
@@ -762,8 +922,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result);
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolVersion(SymbolRef SymRef,
StringRef &Version,
bool &IsDefault) const {
@@ -774,17 +934,18 @@ error_code ELFObjectFile<target_endianness, is64Bits>
Version, IsDefault);
}
-template<support::endianness target_endianness, bool is64Bits>
-ELF::Elf64_Word ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+ELF::Elf64_Word ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolTableIndex(const Elf_Sym *symb) const {
if (symb->st_shndx == ELF::SHN_XINDEX)
return ExtendedSymbolTable.lookup(symb);
return symb->st_shndx;
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
-ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Shdr *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSection(const Elf_Sym *symb) const {
if (symb->st_shndx == ELF::SHN_XINDEX)
return getSection(ExtendedSymbolTable.lookup(symb));
@@ -793,23 +954,36 @@ ELFObjectFile<target_endianness, is64Bits>
return getSection(symb->st_shndx);
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
-ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Shdr *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getElfSection(section_iterator &It) const {
llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl();
return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p);
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
-ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Sym *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getElfSymbol(symbol_iterator &It) const {
return getSymbol(It->getRawDataRefImpl());
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Sym *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getElfSymbol(uint32_t index) const {
+ DataRefImpl SymbolData;
+ SymbolData.d.a = index;
+ SymbolData.d.b = 1;
+ return getSymbol(SymbolData);
+}
+
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolFileOffset(DataRefImpl Symb,
uint64_t &Result) const {
validateSymbol(Symb);
@@ -843,8 +1017,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
}
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolAddress(DataRefImpl Symb,
uint64_t &Result) const {
validateSymbol(Symb);
@@ -868,7 +1042,18 @@ error_code ELFObjectFile<target_endianness, is64Bits>
case ELF::STT_FUNC:
case ELF::STT_OBJECT:
case ELF::STT_NOTYPE:
- Result = symb->st_value + (Section ? Section->sh_addr : 0);
+ bool IsRelocatable;
+ switch(Header->e_type) {
+ case ELF::ET_EXEC:
+ case ELF::ET_DYN:
+ IsRelocatable = false;
+ break;
+ default:
+ IsRelocatable = true;
+ }
+ Result = symb->st_value;
+ if (IsRelocatable && Section != 0)
+ Result += Section->sh_addr;
return object_error::success;
default:
Result = UnknownAddressOrSize;
@@ -876,8 +1061,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
}
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolSize(DataRefImpl Symb,
uint64_t &Result) const {
validateSymbol(Symb);
@@ -888,8 +1073,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolNMTypeChar(DataRefImpl Symb,
char &Result) const {
validateSymbol(Symb);
@@ -953,8 +1138,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolType(DataRefImpl Symb,
SymbolRef::Type &Result) const {
validateSymbol(Symb);
@@ -985,8 +1170,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolFlags(DataRefImpl Symb,
uint32_t &Result) const {
validateSymbol(Symb);
@@ -1020,8 +1205,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const {
validateSymbol(Symb);
@@ -1037,8 +1222,18 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getSymbolValue(DataRefImpl Symb,
+ uint64_t &Val) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ Val = symb->st_value;
+ return object_error::success;
+}
+
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
sec += Header->e_shentsize;
@@ -1047,8 +1242,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionName(DataRefImpl Sec,
StringRef &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1056,8 +1251,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionAddress(DataRefImpl Sec,
uint64_t &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1065,8 +1260,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionSize(DataRefImpl Sec,
uint64_t &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1074,8 +1269,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionContents(DataRefImpl Sec,
StringRef &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1084,8 +1279,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionContents(const Elf_Shdr *Sec,
StringRef &Result) const {
const char *start = (const char*)base() + Sec->sh_offset;
@@ -1093,8 +1288,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionAlignment(DataRefImpl Sec,
uint64_t &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1102,8 +1297,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::isSectionText(DataRefImpl Sec,
bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1114,8 +1309,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::isSectionData(DataRefImpl Sec,
bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1127,8 +1322,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::isSectionBSS(DataRefImpl Sec,
bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1140,8 +1335,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::isSectionRequiredForExecution(DataRefImpl Sec,
bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1152,8 +1347,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::isSectionVirtual(DataRefImpl Sec,
bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1164,21 +1359,31 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>::isSectionZeroInit(DataRefImpl Sec,
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::isSectionZeroInit(DataRefImpl Sec,
bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
// For ELF, all zero-init sections are virtual (that is, they occupy no space
// in the object image) and vice versa.
- if (sec->sh_flags & ELF::SHT_NOBITS)
- Result = true;
- else
+ Result = sec->sh_type == ELF::SHT_NOBITS;
+ return object_error::success;
+}
+
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR)
Result = false;
+ else
+ Result = true;
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::sectionContainsSymbol(DataRefImpl Sec,
DataRefImpl Symb,
bool &Result) const {
@@ -1187,8 +1392,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-relocation_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+relocation_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionRelBegin(DataRefImpl Sec) const {
DataRefImpl RelData;
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1201,8 +1406,8 @@ relocation_iterator ELFObjectFile<target_endianness, is64Bits>
return relocation_iterator(RelocationRef(RelData, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-relocation_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+relocation_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionRelEnd(DataRefImpl Sec) const {
DataRefImpl RelData;
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
@@ -1219,8 +1424,8 @@ relocation_iterator ELFObjectFile<target_endianness, is64Bits>
}
// Relocations
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationNext(DataRefImpl Rel,
RelocationRef &Result) const {
++Rel.w.c;
@@ -1248,8 +1453,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Result) const {
uint32_t symbolIdx;
@@ -1276,8 +1481,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationAddress(DataRefImpl Rel,
uint64_t &Result) const {
uint64_t offset;
@@ -1299,8 +1504,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationOffset(DataRefImpl Rel,
uint64_t &Result) const {
uint64_t offset;
@@ -1322,8 +1527,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationType(DataRefImpl Rel,
uint64_t &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
@@ -1345,12 +1550,12 @@ error_code ELFObjectFile<target_endianness, is64Bits>
#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
case ELF::enum: res = #enum; break;
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
- uint8_t type;
+ uint32_t type;
StringRef res;
switch (sec->sh_type) {
default :
@@ -1687,8 +1892,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationAdditionalInfo(DataRefImpl Rel,
int64_t &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
@@ -1706,8 +1911,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
}
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getRelocationValueString(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
@@ -1777,8 +1982,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
}
// Verify that the last byte in the string table in a null.
-template<support::endianness target_endianness, bool is64Bits>
-void ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+void ELFObjectFile<target_endianness, max_alignment, is64Bits>
::VerifyStrTab(const Elf_Shdr *sh) const {
const char *strtab = (const char*)base() + sh->sh_offset;
if (strtab[sh->sh_size - 1] != 0)
@@ -1786,9 +1991,9 @@ void ELFObjectFile<target_endianness, is64Bits>
report_fatal_error("String table must end with a null terminator!");
}
-template<support::endianness target_endianness, bool is64Bits>
-ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
- , error_code &ec)
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
: ObjectFile(getELFType(target_endianness == support::little, is64Bits),
Object, ec)
, isDyldELFObject(false)
@@ -1947,8 +2152,23 @@ ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
}
}
-template<support::endianness target_endianness, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+// Get the symbol table index in the symtab section given a symbol
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+uint64_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getSymbolIndex(const Elf_Sym *Sym) const {
+ assert(SymbolTableSections.size() == 1 && "Only one symbol table supported!");
+ const Elf_Shdr *SymTab = *SymbolTableSections.begin();
+ uintptr_t SymLoc = uintptr_t(Sym);
+ uintptr_t SymTabLoc = uintptr_t(base() + SymTab->sh_offset);
+ assert(SymLoc > SymTabLoc && "Symbol not in symbol table!");
+ uint64_t SymOffset = SymLoc - SymTabLoc;
+ assert(SymOffset % SymTab->sh_entsize == 0 &&
+ "Symbol not multiple of symbol size!");
+ return SymOffset / SymTab->sh_entsize;
+}
+
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::begin_symbols() const {
DataRefImpl SymbolData;
if (SymbolTableSections.size() <= 1) {
@@ -1961,8 +2181,8 @@ symbol_iterator ELFObjectFile<target_endianness, is64Bits>
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::end_symbols() const {
DataRefImpl SymbolData;
SymbolData.d.a = std::numeric_limits<uint32_t>::max();
@@ -1970,8 +2190,8 @@ symbol_iterator ELFObjectFile<target_endianness, is64Bits>
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::begin_dynamic_symbols() const {
DataRefImpl SymbolData;
if (SymbolTableSections[0] == NULL) {
@@ -1984,8 +2204,8 @@ symbol_iterator ELFObjectFile<target_endianness, is64Bits>
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::end_dynamic_symbols() const {
DataRefImpl SymbolData;
SymbolData.d.a = std::numeric_limits<uint32_t>::max();
@@ -1993,16 +2213,16 @@ symbol_iterator ELFObjectFile<target_endianness, is64Bits>
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-section_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+section_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::begin_sections() const {
DataRefImpl ret;
ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
return section_iterator(SectionRef(ret, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-section_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+section_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::end_sections() const {
DataRefImpl ret;
ret.p = reinterpret_cast<intptr_t>(base()
@@ -2011,9 +2231,10 @@ section_iterator ELFObjectFile<target_endianness, is64Bits>
return section_iterator(SectionRef(ret, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator
-ELFObjectFile<target_endianness, is64Bits>::begin_dynamic_table() const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+typename ELFObjectFile<target_endianness, max_alignment, is64Bits>::dyn_iterator
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::begin_dynamic_table() const {
DataRefImpl DynData;
if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) {
DynData.d.a = std::numeric_limits<uint32_t>::max();
@@ -2023,17 +2244,17 @@ ELFObjectFile<target_endianness, is64Bits>::begin_dynamic_table() const {
return dyn_iterator(DynRef(DynData, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator
-ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+typename ELFObjectFile<target_endianness, max_alignment, is64Bits>::dyn_iterator
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
::end_dynamic_table() const {
DataRefImpl DynData;
DynData.d.a = std::numeric_limits<uint32_t>::max();
return dyn_iterator(DynRef(DynData, this));
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getDynNext(DataRefImpl DynData,
DynRef &Result) const {
++DynData.d.a;
@@ -2048,9 +2269,9 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
StringRef
-ELFObjectFile<target_endianness, is64Bits>::getLoadName() const {
+ELFObjectFile<target_endianness, max_alignment, is64Bits>::getLoadName() const {
if (!dt_soname) {
// Find the DT_SONAME entry
dyn_iterator it = begin_dynamic_table();
@@ -2074,8 +2295,8 @@ ELFObjectFile<target_endianness, is64Bits>::getLoadName() const {
return dt_soname;
}
-template<support::endianness target_endianness, bool is64Bits>
-library_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+library_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::begin_libraries_needed() const {
// Find the first DT_NEEDED entry
dyn_iterator i = begin_dynamic_table();
@@ -2092,8 +2313,8 @@ library_iterator ELFObjectFile<target_endianness, is64Bits>
return library_iterator(LibraryRef(i->getRawDataRefImpl(), this));
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getLibraryNext(DataRefImpl Data,
LibraryRef &Result) const {
// Use the same DataRefImpl format as DynRef.
@@ -2121,8 +2342,8 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getLibraryPath(DataRefImpl Data, StringRef &Res) const {
dyn_iterator i = dyn_iterator(DynRef(Data, this));
if (i == end_dynamic_table())
@@ -2142,21 +2363,22 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-library_iterator ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+library_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
::end_libraries_needed() const {
dyn_iterator e = end_dynamic_table();
// Use the same DataRefImpl format as DynRef.
return library_iterator(LibraryRef(e->getRawDataRefImpl(), this));
}
-template<support::endianness target_endianness, bool is64Bits>
-uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+uint8_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getBytesInAddress() const {
return is64Bits ? 8 : 4;
}
-template<support::endianness target_endianness, bool is64Bits>
-StringRef ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+StringRef ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getFileFormatName() const {
switch(Header->e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
@@ -2178,6 +2400,8 @@ StringRef ELFObjectFile<target_endianness, is64Bits>
return "ELF64-i386";
case ELF::EM_X86_64:
return "ELF64-x86-64";
+ case ELF::EM_PPC64:
+ return "ELF64-ppc64";
default:
return "ELF64-unknown";
}
@@ -2187,8 +2411,9 @@ StringRef ELFObjectFile<target_endianness, is64Bits>
}
}
-template<support::endianness target_endianness, bool is64Bits>
-unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+unsigned ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getArch() const {
switch(Header->e_machine) {
case ELF::EM_386:
return Triple::x86;
@@ -2201,13 +2426,16 @@ unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
case ELF::EM_MIPS:
return (target_endianness == support::little) ?
Triple::mipsel : Triple::mips;
+ case ELF::EM_PPC64:
+ return Triple::ppc64;
default:
return Triple::UnknownArch;
}
}
-template<support::endianness target_endianness, bool is64Bits>
-uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+uint64_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getNumSections() const {
assert(Header && "Header not initialized!");
if (Header->e_shnum == ELF::SHN_UNDEF) {
assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
@@ -2216,9 +2444,10 @@ uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const {
return Header->e_shnum;
}
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
uint64_t
-ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const {
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getStringTableIndex() const {
if (Header->e_shnum == ELF::SHN_UNDEF) {
if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
return SectionHeaderTable->sh_link;
@@ -2228,53 +2457,62 @@ ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const {
return Header->e_shstrndx;
}
-
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
template<typename T>
inline const T *
-ELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section,
- uint32_t Entry) const {
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getEntry(uint16_t Section, uint32_t Entry) const {
return getEntry<T>(getSection(Section), Entry);
}
-template<support::endianness target_endianness, bool is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
template<typename T>
inline const T *
-ELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section,
- uint32_t Entry) const {
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getEntry(const Elf_Shdr * Section, uint32_t Entry) const {
return reinterpret_cast<const T *>(
base()
+ Section->sh_offset
+ (Entry * Section->sh_entsize));
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
-ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Sym *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getSymbol(DataRefImpl Symb) const {
return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a);
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Dyn *
-ELFObjectFile<target_endianness, is64Bits>::getDyn(DataRefImpl DynData) const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Dyn *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getDyn(DataRefImpl DynData) const {
return getEntry<Elf_Dyn>(dot_dynamic_sec, DynData.d.a);
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel *
-ELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Rel *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getRel(DataRefImpl Rel) const {
return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela *
-ELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Rela *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getRela(DataRefImpl Rela) const {
return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
-ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Shdr *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getSection(DataRefImpl Symb) const {
const Elf_Shdr *sec = getSection(Symb.d.b);
if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM)
// FIXME: Proper error handling.
@@ -2282,9 +2520,11 @@ ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
return sec;
}
-template<support::endianness target_endianness, bool is64Bits>
-const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
-ELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const {
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::Elf_Shdr *
+ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ ::getSection(uint32_t index) const {
if (index == 0)
return 0;
if (!SectionHeaderTable || index >= getNumSections())
@@ -2296,15 +2536,15 @@ ELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const {
+ (index * Header->e_shentsize));
}
-template<support::endianness target_endianness, bool is64Bits>
-const char *ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const char *ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getString(uint32_t section,
ELF::Elf32_Word offset) const {
return getString(getSection(section), offset);
}
-template<support::endianness target_endianness, bool is64Bits>
-const char *ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+const char *ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getString(const Elf_Shdr *section,
ELF::Elf32_Word offset) const {
assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
@@ -2314,8 +2554,8 @@ const char *ELFObjectFile<target_endianness, is64Bits>
return (const char *)base() + section->sh_offset + offset;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolName(const Elf_Shdr *section,
const Elf_Sym *symb,
StringRef &Result) const {
@@ -2338,16 +2578,16 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSectionName(const Elf_Shdr *section,
StringRef &Result) const {
Result = StringRef(getString(dot_shstrtab_sec, section->sh_name));
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-error_code ELFObjectFile<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
::getSymbolVersion(const Elf_Shdr *section,
const Elf_Sym *symb,
StringRef &Version,
@@ -2429,50 +2669,50 @@ error_code ELFObjectFile<target_endianness, is64Bits>
return object_error::success;
}
-template<support::endianness target_endianness, bool is64Bits>
-inline DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline DynRefImpl<target_endianness, max_alignment, is64Bits>
::DynRefImpl(DataRefImpl DynP, const OwningType *Owner)
: DynPimpl(DynP)
, OwningObject(Owner) {}
-template<support::endianness target_endianness, bool is64Bits>
-inline bool DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline bool DynRefImpl<target_endianness, max_alignment, is64Bits>
::operator==(const DynRefImpl &Other) const {
return DynPimpl == Other.DynPimpl;
}
-template<support::endianness target_endianness, bool is64Bits>
-inline bool DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline bool DynRefImpl<target_endianness, max_alignment, is64Bits>
::operator <(const DynRefImpl &Other) const {
return DynPimpl < Other.DynPimpl;
}
-template<support::endianness target_endianness, bool is64Bits>
-inline error_code DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline error_code DynRefImpl<target_endianness, max_alignment, is64Bits>
::getNext(DynRefImpl &Result) const {
return OwningObject->getDynNext(DynPimpl, Result);
}
-template<support::endianness target_endianness, bool is64Bits>
-inline int64_t DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline int64_t DynRefImpl<target_endianness, max_alignment, is64Bits>
::getTag() const {
return OwningObject->getDyn(DynPimpl)->d_tag;
}
-template<support::endianness target_endianness, bool is64Bits>
-inline uint64_t DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline uint64_t DynRefImpl<target_endianness, max_alignment, is64Bits>
::getVal() const {
return OwningObject->getDyn(DynPimpl)->d_un.d_val;
}
-template<support::endianness target_endianness, bool is64Bits>
-inline uint64_t DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline uint64_t DynRefImpl<target_endianness, max_alignment, is64Bits>
::getPtr() const {
return OwningObject->getDyn(DynPimpl)->d_un.d_ptr;
}
-template<support::endianness target_endianness, bool is64Bits>
-inline DataRefImpl DynRefImpl<target_endianness, is64Bits>
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+inline DataRefImpl DynRefImpl<target_endianness, max_alignment, is64Bits>
::getRawDataRefImpl() const {
return DynPimpl;
}
@@ -2484,23 +2724,23 @@ static inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
StringRef &Version,
bool &IsDefault) {
// Little-endian 32-bit
- if (const ELFObjectFile<support::little, false> *ELFObj =
- dyn_cast<ELFObjectFile<support::little, false> >(Obj))
+ if (const ELFObjectFile<support::little, 4, false> *ELFObj =
+ dyn_cast<ELFObjectFile<support::little, 4, false> >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
// Big-endian 32-bit
- if (const ELFObjectFile<support::big, false> *ELFObj =
- dyn_cast<ELFObjectFile<support::big, false> >(Obj))
+ if (const ELFObjectFile<support::big, 4, false> *ELFObj =
+ dyn_cast<ELFObjectFile<support::big, 4, false> >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
// Little-endian 64-bit
- if (const ELFObjectFile<support::little, true> *ELFObj =
- dyn_cast<ELFObjectFile<support::little, true> >(Obj))
+ if (const ELFObjectFile<support::little, 8, true> *ELFObj =
+ dyn_cast<ELFObjectFile<support::little, 8, true> >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
// Big-endian 64-bit
- if (const ELFObjectFile<support::big, true> *ELFObj =
- dyn_cast<ELFObjectFile<support::big, true> >(Obj))
+ if (const ELFObjectFile<support::big, 8, true> *ELFObj =
+ dyn_cast<ELFObjectFile<support::big, 8, true> >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 0b73f94..ed7aabd 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -15,11 +15,11 @@
#ifndef LLVM_OBJECT_MACHO_H
#define LLVM_OBJECT_MACHO_H
-#include "llvm/Object/ObjectFile.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Object/MachOObject.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MachO.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/SmallVector.h"
namespace llvm {
namespace object {
@@ -44,12 +44,16 @@ public:
virtual unsigned getArch() const;
virtual StringRef getLoadName() const;
- MachOObject *getObject() { return MachOObj; }
+ // In a MachO file, sections have a segment name. This is used in the .o
+ // files. They have a single segment, but this field specifies which segment
+ // a section should be put in in the final object.
+ error_code getSectionFinalSegmentName(DataRefImpl Sec, StringRef &Res) const;
+
+ MachOObject *getObject() { return MachOObj.get(); }
static inline bool classof(const Binary *v) {
return v->isMachO();
}
- static inline bool classof(const MachOObjectFile *v) { return true; }
protected:
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
@@ -62,6 +66,7 @@ protected:
virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
virtual error_code getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const;
+ virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
@@ -76,6 +81,7 @@ protected:
bool &Res) const;
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S,
bool &Result) const;
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
@@ -103,7 +109,7 @@ protected:
virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
private:
- MachOObject *MachOObj;
+ OwningPtr<MachOObject> MachOObj;
mutable uint32_t RegisteredStringTable;
typedef SmallVector<DataRefImpl, 1> SectionList;
SectionList Sections;
diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h
index e4bfcc6..a17d58d 100644
--- a/include/llvm/Object/MachOFormat.h
+++ b/include/llvm/Object/MachOFormat.h
@@ -61,7 +61,10 @@ namespace mach {
CSARM_V6 = 6,
CSARM_V5TEJ = 7,
CSARM_XSCALE = 8,
- CSARM_V7 = 9
+ CSARM_V7 = 9,
+ CSARM_V7F = 10,
+ CSARM_V7S = 11,
+ CSARM_V7K = 12
};
/// \brief PowerPC Machine Subtypes.
@@ -234,6 +237,10 @@ namespace macho {
/// @name Section Data
/// @{
+ enum SectionFlags {
+ SF_PureInstructions = 0x80000000
+ };
+
struct Section {
char Name[16];
char SegmentName[16];
diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h
index 86f150a..e32a85d 100644
--- a/include/llvm/Object/MachOObject.h
+++ b/include/llvm/Object/MachOObject.h
@@ -10,11 +10,11 @@
#ifndef LLVM_OBJECT_MACHOOBJECT_H
#define LLVM_OBJECT_MACHOOBJECT_H
-#include <string>
#include "llvm/ADT/InMemoryStruct.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/MachOFormat.h"
+#include <string>
namespace llvm {
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 2ec656b..e63f554 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -14,8 +14,8 @@
#ifndef LLVM_OBJECT_OBJECT_FILE_H
#define LLVM_OBJECT_OBJECT_FILE_H
-#include "llvm/Object/Binary.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -76,13 +76,13 @@ public:
}
};
-inline bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
+inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
// Check bitwise identical. This is the only legal way to compare a union w/o
// knowing which member is in use.
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
}
-inline bool operator <(const DataRefImpl &a, const DataRefImpl &b) {
+inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
// Check bitwise identical. This is the only legal way to compare a union w/o
// knowing which member is in use.
return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
@@ -144,7 +144,7 @@ public:
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
bool operator==(const SectionRef &Other) const;
- bool operator <(const SectionRef &Other) const;
+ bool operator<(const SectionRef &Other) const;
error_code getNext(SectionRef &Result) const;
@@ -163,6 +163,7 @@ public:
error_code isRequiredForExecution(bool &Result) const;
error_code isVirtual(bool &Result) const;
error_code isZeroInit(bool &Result) const;
+ error_code isReadOnlyData(bool &Result) const;
error_code containsSymbol(SymbolRef S, bool &Result) const;
@@ -207,11 +208,13 @@ public:
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
bool operator==(const SymbolRef &Other) const;
- bool operator <(const SymbolRef &Other) const;
+ bool operator<(const SymbolRef &Other) const;
error_code getNext(SymbolRef &Result) const;
error_code getName(StringRef &Result) const;
+ /// Returns the symbol virtual address (i.e. address at which it will be
+ /// mapped).
error_code getAddress(uint64_t &Result) const;
error_code getFileOffset(uint64_t &Result) const;
error_code getSize(uint64_t &Result) const;
@@ -231,6 +234,9 @@ public:
/// end_sections() if it is undefined or is an absolute symbol.
error_code getSection(section_iterator &Result) const;
+ /// @brief Get value of the symbol in the symbol table.
+ error_code getValue(uint64_t &Val) const;
+
DataRefImpl getRawDataRefImpl() const;
};
typedef content_iterator<SymbolRef> symbol_iterator;
@@ -248,7 +254,7 @@ public:
LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
bool operator==(const LibraryRef &Other) const;
- bool operator <(const LibraryRef &Other) const;
+ bool operator<(const LibraryRef &Other) const;
error_code getNext(LibraryRef &Result) const;
@@ -263,11 +269,11 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
/// ObjectFile - This class is the base class for all object file types.
/// Concrete instances of this object are created by createObjectFile, which
-/// figure out which type to create.
+/// figures out which type to create.
class ObjectFile : public Binary {
virtual void anchor();
- ObjectFile(); // = delete
- ObjectFile(const ObjectFile &other); // = delete
+ ObjectFile() LLVM_DELETED_FUNCTION;
+ ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
protected:
ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
@@ -287,8 +293,8 @@ protected:
friend class SymbolRef;
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
- virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0;
- virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const =0;
+ virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0;
+ virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0;
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
virtual error_code getSymbolType(DataRefImpl Symb,
SymbolRef::Type &Res) const = 0;
@@ -297,6 +303,7 @@ protected:
uint32_t &Res) const = 0;
virtual error_code getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const = 0;
+ virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0;
// Same as above for SectionRef.
friend class SectionRef;
@@ -314,6 +321,7 @@ protected:
// A section is 'virtual' if its contents aren't present in the object image.
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0;
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0;
+ virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const =0;
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
bool &Result) const = 0;
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0;
@@ -384,7 +392,6 @@ public:
static inline bool classof(const Binary *v) {
return v->isObject();
}
- static inline bool classof(const ObjectFile *v) { return true; }
public:
static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
@@ -401,7 +408,7 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const {
return SymbolPimpl == Other.SymbolPimpl;
}
-inline bool SymbolRef::operator <(const SymbolRef &Other) const {
+inline bool SymbolRef::operator<(const SymbolRef &Other) const {
return SymbolPimpl < Other.SymbolPimpl;
}
@@ -441,6 +448,10 @@ inline error_code SymbolRef::getType(SymbolRef::Type &Result) const {
return OwningObject->getSymbolType(SymbolPimpl, Result);
}
+inline error_code SymbolRef::getValue(uint64_t &Val) const {
+ return OwningObject->getSymbolValue(SymbolPimpl, Val);
+}
+
inline DataRefImpl SymbolRef::getRawDataRefImpl() const {
return SymbolPimpl;
}
@@ -456,7 +467,7 @@ inline bool SectionRef::operator==(const SectionRef &Other) const {
return SectionPimpl == Other.SectionPimpl;
}
-inline bool SectionRef::operator <(const SectionRef &Other) const {
+inline bool SectionRef::operator<(const SectionRef &Other) const {
return SectionPimpl < Other.SectionPimpl;
}
@@ -508,6 +519,10 @@ inline error_code SectionRef::isZeroInit(bool &Result) const {
return OwningObject->isSectionZeroInit(SectionPimpl, Result);
}
+inline error_code SectionRef::isReadOnlyData(bool &Result) const {
+ return OwningObject->isSectionReadOnlyData(SectionPimpl, Result);
+}
+
inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
Result);
@@ -586,7 +601,7 @@ inline bool LibraryRef::operator==(const LibraryRef &Other) const {
return LibraryPimpl == Other.LibraryPimpl;
}
-inline bool LibraryRef::operator <(const LibraryRef &Other) const {
+inline bool LibraryRef::operator<(const LibraryRef &Other) const {
return LibraryPimpl < Other.LibraryPimpl;
}
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
new file mode 100644
index 0000000..2c2dd03
--- /dev/null
+++ b/include/llvm/Object/RelocVisitor.h
@@ -0,0 +1,146 @@
+//===-- RelocVisitor.h - Visitor for object file relocations -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around all the different types of relocations
+// in different file formats, such that a client can handle them in a unified
+// manner by only implementing a minimal number of functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LLVM_OBJECT_RELOCVISITOR
+#define _LLVM_OBJECT_RELOCVISITOR
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace object {
+
+struct RelocToApply {
+ // The computed value after applying the relevant relocations.
+ int64_t Value;
+
+ // The width of the value; how many bytes to touch when applying the
+ // relocation.
+ char Width;
+ RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) {}
+ RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
+ RelocToApply() : Value(0), Width(0) {}
+};
+
+/// @brief Base class for object file relocation visitors.
+class RelocVisitor {
+public:
+ explicit RelocVisitor(llvm::StringRef FileFormat)
+ : FileFormat(FileFormat), HasError(false) {}
+
+ // TODO: Should handle multiple applied relocations via either passing in the
+ // previously computed value or just count paired relocations as a single
+ // visit.
+ RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
+ uint64_t Value = 0) {
+ if (FileFormat == "ELF64-x86-64") {
+ switch (RelocType) {
+ case llvm::ELF::R_X86_64_NONE:
+ return visitELF_X86_64_NONE(R);
+ case llvm::ELF::R_X86_64_64:
+ return visitELF_X86_64_64(R, Value);
+ case llvm::ELF::R_X86_64_PC32:
+ return visitELF_X86_64_PC32(R, Value, SecAddr);
+ case llvm::ELF::R_X86_64_32:
+ return visitELF_X86_64_32(R, Value);
+ case llvm::ELF::R_X86_64_32S:
+ return visitELF_X86_64_32S(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ } else if (FileFormat == "ELF32-i386") {
+ switch (RelocType) {
+ case llvm::ELF::R_386_NONE:
+ return visitELF_386_NONE(R);
+ case llvm::ELF::R_386_32:
+ return visitELF_386_32(R, Value);
+ case llvm::ELF::R_386_PC32:
+ return visitELF_386_PC32(R, Value, SecAddr);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ }
+ return RelocToApply();
+ }
+
+ bool error() { return HasError; }
+
+private:
+ llvm::StringRef FileFormat;
+ bool HasError;
+
+ /// Operations
+
+ /// 386-ELF
+ RelocToApply visitELF_386_NONE(RelocationRef R) {
+ return RelocToApply(0, 0);
+ }
+
+ // Ideally the Addend here will be the addend in the data for
+ // the relocation. It's not actually the case for Rel relocations.
+ RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ return RelocToApply(Value + Addend, 4);
+ }
+
+ RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value,
+ uint64_t SecAddr) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ uint64_t Address;
+ R.getAddress(Address);
+ return RelocToApply(Value + Addend - Address, 4);
+ }
+
+ /// X86-64 ELF
+ RelocToApply visitELF_X86_64_NONE(RelocationRef R) {
+ return RelocToApply(0, 0);
+ }
+ RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ return RelocToApply(Value + Addend, 8);
+ }
+ RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value,
+ uint64_t SecAddr) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ uint64_t Address;
+ R.getAddress(Address);
+ return RelocToApply(Value + Addend - Address, 4);
+ }
+ RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+ return RelocToApply(Res, 4);
+ }
+ RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ int32_t Res = (Value + Addend) & 0xFFFFFFFF;
+ return RelocToApply(Res, 4);
+ }
+};
+
+}
+}
+#endif
diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h
new file mode 100644
index 0000000..baa4b6a
--- /dev/null
+++ b/include/llvm/Option/Arg.h
@@ -0,0 +1,132 @@
+//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the llvm::Arg class for parsed arguments.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARG_H_
+#define LLVM_SUPPORT_ARG_H_
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <string>
+
+namespace llvm {
+namespace opt {
+class ArgList;
+
+/// \brief A concrete instance of a particular driver option.
+///
+/// The Arg class encodes just enough information to be able to
+/// derive the argument values efficiently. In addition, Arg
+/// instances have an intrusive double linked list which is used by
+/// ArgList to provide efficient iteration over all instances of a
+/// particular option.
+class Arg {
+ Arg(const Arg &) LLVM_DELETED_FUNCTION;
+ void operator=(const Arg &) LLVM_DELETED_FUNCTION;
+
+private:
+ /// \brief The option this argument is an instance of.
+ const Option Opt;
+
+ /// \brief The argument this argument was derived from (during tool chain
+ /// argument translation), if any.
+ const Arg *BaseArg;
+
+ /// \brief How this instance of the option was spelled.
+ StringRef Spelling;
+
+ /// \brief The index at which this argument appears in the containing
+ /// ArgList.
+ unsigned Index;
+
+ /// \brief Was this argument used to effect compilation?
+ ///
+ /// This is used for generating "argument unused" diagnostics.
+ mutable unsigned Claimed : 1;
+
+ /// \brief Does this argument own its values?
+ mutable unsigned OwnsValues : 1;
+
+ /// \brief The argument values, as C strings.
+ SmallVector<const char *, 2> Values;
+
+public:
+ Arg(const Option Opt, StringRef Spelling, unsigned Index,
+ const Arg *BaseArg = 0);
+ Arg(const Option Opt, StringRef Spelling, unsigned Index,
+ const char *Value0, const Arg *BaseArg = 0);
+ Arg(const Option Opt, StringRef Spelling, unsigned Index,
+ const char *Value0, const char *Value1, const Arg *BaseArg = 0);
+ ~Arg();
+
+ const Option getOption() const { return Opt; }
+ StringRef getSpelling() const { return Spelling; }
+ unsigned getIndex() const { return Index; }
+
+ /// \brief Return the base argument which generated this arg.
+ ///
+ /// This is either the argument itself or the argument it was
+ /// derived from during tool chain specific argument translation.
+ const Arg &getBaseArg() const {
+ return BaseArg ? *BaseArg : *this;
+ }
+ void setBaseArg(const Arg *_BaseArg) {
+ BaseArg = _BaseArg;
+ }
+
+ bool getOwnsValues() const { return OwnsValues; }
+ void setOwnsValues(bool Value) const { OwnsValues = Value; }
+
+ bool isClaimed() const { return getBaseArg().Claimed; }
+
+ /// \brief Set the Arg claimed bit.
+ void claim() const { getBaseArg().Claimed = true; }
+
+ unsigned getNumValues() const { return Values.size(); }
+ const char *getValue(unsigned N = 0) const {
+ return Values[N];
+ }
+
+ SmallVectorImpl<const char*> &getValues() {
+ return Values;
+ }
+
+ bool containsValue(StringRef Value) const {
+ for (unsigned i = 0, e = getNumValues(); i != e; ++i)
+ if (Values[i] == Value)
+ return true;
+ return false;
+ }
+
+ /// \brief Append the argument onto the given array as strings.
+ void render(const ArgList &Args, ArgStringList &Output) const;
+
+ /// \brief Append the argument, render as an input, onto the given
+ /// array as strings.
+ ///
+ /// The distinction is that some options only render their values
+ /// when rendered as a input (e.g., Xlinker).
+ void renderAsInput(const ArgList &Args, ArgStringList &Output) const;
+
+ void dump() const;
+
+ /// \brief Return a formatted version of the argument and
+ /// its values, for debugging and diagnostics.
+ std::string getAsString(const ArgList &Args) const;
+};
+
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
new file mode 100644
index 0000000..378b58a
--- /dev/null
+++ b/include/llvm/Option/ArgList.h
@@ -0,0 +1,414 @@
+//===--- ArgList.h - Argument List Management -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARGLIST_H_
+#define LLVM_SUPPORT_ARGLIST_H_
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/OptSpecifier.h"
+#include "llvm/Option/Option.h"
+#include <list>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace opt {
+class Arg;
+class ArgList;
+class Option;
+
+/// arg_iterator - Iterates through arguments stored inside an ArgList.
+class arg_iterator {
+ /// The current argument.
+ SmallVectorImpl<Arg*>::const_iterator Current;
+
+ /// The argument list we are iterating over.
+ const ArgList &Args;
+
+ /// Optional filters on the arguments which will be match. Most clients
+ /// should never want to iterate over arguments without filters, so we won't
+ /// bother to factor this into two separate iterator implementations.
+ //
+ // FIXME: Make efficient; the idea is to provide efficient iteration over
+ // all arguments which match a particular id and then just provide an
+ // iterator combinator which takes multiple iterators which can be
+ // efficiently compared and returns them in order.
+ OptSpecifier Id0, Id1, Id2;
+
+ void SkipToNextArg();
+
+public:
+ typedef Arg * const * value_type;
+ typedef Arg * const & reference;
+ typedef Arg * const * pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ arg_iterator(SmallVectorImpl<Arg*>::const_iterator it,
+ const ArgList &_Args, OptSpecifier _Id0 = 0U,
+ OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
+ : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+ SkipToNextArg();
+ }
+
+ operator const Arg*() { return *Current; }
+ reference operator*() const { return *Current; }
+ pointer operator->() const { return Current; }
+
+ arg_iterator &operator++() {
+ ++Current;
+ SkipToNextArg();
+ return *this;
+ }
+
+ arg_iterator operator++(int) {
+ arg_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
+ return LHS.Current == RHS.Current;
+ }
+ friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
+ return !(LHS == RHS);
+ }
+};
+
+/// ArgList - Ordered collection of driver arguments.
+///
+/// The ArgList class manages a list of Arg instances as well as
+/// auxiliary data and convenience methods to allow Tools to quickly
+/// check for the presence of Arg instances for a particular Option
+/// and to iterate over groups of arguments.
+class ArgList {
+private:
+ ArgList(const ArgList &) LLVM_DELETED_FUNCTION;
+ void operator=(const ArgList &) LLVM_DELETED_FUNCTION;
+
+public:
+ typedef SmallVector<Arg*, 16> arglist_type;
+ typedef arglist_type::iterator iterator;
+ typedef arglist_type::const_iterator const_iterator;
+ typedef arglist_type::reverse_iterator reverse_iterator;
+ typedef arglist_type::const_reverse_iterator const_reverse_iterator;
+
+private:
+ /// The internal list of arguments.
+ arglist_type Args;
+
+protected:
+ ArgList();
+
+public:
+ virtual ~ArgList();
+
+ /// @name Arg Access
+ /// @{
+
+ /// append - Append \p A to the arg list.
+ void append(Arg *A);
+
+ arglist_type &getArgs() { return Args; }
+ const arglist_type &getArgs() const { return Args; }
+
+ unsigned size() const { return Args.size(); }
+
+ /// @}
+ /// @name Arg Iteration
+ /// @{
+
+ iterator begin() { return Args.begin(); }
+ iterator end() { return Args.end(); }
+
+ reverse_iterator rbegin() { return Args.rbegin(); }
+ reverse_iterator rend() { return Args.rend(); }
+
+ const_iterator begin() const { return Args.begin(); }
+ const_iterator end() const { return Args.end(); }
+
+ const_reverse_iterator rbegin() const { return Args.rbegin(); }
+ const_reverse_iterator rend() const { return Args.rend(); }
+
+ arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+ OptSpecifier Id2 = 0U) const {
+ return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
+ }
+ arg_iterator filtered_end() const {
+ return arg_iterator(Args.end(), *this);
+ }
+
+ /// @}
+ /// @name Arg Removal
+ /// @{
+
+ /// eraseArg - Remove any option matching \p Id.
+ void eraseArg(OptSpecifier Id);
+
+ /// @}
+ /// @name Arg Access
+ /// @{
+
+ /// hasArg - Does the arg list contain any option matching \p Id.
+ ///
+ /// \p Claim Whether the argument should be claimed, if it exists.
+ bool hasArgNoClaim(OptSpecifier Id) const {
+ return getLastArgNoClaim(Id) != 0;
+ }
+ bool hasArg(OptSpecifier Id) const {
+ return getLastArg(Id) != 0;
+ }
+ bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
+ return getLastArg(Id0, Id1) != 0;
+ }
+ bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
+ return getLastArg(Id0, Id1, Id2) != 0;
+ }
+
+ /// getLastArg - Return the last argument matching \p Id, or null.
+ ///
+ /// \p Claim Whether the argument should be claimed, if it exists.
+ Arg *getLastArgNoClaim(OptSpecifier Id) const;
+ Arg *getLastArg(OptSpecifier Id) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+ OptSpecifier Id3) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+ OptSpecifier Id3, OptSpecifier Id4) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+ OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+ OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
+ OptSpecifier Id6) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+ OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
+ OptSpecifier Id6, OptSpecifier Id7) const;
+
+ /// getArgString - Return the input argument string at \p Index.
+ virtual const char *getArgString(unsigned Index) const = 0;
+
+ /// getNumInputArgStrings - Return the number of original argument strings,
+ /// which are guaranteed to be the first strings in the argument string
+ /// list.
+ virtual unsigned getNumInputArgStrings() const = 0;
+
+ /// @}
+ /// @name Argument Lookup Utilities
+ /// @{
+
+ /// getLastArgValue - Return the value of the last argument, or a default.
+ StringRef getLastArgValue(OptSpecifier Id,
+ StringRef Default = "") const;
+
+ /// getAllArgValues - Get the values of all instances of the given argument
+ /// as strings.
+ std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
+
+ /// @}
+ /// @name Translation Utilities
+ /// @{
+
+ /// hasFlag - Given an option \p Pos and its negative form \p Neg, return
+ /// true if the option is present, false if the negation is present, and
+ /// \p Default if neither option is given. If both the option and its
+ /// negation are present, the last one wins.
+ bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
+
+ /// AddLastArg - Render only the last argument match \p Id0, if present.
+ void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
+
+ /// AddAllArgs - Render all arguments matching the given ids.
+ void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+ /// AddAllArgValues - Render the argument values of all arguments
+ /// matching the given ids.
+ void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+ /// AddAllArgsTranslated - Render all the arguments matching the
+ /// given ids, but forced to separate args and using the provided
+ /// name instead of the first option value.
+ ///
+ /// \param Joined - If true, render the argument as joined with
+ /// the option specifier.
+ void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
+ const char *Translation,
+ bool Joined = false) const;
+
+ /// ClaimAllArgs - Claim all arguments which match the given
+ /// option id.
+ void ClaimAllArgs(OptSpecifier Id0) const;
+
+ /// ClaimAllArgs - Claim all arguments.
+ ///
+ void ClaimAllArgs() const;
+
+ /// @}
+ /// @name Arg Synthesis
+ /// @{
+
+ /// MakeArgString - Construct a constant string pointer whose
+ /// lifetime will match that of the ArgList.
+ virtual const char *MakeArgString(StringRef Str) const = 0;
+ const char *MakeArgString(const char *Str) const {
+ return MakeArgString(StringRef(Str));
+ }
+ const char *MakeArgString(std::string Str) const {
+ return MakeArgString(StringRef(Str));
+ }
+ const char *MakeArgString(const Twine &Str) const;
+
+ /// \brief Create an arg string for (\p LHS + \p RHS), reusing the
+ /// string at \p Index if possible.
+ const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS,
+ StringRef RHS) const;
+
+ /// @}
+};
+
+class InputArgList : public ArgList {
+private:
+ /// List of argument strings used by the contained Args.
+ ///
+ /// This is mutable since we treat the ArgList as being the list
+ /// of Args, and allow routines to add new strings (to have a
+ /// convenient place to store the memory) via MakeIndex.
+ mutable ArgStringList ArgStrings;
+
+ /// Strings for synthesized arguments.
+ ///
+ /// This is mutable since we treat the ArgList as being the list
+ /// of Args, and allow routines to add new strings (to have a
+ /// convenient place to store the memory) via MakeIndex.
+ mutable std::list<std::string> SynthesizedStrings;
+
+ /// The number of original input argument strings.
+ unsigned NumInputArgStrings;
+
+public:
+ InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
+ ~InputArgList();
+
+ virtual const char *getArgString(unsigned Index) const {
+ return ArgStrings[Index];
+ }
+
+ virtual unsigned getNumInputArgStrings() const {
+ return NumInputArgStrings;
+ }
+
+ /// @name Arg Synthesis
+ /// @{
+
+public:
+ /// MakeIndex - Get an index for the given string(s).
+ unsigned MakeIndex(StringRef String0) const;
+ unsigned MakeIndex(StringRef String0, StringRef String1) const;
+
+ virtual const char *MakeArgString(StringRef Str) const;
+
+ /// @}
+};
+
+/// DerivedArgList - An ordered collection of driver arguments,
+/// whose storage may be in another argument list.
+class DerivedArgList : public ArgList {
+ const InputArgList &BaseArgs;
+
+ /// The list of arguments we synthesized.
+ mutable arglist_type SynthesizedArgs;
+
+public:
+ /// Construct a new derived arg list from \p BaseArgs.
+ DerivedArgList(const InputArgList &BaseArgs);
+ ~DerivedArgList();
+
+ virtual const char *getArgString(unsigned Index) const {
+ return BaseArgs.getArgString(Index);
+ }
+
+ virtual unsigned getNumInputArgStrings() const {
+ return BaseArgs.getNumInputArgStrings();
+ }
+
+ const InputArgList &getBaseArgs() const {
+ return BaseArgs;
+ }
+
+ /// @name Arg Synthesis
+ /// @{
+
+ /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
+ /// (to be freed).
+ void AddSynthesizedArg(Arg *A) {
+ SynthesizedArgs.push_back(A);
+ }
+
+ virtual const char *MakeArgString(StringRef Str) const;
+
+ /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
+ /// append it to the argument list.
+ void AddFlagArg(const Arg *BaseArg, const Option Opt) {
+ append(MakeFlagArg(BaseArg, Opt));
+ }
+
+ /// AddPositionalArg - Construct a new Positional arg for the given option
+ /// \p Id, with the provided \p Value and append it to the argument
+ /// list.
+ void AddPositionalArg(const Arg *BaseArg, const Option Opt,
+ StringRef Value) {
+ append(MakePositionalArg(BaseArg, Opt, Value));
+ }
+
+
+ /// AddSeparateArg - Construct a new Positional arg for the given option
+ /// \p Id, with the provided \p Value and append it to the argument
+ /// list.
+ void AddSeparateArg(const Arg *BaseArg, const Option Opt,
+ StringRef Value) {
+ append(MakeSeparateArg(BaseArg, Opt, Value));
+ }
+
+
+ /// AddJoinedArg - Construct a new Positional arg for the given option
+ /// \p Id, with the provided \p Value and append it to the argument list.
+ void AddJoinedArg(const Arg *BaseArg, const Option Opt,
+ StringRef Value) {
+ append(MakeJoinedArg(BaseArg, Opt, Value));
+ }
+
+
+ /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
+ Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
+
+ /// MakePositionalArg - Construct a new Positional arg for the
+ /// given option \p Id, with the provided \p Value.
+ Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt,
+ StringRef Value) const;
+
+ /// MakeSeparateArg - Construct a new Positional arg for the
+ /// given option \p Id, with the provided \p Value.
+ Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt,
+ StringRef Value) const;
+
+ /// MakeJoinedArg - Construct a new Positional arg for the
+ /// given option \p Id, with the provided \p Value.
+ Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt,
+ StringRef Value) const;
+
+ /// @}
+};
+
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Option/OptParser.td b/include/llvm/Option/OptParser.td
new file mode 100644
index 0000000..e781fa0
--- /dev/null
+++ b/include/llvm/Option/OptParser.td
@@ -0,0 +1,127 @@
+//===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
+//
+// 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 common interfaces used by the option parsing TableGen
+// backend.
+//
+//===----------------------------------------------------------------------===//
+
+// Define the kinds of options.
+
+class OptionKind<string name, int predecence = 0, bit sentinel = 0> {
+ string Name = name;
+ // The kind precedence, kinds with lower precedence are matched first.
+ int Precedence = predecence;
+ // Indicate a sentinel option.
+ bit Sentinel = sentinel;
+}
+
+// An option group.
+def KIND_GROUP : OptionKind<"Group">;
+// The input option kind.
+def KIND_INPUT : OptionKind<"Input", 1, 1>;
+// The unknown option kind.
+def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>;
+// A flag with no values.
+def KIND_FLAG : OptionKind<"Flag">;
+// An option which prefixes its (single) value.
+def KIND_JOINED : OptionKind<"Joined", 1>;
+// An option which is followed by its value.
+def KIND_SEPARATE : OptionKind<"Separate">;
+// An option followed by its values, which are separated by commas.
+def KIND_COMMAJOINED : OptionKind<"CommaJoined">;
+// An option which is which takes multiple (separate) arguments.
+def KIND_MULTIARG : OptionKind<"MultiArg">;
+// An option which is either joined to its (non-empty) value, or followed by its
+// value.
+def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
+// An option which is both joined to its (first) value, and followed by its
+// (second) value.
+def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
+
+// Define the option flags.
+
+class OptionFlag {}
+
+// HelpHidden - The option should not be displayed in --help, even if it has
+// help text. Clients *can* use this in conjunction with the OptTable::PrintHelp
+// arguments to implement hidden help groups.
+def HelpHidden : OptionFlag;
+
+// RenderAsInput - The option should not render the name when rendered as an
+// input (i.e., the option is rendered as values).
+def RenderAsInput : OptionFlag;
+
+// RenderJoined - The option should be rendered joined, even if separate (only
+// sensible on single value separate options).
+def RenderJoined : OptionFlag;
+
+// RenderSeparate - The option should be rendered separately, even if joined
+// (only sensible on joined options).
+def RenderSeparate : OptionFlag;
+
+// Define the option group class.
+
+class OptionGroup<string name> {
+ string EnumName = ?; // Uses the def name if undefined.
+ string Name = name;
+ string HelpText = ?;
+ OptionGroup Group = ?;
+}
+
+// Define the option class.
+
+class Option<list<string> prefixes, string name, OptionKind kind> {
+ string EnumName = ?; // Uses the def name if undefined.
+ list<string> Prefixes = prefixes;
+ string Name = name;
+ OptionKind Kind = kind;
+ // Used by MultiArg option kind.
+ int NumArgs = 0;
+ string HelpText = ?;
+ string MetaVarName = ?;
+ list<OptionFlag> Flags = [];
+ OptionGroup Group = ?;
+ Option Alias = ?;
+}
+
+// Helpers for defining options.
+
+class Flag<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_FLAG>;
+class Joined<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_JOINED>;
+class Separate<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_SEPARATE>;
+class CommaJoined<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_COMMAJOINED>;
+class MultiArg<list<string> prefixes, string name, int numargs>
+ : Option<prefixes, name, KIND_MULTIARG> {
+ int NumArgs = numargs;
+}
+class JoinedOrSeparate<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>;
+class JoinedAndSeparate<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>;
+
+// Mix-ins for adding optional attributes.
+
+class Alias<Option alias> { Option Alias = alias; }
+class EnumName<string name> { string EnumName = name; }
+class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
+class Group<OptionGroup group> { OptionGroup Group = group; }
+class HelpText<string text> { string HelpText = text; }
+class MetaVarName<string name> { string MetaVarName = name; }
+
+// Predefined options.
+
+// FIXME: Have generator validate that these appear in correct position (and
+// aren't duplicated).
+def INPUT : Option<[], "<input>", KIND_INPUT>;
+def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>;
diff --git a/include/llvm/Option/OptSpecifier.h b/include/llvm/Option/OptSpecifier.h
new file mode 100644
index 0000000..3bc9bb2
--- /dev/null
+++ b/include/llvm/Option/OptSpecifier.h
@@ -0,0 +1,39 @@
+//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OPTSPECIFIER_H
+#define LLVM_SUPPORT_OPTSPECIFIER_H
+
+namespace llvm {
+namespace opt {
+ class Option;
+
+ /// OptSpecifier - Wrapper class for abstracting references to option IDs.
+ class OptSpecifier {
+ unsigned ID;
+
+ private:
+ explicit OptSpecifier(bool); // DO NOT IMPLEMENT
+
+ public:
+ OptSpecifier() : ID(0) {}
+ /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
+ /*implicit*/ OptSpecifier(const Option *Opt);
+
+ bool isValid() const { return ID != 0; }
+
+ unsigned getID() const { return ID; }
+
+ bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
+ bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
+ };
+}
+}
+
+#endif
diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h
new file mode 100644
index 0000000..930549f
--- /dev/null
+++ b/include/llvm/Option/OptTable.h
@@ -0,0 +1,161 @@
+//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OPTTABLE_H
+#define LLVM_SUPPORT_OPTTABLE_H
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Option/OptSpecifier.h"
+
+namespace llvm {
+class raw_ostream;
+namespace opt {
+class Arg;
+class ArgList;
+class InputArgList;
+class Option;
+
+/// \brief Provide access to the Option info table.
+///
+/// The OptTable class provides a layer of indirection which allows Option
+/// instance to be created lazily. In the common case, only a few options will
+/// be needed at runtime; the OptTable class maintains enough information to
+/// parse command lines without instantiating Options, while letting other
+/// parts of the driver still use Option instances where convenient.
+class OptTable {
+public:
+ /// \brief Entry for a single option instance in the option data table.
+ struct Info {
+ /// A null terminated array of prefix strings to apply to name while
+ /// matching.
+ const char *const *Prefixes;
+ const char *Name;
+ const char *HelpText;
+ const char *MetaVar;
+ unsigned ID;
+ unsigned char Kind;
+ unsigned char Param;
+ unsigned short Flags;
+ unsigned short GroupID;
+ unsigned short AliasID;
+ };
+
+private:
+ /// \brief The static option information table.
+ const Info *OptionInfos;
+ unsigned NumOptionInfos;
+
+ unsigned TheInputOptionID;
+ unsigned TheUnknownOptionID;
+
+ /// The index of the first option which can be parsed (i.e., is not a
+ /// special option like 'input' or 'unknown', and is not an option group).
+ unsigned FirstSearchableIndex;
+
+ /// The union of all option prefixes. If an argument does not begin with
+ /// one of these, it is an input.
+ StringSet<> PrefixesUnion;
+ std::string PrefixChars;
+
+private:
+ const Info &getInfo(OptSpecifier Opt) const {
+ unsigned id = Opt.getID();
+ assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
+ return OptionInfos[id - 1];
+ }
+
+protected:
+ OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
+public:
+ ~OptTable();
+
+ /// \brief Return the total number of option classes.
+ unsigned getNumOptions() const { return NumOptionInfos; }
+
+ /// \brief Get the given Opt's Option instance, lazily creating it
+ /// if necessary.
+ ///
+ /// \return The option, or null for the INVALID option id.
+ const Option getOption(OptSpecifier Opt) const;
+
+ /// \brief Lookup the name of the given option.
+ const char *getOptionName(OptSpecifier id) const {
+ return getInfo(id).Name;
+ }
+
+ /// \brief Get the kind of the given option.
+ unsigned getOptionKind(OptSpecifier id) const {
+ return getInfo(id).Kind;
+ }
+
+ /// \brief Get the group id for the given option.
+ unsigned getOptionGroupID(OptSpecifier id) const {
+ return getInfo(id).GroupID;
+ }
+
+ /// \brief Should the help for the given option be hidden by default.
+ bool isOptionHelpHidden(OptSpecifier id) const;
+
+ /// \brief Get the help text to use to describe this option.
+ const char *getOptionHelpText(OptSpecifier id) const {
+ return getInfo(id).HelpText;
+ }
+
+ /// \brief Get the meta-variable name to use when describing
+ /// this options values in the help text.
+ const char *getOptionMetaVar(OptSpecifier id) const {
+ return getInfo(id).MetaVar;
+ }
+
+ /// \brief Parse a single argument; returning the new argument and
+ /// updating Index.
+ ///
+ /// \param [in,out] Index - The current parsing position in the argument
+ /// string list; on return this will be the index of the next argument
+ /// string to parse.
+ ///
+ /// \return The parsed argument, or 0 if the argument is missing values
+ /// (in which case Index still points at the conceptual next argument string
+ /// to parse).
+ Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const;
+
+ /// \brief Parse an list of arguments into an InputArgList.
+ ///
+ /// The resulting InputArgList will reference the strings in [\p ArgBegin,
+ /// \p ArgEnd), and their lifetime should extend past that of the returned
+ /// InputArgList.
+ ///
+ /// The only error that can occur in this routine is if an argument is
+ /// missing values; in this case \p MissingArgCount will be non-zero.
+ ///
+ /// \param ArgBegin - The beginning of the argument vector.
+ /// \param ArgEnd - The end of the argument vector.
+ /// \param MissingArgIndex - On error, the index of the option which could
+ /// not be parsed.
+ /// \param MissingArgCount - On error, the number of missing options.
+ /// \return An InputArgList; on error this will contain all the options
+ /// which could be parsed.
+ InputArgList *ParseArgs(const char* const *ArgBegin,
+ const char* const *ArgEnd,
+ unsigned &MissingArgIndex,
+ unsigned &MissingArgCount) const;
+
+ /// \brief Render the help text for an option table.
+ ///
+ /// \param OS - The stream to write the help text to.
+ /// \param Name - The name to use in the usage line.
+ /// \param Title - The title to use in the usage line.
+ /// \param ShowHidden - Whether help-hidden arguments should be shown.
+ void PrintHelp(raw_ostream &OS, const char *Name,
+ const char *Title, bool ShowHidden = false) const;
+};
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h
new file mode 100644
index 0000000..ee5eec4
--- /dev/null
+++ b/include/llvm/Option/Option.h
@@ -0,0 +1,193 @@
+//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OPTION_H_
+#define LLVM_SUPPORT_OPTION_H_
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+namespace opt {
+class Arg;
+class ArgList;
+/// ArgStringList - Type used for constructing argv lists for subprocesses.
+typedef SmallVector<const char*, 16> ArgStringList;
+
+/// Base flags for all options. Custom flags may be added after.
+enum DriverFlag {
+ HelpHidden = (1 << 0),
+ RenderAsInput = (1 << 1),
+ RenderJoined = (1 << 2),
+ RenderSeparate = (1 << 3)
+};
+
+/// Option - Abstract representation for a single form of driver
+/// argument.
+///
+/// An Option class represents a form of option that the driver
+/// takes, for example how many arguments the option has and how
+/// they can be provided. Individual option instances store
+/// additional information about what group the option is a member
+/// of (if any), if the option is an alias, and a number of
+/// flags. At runtime the driver parses the command line into
+/// concrete Arg instances, each of which corresponds to a
+/// particular Option instance.
+class Option {
+public:
+ enum OptionClass {
+ GroupClass = 0,
+ InputClass,
+ UnknownClass,
+ FlagClass,
+ JoinedClass,
+ SeparateClass,
+ CommaJoinedClass,
+ MultiArgClass,
+ JoinedOrSeparateClass,
+ JoinedAndSeparateClass
+ };
+
+ enum RenderStyleKind {
+ RenderCommaJoinedStyle,
+ RenderJoinedStyle,
+ RenderSeparateStyle,
+ RenderValuesStyle
+ };
+
+protected:
+ const OptTable::Info *Info;
+ const OptTable *Owner;
+
+public:
+ Option(const OptTable::Info *Info, const OptTable *Owner);
+ ~Option();
+
+ bool isValid() const {
+ return Info != 0;
+ }
+
+ unsigned getID() const {
+ assert(Info && "Must have a valid info!");
+ return Info->ID;
+ }
+
+ OptionClass getKind() const {
+ assert(Info && "Must have a valid info!");
+ return OptionClass(Info->Kind);
+ }
+
+ /// \brief Get the name of this option without any prefix.
+ StringRef getName() const {
+ assert(Info && "Must have a valid info!");
+ return Info->Name;
+ }
+
+ const Option getGroup() const {
+ assert(Info && "Must have a valid info!");
+ assert(Owner && "Must have a valid owner!");
+ return Owner->getOption(Info->GroupID);
+ }
+
+ const Option getAlias() const {
+ assert(Info && "Must have a valid info!");
+ assert(Owner && "Must have a valid owner!");
+ return Owner->getOption(Info->AliasID);
+ }
+
+ /// \brief Get the default prefix for this option.
+ StringRef getPrefix() const {
+ const char *Prefix = *Info->Prefixes;
+ return Prefix ? Prefix : StringRef();
+ }
+
+ /// \brief Get the name of this option with the default prefix.
+ std::string getPrefixedName() const {
+ std::string Ret = getPrefix();
+ Ret += getName();
+ return Ret;
+ }
+
+ unsigned getNumArgs() const { return Info->Param; }
+
+ bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
+
+ RenderStyleKind getRenderStyle() const {
+ if (Info->Flags & RenderJoined)
+ return RenderJoinedStyle;
+ if (Info->Flags & RenderSeparate)
+ return RenderSeparateStyle;
+ switch (getKind()) {
+ case GroupClass:
+ case InputClass:
+ case UnknownClass:
+ return RenderValuesStyle;
+ case JoinedClass:
+ case JoinedAndSeparateClass:
+ return RenderJoinedStyle;
+ case CommaJoinedClass:
+ return RenderCommaJoinedStyle;
+ case FlagClass:
+ case SeparateClass:
+ case MultiArgClass:
+ case JoinedOrSeparateClass:
+ return RenderSeparateStyle;
+ }
+ llvm_unreachable("Unexpected kind!");
+ }
+
+ /// Test if this option has the flag \a Val.
+ bool hasFlag(unsigned Val) const {
+ return Info->Flags & Val;
+ }
+
+ /// getUnaliasedOption - Return the final option this option
+ /// aliases (itself, if the option has no alias).
+ const Option getUnaliasedOption() const {
+ const Option Alias = getAlias();
+ if (Alias.isValid()) return Alias.getUnaliasedOption();
+ return *this;
+ }
+
+ /// getRenderName - Return the name to use when rendering this
+ /// option.
+ StringRef getRenderName() const {
+ return getUnaliasedOption().getName();
+ }
+
+ /// matches - Predicate for whether this option is part of the
+ /// given option (which may be a group).
+ ///
+ /// Note that matches against options which are an alias should never be
+ /// done -- aliases do not participate in matching and so such a query will
+ /// always be false.
+ bool matches(OptSpecifier ID) const;
+
+ /// accept - Potentially accept the current argument, returning a
+ /// new Arg instance, or 0 if the option does not accept this
+ /// argument (or the argument is missing values).
+ ///
+ /// If the option accepts the current argument, accept() sets
+ /// Index to the position where argument parsing should resume
+ /// (even if the argument is missing values).
+ ///
+ /// \parm ArgSize The number of bytes taken up by the matched Option prefix
+ /// and name. This is used to determine where joined values
+ /// start.
+ Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
+
+ void dump() const;
+};
+
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index 888537d..35ec022 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -29,6 +29,7 @@
#ifndef LLVM_PASS_H
#define LLVM_PASS_H
+#include "llvm/Support/Compiler.h"
#include <string>
namespace llvm {
@@ -82,8 +83,8 @@ class Pass {
AnalysisResolver *Resolver; // Used to resolve analysis
const void *PassID;
PassKind Kind;
- void operator=(const Pass&); // DO NOT IMPLEMENT
- Pass(const Pass &); // DO NOT IMPLEMENT
+ void operator=(const Pass&) LLVM_DELETED_FUNCTION;
+ Pass(const Pass &) LLVM_DELETED_FUNCTION;
public:
explicit Pass(PassKind K, char &pid) : Resolver(0), PassID(&pid), Kind(K) { }
@@ -103,6 +104,16 @@ public:
return PassID;
}
+ /// doInitialization - Virtual method overridden by subclasses to do
+ /// any necessary initialization before any pass is run.
+ ///
+ virtual bool doInitialization(Module &) { return false; }
+
+ /// doFinalization - Virtual method overriden by subclasses to do any
+ /// necessary clean up after all passes have run.
+ ///
+ virtual bool doFinalization(Module &) { return false; }
+
/// print - Print out the internal state of the pass. This is called by
/// Analyze to print out the contents of an analysis. Otherwise it is not
/// necessary to implement this method. Beware that the module pointer MAY be
@@ -286,21 +297,11 @@ public:
/// createPrinterPass - Get a function printer pass.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
- /// doInitialization - Virtual method overridden by subclasses to do
- /// any necessary per-module initialization.
- ///
- virtual bool doInitialization(Module &);
-
/// runOnFunction - Virtual method overriden by subclasses to do the
/// per-function processing of the pass.
///
virtual bool runOnFunction(Function &F) = 0;
- /// doFinalization - Virtual method overriden by subclasses to do any post
- /// processing needed after all passes have run.
- ///
- virtual bool doFinalization(Module &);
-
virtual void assignPassManager(PMStack &PMS,
PassManagerType T);
@@ -327,10 +328,8 @@ public:
/// createPrinterPass - Get a basic block printer pass.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
- /// doInitialization - Virtual method overridden by subclasses to do
- /// any necessary per-module initialization.
- ///
- virtual bool doInitialization(Module &);
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
/// doInitialization - Virtual method overridden by BasicBlockPass subclasses
/// to do any necessary per-function initialization.
@@ -347,11 +346,6 @@ public:
///
virtual bool doFinalization(Function &);
- /// doFinalization - Virtual method overriden by subclasses to do any post
- /// processing needed after all passes have run.
- ///
- virtual bool doFinalization(Module &);
-
virtual void assignPassManager(PMStack &PMS,
PassManagerType T);
diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h
index 5c6a2d7..1cc5741 100644
--- a/include/llvm/PassAnalysisSupport.h
+++ b/include/llvm/PassAnalysisSupport.h
@@ -19,9 +19,9 @@
#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H
#define LLVM_PASS_ANALYSIS_SUPPORT_H
-#include "llvm/Pass.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Pass.h"
#include <vector>
namespace llvm {
@@ -120,7 +120,7 @@ public:
class PMDataManager;
class AnalysisResolver {
private:
- AnalysisResolver(); // DO NOT IMPLEMENT
+ AnalysisResolver() LLVM_DELETED_FUNCTION;
public:
explicit AnalysisResolver(PMDataManager &P) : PM(P) { }
diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h
index 0af5853..fac7928 100644
--- a/include/llvm/PassManagers.h
+++ b/include/llvm/PassManagers.h
@@ -14,13 +14,13 @@
#ifndef LLVM_PASSMANAGERS_H
#define LLVM_PASSMANAGERS_H
-#include "llvm/Pass.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/DenseMap.h"
-#include <vector>
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Pass.h"
#include <map>
+#include <vector>
//===----------------------------------------------------------------------===//
// Overview:
@@ -168,7 +168,7 @@ class PMTopLevelManager {
protected:
explicit PMTopLevelManager(PMDataManager *PMDM);
- virtual unsigned getNumContainedManagers() const {
+ unsigned getNumContainedManagers() const {
return (unsigned)PassManagers.size();
}
@@ -343,7 +343,7 @@ public:
void dumpRequiredSet(const Pass *P) const;
void dumpPreservedSet(const Pass *P) const;
- virtual unsigned getNumContainedPasses() const {
+ unsigned getNumContainedPasses() const {
return (unsigned)PassVector.size();
}
@@ -420,10 +420,20 @@ public:
/// cleanup - After running all passes, clean up pass manager cache.
void cleanup();
+ /// doInitialization - Overrides ModulePass doInitialization for global
+ /// initialization tasks
+ ///
+ using ModulePass::doInitialization;
+
/// doInitialization - Run all of the initializers for the function passes.
///
bool doInitialization(Module &M);
+ /// doFinalization - Overrides ModulePass doFinalization for global
+ /// finalization tasks
+ ///
+ using ModulePass::doFinalization;
+
/// doFinalization - Run all of the finalizers for the function passes.
///
bool doFinalization(Module &M);
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index c50c2cc..3633f47 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -22,8 +22,8 @@
#define LLVM_PASS_SUPPORT_H
#include "Pass.h"
-#include "llvm/PassRegistry.h"
#include "llvm/InitializePasses.h"
+#include "llvm/PassRegistry.h"
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Valgrind.h"
#include <vector>
@@ -126,8 +126,8 @@ public:
}
private:
- void operator=(const PassInfo &); // do not implement
- PassInfo(const PassInfo &); // do not implement
+ void operator=(const PassInfo &) LLVM_DELETED_FUNCTION;
+ PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION;
};
#define CALL_ONCE_INITIALIZATION(function) \
@@ -305,7 +305,7 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
/// clients that are interested in which passes get registered and unregistered
/// at runtime (which can be because of the RegisterPass constructors being run
/// as the program starts up, or may be because a shared object just got
-/// loaded). Deriving from the PassRegistationListener class automatically
+/// loaded). Deriving from the PassRegistrationListener class automatically
/// registers your object to receive callbacks indicating when passes are loaded
/// and removed.
///
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index 8c389af..0894316 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -19,7 +19,6 @@
#include <cstddef>
namespace llvm {
-
template <typename T>
struct AlignmentCalcImpl {
char x;
@@ -49,7 +48,6 @@ struct AlignOf {
enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
-
};
/// alignOf - A templated function that returns the minimum alignment of
@@ -59,121 +57,145 @@ struct AlignOf {
template <typename T>
inline unsigned alignOf() { return AlignOf<T>::Alignment; }
-
+/// \struct AlignedCharArray
/// \brief Helper for building an aligned character array type.
///
/// This template is used to explicitly build up a collection of aligned
-/// character types. We have to build these up using a macro and explicit
+/// character array types. We have to build these up using a macro and explicit
/// specialization to cope with old versions of MSVC and GCC where only an
/// integer literal can be used to specify an alignment constraint. Once built
/// up here, we can then begin to indirect between these using normal C++
/// template parameters.
-template <size_t Alignment> struct AlignedCharArrayImpl {};
-template <> struct AlignedCharArrayImpl<0> {
- typedef char type;
-};
// MSVC requires special handling here.
#ifndef _MSC_VER
#if __has_feature(cxx_alignas)
+template<std::size_t Alignment, std::size_t Size>
+struct AlignedCharArray {
+ alignas(Alignment) char buffer[Size];
+};
+
+#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
+/// \brief Create a type with an aligned char buffer.
+template<std::size_t Alignment, std::size_t Size>
+struct AlignedCharArray;
+
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
- template <> struct AlignedCharArrayImpl<x> { \
- typedef char alignas(x) type; \
- }
-#elif defined(__clang__) || defined(__GNUC__)
-#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
- template <> struct AlignedCharArrayImpl<x> { \
- typedef char type __attribute__((aligned(x))); \
- }
-#else
-# error No supported align as directive.
-#endif
+ template<std::size_t Size> \
+ struct AlignedCharArray<x, Size> { \
+ __attribute__((aligned(x))) char buffer[Size]; \
+ };
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
+#else
+# error No supported align as directive.
+#endif
+
#else // _MSC_VER
+/// \brief Create a type with an aligned char buffer.
+template<std::size_t Alignment, std::size_t Size>
+struct AlignedCharArray;
+
// We provide special variations of this template for the most common
// alignments because __declspec(align(...)) doesn't actually work when it is
// a member of a by-value function argument in MSVC, even if the alignment
-// request is something reasonably like 8-byte or 16-byte.
-template <> struct AlignedCharArrayImpl<1> { typedef char type; };
-template <> struct AlignedCharArrayImpl<2> { typedef short type; };
-template <> struct AlignedCharArrayImpl<4> { typedef int type; };
-template <> struct AlignedCharArrayImpl<8> { typedef double type; };
+// request is something reasonably like 8-byte or 16-byte. Note that we can't
+// even include the declspec with the union that forces the alignment because
+// MSVC warns on the existence of the declspec despite the union member forcing
+// proper alignment.
+
+template<std::size_t Size>
+struct AlignedCharArray<1, Size> {
+ union {
+ char aligned;
+ char buffer[Size];
+ };
+};
+
+template<std::size_t Size>
+struct AlignedCharArray<2, Size> {
+ union {
+ short aligned;
+ char buffer[Size];
+ };
+};
+
+template<std::size_t Size>
+struct AlignedCharArray<4, Size> {
+ union {
+ int aligned;
+ char buffer[Size];
+ };
+};
+
+template<std::size_t Size>
+struct AlignedCharArray<8, Size> {
+ union {
+ double aligned;
+ char buffer[Size];
+ };
+};
+
+
+// The rest of these are provided with a __declspec(align(...)) and we simply
+// can't pass them by-value as function arguments on MSVC.
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
- template <> struct AlignedCharArrayImpl<x> { \
- typedef __declspec(align(x)) char type; \
- }
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
-// Any larger and MSVC complains.
+ template<std::size_t Size> \
+ struct AlignedCharArray<x, Size> { \
+ __declspec(align(x)) char buffer[Size]; \
+ };
+
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
+
#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
#endif // _MSC_VER
+namespace detail {
+template <typename T1,
+ typename T2 = char, typename T3 = char, typename T4 = char>
+class AlignerImpl {
+ T1 t1; T2 t2; T3 t3; T4 t4;
+
+ AlignerImpl(); // Never defined or instantiated.
+};
+
+template <typename T1,
+ typename T2 = char, typename T3 = char, typename T4 = char>
+union SizerImpl {
+ char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)];
+};
+} // end namespace detail
+
/// \brief This union template exposes a suitably aligned and sized character
/// array member which can hold elements of any of up to four types.
///
/// These types may be arrays, structs, or any other types. The goal is to
-/// produce a union type containing a character array which, when used, forms
-/// storage suitable to placement new any of these types over. Support for more
-/// than four types can be added at the cost of more boiler plate.
+/// expose a char array buffer member which can be used as suitable storage for
+/// a placement new of any of these types. Support for more than four types can
+/// be added at the cost of more boiler plate.
template <typename T1,
typename T2 = char, typename T3 = char, typename T4 = char>
-union AlignedCharArrayUnion {
-private:
- class AlignerImpl {
- T1 t1; T2 t2; T3 t3; T4 t4;
-
- AlignerImpl(); // Never defined or instantiated.
- };
- union SizerImpl {
- char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)];
- };
-
-public:
- /// \brief The character array buffer for use by clients.
- ///
- /// No other member of this union should be referenced. The exist purely to
- /// constrain the layout of this character array.
- char buffer[sizeof(SizerImpl)];
-
- // Sadly, Clang and GCC both fail to align a character array properly even
- // with an explicit alignment attribute. To work around this, we union
- // the character array that will actually be used with a struct that contains
- // a single aligned character member. Tests seem to indicate that both Clang
- // and GCC will properly register the alignment of a struct containing an
- // aligned member, and this alignment should carry over to the character
- // array in the union.
- struct {
- typename llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment>::type
- nonce_inner_member;
- } nonce_member;
+struct AlignedCharArrayUnion :
+ llvm::AlignedCharArray<AlignOf<detail::AlignerImpl<T1, T2, T3, T4> >
+ ::Alignment,
+ sizeof(detail::SizerImpl<T1, T2, T3, T4>)> {
};
-
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index a2ad24f..3243fd9 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -15,12 +15,12 @@
#define LLVM_SUPPORT_ALLOCATOR_H
#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cassert>
-#include <cstdlib>
#include <cstddef>
+#include <cstdlib>
namespace llvm {
template <typename T> struct ReferenceAdder { typedef T& result; };
@@ -79,8 +79,8 @@ class MallocSlabAllocator : public SlabAllocator {
public:
MallocSlabAllocator() : Allocator() { }
virtual ~MallocSlabAllocator();
- virtual MemSlab *Allocate(size_t Size);
- virtual void Deallocate(MemSlab *Slab);
+ virtual MemSlab *Allocate(size_t Size) LLVM_OVERRIDE;
+ virtual void Deallocate(MemSlab *Slab) LLVM_OVERRIDE;
};
/// BumpPtrAllocator - This allocator is useful for containers that need
@@ -88,8 +88,8 @@ public:
/// allocating memory, and never deletes it until the entire block is dead. This
/// makes allocation speedy, but must only be used when the trade-off is ok.
class BumpPtrAllocator {
- BumpPtrAllocator(const BumpPtrAllocator &); // do not implement
- void operator=(const BumpPtrAllocator &); // do not implement
+ BumpPtrAllocator(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION;
+ void operator=(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION;
/// SlabSize - Allocate data into slabs of this size unless we get an
/// allocation above SizeThreshold.
diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h
new file mode 100644
index 0000000..0fbe79c
--- /dev/null
+++ b/include/llvm/Support/ArrayRecycler.h
@@ -0,0 +1,143 @@
+//==- llvm/Support/ArrayRecycler.h - Recycling of Arrays ---------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ArrayRecycler class template which can recycle small
+// arrays allocated from one of the allocators in Allocator.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARRAY_RECYCLER_H
+#define LLVM_SUPPORT_ARRAY_RECYCLER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/MathExtras.h"
+
+namespace llvm {
+
+class BumpPtrAllocator;
+
+/// Recycle small arrays allocated from a BumpPtrAllocator.
+///
+/// Arrays are allocated in a small number of fixed sizes. For each supported
+/// array size, the ArrayRecycler keeps a free list of available arrays.
+///
+template<class T, size_t Align = AlignOf<T>::Alignment>
+class ArrayRecycler {
+ // The free list for a given array size is a simple singly linked list.
+ // We can't use iplist or Recycler here since those classes can't be copied.
+ struct FreeList {
+ FreeList *Next;
+ };
+
+ // Keep a free list for each array size.
+ SmallVector<FreeList*, 8> Bucket;
+
+ // Remove an entry from the free list in Bucket[Idx] and return it.
+ // Return NULL if no entries are available.
+ T *pop(unsigned Idx) {
+ if (Idx >= Bucket.size())
+ return 0;
+ FreeList *Entry = Bucket[Idx];
+ if (!Entry)
+ return 0;
+ Bucket[Idx] = Entry->Next;
+ return reinterpret_cast<T*>(Entry);
+ }
+
+ // Add an entry to the free list at Bucket[Idx].
+ void push(unsigned Idx, T *Ptr) {
+ assert(Ptr && "Cannot recycle NULL pointer");
+ assert(sizeof(T) >= sizeof(FreeList) && "Objects are too small");
+ assert(Align >= AlignOf<FreeList>::Alignment && "Object underaligned");
+ FreeList *Entry = reinterpret_cast<FreeList*>(Ptr);
+ if (Idx >= Bucket.size())
+ Bucket.resize(size_t(Idx) + 1);
+ Entry->Next = Bucket[Idx];
+ Bucket[Idx] = Entry;
+ }
+
+public:
+ /// The size of an allocated array is represented by a Capacity instance.
+ ///
+ /// This class is much smaller than a size_t, and it provides methods to work
+ /// with the set of legal array capacities.
+ class Capacity {
+ uint8_t Index;
+ explicit Capacity(uint8_t idx) : Index(idx) {}
+
+ public:
+ Capacity() : Index(0) {}
+
+ /// Get the capacity of an array that can hold at least N elements.
+ static Capacity get(size_t N) {
+ return Capacity(N ? Log2_64_Ceil(N) : 0);
+ }
+
+ /// Get the number of elements in an array with this capacity.
+ size_t getSize() const { return size_t(1u) << Index; }
+
+ /// Get the bucket number for this capacity.
+ unsigned getBucket() const { return Index; }
+
+ /// Get the next larger capacity. Large capacities grow exponentially, so
+ /// this function can be used to reallocate incrementally growing vectors
+ /// in amortized linear time.
+ Capacity getNext() const { return Capacity(Index + 1); }
+ };
+
+ ~ArrayRecycler() {
+ // The client should always call clear() so recycled arrays can be returned
+ // to the allocator.
+ assert(Bucket.empty() && "Non-empty ArrayRecycler deleted!");
+ }
+
+ /// Release all the tracked allocations to the allocator. The recycler must
+ /// be free of any tracked allocations before being deleted.
+ template<class AllocatorType>
+ void clear(AllocatorType &Allocator) {
+ for (; !Bucket.empty(); Bucket.pop_back())
+ while (T *Ptr = pop(Bucket.size() - 1))
+ Allocator.Deallocate(Ptr);
+ }
+
+ /// Special case for BumpPtrAllocator which has an empty Deallocate()
+ /// function.
+ ///
+ /// There is no need to traverse the free lists, pulling all the objects into
+ /// cache.
+ void clear(BumpPtrAllocator&) {
+ Bucket.clear();
+ }
+
+ /// Allocate an array of at least the requested capacity.
+ ///
+ /// Return an existing recycled array, or allocate one from Allocator if
+ /// none are available for recycling.
+ ///
+ template<class AllocatorType>
+ T *allocate(Capacity Cap, AllocatorType &Allocator) {
+ // Try to recycle an existing array.
+ if (T *Ptr = pop(Cap.getBucket()))
+ return Ptr;
+ // Nope, get more memory.
+ return static_cast<T*>(Allocator.Allocate(sizeof(T)*Cap.getSize(), Align));
+ }
+
+ /// Deallocate an array with the specified Capacity.
+ ///
+ /// Cap must be the same capacity that was given to allocate().
+ ///
+ void deallocate(Capacity Cap, T *Ptr) {
+ push(Cap.getBucket(), Ptr);
+ }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index f5dc8ea..a9fb65c 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -16,8 +16,8 @@
#define LLVM_SUPPORT_CFG_H
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/Function.h"
-#include "llvm/InstrTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 8905e1e..3ce0fef 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -26,11 +26,11 @@
#ifndef LLVM_SUPPORT_CALLSITE_H
#define LLVM_SUPPORT_CALLSITE_H
-#include "llvm/Attributes.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Instructions.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Instructions.h"
namespace llvm {
@@ -177,21 +177,21 @@ public:
/// getAttributes/setAttributes - get or set the parameter attributes of
/// the call.
- const AttrListPtr &getAttributes() const {
+ const AttributeSet &getAttributes() const {
CALLSITE_DELEGATE_GETTER(getAttributes());
}
- void setAttributes(const AttrListPtr &PAL) {
+ void setAttributes(const AttributeSet &PAL) {
CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
/// \brief Return true if this function has the given attribute.
- bool hasFnAttr(Attributes N) const {
- CALLSITE_DELEGATE_GETTER(hasFnAttr(N));
+ bool hasFnAttr(Attribute::AttrKind A) const {
+ CALLSITE_DELEGATE_GETTER(hasFnAttr(A));
}
- /// paramHasAttr - whether the call or the callee has the given attribute.
- bool paramHasAttr(uint16_t i, Attributes attr) const {
- CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
+ /// \brief Return true if the call or the callee has the given attribute.
+ bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
+ CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
}
/// @brief Extract the alignment for a call or parameter (0=unknown).
@@ -211,32 +211,32 @@ public:
bool doesNotAccessMemory() const {
CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
}
- void setDoesNotAccessMemory(bool doesNotAccessMemory = true) {
- CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
+ void setDoesNotAccessMemory() {
+ CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory());
}
/// @brief Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
}
- void setOnlyReadsMemory(bool onlyReadsMemory = true) {
- CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
+ void setOnlyReadsMemory() {
+ CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
}
/// @brief Determine if the call cannot return.
bool doesNotReturn() const {
CALLSITE_DELEGATE_GETTER(doesNotReturn());
}
- void setDoesNotReturn(bool doesNotReturn = true) {
- CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
+ void setDoesNotReturn() {
+ CALLSITE_DELEGATE_SETTER(setDoesNotReturn());
}
/// @brief Determine if the call cannot unwind.
bool doesNotThrow() const {
CALLSITE_DELEGATE_GETTER(doesNotThrow());
}
- void setDoesNotThrow(bool doesNotThrow = true) {
- CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
+ void setDoesNotThrow() {
+ CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
}
#undef CALLSITE_DELEGATE_GETTER
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 3aab436..0c71882 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_CASTING_H
#define LLVM_SUPPORT_CASTING_H
+#include "llvm/Support/type_traits.h"
#include <cassert>
namespace llvm {
@@ -44,13 +45,23 @@ template<typename From> struct simplify_type<const From> {
// The core of the implementation of isa<X> is here; To and From should be
// the names of classes. This template can be specialized to customize the
// implementation of isa<> without rewriting it from scratch.
-template <typename To, typename From>
+template <typename To, typename From, typename Enabler = void>
struct isa_impl {
static inline bool doit(const From &Val) {
return To::classof(&Val);
}
};
+/// \brief Always allow upcasts, and perform no dynamic check for them.
+template <typename To, typename From>
+struct isa_impl<To, From,
+ typename llvm::enable_if_c<
+ llvm::is_base_of<To, From>::value
+ >::type
+ > {
+ static inline bool doit(const From &) { return true; }
+};
+
template <typename To, typename From> struct isa_impl_cl {
static inline bool doit(const From &Val) {
return isa_impl<To, From>::doit(Val);
@@ -65,18 +76,21 @@ template <typename To, typename From> struct isa_impl_cl<To, const From> {
template <typename To, typename From> struct isa_impl_cl<To, From*> {
static inline bool doit(const From *Val) {
+ assert(Val && "isa<> used on a null pointer");
return isa_impl<To, From>::doit(*Val);
}
};
template <typename To, typename From> struct isa_impl_cl<To, const From*> {
static inline bool doit(const From *Val) {
+ assert(Val && "isa<> used on a null pointer");
return isa_impl<To, From>::doit(*Val);
}
};
template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
static inline bool doit(const From *Val) {
+ assert(Val && "isa<> used on a null pointer");
return isa_impl<To, From>::doit(*Val);
}
};
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index ae1570d..0ab39fc 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -20,10 +20,10 @@
#ifndef LLVM_SUPPORT_COMMANDLINE_H
#define LLVM_SUPPORT_COMMANDLINE_H
-#include "llvm/Support/type_traits.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <climits>
#include <cstdarg>
@@ -41,16 +41,14 @@ namespace cl {
// ParseCommandLineOptions - Command line option processing entry point.
//
void ParseCommandLineOptions(int argc, const char * const *argv,
- const char *Overview = 0,
- bool ReadResponseFiles = false);
+ const char *Overview = 0);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
// entry point.
//
void ParseEnvironmentOptions(const char *progName, const char *envvar,
- const char *Overview = 0,
- bool ReadResponseFiles = false);
+ const char *Overview = 0);
///===---------------------------------------------------------------------===//
/// SetVersionPrinter - Override the default (LLVM specific) version printer
@@ -1509,7 +1507,7 @@ class bits : public Option, public bits_storage<DataType, Storage> {
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse Error!
- addValue(Val);
+ this->addValue(Val);
setPosition(pos);
Positions.push_back(pos);
return false;
@@ -1608,15 +1606,16 @@ public:
class alias : public Option {
Option *AliasFor;
virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
- StringRef Arg) {
+ StringRef Arg) LLVM_OVERRIDE {
return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
}
// Handle printing stuff...
- virtual size_t getOptionWidth() const;
- virtual void printOptionInfo(size_t GlobalWidth) const;
+ virtual size_t getOptionWidth() const LLVM_OVERRIDE;
+ virtual void printOptionInfo(size_t GlobalWidth) const LLVM_OVERRIDE;
// Aliases do not need to print their values.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ virtual void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const LLVM_OVERRIDE {}
void done() {
if (!hasArgStr())
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 1136ff7..b32939e 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -19,28 +19,50 @@
# define __has_feature(x) 0
#endif
-/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references?
+/// \brief Does the compiler support r-value references?
/// This implies that <utility> provides the one-argument std::move; it
/// does not imply the existence of any other C++ library features.
#if (__has_feature(cxx_rvalue_references) \
|| defined(__GXX_EXPERIMENTAL_CXX0X__) \
|| (defined(_MSC_VER) && _MSC_VER >= 1600))
-#define LLVM_USE_RVALUE_REFERENCES 1
+#define LLVM_HAS_RVALUE_REFERENCES 1
#else
-#define LLVM_USE_RVALUE_REFERENCES 0
+#define LLVM_HAS_RVALUE_REFERENCES 0
+#endif
+
+/// \brief Does the compiler support r-value reference *this?
+///
+/// Sadly, this is separate from just r-value reference support because GCC
+/// implemented everything but this thus far. No release of GCC yet has support
+/// for this feature so it is enabled with Clang only.
+/// FIXME: This should change to a version check when GCC grows support for it.
+#if __has_feature(cxx_rvalue_references)
+#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
+#else
+#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
#endif
/// llvm_move - Expands to ::std::move if the compiler supports
/// r-value references; otherwise, expands to the argument.
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
#define llvm_move(value) (::std::move(value))
#else
#define llvm_move(value) (value)
#endif
+/// Expands to '&' if r-value references are supported.
+///
+/// This can be used to provide l-value/r-value overrides of member functions.
+/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+#define LLVM_LVALUE_FUNCTION &
+#else
+#define LLVM_LVALUE_FUNCTION
+#endif
+
/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it.
/// Use to mark functions as uncallable. Member functions with this should
-/// be declared private so that some behaivor is kept in C++03 mode.
+/// be declared private so that some behavior is kept in C++03 mode.
///
/// class DontCopy {
/// private:
@@ -57,6 +79,22 @@
#define LLVM_DELETED_FUNCTION
#endif
+/// LLVM_FINAL - Expands to 'final' if the compiler supports it.
+/// Use to mark classes or virtual methods as final.
+#if (__has_feature(cxx_override_control))
+#define LLVM_FINAL final
+#else
+#define LLVM_FINAL
+#endif
+
+/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it.
+/// Use to mark virtual methods as overriding a base class method.
+#if (__has_feature(cxx_override_control))
+#define LLVM_OVERRIDE override
+#else
+#define LLVM_OVERRIDE
+#endif
+
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
/// into a shared library, then the class should be private to the library and
/// not accessible from outside it. Can also be used to mark variables and
@@ -113,7 +151,6 @@
#define LLVM_UNLIKELY(EXPR) (EXPR)
#endif
-
// C++ doesn't support 'extern template' of template specializations. GCC does,
// but requires __extension__ before it. In the header, use this:
// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
@@ -127,8 +164,8 @@
#define TEMPLATE_INSTANTIATION(X)
#endif
-// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
-// mark a method "not for inlining".
+/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
+/// mark a method "not for inlining".
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
@@ -137,10 +174,10 @@
#define LLVM_ATTRIBUTE_NOINLINE
#endif
-// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
-// so, mark a method "always inline" because it is performance sensitive. GCC
-// 3.4 supported this but is buggy in various cases and produces unimplemented
-// errors, just use it in GCC 4.0 and later.
+/// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
+/// so, mark a method "always inline" because it is performance sensitive. GCC
+/// 3.4 supported this but is buggy in various cases and produces unimplemented
+/// errors, just use it in GCC 4.0 and later.
#if __GNUC__ > 3
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
@@ -149,7 +186,6 @@
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
#endif
-
#ifdef __GNUC__
#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
@@ -158,8 +194,8 @@
#define LLVM_ATTRIBUTE_NORETURN
#endif
-// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
-// pedantic diagnostics.
+/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
+/// pedantic diagnostics.
#ifdef __GNUC__
#define LLVM_EXTENSION __extension__
#else
@@ -181,16 +217,18 @@
decl
#endif
-// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
-// to an expression which states that it is undefined behavior for the
-// compiler to reach this point. Otherwise is not defined.
+/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
+/// to an expression which states that it is undefined behavior for the
+/// compiler to reach this point. Otherwise is not defined.
#if defined(__clang__) || (__GNUC__ > 4) \
|| (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
+#elif defined(_MSC_VER)
+# define LLVM_BUILTIN_UNREACHABLE __assume(false)
#endif
-// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
-// which causes the program to exit abnormally.
+/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
+/// which causes the program to exit abnormally.
#if defined(__clang__) || (__GNUC__ > 4) \
|| (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
# define LLVM_BUILTIN_TRAP __builtin_trap()
@@ -198,4 +236,17 @@
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
#endif
+/// \macro LLVM_ASSUME_ALIGNED
+/// \brief Returns a pointer with an assumed alignment.
+#if !defined(__clang__) && ((__GNUC__ > 4) \
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+// FIXME: Enable on clang when it supports it.
+# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
+#elif defined(LLVM_BUILTIN_UNREACHABLE)
+# define LLVM_ASSUME_ALIGNED(p, a) \
+ (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
+#else
+# define LLVM_ASSUME_ALIGNED(p, a) (p)
+#endif
+
#endif
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
index 93aa343..4aad952 100644
--- a/include/llvm/Support/ConstantFolder.h
+++ b/include/llvm/Support/ConstantFolder.h
@@ -17,8 +17,8 @@
#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H
#define LLVM_SUPPORT_CONSTANTFOLDER_H
-#include "llvm/Constants.h"
-#include "llvm/InstrTypes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h
index 8d880fd..a3ae782 100644
--- a/include/llvm/Support/DataExtractor.h
+++ b/include/llvm/Support/DataExtractor.h
@@ -10,6 +10,7 @@
#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
#define LLVM_SUPPORT_DATAEXTRACTOR_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/DataFlow.h b/include/llvm/Support/DataFlow.h
index 355c402..a09ccaa 100644
--- a/include/llvm/Support/DataFlow.h
+++ b/include/llvm/Support/DataFlow.h
@@ -14,8 +14,8 @@
#ifndef LLVM_SUPPORT_DATAFLOW_H
#define LLVM_SUPPORT_DATAFLOW_H
-#include "llvm/User.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/IR/User.h"
namespace llvm {
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 8f18a99..c703da5 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -37,7 +37,7 @@ enum {
namespace dwarf {
//===----------------------------------------------------------------------===//
-// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
+// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
// reference manual http://dwarf.freestandards.org .
//
@@ -50,8 +50,6 @@ enum llvm_dwarf_constants {
DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
DW_TAG_arg_variable = 0x101, // Tag for argument variables.
- DW_TAG_return_variable = 0x102, // Tag for return variables.
- DW_TAG_vector_type = 0x103, // Tag for vector types.
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
@@ -231,6 +229,10 @@ enum dwarf_constants {
DW_AT_const_expr = 0x6c,
DW_AT_enum_class = 0x6d,
DW_AT_linkage_name = 0x6e,
+
+ DW_AT_lo_user = 0x2000,
+ DW_AT_hi_user = 0x3fff,
+
DW_AT_MIPS_loop_begin = 0x2002,
DW_AT_MIPS_tail_loop_begin = 0x2003,
DW_AT_MIPS_epilog_begin = 0x2004,
@@ -246,6 +248,12 @@ enum dwarf_constants {
DW_AT_MIPS_ptr_dopetype = 0x200e,
DW_AT_MIPS_allocatable_dopetype = 0x200f,
DW_AT_MIPS_assumed_shape_dopetype = 0x2010,
+
+ // This one appears to have only been implemented by Open64 for
+ // fortran and may conflict with other extensions.
+ DW_AT_MIPS_assumed_size = 0x2011,
+
+ // GNU extensions
DW_AT_sf_names = 0x2101,
DW_AT_src_info = 0x2102,
DW_AT_mac_info = 0x2103,
@@ -254,9 +262,14 @@ enum dwarf_constants {
DW_AT_body_end = 0x2106,
DW_AT_GNU_vector = 0x2107,
DW_AT_GNU_template_name = 0x2110,
- DW_AT_MIPS_assumed_size = 0x2011,
- DW_AT_lo_user = 0x2000,
- DW_AT_hi_user = 0x3fff,
+
+ // Extensions for Fission proposal.
+ DW_AT_GNU_dwo_name = 0x2130,
+ DW_AT_GNU_dwo_id = 0x2131,
+ DW_AT_GNU_ranges_base = 0x2132,
+ DW_AT_GNU_addr_base = 0x2133,
+ DW_AT_GNU_pubnames = 0x2134,
+ DW_AT_GNU_pubtypes = 0x2135,
// Apple extensions.
DW_AT_APPLE_optimized = 0x3fe1,
@@ -300,6 +313,10 @@ enum dwarf_constants {
DW_FORM_flag_present = 0x19,
DW_FORM_ref_sig8 = 0x20,
+ // Extensions for Fission proposal
+ DW_FORM_GNU_addr_index = 0x1f01,
+ DW_FORM_GNU_str_index = 0x1f02,
+
// Operation encodings
DW_OP_addr = 0x03,
DW_OP_deref = 0x06,
@@ -458,6 +475,10 @@ enum dwarf_constants {
DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff,
+ // Extensions for Fission proposal.
+ DW_OP_GNU_addr_index = 0xfb,
+ DW_OP_GNU_const_index = 0xfc,
+
// Encoding attribute values
DW_ATE_address = 0x01,
DW_ATE_boolean = 0x02,
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 0e1cfac..d6e54be 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -441,6 +441,7 @@ enum {
R_MICROBLAZE_COPY = 21
};
+// ELF Relocation types for PPC32
enum {
R_PPC_NONE = 0, /* No relocation. */
R_PPC_ADDR32 = 1,
@@ -456,7 +457,39 @@ enum {
R_PPC_REL14 = 11,
R_PPC_REL14_BRTAKEN = 12,
R_PPC_REL14_BRNTAKEN = 13,
- R_PPC_REL32 = 26
+ R_PPC_REL32 = 26,
+ R_PPC_TPREL16_LO = 70,
+ R_PPC_TPREL16_HA = 72
+};
+
+// ELF Relocation types for PPC64
+enum {
+ R_PPC64_ADDR32 = 1,
+ R_PPC64_ADDR16_LO = 4,
+ R_PPC64_ADDR16_HI = 5,
+ R_PPC64_ADDR14 = 7,
+ R_PPC64_REL24 = 10,
+ R_PPC64_ADDR64 = 38,
+ R_PPC64_ADDR16_HIGHER = 39,
+ R_PPC64_ADDR16_HIGHEST = 41,
+ R_PPC64_REL64 = 44,
+ R_PPC64_TOC16 = 47,
+ R_PPC64_TOC16_LO = 48,
+ R_PPC64_TOC16_HA = 50,
+ R_PPC64_TOC = 51,
+ R_PPC64_TOC16_DS = 63,
+ R_PPC64_TOC16_LO_DS = 64,
+ R_PPC64_TLS = 67,
+ R_PPC64_DTPREL16_LO = 75,
+ R_PPC64_DTPREL16_HA = 77,
+ R_PPC64_GOT_TLSGD16_LO = 80,
+ R_PPC64_GOT_TLSGD16_HA = 82,
+ R_PPC64_GOT_TLSLD16_LO = 84,
+ R_PPC64_GOT_TLSLD16_HA = 86,
+ R_PPC64_GOT_TPREL16_LO_DS = 88,
+ R_PPC64_GOT_TPREL16_HA = 90,
+ R_PPC64_TLSGD = 107,
+ R_PPC64_TLSLD = 108
};
// ARM Specific e_flags
@@ -674,8 +707,36 @@ enum {
R_MIPS_NUM = 218
};
+// Hexagon Specific e_flags
+// Release 5 ABI
+enum {
+ // Object processor version flags, bits[3:0]
+ EF_HEXAGON_MACH_V2 = 0x00000001, // Hexagon V2
+ EF_HEXAGON_MACH_V3 = 0x00000002, // Hexagon V3
+ EF_HEXAGON_MACH_V4 = 0x00000003, // Hexagon V4
+ EF_HEXAGON_MACH_V5 = 0x00000004, // Hexagon V5
+
+ // Highest ISA version flags
+ EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[3:0]
+ // of e_flags
+ EF_HEXAGON_ISA_V2 = 0x00000010, // Hexagon V2 ISA
+ EF_HEXAGON_ISA_V3 = 0x00000020, // Hexagon V3 ISA
+ EF_HEXAGON_ISA_V4 = 0x00000030, // Hexagon V4 ISA
+ EF_HEXAGON_ISA_V5 = 0x00000040 // Hexagon V5 ISA
+};
+
+// Hexagon specific Section indexes for common small data
+// Release 5 ABI
+enum {
+ SHN_HEXAGON_SCOMMON = 0xff00, // Other access sizes
+ SHN_HEXAGON_SCOMMON_1 = 0xff01, // Byte-sized access
+ SHN_HEXAGON_SCOMMON_2 = 0xff02, // Half-word-sized access
+ SHN_HEXAGON_SCOMMON_4 = 0xff03, // Word-sized access
+ SHN_HEXAGON_SCOMMON_8 = 0xff04 // Double-word-size access
+};
+
// ELF Relocation types for Hexagon
-// Release 5 ABI - Document: 80-V9418-3 Rev. J
+// Release 5 ABI
enum {
R_HEX_NONE = 0,
R_HEX_B22_PCREL = 1,
@@ -1104,6 +1165,9 @@ enum {
PT_PHDR = 6, // The program header table itself.
PT_TLS = 7, // The thread-local storage template.
PT_LOOS = 0x60000000, // Lowest operating system-specific pt entry type.
+ PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type.
+ PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type.
+ PT_HIPROC = 0x7fffffff, // Highest processor-specific program hdr entry type.
// x86-64 program header types.
// These all contain stack unwind tables.
@@ -1114,9 +1178,11 @@ enum {
PT_GNU_STACK = 0x6474e551, // Indicates stack executability.
PT_GNU_RELRO = 0x6474e552, // Read-only after relocation.
- PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type.
- PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type.
- PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type.
+ // ARM program header types.
+ PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility information
+ // These all contain stack unwind tables.
+ PT_ARM_EXIDX = 0x70000001,
+ PT_ARM_UNWIND = 0x70000001
};
// Segment flag bits.
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 8d5649d..d438fac 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -14,136 +14,78 @@
#ifndef LLVM_SUPPORT_ENDIAN_H
#define LLVM_SUPPORT_ENDIAN_H
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/type_traits.h"
namespace llvm {
namespace support {
+enum endianness {big, little, native};
-enum endianness {big, little};
-enum alignment {unaligned, aligned};
+// These are named values for common alignments.
+enum {aligned = 0, unaligned = 1};
namespace detail {
-
-template<typename value_type, alignment align>
-struct alignment_access_helper;
-
-template<typename value_type>
-struct alignment_access_helper<value_type, aligned>
-{
- value_type val;
-};
-
-// Provides unaligned loads and stores.
-#pragma pack(push)
-#pragma pack(1)
-template<typename value_type>
-struct alignment_access_helper<value_type, unaligned>
-{
- value_type val;
-};
-#pragma pack(pop)
-
+ /// \brief ::value is either alignment, or alignof(T) if alignment is 0.
+ template<class T, int alignment>
+ struct PickAlignment {
+ enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment};
+ };
} // end namespace detail
namespace endian {
- template<typename value_type, alignment align>
- inline value_type read_le(const void *memory) {
- value_type t =
- reinterpret_cast<const detail::alignment_access_helper
- <value_type, align> *>(memory)->val;
- if (sys::isBigEndianHost())
- return sys::SwapByteOrder(t);
- return t;
- }
-
- template<typename value_type, alignment align>
- inline void write_le(void *memory, value_type value) {
- if (sys::isBigEndianHost())
- value = sys::SwapByteOrder(value);
- reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
- (memory)->val = value;
- }
+template<typename value_type, endianness endian>
+inline value_type byte_swap(value_type value) {
+ if (endian != native && sys::isBigEndianHost() != (endian == big))
+ return sys::SwapByteOrder(value);
+ return value;
+}
- template<typename value_type, alignment align>
- inline value_type read_be(const void *memory) {
- value_type t =
- reinterpret_cast<const detail::alignment_access_helper
- <value_type, align> *>(memory)->val;
- if (sys::isLittleEndianHost())
- return sys::SwapByteOrder(t);
- return t;
- }
+template<typename value_type,
+ endianness endian,
+ std::size_t alignment>
+inline value_type read(const void *memory) {
+ value_type ret;
+
+ memcpy(&ret,
+ LLVM_ASSUME_ALIGNED(memory,
+ (detail::PickAlignment<value_type, alignment>::value)),
+ sizeof(value_type));
+ return byte_swap<value_type, endian>(ret);
+}
- template<typename value_type, alignment align>
- inline void write_be(void *memory, value_type value) {
- if (sys::isLittleEndianHost())
- value = sys::SwapByteOrder(value);
- reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
- (memory)->val = value;
- }
+template<typename value_type,
+ endianness endian,
+ std::size_t alignment>
+inline void write(void *memory, value_type value) {
+ value = byte_swap<value_type, endian>(value);
+ memcpy(LLVM_ASSUME_ALIGNED(memory,
+ (detail::PickAlignment<value_type, alignment>::value)),
+ &value,
+ sizeof(value_type));
}
+} // end namespace endian
namespace detail {
-
template<typename value_type,
endianness endian,
- alignment align>
-class packed_endian_specific_integral;
-
-template<typename value_type>
-class packed_endian_specific_integral<value_type, little, unaligned> {
-public:
- operator value_type() const {
- return endian::read_le<value_type, unaligned>(Value);
- }
- void operator=(value_type newValue) {
- endian::write_le<value_type, unaligned>((void *)&Value, newValue);
- }
-private:
- uint8_t Value[sizeof(value_type)];
-};
-
-template<typename value_type>
-class packed_endian_specific_integral<value_type, big, unaligned> {
-public:
+ std::size_t alignment>
+struct packed_endian_specific_integral {
operator value_type() const {
- return endian::read_be<value_type, unaligned>(Value);
+ return endian::read<value_type, endian, alignment>(
+ (const void*)Value.buffer);
}
- void operator=(value_type newValue) {
- endian::write_be<value_type, unaligned>((void *)&Value, newValue);
- }
-private:
- uint8_t Value[sizeof(value_type)];
-};
-template<typename value_type>
-class packed_endian_specific_integral<value_type, little, aligned> {
-public:
- operator value_type() const {
- return endian::read_le<value_type, aligned>(&Value);
- }
void operator=(value_type newValue) {
- endian::write_le<value_type, aligned>((void *)&Value, newValue);
+ endian::write<value_type, endian, alignment>(
+ (void*)Value.buffer, newValue);
}
-private:
- value_type Value;
-};
-template<typename value_type>
-class packed_endian_specific_integral<value_type, big, aligned> {
-public:
- operator value_type() const {
- return endian::read_be<value_type, aligned>(&Value);
- }
- void operator=(value_type newValue) {
- endian::write_be<value_type, aligned>((void *)&Value, newValue);
- }
private:
- value_type Value;
+ AlignedCharArray<PickAlignment<value_type, alignment>::value,
+ sizeof(value_type)> Value;
};
-
} // end namespace detail
typedef detail::packed_endian_specific_integral
@@ -218,6 +160,19 @@ typedef detail::packed_endian_specific_integral
typedef detail::packed_endian_specific_integral
<int64_t, big, aligned> aligned_big64_t;
+typedef detail::packed_endian_specific_integral
+ <uint16_t, native, unaligned> unaligned_uint16_t;
+typedef detail::packed_endian_specific_integral
+ <uint32_t, native, unaligned> unaligned_uint32_t;
+typedef detail::packed_endian_specific_integral
+ <uint64_t, native, unaligned> unaligned_uint64_t;
+
+typedef detail::packed_endian_specific_integral
+ <int16_t, native, unaligned> unaligned_int16_t;
+typedef detail::packed_endian_specific_integral
+ <int32_t, native, unaligned> unaligned_int32_t;
+typedef detail::packed_endian_specific_integral
+ <int64_t, native, unaligned> unaligned_int64_t;
} // end namespace llvm
} // end namespace support
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
index 95b0109..ca5dec0 100644
--- a/include/llvm/Support/ErrorHandling.h
+++ b/include/llvm/Support/ErrorHandling.h
@@ -15,8 +15,8 @@
#ifndef LLVM_SUPPORT_ERRORHANDLING_H
#define LLVM_SUPPORT_ERRORHANDLING_H
-#include "llvm/Support/Compiler.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include <string>
namespace llvm {
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index 0f07164..cbc9c46 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -14,84 +14,79 @@
#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/FileSystem.h"
namespace llvm {
-
class error_code;
-template<class T> class OwningPtr;
/// FileOutputBuffer - This interface provides simple way to create an in-memory
-/// buffer which will be written to a file. During the lifetime of these
+/// buffer which will be written to a file. During the lifetime of these
/// objects, the content or existence of the specified file is undefined. That
/// is, creating an OutputBuffer for a file may immediately remove the file.
-/// If the FileOutputBuffer is committed, the target file's content will become
-/// the buffer content at the time of the commit. If the FileOutputBuffer is
+/// If the FileOutputBuffer is committed, the target file's content will become
+/// the buffer content at the time of the commit. If the FileOutputBuffer is
/// not committed, the file will be deleted in the FileOutputBuffer destructor.
class FileOutputBuffer {
public:
enum {
F_executable = 1 /// set the 'x' bit on the resulting file
- };
+ };
/// Factory method to create an OutputBuffer object which manages a read/write
/// buffer of the specified size. When committed, the buffer will be written
- /// to the file at the specified path.
- static error_code create(StringRef FilePath, size_t Size,
- OwningPtr<FileOutputBuffer> &Result,
- unsigned Flags=0);
-
+ /// to the file at the specified path.
+ static error_code create(StringRef FilePath, size_t Size,
+ OwningPtr<FileOutputBuffer> &Result,
+ unsigned Flags = 0);
/// Returns a pointer to the start of the buffer.
- uint8_t *getBufferStart() const {
- return BufferStart;
+ uint8_t *getBufferStart() {
+ return (uint8_t*)Region->data();
}
-
+
/// Returns a pointer to the end of the buffer.
- uint8_t *getBufferEnd() const {
- return BufferEnd;
+ uint8_t *getBufferEnd() {
+ return (uint8_t*)Region->data() + Region->size();
}
-
+
/// Returns size of the buffer.
size_t getBufferSize() const {
- return BufferEnd - BufferStart;
+ return Region->size();
}
-
+
/// Returns path where file will show up if buffer is committed.
StringRef getPath() const {
return FinalPath;
}
-
- /// Flushes the content of the buffer to its file and deallocates the
+
+ /// Flushes the content of the buffer to its file and deallocates the
/// buffer. If commit() is not called before this object's destructor
/// is called, the file is deleted in the destructor. The optional parameter
/// is used if it turns out you want the file size to be smaller than
/// initially requested.
error_code commit(int64_t NewSmallerSize = -1);
-
+
/// If this object was previously committed, the destructor just deletes
/// this object. If this object was not committed, the destructor
/// deallocates the buffer and the target file is never written.
~FileOutputBuffer();
-
-protected:
- FileOutputBuffer(const FileOutputBuffer &); // DO NOT IMPLEMENT
- FileOutputBuffer &operator=(const FileOutputBuffer &); // DO NOT IMPLEMENT
- FileOutputBuffer(uint8_t *Start, uint8_t *End,
- StringRef Path, StringRef TempPath);
-
- uint8_t *BufferStart;
- uint8_t *BufferEnd;
+private:
+ FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
+ FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
+
+ FileOutputBuffer(llvm::sys::fs::mapped_file_region *R,
+ StringRef Path, StringRef TempPath);
+
+ OwningPtr<llvm::sys::fs::mapped_file_region> Region;
SmallString<128> FinalPath;
SmallString<128> TempPath;
};
-
-
-
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 5d60205..f1cbe97 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -280,7 +280,7 @@ error_code create_symlink(const Twine &to, const Twine &from);
/// @brief Get the current path.
///
/// @param result Holds the current path on return.
-/// @results errc::success if the current path has been stored in result,
+/// @returns errc::success if the current path has been stored in result,
/// otherwise a platform specific error_code.
error_code current_path(SmallVectorImpl<char> &result);
@@ -289,7 +289,7 @@ error_code current_path(SmallVectorImpl<char> &result);
/// @param path Input path.
/// @param existed Set to true if \a path existed, false if it did not.
/// undefined otherwise.
-/// @results errc::success if path has been removed and existed has been
+/// @returns errc::success if path has been removed and existed has been
/// successfully set, otherwise a platform specific error_code.
error_code remove(const Twine &path, bool &existed);
@@ -298,7 +298,7 @@ error_code remove(const Twine &path, bool &existed);
///
/// @param path Input path.
/// @param num_removed Number of files removed.
-/// @results errc::success if path has been removed and num_removed has been
+/// @returns errc::success if path has been removed and num_removed has been
/// successfully set, otherwise a platform specific error_code.
error_code remove_all(const Twine &path, uint32_t &num_removed);
@@ -323,7 +323,7 @@ error_code resize_file(const Twine &path, uint64_t size);
/// @brief Does file exist?
///
/// @param status A file_status previously returned from stat.
-/// @results True if the file represented by status exists, false if it does
+/// @returns True if the file represented by status exists, false if it does
/// not.
bool exists(file_status status);
@@ -332,7 +332,7 @@ bool exists(file_status status);
/// @param path Input path.
/// @param result Set to true if the file represented by status exists, false if
/// it does not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code exists(const Twine &path, bool &result);
@@ -350,7 +350,7 @@ inline bool exists(const Twine &path) {
///
/// assert(status_known(A) || status_known(B));
///
-/// @results True if A and B both represent the same file system entity, false
+/// @returns True if A and B both represent the same file system entity, false
/// otherwise.
bool equivalent(file_status A, file_status B);
@@ -362,7 +362,7 @@ bool equivalent(file_status A, file_status B);
/// @param B Input path B.
/// @param result Set to true if stat(A) and stat(B) have the same device and
/// inode (or equivalent).
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code equivalent(const Twine &A, const Twine &B, bool &result);
@@ -384,7 +384,7 @@ error_code file_size(const Twine &path, uint64_t &result);
/// @brief Does status represent a directory?
///
/// @param status A file_status previously returned from status.
-/// @results status.type() == file_type::directory_file.
+/// @returns status.type() == file_type::directory_file.
bool is_directory(file_status status);
/// @brief Is path a directory?
@@ -392,14 +392,14 @@ bool is_directory(file_status status);
/// @param path Input path.
/// @param result Set to true if \a path is a directory, false if it is not.
/// Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code is_directory(const Twine &path, bool &result);
/// @brief Does status represent a regular file?
///
/// @param status A file_status previously returned from status.
-/// @results status_known(status) && status.type() == file_type::regular_file.
+/// @returns status_known(status) && status.type() == file_type::regular_file.
bool is_regular_file(file_status status);
/// @brief Is path a regular file?
@@ -407,7 +407,7 @@ bool is_regular_file(file_status status);
/// @param path Input path.
/// @param result Set to true if \a path is a regular file, false if it is not.
/// Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code is_regular_file(const Twine &path, bool &result);
@@ -415,7 +415,7 @@ error_code is_regular_file(const Twine &path, bool &result);
/// directory, regular file, or symlink?
///
/// @param status A file_status previously returned from status.
-/// @results exists(s) && !is_regular_file(s) && !is_directory(s) &&
+/// @returns exists(s) && !is_regular_file(s) && !is_directory(s) &&
/// !is_symlink(s)
bool is_other(file_status status);
@@ -425,7 +425,7 @@ bool is_other(file_status status);
/// @param path Input path.
/// @param result Set to true if \a path exists, but is not a directory, regular
/// file, or a symlink, false if it does not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code is_other(const Twine &path, bool &result);
@@ -440,7 +440,7 @@ bool is_symlink(file_status status);
/// @param path Input path.
/// @param result Set to true if \a path is a symlink, false if it is not.
/// Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code is_symlink(const Twine &path, bool &result);
@@ -448,28 +448,28 @@ error_code is_symlink(const Twine &path, bool &result);
///
/// @param path Input path.
/// @param result Set to the file status.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code status(const Twine &path, file_status &result);
/// @brief Modifies permission bits on a file
///
/// @param path Input path.
-/// @results errc::success if permissions have been changed, otherwise a
+/// @returns errc::success if permissions have been changed, otherwise a
/// platform specific error_code.
error_code permissions(const Twine &path, perms prms);
/// @brief Is status available?
///
/// @param s Input file status.
-/// @results True if status() != status_error.
+/// @returns True if status() != status_error.
bool status_known(file_status s);
/// @brief Is status available?
///
/// @param path Input path.
/// @param result Set to true if status() != status_error.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code status_known(const Twine &path, bool &result);
@@ -488,9 +488,9 @@ error_code status_known(const Twine &path, bool &result);
/// @param model Name to base unique path off of.
/// @param result_fd Set to the opened file's file descriptor.
/// @param result_path Set to the opened file's absolute path.
-/// @param makeAbsolute If true and @model is not an absolute path, a temp
+/// @param makeAbsolute If true and \a model is not an absolute path, a temp
/// directory will be prepended.
-/// @results errc::success if result_{fd,path} have been successfully set,
+/// @returns errc::success if result_{fd,path} have been successfully set,
/// otherwise a platform specific error_code.
error_code unique_file(const Twine &model, int &result_fd,
SmallVectorImpl<char> &result_path,
@@ -503,7 +503,7 @@ error_code unique_file(const Twine &model, int &result_fd,
///
/// @param path Input path.
/// @param result Set to the canonicalized version of \a path.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
@@ -511,7 +511,7 @@ error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
///
/// @param path Input path.
/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code has_magic(const Twine &path, const Twine &magic, bool &result);
@@ -522,7 +522,7 @@ error_code has_magic(const Twine &path, const Twine &magic, bool &result);
/// @param result Set to the first \a len bytes in the file pointed to by
/// \a path. Or the entire file if file_size(path) < len, in which
/// case result.size() returns the size of the file.
-/// @results errc::success if result has been successfully set,
+/// @returns errc::success if result has been successfully set,
/// errc::value_too_large if len is larger then the file pointed to by
/// \a path, otherwise a platform specific error_code.
error_code get_magic(const Twine &path, uint32_t len,
@@ -535,14 +535,14 @@ file_magic identify_magic(StringRef magic);
///
/// @param path Input path.
/// @param result Set to the type of file, or LLVMFileType::Unknown_FileType.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code identify_magic(const Twine &path, file_magic &result);
/// @brief Get library paths the system linker uses.
///
/// @param result Set to the list of system library paths.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
@@ -550,7 +550,7 @@ error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
/// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR.
///
/// @param result Set to the list of bitcode library paths.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
@@ -563,7 +563,7 @@ error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
///
/// @param short_name Library name one would give to the system linker.
/// @param result Set to the absolute path \a short_name represents.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
@@ -572,7 +572,7 @@ error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
/// @param argv0 The program name as it was spelled on the command line.
/// @param MainAddr Address of some symbol in the executable (not in a library).
/// @param result Set to the absolute path of the current executable.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code GetMainExecutable(const char *argv0, void *MainAddr,
SmallVectorImpl<char> &result);
@@ -607,7 +607,7 @@ private:
public:
typedef char char_type;
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
mapped_file_region(mapped_file_region&&);
mapped_file_region &operator =(mapped_file_region&&);
#endif
@@ -664,7 +664,7 @@ public:
/// to the file. If false, the file will be mapped read-only
/// and the buffer will be read-only.
/// @param result Set to the start address of the mapped buffer.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
bool map_writable, void *&result);
@@ -674,7 +674,7 @@ error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
///
/// @param base Pointer to the start of the buffer.
/// @param size Byte length of the range to unmmap.
-/// @results errc::success if result has been successfully set, otherwise a
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code unmap_file_pages(void *base, size_t size);
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index 59812d9..aaa54e1 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -170,31 +170,47 @@ public:
}
};
-/// format - This is a helper function that is used to produce formatted output.
-/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+/// This is a helper function that is used to produce formatted output.
+///
+/// This is typically used like:
+/// \code
+/// OS << format("%0.4f", myfloat) << '\n';
+/// \endcode
template <typename T>
inline format_object1<T> format(const char *Fmt, const T &Val) {
return format_object1<T>(Fmt, Val);
}
-/// format - This is a helper function that is used to produce formatted output.
-/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+/// This is a helper function that is used to produce formatted output.
+///
+/// This is typically used like:
+/// \code
+/// OS << format("%0.4f", myfloat) << '\n';
+/// \endcode
template <typename T1, typename T2>
inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1,
const T2 &Val2) {
return format_object2<T1, T2>(Fmt, Val1, Val2);
}
-/// format - This is a helper function that is used to produce formatted output.
-/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+/// This is a helper function that is used to produce formatted output.
+///
+/// This is typically used like:
+/// \code
+/// OS << format("%0.4f", myfloat) << '\n';
+/// \endcode
template <typename T1, typename T2, typename T3>
inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1,
const T2 &Val2, const T3 &Val3) {
return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
}
-/// format - This is a helper function that is used to produce formatted output.
-/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+/// This is a helper function that is used to produce formatted output.
+///
+/// This is typically used like:
+/// \code
+/// OS << format("%0.4f", myfloat) << '\n';
+/// \endcode
template <typename T1, typename T2, typename T3, typename T4>
inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
const T2 &Val2, const T3 &Val3,
@@ -202,8 +218,12 @@ inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4);
}
-/// format - This is a helper function that is used to produce formatted output.
-/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+/// This is a helper function that is used to produce formatted output.
+///
+/// This is typically used like:
+/// \code
+/// OS << format("%0.4f", myfloat) << '\n';
+/// \endcode
template <typename T1, typename T2, typename T3, typename T4, typename T5>
inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
const T2 &Val2, const T3 &Val3,
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 58a1885..21635dc 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -55,14 +55,15 @@ namespace llvm
///
const char *Scanned;
- virtual void write_impl(const char *Ptr, size_t Size);
+ virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
/// current_pos - Return the current position within the stream,
/// not counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const {
- // This has the same effect as calling TheStream.current_pos(),
- // but that interface is private.
- return TheStream->tell() - TheStream->GetNumBytesInBuffer();
+ virtual uint64_t current_pos() const LLVM_OVERRIDE {
+ // Our current position in the stream is all the contents which have been
+ // written to the underlying stream (*not* the current position of the
+ // underlying stream).
+ return TheStream->tell();
}
/// ComputeColumn - Examine the given output buffer and figure out which
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
index ef92c95..52b06ad 100644
--- a/include/llvm/Support/GetElementPtrTypeIterator.h
+++ b/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -15,8 +15,8 @@
#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
-#include "llvm/User.h"
-#include "llvm/DerivedTypes.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/User.h"
namespace llvm {
template<typename ItTy = User::const_op_iterator>
@@ -83,15 +83,15 @@ namespace llvm {
typedef generic_gep_type_iterator<> gep_type_iterator;
inline gep_type_iterator gep_type_begin(const User *GEP) {
- return gep_type_iterator::begin(GEP->getOperand(0)->getType(),
- GEP->op_begin()+1);
+ return gep_type_iterator::begin
+ (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
}
inline gep_type_iterator gep_type_end(const User *GEP) {
return gep_type_iterator::end(GEP->op_end());
}
inline gep_type_iterator gep_type_begin(const User &GEP) {
- return gep_type_iterator::begin(GEP.getOperand(0)->getType(),
- GEP.op_begin()+1);
+ return gep_type_iterator::begin
+ (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1);
}
inline gep_type_iterator gep_type_end(const User &GEP) {
return gep_type_iterator::end(GEP.op_end());
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index f178b0c..30cfe61 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -23,12 +23,12 @@
#ifndef LLVM_SUPPORT_GRAPHWRITER_H
#define LLVM_SUPPORT_GRAPHWRITER_H
-#include "llvm/Support/DOTGraphTraits.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/Path.h"
-#include <vector>
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
+#include <vector>
namespace llvm {
diff --git a/include/llvm/Support/InstIterator.h b/include/llvm/Support/InstIterator.h
index 7d3f883..ac936a1 100644
--- a/include/llvm/Support/InstIterator.h
+++ b/include/llvm/Support/InstIterator.h
@@ -19,8 +19,8 @@
#ifndef LLVM_SUPPORT_INSTITERATOR_H
#define LLVM_SUPPORT_INSTITERATOR_H
-#include "llvm/BasicBlock.h"
-#include "llvm/Function.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
namespace llvm {
diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
index bb9e769..9e5361c 100644
--- a/include/llvm/Support/IntegersSubset.h
+++ b/include/llvm/Support/IntegersSubset.h
@@ -18,12 +18,11 @@
#ifndef CONSTANTRANGESSET_H_
#define CONSTANTRANGESSET_H_
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
#include <list>
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-
namespace llvm {
// The IntItem is a wrapper for APInt.
@@ -411,8 +410,8 @@ public:
unsigned getSize() const {
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
- const APInt &Low = getItem(i).getLow();
- const APInt &High = getItem(i).getHigh();
+ const APInt Low = getItem(i).getLow();
+ const APInt High = getItem(i).getHigh();
APInt S = High - Low + 1;
sz += S;
}
@@ -426,8 +425,8 @@ public:
APInt getSingleValue(unsigned idx) const {
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
- const APInt &Low = getItem(i).getLow();
- const APInt &High = getItem(i).getHigh();
+ const APInt Low = getItem(i).getLow();
+ const APInt High = getItem(i).getHigh();
APInt S = High - Low + 1;
APInt oldSz = sz;
sz += S;
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index 410edd4..b52e5bc 100644
--- a/include/llvm/Support/LEB128.h
+++ b/include/llvm/Support/LEB128.h
@@ -15,7 +15,7 @@
#ifndef LLVM_SYSTEM_LEB128_H
#define LLVM_SYSTEM_LEB128_H
-#include <llvm/Support/raw_ostream.h>
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index e2fa8eb..8c4a760 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -47,8 +47,8 @@ private:
Optional<std::pair<std::string, int> > Owner;
Optional<error_code> Error;
- LockFileManager(const LockFileManager &);
- LockFileManager &operator=(const LockFileManager &);
+ LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
+ LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
static Optional<std::pair<std::string, int> >
readLockFile(StringRef LockFileName);
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 35c2694..11f9e63 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -431,21 +431,22 @@ inline uint64_t NextPowerOf2(uint64_t A) {
return A + 1;
}
-/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
-/// greater than or equal to \arg Value and is a multiple of \arg
-/// Align. Align must be non-zero.
+/// Returns the next integer (mod 2**64) that is greater than or equal to
+/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
///
/// Examples:
-/// RoundUpToAlignment(5, 8) = 8
-/// RoundUpToAlignment(17, 8) = 24
-/// RoundUpToAlignment(~0LL, 8) = 0
+/// \code
+/// RoundUpToAlignment(5, 8) = 8
+/// RoundUpToAlignment(17, 8) = 24
+/// RoundUpToAlignment(~0LL, 8) = 0
+/// \endcode
inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
return ((Value + Align - 1) / Align) * Align;
}
-/// OffsetToAlignment - Return the offset to the next integer (mod 2**64) that
-/// is greater than or equal to \arg Value and is a multiple of \arg
-/// Align. Align must be non-zero.
+/// Returns the offset to the next integer (mod 2**64) that is greater than
+/// or equal to \p Value and is a multiple of \p Align. \p Align must be
+/// non-zero.
inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
return RoundUpToAlignment(Value, Align) - Value;
}
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index 37890e7..025eee7 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -15,6 +15,7 @@
#define LLVM_SYSTEM_MEMORY_H
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/system_error.h"
#include <string>
namespace llvm {
@@ -43,6 +44,70 @@ namespace sys {
/// @brief An abstraction for memory operations.
class Memory {
public:
+ enum ProtectionFlags {
+ MF_READ = 0x1000000,
+ MF_WRITE = 0x2000000,
+ MF_EXEC = 0x4000000
+ };
+
+ /// This method allocates a block of memory that is suitable for loading
+ /// dynamically generated code (e.g. JIT). An attempt to allocate
+ /// \p NumBytes bytes of virtual memory is made.
+ /// \p NearBlock may point to an existing allocation in which case
+ /// an attempt is made to allocate more memory near the existing block.
+ /// The actual allocated address is not guaranteed to be near the requested
+ /// address.
+ /// \p Flags is used to set the initial protection flags for the block
+ /// of the memory.
+ /// \p EC [out] returns an object describing any error that occurs.
+ ///
+ /// This method may allocate more than the number of bytes requested. The
+ /// actual number of bytes allocated is indicated in the returned
+ /// MemoryBlock.
+ ///
+ /// The start of the allocated block must be aligned with the
+ /// system allocation granularity (64K on Windows, page size on Linux).
+ /// If the address following \p NearBlock is not so aligned, it will be
+ /// rounded up to the next allocation granularity boundary.
+ ///
+ /// \r a non-null MemoryBlock if the function was successful,
+ /// otherwise a null MemoryBlock is with \p EC describing the error.
+ ///
+ /// @brief Allocate mapped memory.
+ static MemoryBlock allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned Flags,
+ error_code &EC);
+
+ /// This method releases a block of memory that was allocated with the
+ /// allocateMappedMemory method. It should not be used to release any
+ /// memory block allocated any other way.
+ /// \p Block describes the memory to be released.
+ ///
+ /// \r error_success if the function was successful, or an error_code
+ /// describing the failure if an error occurred.
+ ///
+ /// @brief Release mapped memory.
+ static error_code releaseMappedMemory(MemoryBlock &Block);
+
+ /// This method sets the protection flags for a block of memory to the
+ /// state specified by /p Flags. The behavior is not specified if the
+ /// memory was not allocated using the allocateMappedMemory method.
+ /// \p Block describes the memory block to be protected.
+ /// \p Flags specifies the new protection state to be assigned to the block.
+ /// \p ErrMsg [out] returns a string describing any error that occured.
+ ///
+ /// If \p Flags is MF_WRITE, the actual behavior varies
+ /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
+ /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
+ ///
+ /// \r error_success if the function was successful, or an error_code
+ /// describing the failure if an error occurred.
+ ///
+ /// @brief Set memory protection state.
+ static error_code protectMappedMemory(const MemoryBlock &Block,
+ unsigned Flags);
+
/// This method allocates a block of Read/Write/Execute memory that is
/// suitable for executing dynamically generated code (e.g. JIT). An
/// attempt to allocate \p NumBytes bytes of virtual memory is made.
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 06816de..1f02907 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -15,6 +15,7 @@
#define LLVM_SUPPORT_MEMORYBUFFER_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -36,8 +37,8 @@ class MemoryBuffer {
const char *BufferStart; // Start of the buffer.
const char *BufferEnd; // End of the buffer.
- MemoryBuffer(const MemoryBuffer &); // DO NOT IMPLEMENT
- MemoryBuffer &operator=(const MemoryBuffer &); // DO NOT IMPLEMENT
+ MemoryBuffer(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
+ MemoryBuffer &operator=(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
protected:
MemoryBuffer() {}
void init(const char *BufStart, const char *BufEnd,
diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h
index 42ea630..6abc533 100644
--- a/include/llvm/Support/Mutex.h
+++ b/include/llvm/Support/Mutex.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SYSTEM_MUTEX_H
#define LLVM_SYSTEM_MUTEX_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Threading.h"
#include <cassert>
@@ -75,8 +76,8 @@ namespace llvm
/// @name Do Not Implement
/// @{
private:
- MutexImpl(const MutexImpl & original);
- void operator=(const MutexImpl &);
+ MutexImpl(const MutexImpl &) LLVM_DELETED_FUNCTION;
+ void operator=(const MutexImpl &) LLVM_DELETED_FUNCTION;
/// @}
};
diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h
index cd13bfe..6bb1622 100644
--- a/include/llvm/Support/MutexGuard.h
+++ b/include/llvm/Support/MutexGuard.h
@@ -26,8 +26,8 @@ namespace llvm {
/// @brief Guard a section of code with a Mutex.
class MutexGuard {
sys::Mutex &M;
- MutexGuard(const MutexGuard &); // DO NOT IMPLEMENT
- void operator=(const MutexGuard &); // DO NOT IMPLEMENT
+ MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION;
+ void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION;
public:
MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); }
~MutexGuard() { M.release(); }
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
index 8e41a64..ecfbbaa 100644
--- a/include/llvm/Support/NoFolder.h
+++ b/include/llvm/Support/NoFolder.h
@@ -23,8 +23,8 @@
#define LLVM_SUPPORT_NOFOLDER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
namespace llvm {
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
index a24a6f0..bdfab39 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/include/llvm/Support/PassNameParser.h
@@ -23,8 +23,8 @@
#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
#define LLVM_SUPPORT_PASS_NAME_PARSER_H
-#include "llvm/Pass.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h
index 967ea1e..ae1a21c 100644
--- a/include/llvm/Support/PathV2.h
+++ b/include/llvm/Support/PathV2.h
@@ -39,13 +39,14 @@ namespace path {
/// The backwards traversal order is the reverse of forward traversal.
///
/// Iteration examples. Each component is separated by ',':
-/// / => /
-/// /foo => /,foo
-/// foo/ => foo,.
-/// /foo/bar => /,foo,bar
-/// ../ => ..,.
-/// C:\foo\bar => C:,/,foo,bar
-///
+/// @code
+/// / => /
+/// /foo => /,foo
+/// foo/ => foo,.
+/// /foo/bar => /,foo,bar
+/// ../ => ..,.
+/// C:\foo\bar => C:,/,foo,bar
+/// @endcode
class const_iterator {
StringRef Path; ///< The entire path.
StringRef Component; ///< The current component. Not necessarily in Path.
@@ -107,18 +108,22 @@ inline reverse_iterator rend(StringRef path) {
/// @brief Remove the last component from \a path unless it is the root dir.
///
-/// directory/filename.cpp => directory/
-/// directory/ => directory
-/// / => /
+/// @code
+/// directory/filename.cpp => directory/
+/// directory/ => directory
+/// / => /
+/// @endcode
///
/// @param path A path that is modified to not have a file component.
void remove_filename(SmallVectorImpl<char> &path);
/// @brief Replace the file extension of \a path with \a extension.
///
-/// ./filename.cpp => ./filename.extension
-/// ./filename => ./filename.extension
-/// ./ => ./.extension
+/// @code
+/// ./filename.cpp => ./filename.extension
+/// ./filename => ./filename.extension
+/// ./ => ./.extension
+/// @endcode
///
/// @param path A path that has its extension replaced with \a extension.
/// @param extension The extension to be added. It may be empty. It may also
@@ -128,9 +133,11 @@ void replace_extension(SmallVectorImpl<char> &path, const Twine &extension);
/// @brief Append to path.
///
-/// /foo + bar/f => /foo/bar/f
-/// /foo/ + bar/f => /foo/bar/f
-/// foo + bar/f => foo/bar/f
+/// @code
+/// /foo + bar/f => /foo/bar/f
+/// /foo/ + bar/f => /foo/bar/f
+/// foo + bar/f => foo/bar/f
+/// @endcode
///
/// @param path Set to \a path + \a component.
/// @param a The component to be appended to \a path.
@@ -141,9 +148,11 @@ void append(SmallVectorImpl<char> &path, const Twine &a,
/// @brief Append to path.
///
-/// /foo + [bar,f] => /foo/bar/f
-/// /foo/ + [bar,f] => /foo/bar/f
-/// foo + [bar,f] => foo/bar/f
+/// @code
+/// /foo + [bar,f] => /foo/bar/f
+/// /foo/ + [bar,f] => /foo/bar/f
+/// foo + [bar,f] => foo/bar/f
+/// @endcode
///
/// @param path Set to \a path + [\a begin, \a end).
/// @param begin Start of components to append.
@@ -169,9 +178,11 @@ void native(const Twine &path, SmallVectorImpl<char> &result);
/// @brief Get root name.
///
-/// //net/hello => //net
-/// c:/hello => c: (on Windows, on other platforms nothing)
-/// /hello => <empty>
+/// @code
+/// //net/hello => //net
+/// c:/hello => c: (on Windows, on other platforms nothing)
+/// /hello => <empty>
+/// @endcode
///
/// @param path Input path.
/// @result The root name of \a path if it has one, otherwise "".
@@ -179,9 +190,11 @@ const StringRef root_name(StringRef path);
/// @brief Get root directory.
///
-/// /goo/hello => /
-/// c:/hello => /
-/// d/file.txt => <empty>
+/// @code
+/// /goo/hello => /
+/// c:/hello => /
+/// d/file.txt => <empty>
+/// @endcode
///
/// @param path Input path.
/// @result The root directory of \a path if it has one, otherwise
@@ -198,9 +211,11 @@ const StringRef root_path(StringRef path);
/// @brief Get relative path.
///
-/// C:\hello\world => hello\world
-/// foo/bar => foo/bar
-/// /foo/bar => foo/bar
+/// @code
+/// C:\hello\world => hello\world
+/// foo/bar => foo/bar
+/// /foo/bar => foo/bar
+/// @endcode
///
/// @param path Input path.
/// @result The path starting after root_path if one exists, otherwise "".
@@ -208,9 +223,11 @@ const StringRef relative_path(StringRef path);
/// @brief Get parent path.
///
-/// / => <empty>
-/// /foo => /
-/// foo/../bar => foo/..
+/// @code
+/// / => <empty>
+/// /foo => /
+/// foo/../bar => foo/..
+/// @endcode
///
/// @param path Input path.
/// @result The parent path of \a path if one exists, otherwise "".
@@ -218,10 +235,12 @@ const StringRef parent_path(StringRef path);
/// @brief Get filename.
///
-/// /foo.txt => foo.txt
-/// . => .
-/// .. => ..
-/// / => /
+/// @code
+/// /foo.txt => foo.txt
+/// . => .
+/// .. => ..
+/// / => /
+/// @endcode
///
/// @param path Input path.
/// @result The filename part of \a path. This is defined as the last component
@@ -234,11 +253,13 @@ const StringRef filename(StringRef path);
/// substring of filename ending at (but not including) the last dot. Otherwise
/// it is filename.
///
-/// /foo/bar.txt => bar
-/// /foo/bar => bar
-/// /foo/.txt => <empty>
-/// /foo/. => .
-/// /foo/.. => ..
+/// @code
+/// /foo/bar.txt => bar
+/// /foo/bar => bar
+/// /foo/.txt => <empty>
+/// /foo/. => .
+/// /foo/.. => ..
+/// @endcode
///
/// @param path Input path.
/// @result The stem of \a path.
@@ -250,9 +271,11 @@ const StringRef stem(StringRef path);
/// substring of filename starting at (and including) the last dot, and ending
/// at the end of \a path. Otherwise "".
///
-/// /foo/bar.txt => .txt
-/// /foo/bar => <empty>
-/// /foo/.txt => .txt
+/// @code
+/// /foo/bar.txt => .txt
+/// /foo/bar => <empty>
+/// /foo/.txt => .txt
+/// @endcode
///
/// @param path Input path.
/// @result The extension of \a path.
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index 221fa8b..9fbe434 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -29,9 +29,11 @@
#ifndef LLVM_SUPPORT_PATTERNMATCH_H
#define LLVM_SUPPORT_PATTERNMATCH_H
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
-#include "llvm/Operator.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/Support/CallSite.h"
namespace llvm {
namespace PatternMatch {
@@ -41,13 +43,13 @@ bool match(Val *V, const Pattern &P) {
return const_cast<Pattern&>(P).match(V);
}
-
+
template<typename SubPattern_t>
struct OneUse_match {
SubPattern_t SubPattern;
-
+
OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {}
-
+
template<typename OpTy>
bool match(OpTy *V) {
return V->hasOneUse() && SubPattern.match(V);
@@ -56,8 +58,8 @@ struct OneUse_match {
template<typename T>
inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; }
-
-
+
+
template<typename Class>
struct class_match {
template<typename ITy>
@@ -74,7 +76,53 @@ inline class_match<ConstantInt> m_ConstantInt() {
inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
-
+
+/// Matching combinators
+template<typename LTy, typename RTy>
+struct match_combine_or {
+ LTy L;
+ RTy R;
+
+ match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) { }
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (L.match(V))
+ return true;
+ if (R.match(V))
+ return true;
+ return false;
+ }
+};
+
+template<typename LTy, typename RTy>
+struct match_combine_and {
+ LTy L;
+ RTy R;
+
+ match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) { }
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (L.match(V))
+ if (R.match(V))
+ return true;
+ return false;
+ }
+};
+
+/// Combine two pattern matchers matching L || R
+template<typename LTy, typename RTy>
+inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) {
+ return match_combine_or<LTy, RTy>(L, R);
+}
+
+/// Combine two pattern matchers matching L && R
+template<typename LTy, typename RTy>
+inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) {
+ return match_combine_and<LTy, RTy>(L, R);
+}
+
struct match_zero {
template<typename ITy>
bool match(ITy *V) {
@@ -83,12 +131,33 @@ struct match_zero {
return false;
}
};
-
+
/// m_Zero() - Match an arbitrary zero/null constant. This includes
/// zero_initializer for vectors and ConstantPointerNull for pointers.
inline match_zero m_Zero() { return match_zero(); }
-
-
+
+struct match_neg_zero {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const Constant *C = dyn_cast<Constant>(V))
+ return C->isNegativeZeroValue();
+ return false;
+ }
+};
+
+/// m_NegZero() - Match an arbitrary zero/null constant. This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers. For
+/// floating point constants, this will match negative zero but not positive
+/// zero
+inline match_neg_zero m_NegZero() { return match_neg_zero(); }
+
+/// m_AnyZero() - Match an arbitrary zero/null constant. This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers. For
+/// floating point constants, this will match negative zero and positive zero
+inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() {
+ return m_CombineOr(m_Zero(), m_NegZero());
+}
+
struct apint_match {
const APInt *&Res;
apint_match(const APInt *&R) : Res(R) {}
@@ -98,28 +167,22 @@ struct apint_match {
Res = &CI->getValue();
return true;
}
- // FIXME: Remove this.
- if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) {
- Res = &CI->getValue();
- return true;
- }
- if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
- if (ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) {
- Res = &CI->getValue();
- return true;
- }
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(C->getSplatValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
return false;
}
};
-
+
/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the
/// specified pointer to the contained APInt.
inline apint_match m_APInt(const APInt *&Res) { return Res; }
-
+
template<int64_t Val>
struct constantint_match {
template<typename ITy>
@@ -151,17 +214,15 @@ struct cst_pred_ty : public Predicate {
bool match(ITy *V) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
return this->isValue(CI->getValue());
- // FIXME: Remove this.
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- return this->isValue(CI->getValue());
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- return this->isValue(CI->getValue());
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (const ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
+ return this->isValue(CI->getValue());
return false;
}
};
-
+
/// api_pred_ty - This helper class is used to match scalar and vector constants
/// that satisfy a specified predicate, and bind them to an APInt.
template<typename Predicate>
@@ -175,27 +236,19 @@ struct api_pred_ty : public Predicate {
Res = &CI->getValue();
return true;
}
-
- // FIXME: remove.
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- if (this->isValue(CI->getValue())) {
- Res = &CI->getValue();
- return true;
- }
-
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- if (this->isValue(CI->getValue())) {
- Res = &CI->getValue();
- return true;
- }
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
return false;
}
};
-
-
+
+
struct is_one {
bool isValue(const APInt &C) { return C == 1; }
};
@@ -203,11 +256,11 @@ struct is_one {
/// m_One() - Match an integer 1 or a vector with all elements equal to 1.
inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); }
inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; }
-
+
struct is_all_ones {
bool isValue(const APInt &C) { return C.isAllOnesValue(); }
};
-
+
/// m_AllOnes() - Match an integer or vector with all bits set to true.
inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();}
inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; }
@@ -252,6 +305,9 @@ inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
/// m_Constant - Match a Constant, capturing the value if we match.
inline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
+/// m_ConstantFP - Match a ConstantFP, capturing the value if we match.
+inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
+
/// specificval_ty - Match a specified Value*.
struct specificval_ty {
const Value *Val;
@@ -266,10 +322,35 @@ struct specificval_ty {
/// m_Specific - Match if we have a specific specified value.
inline specificval_ty m_Specific(const Value *V) { return V; }
+/// Match a specified floating point value or vector of all elements of that
+/// value.
+struct specific_fpval {
+ double Val;
+ specific_fpval(double V) : Val(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V))
+ return CFP->isExactlyValue(Val);
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue()))
+ return CFP->isExactlyValue(Val);
+ return false;
+ }
+};
+
+/// Match a specific floating point value or vector with all elements equal to
+/// the value.
+inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); }
+
+/// Match a float 1.0 or vector with all elements equal to 1.0.
+inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); }
+
struct bind_const_intval_ty {
uint64_t &VR;
bind_const_intval_ty(uint64_t &V) : VR(V) {}
-
+
template<typename ITy>
bool match(ITy *V) {
if (ConstantInt *CV = dyn_cast<ConstantInt>(V))
@@ -284,7 +365,7 @@ struct bind_const_intval_ty {
/// m_ConstantInt - Match a ConstantInt and bind to its value. This does not
/// match ConstantInts wider than 64-bits.
inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }
-
+
//===----------------------------------------------------------------------===//
// Matchers for specific binary operators.
//
@@ -583,7 +664,7 @@ inline CastClass_match<OpTy, Instruction::BitCast>
m_BitCast(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::BitCast>(Op);
}
-
+
/// m_PtrToInt
template<typename OpTy>
inline CastClass_match<OpTy, Instruction::PtrToInt>
@@ -611,7 +692,7 @@ inline CastClass_match<OpTy, Instruction::ZExt>
m_ZExt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::ZExt>(Op);
}
-
+
//===----------------------------------------------------------------------===//
// Matchers for unary operators
@@ -700,6 +781,25 @@ inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
// Matchers for control flow.
//
+struct br_match {
+ BasicBlock *&Succ;
+ br_match(BasicBlock *&Succ)
+ : Succ(Succ) {
+ }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (BranchInst *BI = dyn_cast<BranchInst>(V))
+ if (BI->isUnconditional()) {
+ Succ = BI->getSuccessor(0);
+ return true;
+ }
+ return false;
+ }
+};
+
+inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); }
+
template<typename Cond_t>
struct brc_match {
Cond_t Cond;
@@ -818,6 +918,102 @@ m_UMin(const LHS &L, const RHS &R) {
return MaxMin_match<LHS, RHS, umin_pred_ty>(L, R);
}
+template<typename Opnd_t>
+struct Argument_match {
+ unsigned OpI;
+ Opnd_t Val;
+ Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) { }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ CallSite CS(V);
+ return CS.isCall() && Val.match(CS.getArgument(OpI));
+ }
+};
+
+/// Match an argument
+template<unsigned OpI, typename Opnd_t>
+inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
+ return Argument_match<Opnd_t>(OpI, Op);
+}
+
+/// Intrinsic matchers.
+struct IntrinsicID_match {
+ unsigned ID;
+ IntrinsicID_match(unsigned IntrID) : ID(IntrID) { }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ IntrinsicInst *II = dyn_cast<IntrinsicInst>(V);
+ return II && II->getIntrinsicID() == ID;
+ }
+};
+
+/// Intrinsic matches are combinations of ID matchers, and argument
+/// matchers. Higher arity matcher are defined recursively in terms of and-ing
+/// them with lower arity matchers. Here's some convenient typedefs for up to
+/// several arguments, and more can be added as needed
+template <typename T0 = void, typename T1 = void, typename T2 = void,
+ typename T3 = void, typename T4 = void, typename T5 = void,
+ typename T6 = void, typename T7 = void, typename T8 = void,
+ typename T9 = void, typename T10 = void> struct m_Intrinsic_Ty;
+template <typename T0>
+struct m_Intrinsic_Ty<T0> {
+ typedef match_combine_and<IntrinsicID_match, Argument_match<T0> > Ty;
+};
+template <typename T0, typename T1>
+struct m_Intrinsic_Ty<T0, T1> {
+ typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty,
+ Argument_match<T1> > Ty;
+};
+template <typename T0, typename T1, typename T2>
+struct m_Intrinsic_Ty<T0, T1, T2> {
+ typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
+ Argument_match<T2> > Ty;
+};
+template <typename T0, typename T1, typename T2, typename T3>
+struct m_Intrinsic_Ty<T0, T1, T2, T3> {
+ typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
+ Argument_match<T3> > Ty;
+};
+
+/// Match intrinsic calls like this:
+/// m_Intrinsic<Intrinsic::fabs>(m_Value(X))
+template <unsigned IntrID>
+inline IntrinsicID_match
+m_Intrinsic() { return IntrinsicID_match(IntrID); }
+
+template<unsigned IntrID, typename T0>
+inline typename m_Intrinsic_Ty<T0>::Ty
+m_Intrinsic(const T0 &Op0) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0));
+}
+
+template<unsigned IntrID, typename T0, typename T1>
+inline typename m_Intrinsic_Ty<T0, T1>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1));
+}
+
+template<unsigned IntrID, typename T0, typename T1, typename T2>
+inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2));
+}
+
+template<unsigned IntrID, typename T0, typename T1, typename T2, typename T3>
+inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3));
+}
+
+// Helper intrinsic matching specializations
+template<typename Opnd0>
+inline typename m_Intrinsic_Ty<Opnd0>::Ty
+m_BSwap(const Opnd0 &Op0) {
+ return m_Intrinsic<Intrinsic::bswap>(Op0);
+}
+
} // end namespace PatternMatch
} // end namespace llvm
diff --git a/include/llvm/Support/PredIteratorCache.h b/include/llvm/Support/PredIteratorCache.h
index bb66a8e..c5fb780 100644
--- a/include/llvm/Support/PredIteratorCache.h
+++ b/include/llvm/Support/PredIteratorCache.h
@@ -11,10 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/CFG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/CFG.h"
#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H
#define LLVM_SUPPORT_PREDITERATORCACHE_H
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 9b3ecda..2122e06 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -16,6 +16,8 @@
#ifndef LLVM_SUPPORT_PRETTYSTACKTRACE_H
#define LLVM_SUPPORT_PRETTYSTACKTRACE_H
+#include "llvm/Support/Compiler.h"
+
namespace llvm {
class raw_ostream;
@@ -32,8 +34,8 @@ namespace llvm {
/// virtual stack trace. This gets dumped out if the program crashes.
class PrettyStackTraceEntry {
const PrettyStackTraceEntry *NextEntry;
- PrettyStackTraceEntry(const PrettyStackTraceEntry &); // DO NOT IMPLEMENT
- void operator=(const PrettyStackTraceEntry&); // DO NOT IMPLEMENT
+ PrettyStackTraceEntry(const PrettyStackTraceEntry &) LLVM_DELETED_FUNCTION;
+ void operator=(const PrettyStackTraceEntry&) LLVM_DELETED_FUNCTION;
public:
PrettyStackTraceEntry();
virtual ~PrettyStackTraceEntry();
@@ -52,7 +54,7 @@ namespace llvm {
const char *Str;
public:
PrettyStackTraceString(const char *str) : Str(str) {}
- virtual void print(raw_ostream &OS) const;
+ virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
};
/// PrettyStackTraceProgram - This object prints a specified program arguments
@@ -63,7 +65,7 @@ namespace llvm {
public:
PrettyStackTraceProgram(int argc, const char * const*argv)
: ArgC(argc), ArgV(argv) {}
- virtual void print(raw_ostream &OS) const;
+ virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
};
} // end namespace llvm
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 088897c..ea8da6d 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -6,152 +6,246 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::Process class.
-//
+/// \file
+///
+/// Provides a library for accessing information about this process and other
+/// processes on the operating system. Also provides means of spawning
+/// subprocess for commands. The design of this library is modeled after the
+/// proposed design of the Boost.Process library, and is design specifically to
+/// follow the style of standard libraries and potentially become a proposal
+/// for a standard library.
+///
+/// This file declares the llvm::sys::Process class which contains a collection
+/// of legacy static interfaces for extracting various information about the
+/// current process. The goal is to migrate users of this API over to the new
+/// interfaces.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_SYSTEM_PROCESS_H
#define LLVM_SYSTEM_PROCESS_H
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
namespace llvm {
namespace sys {
- /// This class provides an abstraction for getting information about the
- /// currently executing process.
- /// @since 1.4
- /// @brief An abstraction for operating system processes.
- class Process {
- /// @name Accessors
- /// @{
- public:
- /// This static function will return the operating system's virtual memory
- /// page size.
- /// @returns The number of bytes in a virtual memory page.
- /// @brief Get the virtual memory page size
- static unsigned GetPageSize();
-
- /// This static function will return the total amount of memory allocated
- /// by the process. This only counts the memory allocated via the malloc,
- /// calloc and realloc functions and includes any "free" holes in the
- /// allocated space.
- /// @brief Return process memory usage.
- static size_t GetMallocUsage();
-
- /// This static function will return the total memory usage of the
- /// process. This includes code, data, stack and mapped pages usage. Notei
- /// that the value returned here is not necessarily the Running Set Size,
- /// it is the total virtual memory usage, regardless of mapped state of
- /// that memory.
- static size_t GetTotalMemoryUsage();
-
- /// This static function will set \p user_time to the amount of CPU time
- /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
- /// time spent in system (kernel) mode. If the operating system does not
- /// support collection of these metrics, a zero TimeValue will be for both
- /// values.
- static void GetTimeUsage(
- TimeValue& elapsed,
- ///< Returns the TimeValue::now() giving current time
- TimeValue& user_time,
- ///< Returns the current amount of user time for the process
- TimeValue& sys_time
- ///< Returns the current amount of system time for the process
- );
-
- /// This static function will return the process' current user id number.
- /// Not all operating systems support this feature. Where it is not
- /// supported, the function should return 65536 as the value.
- static int GetCurrentUserId();
-
- /// This static function will return the process' current group id number.
- /// Not all operating systems support this feature. Where it is not
- /// supported, the function should return 65536 as the value.
- static int GetCurrentGroupId();
-
- /// This function makes the necessary calls to the operating system to
- /// prevent core files or any other kind of large memory dumps that can
- /// occur when a program fails.
- /// @brief Prevent core file generation.
- static void PreventCoreFiles();
-
- /// This function determines if the standard input is connected directly
- /// to a user's input (keyboard probably), rather than coming from a file
- /// or pipe.
- static bool StandardInIsUserInput();
-
- /// This function determines if the standard output is connected to a
- /// "tty" or "console" window. That is, the output would be displayed to
- /// the user rather than being put on a pipe or stored in a file.
- static bool StandardOutIsDisplayed();
-
- /// This function determines if the standard error is connected to a
- /// "tty" or "console" window. That is, the output would be displayed to
- /// the user rather than being put on a pipe or stored in a file.
- static bool StandardErrIsDisplayed();
-
- /// This function determines if the given file descriptor is connected to
- /// a "tty" or "console" window. That is, the output would be displayed to
- /// the user rather than being put on a pipe or stored in a file.
- static bool FileDescriptorIsDisplayed(int fd);
-
- /// This function determines if the given file descriptor is displayd and
- /// supports colors.
- static bool FileDescriptorHasColors(int fd);
-
- /// This function determines the number of columns in the window
- /// if standard output is connected to a "tty" or "console"
- /// window. If standard output is not connected to a tty or
- /// console, or if the number of columns cannot be determined,
- /// this routine returns zero.
- static unsigned StandardOutColumns();
-
- /// This function determines the number of columns in the window
- /// if standard error is connected to a "tty" or "console"
- /// window. If standard error is not connected to a tty or
- /// console, or if the number of columns cannot be determined,
- /// this routine returns zero.
- static unsigned StandardErrColumns();
-
- /// This function determines whether the terminal connected to standard
- /// output supports colors. If standard output is not connected to a
- /// terminal, this function returns false.
- static bool StandardOutHasColors();
-
- /// This function determines whether the terminal connected to standard
- /// error supports colors. If standard error is not connected to a
- /// terminal, this function returns false.
- static bool StandardErrHasColors();
-
- /// Whether changing colors requires the output to be flushed.
- /// This is needed on systems that don't support escape sequences for
- /// changing colors.
- static bool ColorNeedsFlush();
-
- /// This function returns the colorcode escape sequences.
- /// If ColorNeedsFlush() is true then this function will change the colors
- /// and return an empty escape sequence. In that case it is the
- /// responsibility of the client to flush the output stream prior to
- /// calling this function.
- static const char *OutputColor(char c, bool bold, bool bg);
-
- /// Same as OutputColor, but only enables the bold attribute.
- static const char *OutputBold(bool bg);
-
- /// This function returns the escape sequence to reverse forground and
- /// background colors.
- static const char *OutputReverse();
-
- /// Resets the terminals colors, or returns an escape sequence to do so.
- static const char *ResetColor();
-
- /// Get the result of a process wide random number generator. The
- /// generator will be automatically seeded in non-deterministic fashion.
- static unsigned GetRandomNumber();
- /// @}
- };
+class self_process;
+
+/// \brief Generic base class which exposes information about an operating
+/// system process.
+///
+/// This base class is the core interface behind any OS process. It exposes
+/// methods to query for generic information about a particular process.
+///
+/// Subclasses implement this interface based on the mechanisms available, and
+/// can optionally expose more interfaces unique to certain process kinds.
+class process {
+protected:
+ /// \brief Only specific subclasses of process objects can be destroyed.
+ virtual ~process();
+
+public:
+ /// \brief Operating system specific type to identify a process.
+ ///
+ /// Note that the windows one is defined to 'void *' as this is the
+ /// documented type for HANDLE on windows, and we don't want to pull in the
+ /// Windows headers here.
+#if defined(LLVM_ON_UNIX)
+ typedef pid_t id_type;
+#elif defined(LLVM_ON_WIN32)
+ typedef void *id_type; // Must match the type of HANDLE.
+#else
+#error Unsupported operating system.
+#endif
+
+ /// \brief Get the operating system specific identifier for this process.
+ virtual id_type get_id() = 0;
+
+ /// \brief Get the user time consumed by this process.
+ ///
+ /// Note that this is often an approximation and may be zero on platforms
+ /// where we don't have good support for the functionality.
+ virtual TimeValue get_user_time() const = 0;
+
+ /// \brief Get the system time consumed by this process.
+ ///
+ /// Note that this is often an approximation and may be zero on platforms
+ /// where we don't have good support for the functionality.
+ virtual TimeValue get_system_time() const = 0;
+
+ /// \brief Get the wall time consumed by this process.
+ ///
+ /// Note that this is often an approximation and may be zero on platforms
+ /// where we don't have good support for the functionality.
+ virtual TimeValue get_wall_time() const = 0;
+
+ /// \name Static factory routines for processes.
+ /// @{
+
+ /// \brief Get the process object for the current process.
+ static self_process *get_self();
+
+ /// @}
+
+};
+
+/// \brief The specific class representing the current process.
+///
+/// The current process can both specialize the implementation of the routines
+/// and can expose certain information not available for other OS processes.
+class self_process : public process {
+ friend class process;
+
+ /// \brief Private destructor, as users shouldn't create objects of this
+ /// type.
+ virtual ~self_process();
+
+public:
+ virtual id_type get_id();
+ virtual TimeValue get_user_time() const;
+ virtual TimeValue get_system_time() const;
+ virtual TimeValue get_wall_time() const;
+
+ /// \name Process configuration (sysconf on POSIX)
+ /// @{
+
+ /// \brief Get the virtual memory page size.
+ ///
+ /// Query the operating system for this process's page size.
+ size_t page_size() const { return PageSize; };
+
+ /// @}
+
+private:
+ /// \name Cached process state.
+ /// @{
+
+ /// \brief Cached page size, this cannot vary during the life of the process.
+ size_t PageSize;
+
+ /// @}
+
+ /// \brief Constructor, used by \c process::get_self() only.
+ self_process();
+};
+
+
+/// \brief A collection of legacy interfaces for querying information about the
+/// current executing process.
+class Process {
+public:
+ /// \brief Return process memory usage.
+ /// This static function will return the total amount of memory allocated
+ /// by the process. This only counts the memory allocated via the malloc,
+ /// calloc and realloc functions and includes any "free" holes in the
+ /// allocated space.
+ static size_t GetMallocUsage();
+
+ /// This static function will set \p user_time to the amount of CPU time
+ /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
+ /// time spent in system (kernel) mode. If the operating system does not
+ /// support collection of these metrics, a zero TimeValue will be for both
+ /// values.
+ /// \param elapsed Returns the TimeValue::now() giving current time
+ /// \param user_time Returns the current amount of user time for the process
+ /// \param sys_time Returns the current amount of system time for the process
+ static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
+ TimeValue &sys_time);
+
+ /// This static function will return the process' current user id number.
+ /// Not all operating systems support this feature. Where it is not
+ /// supported, the function should return 65536 as the value.
+ static int GetCurrentUserId();
+
+ /// This static function will return the process' current group id number.
+ /// Not all operating systems support this feature. Where it is not
+ /// supported, the function should return 65536 as the value.
+ static int GetCurrentGroupId();
+
+ /// This function makes the necessary calls to the operating system to
+ /// prevent core files or any other kind of large memory dumps that can
+ /// occur when a program fails.
+ /// @brief Prevent core file generation.
+ static void PreventCoreFiles();
+
+ /// This function determines if the standard input is connected directly
+ /// to a user's input (keyboard probably), rather than coming from a file
+ /// or pipe.
+ static bool StandardInIsUserInput();
+
+ /// This function determines if the standard output is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardOutIsDisplayed();
+
+ /// This function determines if the standard error is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardErrIsDisplayed();
+
+ /// This function determines if the given file descriptor is connected to
+ /// a "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool FileDescriptorIsDisplayed(int fd);
+
+ /// This function determines if the given file descriptor is displayd and
+ /// supports colors.
+ static bool FileDescriptorHasColors(int fd);
+
+ /// This function determines the number of columns in the window
+ /// if standard output is connected to a "tty" or "console"
+ /// window. If standard output is not connected to a tty or
+ /// console, or if the number of columns cannot be determined,
+ /// this routine returns zero.
+ static unsigned StandardOutColumns();
+
+ /// This function determines the number of columns in the window
+ /// if standard error is connected to a "tty" or "console"
+ /// window. If standard error is not connected to a tty or
+ /// console, or if the number of columns cannot be determined,
+ /// this routine returns zero.
+ static unsigned StandardErrColumns();
+
+ /// This function determines whether the terminal connected to standard
+ /// output supports colors. If standard output is not connected to a
+ /// terminal, this function returns false.
+ static bool StandardOutHasColors();
+
+ /// This function determines whether the terminal connected to standard
+ /// error supports colors. If standard error is not connected to a
+ /// terminal, this function returns false.
+ static bool StandardErrHasColors();
+
+ /// Whether changing colors requires the output to be flushed.
+ /// This is needed on systems that don't support escape sequences for
+ /// changing colors.
+ static bool ColorNeedsFlush();
+
+ /// This function returns the colorcode escape sequences.
+ /// If ColorNeedsFlush() is true then this function will change the colors
+ /// and return an empty escape sequence. In that case it is the
+ /// responsibility of the client to flush the output stream prior to
+ /// calling this function.
+ static const char *OutputColor(char c, bool bold, bool bg);
+
+ /// Same as OutputColor, but only enables the bold attribute.
+ static const char *OutputBold(bool bg);
+
+ /// This function returns the escape sequence to reverse forground and
+ /// background colors.
+ static const char *OutputReverse();
+
+ /// Resets the terminals colors, or returns an escape sequence to do so.
+ static const char *ResetColor();
+
+ /// Get the result of a process wide random number generator. The
+ /// generator will be automatically seeded in non-deterministic fashion.
+ static unsigned GetRandomNumber();
+};
+
}
}
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index a85f235..028565d 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -34,19 +34,15 @@ namespace sys {
void *Data_;
// Noncopyable.
- Program(const Program& other);
- Program& operator=(const Program& other);
+ Program(const Program& other) LLVM_DELETED_FUNCTION;
+ Program& operator=(const Program& other) LLVM_DELETED_FUNCTION;
/// @name Methods
/// @{
- public:
Program();
~Program();
- /// Return process ID of this program.
- unsigned GetPid() const;
-
/// This function executes the program using the \p arguments provided. The
/// invoked program will inherit the stdin, stdout, and stderr file
/// descriptors, the environment and other configuration settings of the
@@ -103,17 +99,7 @@ namespace sys {
///< is non-empty upon return an error occurred while waiting.
);
- /// This function terminates the program.
- /// @returns true if an error occurred.
- /// @see Execute
- /// @brief Terminates the program.
- bool Kill
- ( std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
- ///< instance in which error messages will be returned. If the string
- ///< is non-empty upon return an error occurred while killing the
- ///< program.
- );
-
+ public:
/// This static constructor (factory) will attempt to locate a program in
/// the operating system's file system using some pre-determined set of
/// locations to search (e.g. the PATH on Unix). Paths with slashes are
diff --git a/include/llvm/Support/RWMutex.h b/include/llvm/Support/RWMutex.h
index 0d4cb81..935b307 100644
--- a/include/llvm/Support/RWMutex.h
+++ b/include/llvm/Support/RWMutex.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SYSTEM_RWMUTEX_H
#define LLVM_SYSTEM_RWMUTEX_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Threading.h"
#include <cassert>
@@ -75,8 +76,8 @@ namespace llvm
/// @name Do Not Implement
/// @{
private:
- RWMutexImpl(const RWMutexImpl & original);
- void operator=(const RWMutexImpl &);
+ RWMutexImpl(const RWMutexImpl & original) LLVM_DELETED_FUNCTION;
+ void operator=(const RWMutexImpl &) LLVM_DELETED_FUNCTION;
/// @}
};
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
index fa6e189..bcc561d 100644
--- a/include/llvm/Support/Recycler.h
+++ b/include/llvm/Support/Recycler.h
@@ -22,6 +22,8 @@
namespace llvm {
+class BumpPtrAllocator;
+
/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
/// printing statistics.
///
@@ -87,6 +89,15 @@ public:
}
}
+ /// Special case for BumpPtrAllocator which has an empty Deallocate()
+ /// function.
+ ///
+ /// There is no need to traverse the free list, pulling all the objects into
+ /// cache.
+ void clear(BumpPtrAllocator&) {
+ FreeList.clearAndLeakNodesUnsafely();
+ }
+
template<class SubClass, class AllocatorType>
SubClass *Allocate(AllocatorType &Allocator) {
assert(sizeof(SubClass) <= Size &&
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index 7648e77..82df2c6 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -7,7 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements a POSIX regular expression matcher.
+// This file implements a POSIX regular expression matcher. Both Basic and
+// Extended POSIX regular expressions (ERE) are supported. EREs were extended
+// to support backreferences in matches.
+// This implementation also supports matching strings with embedded NUL chars.
//
//===----------------------------------------------------------------------===//
@@ -33,12 +36,14 @@ namespace llvm {
/// null string after any newline in the string in addition to its normal
/// function, and the $ anchor matches the null string before any
/// newline in the string in addition to its normal function.
- Newline=2
+ Newline=2,
+ /// By default, the POSIX extended regular expression (ERE) syntax is
+ /// assumed. Pass this flag to turn on basic regular expressions (BRE)
+ /// instead.
+ BasicRegex=4
};
- /// Compiles the given POSIX Extended Regular Expression \arg Regex.
- /// This implementation supports regexes and matching strings with embedded
- /// NUL characters.
+ /// Compiles the given regular expression \p Regex.
Regex(StringRef Regex, unsigned Flags = NoFlags);
~Regex();
@@ -51,17 +56,17 @@ namespace llvm {
/// many entries plus one for the whole regex (as element 0).
unsigned getNumMatches() const;
- /// matches - Match the regex against a given \arg String.
+ /// matches - Match the regex against a given \p String.
///
/// \param Matches - If given, on a successful match this will be filled in
- /// with references to the matched group expressions (inside \arg String),
+ /// with references to the matched group expressions (inside \p String),
/// the first group is always the entire pattern.
///
/// This returns true on a successful match.
bool match(StringRef String, SmallVectorImpl<StringRef> *Matches = 0);
/// sub - Return the result of replacing the first match of the regex in
- /// \arg String with the \arg Repl string. Backreferences like "\0" in the
+ /// \p String with the \p Repl string. Backreferences like "\0" in the
/// replacement string are replaced with the appropriate match substring.
///
/// Note that the replacement string has backslash escaping performed on
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
index d0375be..29eafb6 100644
--- a/include/llvm/Support/Registry.h
+++ b/include/llvm/Support/Registry.h
@@ -37,7 +37,7 @@ namespace llvm {
/// is necessary to define an alternate traits class.
template <typename T>
class RegistryTraits {
- RegistryTraits(); // Do not implement.
+ RegistryTraits() LLVM_DELETED_FUNCTION;
public:
typedef SimpleRegistryEntry<T> entry;
@@ -63,7 +63,7 @@ namespace llvm {
class iterator;
private:
- Registry(); // Do not implement.
+ Registry() LLVM_DELETED_FUNCTION;
static void Announce(const entry &E) {
for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
@@ -120,6 +120,7 @@ namespace llvm {
/// Abstract base class for registry listeners, which are informed when new
/// entries are added to the registry. Simply subclass and instantiate:
///
+ /// \code
/// class CollectorPrinter : public Registry<Collector>::listener {
/// protected:
/// void registered(const Registry<Collector>::entry &e) {
@@ -131,7 +132,7 @@ namespace llvm {
/// };
///
/// CollectorPrinter Printer;
- ///
+ /// \endcode
class listener {
listener *Prev, *Next;
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
index 1bf810b..2b0e9df 100644
--- a/include/llvm/Support/SMLoc.h
+++ b/include/llvm/Support/SMLoc.h
@@ -19,7 +19,7 @@
namespace llvm {
-/// SMLoc - Represents a location in source code.
+/// Represents a location in source code.
class SMLoc {
const char *Ptr;
public:
@@ -39,9 +39,11 @@ public:
}
};
-/// SMRange - Represents a range in source code. Note that unlike standard STL
-/// ranges, the locations specified are considered to be *inclusive*. For
-/// example, [X,X] *does* include X, it isn't an empty range.
+/// Represents a range in source code.
+///
+/// SMRange is implemented using a half-open range, as is the convention in C++.
+/// In the string "abc", the range (1,3] represents the substring "bc", and the
+/// range (2,2] represents an empty range between the characters "b" and "c".
class SMRange {
public:
SMLoc Start, End;
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 3835e84..aaee344 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -16,8 +16,8 @@
#ifndef SUPPORT_SOURCEMGR_H
#define SUPPORT_SOURCEMGR_H
-#include "llvm/Support/SMLoc.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/SMLoc.h"
#include <string>
namespace llvm {
@@ -64,9 +64,9 @@ private:
DiagHandlerTy DiagHandler;
void *DiagContext;
-
- SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT
- void operator=(const SourceMgr&); // DO NOT IMPLEMENT
+
+ SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION;
+ void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
public:
SourceMgr() : LineNoCache(0), DiagHandler(0), DiagContext(0) {}
~SourceMgr();
@@ -95,6 +95,10 @@ public:
return Buffers[i].Buffer;
}
+ unsigned getNumBuffers() const {
+ return Buffers.size();
+ }
+
SMLoc getParentIncludeLoc(unsigned i) const {
assert(i < Buffers.size() && "Invalid Buffer ID!");
return Buffers[i].IncludeLoc;
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index 531dbb2..2e1163f 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -12,8 +12,9 @@
#define STREAMABLEMEMORYOBJECT_H_
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataStream.h"
+#include "llvm/Support/MemoryObject.h"
#include <vector>
namespace llvm {
@@ -107,14 +108,15 @@ class StreamableMemoryObject : public MemoryObject {
class StreamingMemoryObject : public StreamableMemoryObject {
public:
StreamingMemoryObject(DataStreamer *streamer);
- virtual uint64_t getBase() const { return 0; }
- virtual uint64_t getExtent() const;
- virtual int readByte(uint64_t address, uint8_t* ptr) const;
+ virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; }
+ virtual uint64_t getExtent() const LLVM_OVERRIDE;
+ virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE;
virtual int readBytes(uint64_t address,
uint64_t size,
uint8_t* buf,
- uint64_t* copied) const ;
- virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const {
+ uint64_t* copied) const LLVM_OVERRIDE;
+ virtual const uint8_t *getPointer(uint64_t address,
+ uint64_t size) const LLVM_OVERRIDE {
// This could be fixed by ensuring the bytes are fetched and making a copy,
// requiring that the bitcode size be known, or otherwise ensuring that
// the memory doesn't go away/get reallocated, but it's
@@ -122,8 +124,8 @@ public:
assert(0 && "getPointer in streaming memory objects not allowed");
return NULL;
}
- virtual bool isValidAddress(uint64_t address) const;
- virtual bool isObjectEnd(uint64_t address) const;
+ virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE;
+ virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE;
/// Drop s bytes from the front of the stream, pushing the positions of the
/// remaining bytes down by s. This is used to skip past the bitcode header,
@@ -170,8 +172,8 @@ private:
return true;
}
- StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT
- void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT
+ StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
+ void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
};
StreamableMemoryObject *getNonStreamedMemoryObject(
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index de05e0b..71adbc5 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -30,8 +30,8 @@
#define LLVM_SUPPORT_STRINGPOOL_H
#include "llvm/ADT/StringMap.h"
-#include <new>
#include <cassert>
+#include <new>
namespace llvm {
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index c65faa6..5c1978d 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -19,18 +19,18 @@
#ifndef LLVM_SUPPORT_TARGETFOLDER_H
#define LLVM_SUPPORT_TARGETFOLDER_H
-#include "llvm/Constants.h"
-#include "llvm/InstrTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
-class TargetData;
+class DataLayout;
/// TargetFolder - Create constants with target dependent folding.
class TargetFolder {
- const TargetData *TD;
+ const DataLayout *TD;
/// Fold - Fold the constant using target specific information.
Constant *Fold(Constant *C) const {
@@ -41,7 +41,7 @@ class TargetFolder {
}
public:
- explicit TargetFolder(const TargetData *TheTD) : TD(TheTD) {}
+ explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {}
//===--------------------------------------------------------------------===//
// Binary Operators
@@ -177,7 +177,14 @@ public:
return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
}
Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
- return ConstantExpr::getPointerCast(C, DestTy);
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getPointerCast(C, DestTy));
+ }
+ Constant *CreateFPCast(Constant *C, Type *DestTy) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getFPCast(C, DestTy));
}
Constant *CreateBitCast(Constant *C, Type *DestTy) const {
return CreateCast(Instruction::BitCast, C, DestTy);
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index c0be8f1..b06676d 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -19,10 +19,10 @@
#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
#define LLVM_SUPPORT_TARGETREGISTRY_H
-#include "llvm/Support/CodeGen.h"
#include "llvm/ADT/Triple.h"
-#include <string>
+#include "llvm/Support/CodeGen.h"
#include <cassert>
+#include <string>
namespace llvm {
class AsmPrinter;
@@ -41,7 +41,6 @@ namespace llvm {
class MCRegisterInfo;
class MCStreamer;
class MCSubtargetInfo;
- class MCTargetAsmLexer;
class MCTargetAsmParser;
class TargetMachine;
class TargetOptions;
@@ -93,10 +92,9 @@ namespace llvm {
CodeGenOpt::Level OL);
typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
MCStreamer &Streamer);
- typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT);
- typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T,
- const MCRegisterInfo &MRI,
- const MCAsmInfo &MAI);
+ typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
+ StringRef TT,
+ StringRef CPU);
typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
MCAsmParser &P);
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
@@ -180,10 +178,6 @@ namespace llvm {
/// MCAsmBackend, if registered.
MCAsmBackendCtorTy MCAsmBackendCtorFn;
- /// MCAsmLexerCtorFn - Construction function for this target's
- /// MCTargetAsmLexer, if registered.
- MCAsmLexerCtorTy MCAsmLexerCtorFn;
-
/// MCAsmParserCtorFn - Construction function for this target's
/// MCTargetAsmParser, if registered.
MCAsmParserCtorTy MCAsmParserCtorFn;
@@ -240,9 +234,6 @@ namespace llvm {
/// hasMCAsmBackend - Check if this target supports .o generation.
bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; }
- /// hasMCAsmLexer - Check if this target supports .s lexing.
- bool hasMCAsmLexer() const { return MCAsmLexerCtorFn != 0; }
-
/// hasAsmParser - Check if this target supports .s parsing.
bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; }
@@ -271,7 +262,7 @@ namespace llvm {
/// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
/// target triple.
///
- /// \arg Triple - This argument is used to determine the target machine
+ /// \param Triple This argument is used to determine the target machine
/// feature set; it should always be provided. Generally this should be
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
@@ -317,12 +308,12 @@ namespace llvm {
/// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
///
- /// \arg Triple - This argument is used to determine the target machine
+ /// \param Triple This argument is used to determine the target machine
/// feature set; it should always be provided. Generally this should be
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
- /// \arg CPU - This specifies the name of the target CPU.
- /// \arg Features - This specifies the string representation of the
+ /// \param CPU This specifies the name of the target CPU.
+ /// \param Features This specifies the string representation of the
/// additional target features.
MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
StringRef Features) const {
@@ -332,9 +323,9 @@ namespace llvm {
}
/// createTargetMachine - Create a target specific machine implementation
- /// for the specified \arg Triple.
+ /// for the specified \p Triple.
///
- /// \arg Triple - This argument is used to determine the target machine
+ /// \param Triple This argument is used to determine the target machine
/// feature set; it should always be provided. Generally this should be
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
@@ -351,26 +342,16 @@ namespace llvm {
/// createMCAsmBackend - Create a target specific assembly parser.
///
- /// \arg Triple - The target triple string.
- /// \arg Backend - The target independent assembler object.
- MCAsmBackend *createMCAsmBackend(StringRef Triple) const {
+ /// \param Triple The target triple string.
+ MCAsmBackend *createMCAsmBackend(StringRef Triple, StringRef CPU) const {
if (!MCAsmBackendCtorFn)
return 0;
- return MCAsmBackendCtorFn(*this, Triple);
- }
-
- /// createMCAsmLexer - Create a target specific assembly lexer.
- ///
- MCTargetAsmLexer *createMCAsmLexer(const MCRegisterInfo &MRI,
- const MCAsmInfo &MAI) const {
- if (!MCAsmLexerCtorFn)
- return 0;
- return MCAsmLexerCtorFn(*this, MRI, MAI);
+ return MCAsmBackendCtorFn(*this, Triple, CPU);
}
/// createMCAsmParser - Create a target specific assembly parser.
///
- /// \arg Parser - The target independent parser implementation to use for
+ /// \param Parser The target independent parser implementation to use for
/// parsing and lexing.
MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
MCAsmParser &Parser) const {
@@ -416,13 +397,13 @@ namespace llvm {
/// createMCObjectStreamer - Create a target specific MCStreamer.
///
- /// \arg TT - The target triple.
- /// \arg Ctx - The target context.
- /// \arg TAB - The target assembler backend object. Takes ownership.
- /// \arg _OS - The stream object.
- /// \arg _Emitter - The target independent assembler object.Takes ownership.
- /// \arg RelaxAll - Relax all fixups?
- /// \arg NoExecStack - Mark file as not needing a executable stack.
+ /// \param TT The target triple.
+ /// \param Ctx The target context.
+ /// \param TAB The target assembler backend object. Takes ownership.
+ /// \param _OS The stream object.
+ /// \param _Emitter The target independent assembler object.Takes ownership.
+ /// \param RelaxAll Relax all fixups?
+ /// \param NoExecStack Mark file as not needing a executable stack.
MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
MCAsmBackend &TAB,
raw_ostream &_OS,
@@ -675,20 +656,6 @@ namespace llvm {
T.MCAsmBackendCtorFn = Fn;
}
- /// RegisterMCAsmLexer - Register a MCTargetAsmLexer implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCAsmLexer for the target.
- static void RegisterMCAsmLexer(Target &T, Target::MCAsmLexerCtorTy Fn) {
- if (!T.MCAsmLexerCtorFn)
- T.MCAsmLexerCtorFn = Fn;
- }
-
/// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
/// the given target.
///
@@ -1063,30 +1030,9 @@ namespace llvm {
}
private:
- static MCAsmBackend *Allocator(const Target &T, StringRef Triple) {
- return new MCAsmBackendImpl(T, Triple);
- }
- };
-
- /// RegisterMCAsmLexer - Helper template for registering a target specific
- /// assembly lexer, for use in the target machine initialization
- /// function. Usage:
- ///
- /// extern "C" void LLVMInitializeFooMCAsmLexer() {
- /// extern Target TheFooTarget;
- /// RegisterMCAsmLexer<FooMCAsmLexer> X(TheFooTarget);
- /// }
- template<class MCAsmLexerImpl>
- struct RegisterMCAsmLexer {
- RegisterMCAsmLexer(Target &T) {
- TargetRegistry::RegisterMCAsmLexer(T, &Allocator);
- }
-
- private:
- static MCTargetAsmLexer *Allocator(const Target &T,
- const MCRegisterInfo &MRI,
- const MCAsmInfo &MAI) {
- return new MCAsmLexerImpl(T, MRI, MAI);
+ static MCAsmBackend *Allocator(const Target &T, StringRef Triple,
+ StringRef CPU) {
+ return new MCAsmBackendImpl(T, Triple, CPU);
}
};
diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h
index 62ec90a..01f735c 100644
--- a/include/llvm/Support/ThreadLocal.h
+++ b/include/llvm/Support/ThreadLocal.h
@@ -14,8 +14,8 @@
#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
#define LLVM_SYSTEM_THREAD_LOCAL_H
-#include "llvm/Support/Threading.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Threading.h"
#include <cassert>
namespace llvm {
diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h
index c0e842c..9017afb 100644
--- a/include/llvm/Support/Threading.h
+++ b/include/llvm/Support/Threading.h
@@ -41,8 +41,8 @@ namespace llvm {
/// before llvm_start_multithreaded().
void llvm_release_global_lock();
- /// llvm_execute_on_thread - Execute the given \arg UserFn on a separate
- /// thread, passing it the provided \arg UserData.
+ /// llvm_execute_on_thread - Execute the given \p UserFn on a separate
+ /// thread, passing it the provided \p UserData.
///
/// This function does not guarantee that the code will actually be executed
/// on a separate thread or honoring the requested stack size, but tries to do
diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
index e780b50..ab7401a 100644
--- a/include/llvm/Support/TimeValue.h
+++ b/include/llvm/Support/TimeValue.h
@@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/DataTypes.h"
-#include <string>
-
#ifndef LLVM_SYSTEM_TIMEVALUE_H
#define LLVM_SYSTEM_TIMEVALUE_H
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
namespace llvm {
namespace sys {
/// This class is used where a precise fixed point in time is required. The
@@ -82,6 +82,9 @@ namespace sys {
/// @name Constructors
/// @{
public:
+ /// \brief Default construct a time value, initializing to ZeroTime.
+ TimeValue() : seconds_(0), nanos_(0) {}
+
/// Caller provides the exact value in seconds and nanoseconds. The
/// \p nanos argument defaults to zero for convenience.
/// @brief Explicit constructor
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index 404cb6d..789c05f 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -15,12 +15,13 @@
#ifndef LLVM_SUPPORT_TIMER_H
#define LLVM_SUPPORT_TIMER_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <string>
-#include <vector>
#include <utility>
+#include <vector>
namespace llvm {
@@ -130,7 +131,7 @@ private:
///
class TimeRegion {
Timer *T;
- TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT
+ TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION;
public:
explicit TimeRegion(Timer &t) : T(&t) {
T->startTimer();
@@ -168,8 +169,8 @@ class TimerGroup {
std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's.
- TimerGroup(const TimerGroup &TG); // DO NOT IMPLEMENT
- void operator=(const TimerGroup &TG); // DO NOT IMPLEMENT
+ TimerGroup(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
+ void operator=(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
public:
explicit TimerGroup(StringRef name);
~TimerGroup();
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index e147647..a1397db 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -16,8 +16,8 @@
#ifndef LLVM_SYSTEM_VALGRIND_H
#define LLVM_SYSTEM_VALGRIND_H
-#include "llvm/Support/Compiler.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Compiler.h"
#include <stddef.h>
#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index 61e21b8..db44995 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -16,7 +16,7 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Value.h"
+#include "llvm/IR/Value.h"
namespace llvm {
class ValueHandleBase;
@@ -59,8 +59,8 @@ private:
// pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
// access.
PointerIntPair<Value*, 2> VP;
-
- explicit ValueHandleBase(const ValueHandleBase&); // DO NOT IMPLEMENT.
+
+ ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION;
public:
explicit ValueHandleBase(HandleBaseKind Kind)
: PrevPair(0, Kind), Next(0), VP(0, 0) {}
diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h
index 8d74e10..164aca1 100644
--- a/include/llvm/Support/Win64EH.h
+++ b/include/llvm/Support/Win64EH.h
@@ -17,6 +17,7 @@
#define LLVM_SUPPORT_WIN64EH_H
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
namespace llvm {
namespace Win64EH {
@@ -39,11 +40,17 @@ enum UnwindOpcodes {
/// or part thereof.
union UnwindCode {
struct {
- uint8_t codeOffset;
- uint8_t unwindOp:4,
- opInfo:4;
+ support::ulittle8_t CodeOffset;
+ support::ulittle8_t UnwindOpAndOpInfo;
} u;
- uint16_t frameOffset;
+ support::ulittle16_t FrameOffset;
+
+ uint8_t getUnwindOp() const {
+ return u.UnwindOpAndOpInfo & 0x0F;
+ }
+ uint8_t getOpInfo() const {
+ return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
+ }
};
enum {
@@ -60,37 +67,65 @@ enum {
/// RuntimeFunction - An entry in the table of functions with unwind info.
struct RuntimeFunction {
- uint64_t startAddress;
- uint64_t endAddress;
- uint64_t unwindInfoOffset;
+ support::ulittle32_t StartAddress;
+ support::ulittle32_t EndAddress;
+ support::ulittle32_t UnwindInfoOffset;
};
/// UnwindInfo - An entry in the exception table.
struct UnwindInfo {
- uint8_t version:3,
- flags:5;
- uint8_t prologSize;
- uint8_t numCodes;
- uint8_t frameRegister:4,
- frameOffset:4;
- UnwindCode unwindCodes[1];
+ support::ulittle8_t VersionAndFlags;
+ support::ulittle8_t PrologSize;
+ support::ulittle8_t NumCodes;
+ support::ulittle8_t FrameRegisterAndOffset;
+ UnwindCode UnwindCodes[1];
- void *getLanguageSpecificData() {
- return reinterpret_cast<void *>(&unwindCodes[(numCodes+1) & ~1]);
+ uint8_t getVersion() const {
+ return VersionAndFlags & 0x07;
}
- uint64_t getLanguageSpecificHandlerOffset() {
- return *reinterpret_cast<uint64_t *>(getLanguageSpecificData());
+ uint8_t getFlags() const {
+ return (VersionAndFlags >> 3) & 0x1f;
}
- void setLanguageSpecificHandlerOffset(uint64_t offset) {
- *reinterpret_cast<uint64_t *>(getLanguageSpecificData()) = offset;
+ uint8_t getFrameRegister() const {
+ return FrameRegisterAndOffset & 0x0f;
}
- RuntimeFunction *getChainedFunctionEntry() {
- return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
+ uint8_t getFrameOffset() const {
+ return (FrameRegisterAndOffset >> 4) & 0x0f;
+ }
+
+ // The data after unwindCodes depends on flags.
+ // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
+ // the address of the language-specific exception handler.
+ // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
+ // the chained unwind info.
+ // For more information please see MSDN at:
+ // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
+
+ /// \brief Return pointer to language specific data part of UnwindInfo.
+ void *getLanguageSpecificData() {
+ return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
}
+
+ /// \brief Return image-relativ offset of language-specific exception handler.
+ uint32_t getLanguageSpecificHandlerOffset() {
+ return *reinterpret_cast<uint32_t *>(getLanguageSpecificData());
+ }
+
+ /// \brief Set image-relativ offset of language-specific exception handler.
+ void setLanguageSpecificHandlerOffset(uint32_t offset) {
+ *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset;
+ }
+
+ /// \brief Return pointer to exception-specific data.
void *getExceptionData() {
- return reinterpret_cast<void *>(reinterpret_cast<uint64_t *>(
+ return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
getLanguageSpecificData())+1);
}
+
+ /// \brief Return pointer to chained unwind info.
+ RuntimeFunction *getChainedFunctionEntry() {
+ return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
+ }
};
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 98910eb..5b728bc 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -43,7 +43,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
-
#include <limits>
#include <utility>
@@ -77,7 +76,11 @@ std::string escape(StringRef Input);
/// documents.
class Stream {
public:
+ /// @brief This keeps a reference to the string referenced by \p Input.
Stream(StringRef Input, SourceMgr &);
+
+ /// @brief This takes ownership of \p InputBuffer.
+ Stream(MemoryBuffer *InputBuffer, SourceMgr &);
~Stream();
document_iterator begin();
@@ -133,7 +136,6 @@ public:
virtual void skip() {}
unsigned int getType() const { return TypeID; }
- static inline bool classof(const Node *) { return true; }
void *operator new ( size_t Size
, BumpPtrAllocator &Alloc
@@ -166,7 +168,6 @@ class NullNode : public Node {
public:
NullNode(OwningPtr<Document> &D) : Node(NK_Null, D, StringRef()) {}
- static inline bool classof(const NullNode *) { return true; }
static inline bool classof(const Node *N) {
return N->getType() == NK_Null;
}
@@ -183,7 +184,7 @@ public:
: Node(NK_Scalar, D, Anchor)
, Value(Val) {
SMLoc Start = SMLoc::getFromPointer(Val.begin());
- SMLoc End = SMLoc::getFromPointer(Val.end() - 1);
+ SMLoc End = SMLoc::getFromPointer(Val.end());
SourceRange = SMRange(Start, End);
}
@@ -199,7 +200,6 @@ public:
/// This happens with escaped characters and multi-line literals.
StringRef getValue(SmallVectorImpl<char> &Storage) const;
- static inline bool classof(const ScalarNode *) { return true; }
static inline bool classof(const Node *N) {
return N->getType() == NK_Scalar;
}
@@ -241,12 +241,11 @@ public:
/// @returns The value, or nullptr if failed() == true.
Node *getValue();
- virtual void skip() {
+ virtual void skip() LLVM_OVERRIDE {
getKey()->skip();
getValue()->skip();
}
- static inline bool classof(const KeyValueNode *) { return true; }
static inline bool classof(const Node *N) {
return N->getType() == NK_KeyValue;
}
@@ -358,11 +357,10 @@ public:
iterator end() { return iterator(); }
- virtual void skip() {
+ virtual void skip() LLVM_OVERRIDE {
yaml::skip(*this);
}
- static inline bool classof(const MappingNode *) { return true; }
static inline bool classof(const Node *N) {
return N->getType() == NK_Mapping;
}
@@ -421,11 +419,10 @@ public:
iterator end() { return iterator(); }
- virtual void skip() {
+ virtual void skip() LLVM_OVERRIDE {
yaml::skip(*this);
}
- static inline bool classof(const SequenceNode *) { return true; }
static inline bool classof(const Node *N) {
return N->getType() == NK_Sequence;
}
@@ -450,7 +447,6 @@ public:
StringRef getName() const { return Name; }
Node *getTarget();
- static inline bool classof(const ScalarNode *) { return true; }
static inline bool classof(const Node *N) {
return N->getType() == NK_Alias;
}
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
new file mode 100644
index 0000000..1862286
--- /dev/null
+++ b/include/llvm/Support/YAMLTraits.h
@@ -0,0 +1,1104 @@
+//===- llvm/Supporrt/YAMLTraits.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_YAML_TRAITS_H_
+#define LLVM_YAML_TRAITS_H_
+
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/Support/type_traits.h"
+
+
+namespace llvm {
+namespace yaml {
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a YAML mapping. For example:
+///
+/// struct ScalarBitSetTraits<MyStruct> {
+/// static void mapping(IO &io, MyStruct &s) {
+/// io.mapRequired("name", s.name);
+/// io.mapRequired("size", s.size);
+/// io.mapOptional("age", s.age);
+/// }
+/// };
+template<class T>
+struct MappingTraits {
+ // Must provide:
+ // static void mapping(IO &io, T &fields);
+};
+
+
+/// This class should be specialized by any integral type that converts
+/// to/from a YAML scalar where there is a one-to-one mapping between
+/// in-memory values and a string in YAML. For example:
+///
+/// struct ScalarEnumerationTraits<Colors> {
+/// static void enumeration(IO &io, Colors &value) {
+/// io.enumCase(value, "red", cRed);
+/// io.enumCase(value, "blue", cBlue);
+/// io.enumCase(value, "green", cGreen);
+/// }
+/// };
+template<typename T>
+struct ScalarEnumerationTraits {
+ // Must provide:
+ // static void enumeration(IO &io, T &value);
+};
+
+
+/// This class should be specialized by any integer type that is a union
+/// of bit values and the YAML representation is a flow sequence of
+/// strings. For example:
+///
+/// struct ScalarBitSetTraits<MyFlags> {
+/// static void bitset(IO &io, MyFlags &value) {
+/// io.bitSetCase(value, "big", flagBig);
+/// io.bitSetCase(value, "flat", flagFlat);
+/// io.bitSetCase(value, "round", flagRound);
+/// }
+/// };
+template<typename T>
+struct ScalarBitSetTraits {
+ // Must provide:
+ // static void bitset(IO &io, T &value);
+};
+
+
+/// This class should be specialized by type that requires custom conversion
+/// to/from a yaml scalar. For example:
+///
+/// template<>
+/// struct ScalarTraits<MyType> {
+/// static void output(const MyType &val, void*, llvm::raw_ostream &out) {
+/// // stream out custom formatting
+/// out << llvm::format("%x", val);
+/// }
+/// static StringRef input(StringRef scalar, void*, MyType &value) {
+/// // parse scalar and set `value`
+/// // return empty string on success, or error string
+/// return StringRef();
+/// }
+/// };
+template<typename T>
+struct ScalarTraits {
+ // Must provide:
+ //
+ // Function to write the value as a string:
+ //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
+ //
+ // Function to convert a string to a value. Returns the empty
+ // StringRef on success or an error string if string is malformed:
+ //static StringRef input(StringRef scalar, void *ctxt, T &value);
+};
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a YAML sequence. For example:
+///
+/// template<>
+/// struct SequenceTraits< std::vector<MyType> > {
+/// static size_t size(IO &io, std::vector<MyType> &seq) {
+/// return seq.size();
+/// }
+/// static MyType& element(IO &, std::vector<MyType> &seq, size_t index) {
+/// if ( index >= seq.size() )
+/// seq.resize(index+1);
+/// return seq[index];
+/// }
+/// };
+template<typename T>
+struct SequenceTraits {
+ // Must provide:
+ // static size_t size(IO &io, T &seq);
+ // static T::value_type& element(IO &io, T &seq, size_t index);
+ //
+ // The following is option and will cause generated YAML to use
+ // a flow sequence (e.g. [a,b,c]).
+ // static const bool flow = true;
+};
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a list of YAML documents.
+template<typename T>
+struct DocumentListTraits {
+ // Must provide:
+ // static size_t size(IO &io, T &seq);
+ // static T::value_type& element(IO &io, T &seq, size_t index);
+};
+
+
+// Only used by compiler if both template types are the same
+template <typename T, T>
+struct SameType;
+
+// Only used for better diagnostics of missing traits
+template <typename T>
+struct MissingTrait;
+
+
+
+// Test if ScalarEnumerationTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarEnumerationTraits
+{
+ typedef void (*Signature_enumeration)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_enumeration, &U::enumeration>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<ScalarEnumerationTraits<T> >(0)) == 1);
+};
+
+
+// Test if ScalarBitSetTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarBitSetTraits
+{
+ typedef void (*Signature_bitset)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_bitset, &U::bitset>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(0)) == 1);
+};
+
+
+// Test if ScalarTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarTraits
+{
+ typedef llvm::StringRef (*Signature_input)(llvm::StringRef, void*, T&);
+ typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
+
+ template <typename U>
+ static char test(SameType<Signature_input, &U::input>*,
+ SameType<Signature_output, &U::output>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<ScalarTraits<T> >(0,0)) == 1);
+};
+
+
+// Test if MappingTraits<T> is defined on type T.
+template <class T>
+struct has_MappingTraits
+{
+ typedef void (*Signature_mapping)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_mapping, &U::mapping>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
+};
+
+
+// Test if SequenceTraits<T> is defined on type T.
+template <class T>
+struct has_SequenceMethodTraits
+{
+ typedef size_t (*Signature_size)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_size, &U::size>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<SequenceTraits<T> >(0)) == 1);
+};
+
+
+// has_FlowTraits<int> will cause an error with some compilers because
+// it subclasses int. Using this wrapper only instantiates the
+// real has_FlowTraits only if the template type is a class.
+template <typename T, bool Enabled = llvm::is_class<T>::value>
+class has_FlowTraits
+{
+public:
+ static const bool value = false;
+};
+
+// Some older gcc compilers don't support straight forward tests
+// for members, so test for ambiguity cause by the base and derived
+// classes both defining the member.
+template <class T>
+struct has_FlowTraits<T, true>
+{
+ struct Fallback { bool flow; };
+ struct Derived : T, Fallback { };
+
+ template<typename C>
+ static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
+
+ template<typename C>
+ static char (&f(...))[2];
+
+public:
+ static bool const value = sizeof(f<Derived>(0)) == 2;
+};
+
+
+
+// Test if SequenceTraits<T> is defined on type T
+template<typename T>
+struct has_SequenceTraits : public llvm::integral_constant<bool,
+ has_SequenceMethodTraits<T>::value > { };
+
+
+// Test if DocumentListTraits<T> is defined on type T
+template <class T>
+struct has_DocumentListTraits
+{
+ typedef size_t (*Signature_size)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_size, &U::size>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<DocumentListTraits<T> >(0)) == 1);
+};
+
+
+
+
+template<typename T>
+struct missingTraits : public llvm::integral_constant<bool,
+ !has_ScalarEnumerationTraits<T>::value
+ && !has_ScalarBitSetTraits<T>::value
+ && !has_ScalarTraits<T>::value
+ && !has_MappingTraits<T>::value
+ && !has_SequenceTraits<T>::value
+ && !has_DocumentListTraits<T>::value > {};
+
+
+// Base class for Input and Output.
+class IO {
+public:
+
+ IO(void *Ctxt=NULL);
+ virtual ~IO();
+
+ virtual bool outputting() = 0;
+
+ virtual unsigned beginSequence() = 0;
+ virtual bool preflightElement(unsigned, void *&) = 0;
+ virtual void postflightElement(void*) = 0;
+ virtual void endSequence() = 0;
+
+ virtual unsigned beginFlowSequence() = 0;
+ virtual bool preflightFlowElement(unsigned, void *&) = 0;
+ virtual void postflightFlowElement(void*) = 0;
+ virtual void endFlowSequence() = 0;
+
+ virtual void beginMapping() = 0;
+ virtual void endMapping() = 0;
+ virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
+ virtual void postflightKey(void*) = 0;
+
+ virtual void beginEnumScalar() = 0;
+ virtual bool matchEnumScalar(const char*, bool) = 0;
+ virtual void endEnumScalar() = 0;
+
+ virtual bool beginBitSetScalar(bool &) = 0;
+ virtual bool bitSetMatch(const char*, bool) = 0;
+ virtual void endBitSetScalar() = 0;
+
+ virtual void scalarString(StringRef &) = 0;
+
+ virtual void setError(const Twine &) = 0;
+
+ template <typename T>
+ void enumCase(T &Val, const char* Str, const T ConstVal) {
+ if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
+ Val = ConstVal;
+ }
+ }
+
+ // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
+ template <typename T>
+ void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
+ if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
+ Val = ConstVal;
+ }
+ }
+
+ template <typename T>
+ void bitSetCase(T &Val, const char* Str, const T ConstVal) {
+ if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
+ Val = Val | ConstVal;
+ }
+ }
+
+ // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
+ template <typename T>
+ void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
+ if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
+ Val = Val | ConstVal;
+ }
+ }
+
+ void *getContext();
+ void setContext(void *);
+
+ template <typename T>
+ void mapRequired(const char* Key, T& Val) {
+ this->processKey(Key, Val, true);
+ }
+
+ template <typename T>
+ typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
+ mapOptional(const char* Key, T& Val) {
+ // omit key/value instead of outputting empty sequence
+ if ( this->outputting() && !(Val.begin() != Val.end()) )
+ return;
+ this->processKey(Key, Val, false);
+ }
+
+ template <typename T>
+ typename llvm::enable_if_c<!has_SequenceTraits<T>::value,void>::type
+ mapOptional(const char* Key, T& Val) {
+ this->processKey(Key, Val, false);
+ }
+
+ template <typename T>
+ void mapOptional(const char* Key, T& Val, const T& Default) {
+ this->processKeyWithDefault(Key, Val, Default, false);
+ }
+
+
+private:
+ template <typename T>
+ void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
+ bool Required) {
+ void *SaveInfo;
+ bool UseDefault;
+ const bool sameAsDefault = outputting() && Val == DefaultValue;
+ if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+ SaveInfo) ) {
+ yamlize(*this, Val, Required);
+ this->postflightKey(SaveInfo);
+ }
+ else {
+ if ( UseDefault )
+ Val = DefaultValue;
+ }
+ }
+
+ template <typename T>
+ void processKey(const char *Key, T &Val, bool Required) {
+ void *SaveInfo;
+ bool UseDefault;
+ if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
+ yamlize(*this, Val, Required);
+ this->postflightKey(SaveInfo);
+ }
+ }
+
+private:
+ void *Ctxt;
+};
+
+
+
+template<typename T>
+typename llvm::enable_if_c<has_ScalarEnumerationTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+ io.beginEnumScalar();
+ ScalarEnumerationTraits<T>::enumeration(io, Val);
+ io.endEnumScalar();
+}
+
+template<typename T>
+typename llvm::enable_if_c<has_ScalarBitSetTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+ bool DoClear;
+ if ( io.beginBitSetScalar(DoClear) ) {
+ if ( DoClear )
+ Val = static_cast<T>(0);
+ ScalarBitSetTraits<T>::bitset(io, Val);
+ io.endBitSetScalar();
+ }
+}
+
+
+template<typename T>
+typename llvm::enable_if_c<has_ScalarTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+ if ( io.outputting() ) {
+ std::string Storage;
+ llvm::raw_string_ostream Buffer(Storage);
+ ScalarTraits<T>::output(Val, io.getContext(), Buffer);
+ StringRef Str = Buffer.str();
+ io.scalarString(Str);
+ }
+ else {
+ StringRef Str;
+ io.scalarString(Str);
+ StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
+ if ( !Result.empty() ) {
+ io.setError(llvm::Twine(Result));
+ }
+ }
+}
+
+
+template<typename T>
+typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+ io.beginMapping();
+ MappingTraits<T>::mapping(io, Val);
+ io.endMapping();
+}
+
+template<typename T>
+typename llvm::enable_if_c<missingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+ char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+}
+
+template<typename T>
+typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
+yamlize(IO &io, T &Seq, bool) {
+ if ( has_FlowTraits< SequenceTraits<T> >::value ) {
+ unsigned incnt = io.beginFlowSequence();
+ unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
+ for(unsigned i=0; i < count; ++i) {
+ void *SaveInfo;
+ if ( io.preflightFlowElement(i, SaveInfo) ) {
+ yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
+ io.postflightFlowElement(SaveInfo);
+ }
+ }
+ io.endFlowSequence();
+ }
+ else {
+ unsigned incnt = io.beginSequence();
+ unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
+ for(unsigned i=0; i < count; ++i) {
+ void *SaveInfo;
+ if ( io.preflightElement(i, SaveInfo) ) {
+ yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
+ io.postflightElement(SaveInfo);
+ }
+ }
+ io.endSequence();
+ }
+}
+
+
+template<>
+struct ScalarTraits<bool> {
+ static void output(const bool &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, bool &);
+};
+
+template<>
+struct ScalarTraits<StringRef> {
+ static void output(const StringRef &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, StringRef &);
+};
+
+template<>
+struct ScalarTraits<uint8_t> {
+ static void output(const uint8_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, uint8_t &);
+};
+
+template<>
+struct ScalarTraits<uint16_t> {
+ static void output(const uint16_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, uint16_t &);
+};
+
+template<>
+struct ScalarTraits<uint32_t> {
+ static void output(const uint32_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, uint32_t &);
+};
+
+template<>
+struct ScalarTraits<uint64_t> {
+ static void output(const uint64_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, uint64_t &);
+};
+
+template<>
+struct ScalarTraits<int8_t> {
+ static void output(const int8_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, int8_t &);
+};
+
+template<>
+struct ScalarTraits<int16_t> {
+ static void output(const int16_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, int16_t &);
+};
+
+template<>
+struct ScalarTraits<int32_t> {
+ static void output(const int32_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, int32_t &);
+};
+
+template<>
+struct ScalarTraits<int64_t> {
+ static void output(const int64_t &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, int64_t &);
+};
+
+template<>
+struct ScalarTraits<float> {
+ static void output(const float &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, float &);
+};
+
+template<>
+struct ScalarTraits<double> {
+ static void output(const double &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, double &);
+};
+
+
+
+// Utility for use within MappingTraits<>::mapping() method
+// to [de]normalize an object for use with YAML conversion.
+template <typename TNorm, typename TFinal>
+struct MappingNormalization {
+ MappingNormalization(IO &i_o, TFinal &Obj)
+ : io(i_o), BufPtr(NULL), Result(Obj) {
+ if ( io.outputting() ) {
+ BufPtr = new (&Buffer) TNorm(io, Obj);
+ }
+ else {
+ BufPtr = new (&Buffer) TNorm(io);
+ }
+ }
+
+ ~MappingNormalization() {
+ if ( ! io.outputting() ) {
+ Result = BufPtr->denormalize(io);
+ }
+ BufPtr->~TNorm();
+ }
+
+ TNorm* operator->() { return BufPtr; }
+
+private:
+ typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+
+ Storage Buffer;
+ IO &io;
+ TNorm *BufPtr;
+ TFinal &Result;
+};
+
+
+
+// Utility for use within MappingTraits<>::mapping() method
+// to [de]normalize an object for use with YAML conversion.
+template <typename TNorm, typename TFinal>
+struct MappingNormalizationHeap {
+ MappingNormalizationHeap(IO &i_o, TFinal &Obj)
+ : io(i_o), BufPtr(NULL), Result(Obj) {
+ if ( io.outputting() ) {
+ BufPtr = new (&Buffer) TNorm(io, Obj);
+ }
+ else {
+ BufPtr = new TNorm(io);
+ }
+ }
+
+ ~MappingNormalizationHeap() {
+ if ( io.outputting() ) {
+ BufPtr->~TNorm();
+ }
+ else {
+ Result = BufPtr->denormalize(io);
+ }
+ }
+
+ TNorm* operator->() { return BufPtr; }
+
+private:
+ typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+
+ Storage Buffer;
+ IO &io;
+ TNorm *BufPtr;
+ TFinal &Result;
+};
+
+
+
+///
+/// The Input class is used to parse a yaml document into in-memory structs
+/// and vectors.
+///
+/// It works by using YAMLParser to do a syntax parse of the entire yaml
+/// document, then the Input class builds a graph of HNodes which wraps
+/// each yaml Node. The extra layer is buffering. The low level yaml
+/// parser only lets you look at each node once. The buffering layer lets
+/// you search and interate multiple times. This is necessary because
+/// the mapRequired() method calls may not be in the same order
+/// as the keys in the document.
+///
+class Input : public IO {
+public:
+ // Construct a yaml Input object from a StringRef and optional user-data.
+ Input(StringRef InputContent, void *Ctxt=NULL);
+ ~Input();
+
+ // Check if there was an syntax or semantic error during parsing.
+ llvm::error_code error();
+
+ // To set alternate error reporting.
+ void setDiagHandler(llvm::SourceMgr::DiagHandlerTy Handler, void *Ctxt = 0);
+
+private:
+ virtual bool outputting();
+ virtual void beginMapping();
+ virtual void endMapping();
+ virtual bool preflightKey(const char *, bool, bool, bool &, void *&);
+ virtual void postflightKey(void *);
+ virtual unsigned beginSequence();
+ virtual void endSequence();
+ virtual bool preflightElement(unsigned index, void *&);
+ virtual void postflightElement(void *);
+ virtual unsigned beginFlowSequence();
+ virtual bool preflightFlowElement(unsigned , void *&);
+ virtual void postflightFlowElement(void *);
+ virtual void endFlowSequence();
+ virtual void beginEnumScalar();
+ virtual bool matchEnumScalar(const char*, bool);
+ virtual void endEnumScalar();
+ virtual bool beginBitSetScalar(bool &);
+ virtual bool bitSetMatch(const char *, bool );
+ virtual void endBitSetScalar();
+ virtual void scalarString(StringRef &);
+ virtual void setError(const Twine &message);
+
+ class HNode {
+ public:
+ HNode(Node *n) : _node(n) { }
+ virtual ~HNode() { }
+ static inline bool classof(const HNode *) { return true; }
+
+ Node *_node;
+ };
+
+ class EmptyHNode : public HNode {
+ public:
+ EmptyHNode(Node *n) : HNode(n) { }
+ virtual ~EmptyHNode() {}
+ static inline bool classof(const HNode *n) {
+ return NullNode::classof(n->_node);
+ }
+ static inline bool classof(const EmptyHNode *) { return true; }
+ };
+
+ class ScalarHNode : public HNode {
+ public:
+ ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
+ virtual ~ScalarHNode() { }
+
+ StringRef value() const { return _value; }
+
+ static inline bool classof(const HNode *n) {
+ return ScalarNode::classof(n->_node);
+ }
+ static inline bool classof(const ScalarHNode *) { return true; }
+ protected:
+ StringRef _value;
+ };
+
+ class MapHNode : public HNode {
+ public:
+ MapHNode(Node *n) : HNode(n) { }
+ virtual ~MapHNode();
+
+ static inline bool classof(const HNode *n) {
+ return MappingNode::classof(n->_node);
+ }
+ static inline bool classof(const MapHNode *) { return true; }
+
+ struct StrMappingInfo {
+ static StringRef getEmptyKey() { return StringRef(); }
+ static StringRef getTombstoneKey() { return StringRef(" ", 0); }
+ static unsigned getHashValue(StringRef const val) {
+ return llvm::HashString(val); }
+ static bool isEqual(StringRef const lhs,
+ StringRef const rhs) { return lhs.equals(rhs); }
+ };
+ typedef llvm::DenseMap<StringRef, HNode*, StrMappingInfo> NameToNode;
+
+ bool isValidKey(StringRef key);
+
+ NameToNode Mapping;
+ llvm::SmallVector<const char*, 6> ValidKeys;
+ };
+
+ class SequenceHNode : public HNode {
+ public:
+ SequenceHNode(Node *n) : HNode(n) { }
+ virtual ~SequenceHNode();
+
+ static inline bool classof(const HNode *n) {
+ return SequenceNode::classof(n->_node);
+ }
+ static inline bool classof(const SequenceHNode *) { return true; }
+
+ std::vector<HNode*> Entries;
+ };
+
+ Input::HNode *createHNodes(Node *node);
+ void setError(HNode *hnode, const Twine &message);
+ void setError(Node *node, const Twine &message);
+
+
+public:
+ // These are only used by operator>>. They could be private
+ // if those templated things could be made friends.
+ bool setCurrentDocument();
+ void nextDocument();
+
+private:
+ llvm::SourceMgr SrcMgr; // must be before Strm
+ OwningPtr<llvm::yaml::Stream> Strm;
+ OwningPtr<HNode> TopNode;
+ llvm::error_code EC;
+ llvm::BumpPtrAllocator StringAllocator;
+ llvm::yaml::document_iterator DocIterator;
+ std::vector<bool> BitValuesUsed;
+ HNode *CurrentNode;
+ bool ScalarMatchFound;
+};
+
+
+
+
+///
+/// The Output class is used to generate a yaml document from in-memory structs
+/// and vectors.
+///
+class Output : public IO {
+public:
+ Output(llvm::raw_ostream &, void *Ctxt=NULL);
+ virtual ~Output();
+
+ virtual bool outputting();
+ virtual void beginMapping();
+ virtual void endMapping();
+ virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);
+ virtual void postflightKey(void *);
+ virtual unsigned beginSequence();
+ virtual void endSequence();
+ virtual bool preflightElement(unsigned, void *&);
+ virtual void postflightElement(void *);
+ virtual unsigned beginFlowSequence();
+ virtual bool preflightFlowElement(unsigned, void *&);
+ virtual void postflightFlowElement(void *);
+ virtual void endFlowSequence();
+ virtual void beginEnumScalar();
+ virtual bool matchEnumScalar(const char*, bool);
+ virtual void endEnumScalar();
+ virtual bool beginBitSetScalar(bool &);
+ virtual bool bitSetMatch(const char *, bool );
+ virtual void endBitSetScalar();
+ virtual void scalarString(StringRef &);
+ virtual void setError(const Twine &message);
+
+public:
+ // These are only used by operator<<. They could be private
+ // if that templated operator could be made a friend.
+ void beginDocuments();
+ bool preflightDocument(unsigned);
+ void postflightDocument();
+ void endDocuments();
+
+private:
+ void output(StringRef s);
+ void outputUpToEndOfLine(StringRef s);
+ void newLineCheck();
+ void outputNewLine();
+ void paddedKey(StringRef key);
+
+ enum InState { inSeq, inFlowSeq, inMapFirstKey, inMapOtherKey };
+
+ llvm::raw_ostream &Out;
+ SmallVector<InState, 8> StateStack;
+ int Column;
+ int ColumnAtFlowStart;
+ bool NeedBitValueComma;
+ bool NeedFlowSequenceComma;
+ bool EnumerationMatchFound;
+ bool NeedsNewLine;
+};
+
+
+
+
+/// YAML I/O does conversion based on types. But often native data types
+/// are just a typedef of built in intergral types (e.g. int). But the C++
+/// type matching system sees through the typedef and all the typedefed types
+/// look like a built in type. This will cause the generic YAML I/O conversion
+/// to be used. To provide better control over the YAML conversion, you can
+/// use this macro instead of typedef. It will create a class with one field
+/// and automatic conversion operators to and from the base type.
+/// Based on BOOST_STRONG_TYPEDEF
+#define LLVM_YAML_STRONG_TYPEDEF(_base, _type) \
+ struct _type { \
+ _type() { } \
+ _type(const _base v) : value(v) { } \
+ _type(const _type &v) : value(v.value) {} \
+ _type &operator=(const _type &rhs) { value = rhs.value; return *this; }\
+ _type &operator=(const _base &rhs) { value = rhs; return *this; } \
+ operator const _base & () const { return value; } \
+ bool operator==(const _type &rhs) const { return value == rhs.value; } \
+ bool operator==(const _base &rhs) const { return value == rhs; } \
+ bool operator<(const _type &rhs) const { return value < rhs.value; } \
+ _base value; \
+ };
+
+
+
+///
+/// Use these types instead of uintXX_t in any mapping to have
+/// its yaml output formatted as hexadecimal.
+///
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
+LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
+
+
+template<>
+struct ScalarTraits<Hex8> {
+ static void output(const Hex8 &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, Hex8 &);
+};
+
+template<>
+struct ScalarTraits<Hex16> {
+ static void output(const Hex16 &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, Hex16 &);
+};
+
+template<>
+struct ScalarTraits<Hex32> {
+ static void output(const Hex32 &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, Hex32 &);
+};
+
+template<>
+struct ScalarTraits<Hex64> {
+ static void output(const Hex64 &, void*, llvm::raw_ostream &);
+ static llvm::StringRef input(llvm::StringRef , void*, Hex64 &);
+};
+
+
+// Define non-member operator>> so that Input can stream in a document list.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docList) {
+ int i = 0;
+ while ( yin.setCurrentDocument() ) {
+ yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true);
+ if ( yin.error() )
+ return yin;
+ yin.nextDocument();
+ ++i;
+ }
+ return yin;
+}
+
+// Define non-member operator>> so that Input can stream in a map as a document.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_MappingTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docMap) {
+ yin.setCurrentDocument();
+ yamlize(yin, docMap, true);
+ return yin;
+}
+
+// Define non-member operator>> so that Input can stream in a sequence as
+// a document.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docSeq) {
+ yin.setCurrentDocument();
+ yamlize(yin, docSeq, true);
+ return yin;
+}
+
+// Provide better error message about types missing a trait specialization
+template <typename T>
+inline
+typename llvm::enable_if_c<missingTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docSeq) {
+ char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+ return yin;
+}
+
+
+// Define non-member operator<< so that Output can stream out document list.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &docList) {
+ yout.beginDocuments();
+ const size_t count = DocumentListTraits<T>::size(yout, docList);
+ for(size_t i=0; i < count; ++i) {
+ if ( yout.preflightDocument(i) ) {
+ yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true);
+ yout.postflightDocument();
+ }
+ }
+ yout.endDocuments();
+ return yout;
+}
+
+// Define non-member operator<< so that Output can stream out a map.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_MappingTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &map) {
+ yout.beginDocuments();
+ if ( yout.preflightDocument(0) ) {
+ yamlize(yout, map, true);
+ yout.postflightDocument();
+ }
+ yout.endDocuments();
+ return yout;
+}
+
+// Define non-member operator<< so that Output can stream out a sequence.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_SequenceTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &seq) {
+ yout.beginDocuments();
+ if ( yout.preflightDocument(0) ) {
+ yamlize(yout, seq, true);
+ yout.postflightDocument();
+ }
+ yout.endDocuments();
+ return yout;
+}
+
+// Provide better error message about types missing a trait specialization
+template <typename T>
+inline
+typename llvm::enable_if_c<missingTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &seq) {
+ char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+ return yout;
+}
+
+
+} // namespace yaml
+} // namespace llvm
+
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML sequence.
+#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \
+ namespace llvm { \
+ namespace yaml { \
+ template<> \
+ struct SequenceTraits< std::vector<_type> > { \
+ static size_t size(IO &io, std::vector<_type> &seq) { \
+ return seq.size(); \
+ } \
+ static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ if ( index >= seq.size() ) \
+ seq.resize(index+1); \
+ return seq[index]; \
+ } \
+ }; \
+ } \
+ }
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML flow sequence.
+#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \
+ namespace llvm { \
+ namespace yaml { \
+ template<> \
+ struct SequenceTraits< std::vector<_type> > { \
+ static size_t size(IO &io, std::vector<_type> &seq) { \
+ return seq.size(); \
+ } \
+ static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ if ( index >= seq.size() ) \
+ seq.resize(index+1); \
+ return seq[index]; \
+ } \
+ static const bool flow = true; \
+ }; \
+ } \
+ }
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML document list.
+#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \
+ namespace llvm { \
+ namespace yaml { \
+ template<> \
+ struct DocumentListTraits< std::vector<_type> > { \
+ static size_t size(IO &io, std::vector<_type> &seq) { \
+ return seq.size(); \
+ } \
+ static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ if ( index >= seq.size() ) \
+ seq.resize(index+1); \
+ return seq[index]; \
+ } \
+ }; \
+ } \
+ }
+
+
+
+#endif // LLVM_YAML_TRAITS_H_
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
index 2b3c329..9000306 100644
--- a/include/llvm/Support/circular_raw_ostream.h
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -71,7 +71,7 @@ namespace llvm
/// flushBuffer - Dump the contents of the buffer to Stream.
///
- void flushBuffer(void) {
+ void flushBuffer() {
if (Filled)
// Write the older portion of the buffer.
TheStream->write(Cur, BufferArray + BufferSize - Cur);
@@ -81,12 +81,12 @@ namespace llvm
Filled = false;
}
- virtual void write_impl(const char *Ptr, size_t Size);
+ virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
/// current_pos - Return the current position within the stream,
/// not counting the bytes currently in the buffer.
///
- virtual uint64_t current_pos() const {
+ virtual uint64_t current_pos() const LLVM_OVERRIDE {
// This has the same effect as calling TheStream.current_pos(),
// but that interface is private.
return TheStream->tell() - TheStream->GetNumBytesInBuffer();
@@ -151,7 +151,7 @@ namespace llvm
/// flushBufferWithBanner - Force output of the buffer along with
/// a small header.
///
- void flushBufferWithBanner(void);
+ void flushBufferWithBanner();
private:
/// releaseStream - Delete the held stream if needed. Otherwise,
diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h
index 4f5d361..4385721 100644
--- a/include/llvm/Support/raw_os_ostream.h
+++ b/include/llvm/Support/raw_os_ostream.h
@@ -24,14 +24,14 @@ namespace llvm {
/// use the underlying stream to detect errors.
class raw_os_ostream : public raw_ostream {
std::ostream &OS;
-
+
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size);
-
+ virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const;
-
+ virtual uint64_t current_pos() const LLVM_OVERRIDE;
+
public:
raw_os_ostream(std::ostream &O) : OS(O) {}
~raw_os_ostream();
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 9913f98..eab0f2d 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -15,6 +15,7 @@
#define LLVM_SUPPORT_RAW_OSTREAM_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -29,8 +30,8 @@ namespace llvm {
class raw_ostream {
private:
// Do not implement. raw_ostream is noncopyable.
- void operator=(const raw_ostream &);
- raw_ostream(const raw_ostream &);
+ void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION;
+ raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION;
/// The buffer is handled in such a way that the buffer is
/// uninitialized, unbuffered, or out of space when OutBufCur >=
@@ -191,10 +192,10 @@ public:
raw_ostream &operator<<(double N);
- /// write_hex - Output \arg N in hexadecimal, without any prefix or padding.
+ /// write_hex - Output \p N in hexadecimal, without any prefix or padding.
raw_ostream &write_hex(unsigned long long N);
- /// write_escaped - Output \arg Str, turning '\\', '\t', '\n', '"', and
+ /// write_escaped - Output \p Str, turning '\\', '\t', '\n', '"', and
/// anything that doesn't satisfy std::isprint into an escape sequence.
raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
@@ -218,6 +219,9 @@ public:
virtual raw_ostream &changeColor(enum Colors Color,
bool Bold = false,
bool BG = false) {
+ (void)Color;
+ (void)Bold;
+ (void)BG;
return *this;
}
@@ -242,15 +246,16 @@ public:
private:
/// write_impl - The is the piece of the class that is implemented
- /// by subclasses. This writes the \args Size bytes starting at
- /// \arg Ptr to the underlying stream.
+ /// by subclasses. This writes the \p Size bytes starting at
+ /// \p Ptr to the underlying stream.
///
/// This function is guaranteed to only be called at a point at which it is
/// safe for the subclass to install a new buffer via SetBuffer.
///
- /// \arg Ptr - The start of the data to be written. For buffered streams this
+ /// \param Ptr The start of the data to be written. For buffered streams this
/// is guaranteed to be the start of the buffer.
- /// \arg Size - The number of bytes to be written.
+ ///
+ /// \param Size The number of bytes to be written.
///
/// \invariant { Size > 0 }
virtual void write_impl(const char *Ptr, size_t Size) = 0;
@@ -317,14 +322,14 @@ class raw_fd_ostream : public raw_ostream {
uint64_t pos;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size);
+ virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const { return pos; }
+ virtual uint64_t current_pos() const LLVM_OVERRIDE { return pos; }
/// preferred_buffer_size - Determine an efficient buffer size.
- virtual size_t preferred_buffer_size() const;
+ virtual size_t preferred_buffer_size() const LLVM_OVERRIDE;
/// error_detected - Set the flag indicating that an output error has
/// been encountered.
@@ -385,14 +390,14 @@ public:
}
virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
- bool bg=false);
- virtual raw_ostream &resetColor();
+ bool bg=false) LLVM_OVERRIDE;
+ virtual raw_ostream &resetColor() LLVM_OVERRIDE;
- virtual raw_ostream &reverseColor();
+ virtual raw_ostream &reverseColor() LLVM_OVERRIDE;
- virtual bool is_displayed() const;
+ virtual bool is_displayed() const LLVM_OVERRIDE;
- virtual bool has_colors() const;
+ virtual bool has_colors() const LLVM_OVERRIDE;
/// has_error - Return the value of the flag in this raw_fd_ostream indicating
/// whether an output error has been encountered.
@@ -438,11 +443,11 @@ class raw_string_ostream : public raw_ostream {
std::string &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size);
+ virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const { return OS.size(); }
+ virtual uint64_t current_pos() const LLVM_OVERRIDE { return OS.size(); }
public:
explicit raw_string_ostream(std::string &O) : OS(O) {}
~raw_string_ostream();
@@ -462,15 +467,15 @@ class raw_svector_ostream : public raw_ostream {
SmallVectorImpl<char> &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size);
+ virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const;
+ virtual uint64_t current_pos() const LLVM_OVERRIDE;
public:
/// Construct a new raw_svector_ostream.
///
- /// \arg O - The vector to write to; this should generally have at least 128
+ /// \param O The vector to write to; this should generally have at least 128
/// bytes free to avoid any extraneous memory overhead.
explicit raw_svector_ostream(SmallVectorImpl<char> &O);
~raw_svector_ostream();
@@ -488,11 +493,11 @@ public:
/// raw_null_ostream - A raw_ostream that discards all output.
class raw_null_ostream : public raw_ostream {
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t size);
+ virtual void write_impl(const char *Ptr, size_t size) LLVM_OVERRIDE;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const;
+ virtual uint64_t current_pos() const LLVM_OVERRIDE;
public:
explicit raw_null_ostream() {}
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
index af81206..0d164f6 100644
--- a/include/llvm/Support/system_error.h
+++ b/include/llvm/Support/system_error.h
@@ -17,6 +17,8 @@
#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
#define LLVM_SYSTEM_SYSTEM_ERROR_H
+#include "llvm/Support/Compiler.h"
+
/*
system_error synopsis
@@ -629,8 +631,8 @@ public:
private:
error_category();
- error_category(const error_category&);// = delete;
- error_category& operator=(const error_category&);// = delete;
+ error_category(const error_category&) LLVM_DELETED_FUNCTION;
+ error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION;
public:
virtual const char* name() const = 0;
@@ -651,7 +653,7 @@ public:
class _do_message : public error_category
{
public:
- virtual std::string message(int ev) const;
+ virtual std::string message(int ev) const LLVM_OVERRIDE;
};
const error_category& generic_category();
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index 7b97547..f930639 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -54,8 +54,9 @@ struct is_class
// is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
// more details:
// http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
- public:
- enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) };
+public:
+ static const bool value =
+ sizeof(char) == sizeof(dont_use::is_class_helper<T>(0));
};
@@ -162,12 +163,11 @@ template <typename T> class is_integral_or_enum {
static UnderlyingT &nonce_instance;
public:
- enum {
+ static const bool
value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value &&
!is_same<UnderlyingT, float>::value &&
!is_same<UnderlyingT, double>::value &&
- sizeof(char) != sizeof(check_int_convertible(nonce_instance)))
- };
+ sizeof(char) != sizeof(check_int_convertible(nonce_instance)));
};
// enable_if_c - Enable/disable a template based on a metafunction
diff --git a/include/llvm/TableGen/Error.h b/include/llvm/TableGen/Error.h
index 5c1c3ad..2f6b7e6 100644
--- a/include/llvm/TableGen/Error.h
+++ b/include/llvm/TableGen/Error.h
@@ -19,27 +19,17 @@
namespace llvm {
-class TGError {
- SmallVector<SMLoc, 4> Locs;
- std::string Message;
-public:
- TGError(ArrayRef<SMLoc> locs, const std::string &message)
- : Locs(locs.begin(), locs.end()), Message(message) {}
-
- ArrayRef<SMLoc> getLoc() const { return Locs; }
- const std::string &getMessage() const { return Message; }
-};
-
void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg);
void PrintWarning(const char *Loc, const Twine &Msg);
void PrintWarning(const Twine &Msg);
-void PrintWarning(const TGError &Warning);
void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
void PrintError(const char *Loc, const Twine &Msg);
void PrintError(const Twine &Msg);
-void PrintError(const TGError &Error);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const std::string &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc,
+ const std::string &Msg);
extern SourceMgr SrcMgr;
diff --git a/include/llvm/TableGen/Main.h b/include/llvm/TableGen/Main.h
index deaef4a..6b51e20 100644
--- a/include/llvm/TableGen/Main.h
+++ b/include/llvm/TableGen/Main.h
@@ -16,10 +16,13 @@
namespace llvm {
-class TableGenAction;
+class RecordKeeper;
+class raw_ostream;
+/// \brief Perform the action using Records, and write output to OS.
+/// \returns true on error, false otherwise
+typedef bool TableGenMainFn(raw_ostream &OS, RecordKeeper &Records);
-/// Run the table generator, performing the specified Action on parsed records.
-int TableGenMain(char *argv0, TableGenAction &Action);
+int TableGenMain(char *argv0, TableGenMainFn *MainFn);
}
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index adb1a77..8968534 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -18,9 +18,10 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
@@ -66,10 +67,27 @@ class RecordKeeper;
//===----------------------------------------------------------------------===//
class RecTy {
+public:
+ /// \brief Subclass discriminator (for dyn_cast<> et al.)
+ enum RecTyKind {
+ BitRecTyKind,
+ BitsRecTyKind,
+ IntRecTyKind,
+ StringRecTyKind,
+ ListRecTyKind,
+ DagRecTyKind,
+ RecordRecTyKind
+ };
+
+private:
+ RecTyKind Kind;
ListRecTy *ListTy;
virtual void anchor();
+
public:
- RecTy() : ListTy(0) {}
+ RecTyKind getRecTyKind() const { return Kind; }
+
+ RecTy(RecTyKind K) : Kind(K), ListTy(0) {}
virtual ~RecTy() {}
virtual std::string getAsString() const = 0;
@@ -110,16 +128,8 @@ public: // These methods should only be called from subclasses of Init
return convertValue((TypedInit*)FI);
}
-public: // These methods should only be called by subclasses of RecTy.
- // baseClassOf - These virtual methods should be overloaded to return true iff
- // all values of type 'RHS' can be converted to the 'this' type.
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+public:
+ virtual bool baseClassOf(const RecTy*) const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
@@ -132,8 +142,12 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
///
class BitRecTy : public RecTy {
static BitRecTy Shared;
- BitRecTy() {}
+ BitRecTy() : RecTy(BitRecTyKind) {}
public:
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == BitRecTyKind;
+ }
+
static BitRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -152,19 +166,12 @@ public:
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
- std::string getAsString() const { return "bit"; }
+ virtual std::string getAsString() const { return "bit"; }
- bool typeIsConvertibleTo(const RecTy *RHS) const {
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const;
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-
+ virtual bool baseClassOf(const RecTy*) const;
};
@@ -173,8 +180,12 @@ public:
///
class BitsRecTy : public RecTy {
unsigned Size;
- explicit BitsRecTy(unsigned Sz) : Size(Sz) {}
+ explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {}
public:
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == BitsRecTyKind;
+ }
+
static BitsRecTy *get(unsigned Sz);
unsigned getNumBits() const { return Size; }
@@ -195,21 +206,12 @@ public:
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
- std::string getAsString() const;
+ virtual std::string getAsString() const;
- bool typeIsConvertibleTo(const RecTy *RHS) const {
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const {
- return RHS->Size == Size;
- }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-
+ virtual bool baseClassOf(const RecTy*) const;
};
@@ -217,8 +219,12 @@ public:
///
class IntRecTy : public RecTy {
static IntRecTy Shared;
- IntRecTy() {}
+ IntRecTy() : RecTy(IntRecTyKind) {}
public:
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == IntRecTyKind;
+ }
+
static IntRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -237,28 +243,25 @@ public:
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
- std::string getAsString() const { return "int"; }
+ virtual std::string getAsString() const { return "int"; }
- bool typeIsConvertibleTo(const RecTy *RHS) const {
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-
+ virtual bool baseClassOf(const RecTy*) const;
};
/// StringRecTy - 'string' - Represent an string value
///
class StringRecTy : public RecTy {
static StringRecTy Shared;
- StringRecTy() {}
+ StringRecTy() : RecTy(StringRecTyKind) {}
public:
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == StringRecTyKind;
+ }
+
static StringRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -278,19 +281,11 @@ public:
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
- std::string getAsString() const { return "string"; }
+ virtual std::string getAsString() const { return "string"; }
- bool typeIsConvertibleTo(const RecTy *RHS) const {
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
return RHS->baseClassOf(this);
}
-
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
};
// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
@@ -300,9 +295,13 @@ public:
///
class ListRecTy : public RecTy {
RecTy *Ty;
- explicit ListRecTy(RecTy *T) : Ty(T) {}
+ explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {}
friend ListRecTy *RecTy::getListTy();
public:
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == ListRecTyKind;
+ }
+
static ListRecTy *get(RecTy *T) { return T->getListTy(); }
RecTy *getElementType() const { return Ty; }
@@ -322,29 +321,25 @@ public:
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
- std::string getAsString() const;
+ virtual std::string getAsString() const;
- bool typeIsConvertibleTo(const RecTy *RHS) const {
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const {
- return RHS->getElementType()->typeIsConvertibleTo(Ty);
- }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
+ virtual bool baseClassOf(const RecTy*) const;
};
/// DagRecTy - 'dag' - Represent a dag fragment
///
class DagRecTy : public RecTy {
static DagRecTy Shared;
- DagRecTy() {}
+ DagRecTy() : RecTy(DagRecTyKind) {}
public:
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == DagRecTyKind;
+ }
+
static DagRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -363,19 +358,11 @@ public:
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
- std::string getAsString() const { return "dag"; }
+ virtual std::string getAsString() const { return "dag"; }
- bool typeIsConvertibleTo(const RecTy *RHS) const {
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
return RHS->baseClassOf(this);
}
-
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
};
@@ -384,9 +371,13 @@ public:
///
class RecordRecTy : public RecTy {
Record *Rec;
- explicit RecordRecTy(Record *R) : Rec(R) {}
+ explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {}
friend class Record;
public:
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == RecordRecTyKind;
+ }
+
static RecordRecTy *get(Record *R);
Record *getRecord() const { return Rec; }
@@ -407,18 +398,12 @@ public:
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
- std::string getAsString() const;
+ virtual std::string getAsString() const;
- bool typeIsConvertibleTo(const RecTy *RHS) const {
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const;
+ virtual bool baseClassOf(const RecTy*) const;
};
/// resolveTypes - Find a common type that T1 and T2 convert to.
@@ -431,12 +416,53 @@ RecTy *resolveTypes(RecTy *T1, RecTy *T2);
//===----------------------------------------------------------------------===//
class Init {
- Init(const Init &); // Do not define.
- Init &operator=(const Init &); // Do not define.
+protected:
+ /// \brief Discriminator enum (for isa<>, dyn_cast<>, et al.)
+ ///
+ /// This enum is laid out by a preorder traversal of the inheritance
+ /// hierarchy, and does not contain an entry for abstract classes, as per
+ /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst.
+ ///
+ /// We also explicitly include "first" and "last" values for each
+ /// interior node of the inheritance tree, to make it easier to read the
+ /// corresponding classof().
+ ///
+ /// We could pack these a bit tighter by not having the IK_FirstXXXInit
+ /// and IK_LastXXXInit be their own values, but that would degrade
+ /// readability for really no benefit.
+ enum InitKind {
+ IK_BitInit,
+ IK_BitsInit,
+ IK_FirstTypedInit,
+ IK_DagInit,
+ IK_DefInit,
+ IK_FieldInit,
+ IK_IntInit,
+ IK_ListInit,
+ IK_FirstOpInit,
+ IK_BinOpInit,
+ IK_TernOpInit,
+ IK_UnOpInit,
+ IK_LastOpInit,
+ IK_StringInit,
+ IK_VarInit,
+ IK_VarListElementInit,
+ IK_LastTypedInit,
+ IK_UnsetInit,
+ IK_VarBitInit
+ };
+
+private:
+ const InitKind Kind;
+ Init(const Init &) LLVM_DELETED_FUNCTION;
+ Init &operator=(const Init &) LLVM_DELETED_FUNCTION;
virtual void anchor();
+public:
+ InitKind getKind() const { return Kind; }
+
protected:
- Init(void) {}
+ explicit Init(InitKind K) : Kind(K) {}
public:
virtual ~Init() {}
@@ -533,13 +559,17 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
class TypedInit : public Init {
RecTy *Ty;
- TypedInit(const TypedInit &Other); // Do not define.
- TypedInit &operator=(const TypedInit &Other); // Do not define.
+ TypedInit(const TypedInit &Other) LLVM_DELETED_FUNCTION;
+ TypedInit &operator=(const TypedInit &Other) LLVM_DELETED_FUNCTION;
protected:
- explicit TypedInit(RecTy *T) : Ty(T) {}
+ explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {}
public:
+ static bool classof(const Init *I) {
+ return I->getKind() >= IK_FirstTypedInit &&
+ I->getKind() <= IK_LastTypedInit;
+ }
RecTy *getType() const { return Ty; }
virtual Init *
@@ -564,12 +594,15 @@ public:
/// UnsetInit - ? - Represents an uninitialized value
///
class UnsetInit : public Init {
- UnsetInit() : Init() {}
- UnsetInit(const UnsetInit &); // Do not define.
- UnsetInit &operator=(const UnsetInit &Other); // Do not define.
+ UnsetInit() : Init(IK_UnsetInit) {}
+ UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION;
+ UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION;
virtual void anchor();
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_UnsetInit;
+ }
static UnsetInit *get();
virtual Init *convertInitializerTo(RecTy *Ty) const {
@@ -590,12 +623,15 @@ public:
class BitInit : public Init {
bool Value;
- explicit BitInit(bool V) : Value(V) {}
- BitInit(const BitInit &Other); // Do not define.
- BitInit &operator=(BitInit &Other); // Do not define.
+ explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {}
+ BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION;
+ BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION;
virtual void anchor();
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_BitInit;
+ }
static BitInit *get(bool V);
bool getValue() const { return Value; }
@@ -618,12 +654,16 @@ public:
class BitsInit : public Init, public FoldingSetNode {
std::vector<Init*> Bits;
- BitsInit(ArrayRef<Init *> Range) : Bits(Range.begin(), Range.end()) {}
+ BitsInit(ArrayRef<Init *> Range)
+ : Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {}
- BitsInit(const BitsInit &Other); // Do not define.
- BitsInit &operator=(const BitsInit &Other); // Do not define.
+ BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION;
+ BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_BitsInit;
+ }
static BitsInit *get(ArrayRef<Init *> Range);
void Profile(FoldingSetNodeID &ID) const;
@@ -662,12 +702,16 @@ public:
class IntInit : public TypedInit {
int64_t Value;
- explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {}
+ explicit IntInit(int64_t V)
+ : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {}
- IntInit(const IntInit &Other); // Do not define.
- IntInit &operator=(const IntInit &Other); // Do note define.
+ IntInit(const IntInit &Other) LLVM_DELETED_FUNCTION;
+ IntInit &operator=(const IntInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_IntInit;
+ }
static IntInit *get(int64_t V);
int64_t getValue() const { return Value; }
@@ -700,13 +744,16 @@ class StringInit : public TypedInit {
std::string Value;
explicit StringInit(const std::string &V)
- : TypedInit(StringRecTy::get()), Value(V) {}
+ : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
- StringInit(const StringInit &Other); // Do not define.
- StringInit &operator=(const StringInit &Other); // Do not define.
+ StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION;
+ StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION;
virtual void anchor();
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_StringInit;
+ }
static StringInit *get(StringRef);
const std::string &getValue() const { return Value; }
@@ -740,12 +787,16 @@ public:
private:
explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy)
- : TypedInit(ListRecTy::get(EltTy)), Values(Range.begin(), Range.end()) {}
+ : TypedInit(IK_ListInit, ListRecTy::get(EltTy)),
+ Values(Range.begin(), Range.end()) {}
- ListInit(const ListInit &Other); // Do not define.
- ListInit &operator=(const ListInit &Other); // Do not define.
+ ListInit(const ListInit &Other) LLVM_DELETED_FUNCTION;
+ ListInit &operator=(const ListInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_ListInit;
+ }
static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy);
void Profile(FoldingSetNodeID &ID) const;
@@ -758,7 +809,8 @@ public:
Record *getElementAsRecord(unsigned i) const;
- Init *convertInitListSlice(const std::vector<unsigned> &Elements) const;
+ virtual Init *
+ convertInitListSlice(const std::vector<unsigned> &Elements) const;
virtual Init *convertInitializerTo(RecTy *Ty) const {
return Ty->convertValue(const_cast<ListInit *>(this));
@@ -796,13 +848,17 @@ public:
/// OpInit - Base class for operators
///
class OpInit : public TypedInit {
- OpInit(const OpInit &Other); // Do not define.
- OpInit &operator=(OpInit &Other); // Do not define.
+ OpInit(const OpInit &Other) LLVM_DELETED_FUNCTION;
+ OpInit &operator=(OpInit &Other) LLVM_DELETED_FUNCTION;
protected:
- explicit OpInit(RecTy *Type) : TypedInit(Type) {}
+ explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {}
public:
+ static bool classof(const Init *I) {
+ return I->getKind() >= IK_FirstOpInit &&
+ I->getKind() <= IK_LastOpInit;
+ }
// Clone - Clone this operator, replacing arguments with the new list
virtual OpInit *clone(std::vector<Init *> &Operands) const = 0;
@@ -834,12 +890,15 @@ private:
Init *LHS;
UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
- : OpInit(Type), Opc(opc), LHS(lhs) {}
+ : OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {}
- UnOpInit(const UnOpInit &Other); // Do not define.
- UnOpInit &operator=(const UnOpInit &Other); // Do not define.
+ UnOpInit(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
+ UnOpInit &operator=(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_UnOpInit;
+ }
static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type);
// Clone - Clone this operator, replacing arguments with the new list
@@ -849,8 +908,8 @@ public:
return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
}
- int getNumOperands() const { return 1; }
- Init *getOperand(int i) const {
+ virtual int getNumOperands() const { return 1; }
+ virtual Init *getOperand(int i) const {
assert(i == 0 && "Invalid operand id for unary operator");
return getOperand();
}
@@ -860,7 +919,7 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+ virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
@@ -877,12 +936,15 @@ private:
Init *LHS, *RHS;
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
- OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {}
+ OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {}
- BinOpInit(const BinOpInit &Other); // Do not define.
- BinOpInit &operator=(const BinOpInit &Other); // Do not define.
+ BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
+ BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_BinOpInit;
+ }
static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
RecTy *Type);
@@ -893,8 +955,8 @@ public:
return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
}
- int getNumOperands() const { return 2; }
- Init *getOperand(int i) const {
+ virtual int getNumOperands() const { return 2; }
+ virtual Init *getOperand(int i) const {
assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
if (i == 0) {
return getLHS();
@@ -909,7 +971,7 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+ virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
@@ -927,12 +989,15 @@ private:
TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
RecTy *Type) :
- OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
+ OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
- TernOpInit(const TernOpInit &Other); // Do not define.
- TernOpInit &operator=(const TernOpInit &Other); // Do not define.
+ TernOpInit(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
+ TernOpInit &operator=(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_TernOpInit;
+ }
static TernOpInit *get(TernaryOp opc, Init *lhs,
Init *mhs, Init *rhs,
RecTy *Type);
@@ -945,8 +1010,8 @@ public:
getType());
}
- int getNumOperands() const { return 3; }
- Init *getOperand(int i) const {
+ virtual int getNumOperands() const { return 3; }
+ virtual Init *getOperand(int i) const {
assert((i == 0 || i == 1 || i == 2) &&
"Invalid operand id for ternary operator");
if (i == 0) {
@@ -965,7 +1030,7 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+ virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
virtual bool isComplete() const { return false; }
@@ -981,14 +1046,17 @@ class VarInit : public TypedInit {
Init *VarName;
explicit VarInit(const std::string &VN, RecTy *T)
- : TypedInit(T), VarName(StringInit::get(VN)) {}
+ : TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {}
explicit VarInit(Init *VN, RecTy *T)
- : TypedInit(T), VarName(VN) {}
+ : TypedInit(IK_VarInit, T), VarName(VN) {}
- VarInit(const VarInit &Other); // Do not define.
- VarInit &operator=(const VarInit &Other); // Do not define.
+ VarInit(const VarInit &Other) LLVM_DELETED_FUNCTION;
+ VarInit &operator=(const VarInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_VarInit;
+ }
static VarInit *get(const std::string &VN, RecTy *T);
static VarInit *get(Init *VN, RecTy *T);
@@ -1028,18 +1096,21 @@ class VarBitInit : public Init {
TypedInit *TI;
unsigned Bit;
- VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) {
+ VarBitInit(TypedInit *T, unsigned B) : Init(IK_VarBitInit), TI(T), Bit(B) {
assert(T->getType() &&
- (dynamic_cast<IntRecTy*>(T->getType()) ||
- (dynamic_cast<BitsRecTy*>(T->getType()) &&
- dynamic_cast<BitsRecTy*>(T->getType())->getNumBits() > B)) &&
+ (isa<IntRecTy>(T->getType()) ||
+ (isa<BitsRecTy>(T->getType()) &&
+ cast<BitsRecTy>(T->getType())->getNumBits() > B)) &&
"Illegal VarBitInit expression!");
}
- VarBitInit(const VarBitInit &Other); // Do not define.
- VarBitInit &operator=(const VarBitInit &Other); // Do not define.
+ VarBitInit(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
+ VarBitInit &operator=(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_VarBitInit;
+ }
static VarBitInit *get(TypedInit *T, unsigned B);
virtual Init *convertInitializerTo(RecTy *Ty) const {
@@ -1065,18 +1136,20 @@ class VarListElementInit : public TypedInit {
unsigned Element;
VarListElementInit(TypedInit *T, unsigned E)
- : TypedInit(dynamic_cast<ListRecTy*>(T->getType())->getElementType()),
- TI(T), Element(E) {
- assert(T->getType() && dynamic_cast<ListRecTy*>(T->getType()) &&
+ : TypedInit(IK_VarListElementInit,
+ cast<ListRecTy>(T->getType())->getElementType()),
+ TI(T), Element(E) {
+ assert(T->getType() && isa<ListRecTy>(T->getType()) &&
"Illegal VarBitInit expression!");
}
- VarListElementInit(const VarListElementInit &Other); // Do not define.
- VarListElementInit &operator=(const VarListElementInit &Other); // Do
- // not
- // define.
+ VarListElementInit(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
+ void operator=(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_VarListElementInit;
+ }
static VarListElementInit *get(TypedInit *T, unsigned E);
virtual Init *convertInitializerTo(RecTy *Ty) const {
@@ -1104,13 +1177,16 @@ public:
class DefInit : public TypedInit {
Record *Def;
- DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {}
+ DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {}
friend class Record;
- DefInit(const DefInit &Other); // Do not define.
- DefInit &operator=(const DefInit &Other); // Do not define.
+ DefInit(const DefInit &Other) LLVM_DELETED_FUNCTION;
+ DefInit &operator=(const DefInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_DefInit;
+ }
static DefInit *get(Record*);
virtual Init *convertInitializerTo(RecTy *Ty) const {
@@ -1148,14 +1224,17 @@ class FieldInit : public TypedInit {
std::string FieldName; // Field we are accessing
FieldInit(Init *R, const std::string &FN)
- : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) {
+ : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) {
assert(getType() && "FieldInit with non-record type!");
}
- FieldInit(const FieldInit &Other); // Do not define.
- FieldInit &operator=(const FieldInit &Other); // Do not define.
+ FieldInit(const FieldInit &Other) LLVM_DELETED_FUNCTION;
+ FieldInit &operator=(const FieldInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_FieldInit;
+ }
static FieldInit *get(Init *R, const std::string &FN);
static FieldInit *get(Init *R, const Init *FN);
@@ -1189,14 +1268,17 @@ class DagInit : public TypedInit, public FoldingSetNode {
DagInit(Init *V, const std::string &VN,
ArrayRef<Init *> ArgRange,
ArrayRef<std::string> NameRange)
- : TypedInit(DagRecTy::get()), Val(V), ValName(VN),
+ : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN),
Args(ArgRange.begin(), ArgRange.end()),
ArgNames(NameRange.begin(), NameRange.end()) {}
- DagInit(const DagInit &Other); // Do not define.
- DagInit &operator=(const DagInit &Other); // Do not define.
+ DagInit(const DagInit &Other) LLVM_DELETED_FUNCTION;
+ DagInit &operator=(const DagInit &Other) LLVM_DELETED_FUNCTION;
public:
+ static bool classof(const Init *I) {
+ return I->getKind() == IK_DagInit;
+ }
static DagInit *get(Init *V, const std::string &VN,
ArrayRef<Init *> ArgRange,
ArrayRef<std::string> NameRange);
@@ -1329,6 +1411,14 @@ public:
TrackedRecords(records), TheInit(0) {
init();
}
+
+ // When copy-constructing a Record, we must still guarantee a globally unique
+ // ID number. All other fields can be copied normally.
+ Record(const Record &O) :
+ ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
+ Values(O.Values), SuperClasses(O.SuperClasses),
+ TrackedRecords(O.TrackedRecords), TheInit(O.TheInit) { }
+
~Record() {}
@@ -1610,6 +1700,16 @@ struct LessRecord {
}
};
+/// LessRecordByID - Sorting predicate to sort record pointers by their
+/// unique ID. If you just need a deterministic order, use this, since it
+/// just compares two `unsigned`; the other sorting predicates require
+/// string manipulation.
+struct LessRecordByID {
+ bool operator()(const Record *LHS, const Record *RHS) const {
+ return LHS->getID() < RHS->getID();
+ }
+};
+
/// LessRecordFieldName - Sorting predicate to sort record pointers by their
/// name field.
///
diff --git a/include/llvm/TableGen/StringMatcher.h b/include/llvm/TableGen/StringMatcher.h
index 1dadc76..1b0572f 100644
--- a/include/llvm/TableGen/StringMatcher.h
+++ b/include/llvm/TableGen/StringMatcher.h
@@ -14,10 +14,10 @@
#ifndef STRINGMATCHER_H
#define STRINGMATCHER_H
-#include <vector>
+#include "llvm/ADT/StringRef.h"
#include <string>
#include <utility>
-#include "llvm/ADT/StringRef.h"
+#include <vector>
namespace llvm {
class raw_ostream;
diff --git a/include/llvm/TableGen/TableGenAction.h b/include/llvm/TableGen/TableGenAction.h
deleted file mode 100644
index 733ae62..0000000
--- a/include/llvm/TableGen/TableGenAction.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- llvm/TableGen/TableGenAction.h - defines TableGenAction --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TableGenAction base class to be derived from by
-// tblgen tools.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TABLEGEN_TABLEGENACTION_H
-#define LLVM_TABLEGEN_TABLEGENACTION_H
-
-namespace llvm {
-
-class raw_ostream;
-class RecordKeeper;
-
-class TableGenAction {
- virtual void anchor();
-public:
- virtual ~TableGenAction() {}
-
- /// Perform the action using Records, and write output to OS.
- /// @returns true on error, false otherwise
- virtual bool operator()(raw_ostream &OS, RecordKeeper &Records) = 0;
-};
-
-}
-
-#endif
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index d5e165e..a50f54a 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -22,7 +22,7 @@ class GlobalValue;
template <typename T> class SmallVectorImpl;
class MCContext;
class MCSymbol;
-class TargetData;
+class DataLayout;
class Mangler {
public:
@@ -34,7 +34,7 @@ public:
private:
MCContext &Context;
- const TargetData &TD;
+ const DataLayout &TD;
/// AnonGlobalIDs - We need to give global values the same name every time
/// they are mangled. This keeps track of the number we give to anonymous
@@ -47,20 +47,19 @@ private:
unsigned NextAnonGlobalID;
public:
- Mangler(MCContext &context, const TargetData &td)
+ Mangler(MCContext &context, const DataLayout &td)
: Context(context), TD(td), NextAnonGlobalID(1) {}
/// getSymbol - Return the MCSymbol for the specified global value. This
/// symbol is the main label that is the address of the global.
MCSymbol *getSymbol(const GlobalValue *GV);
-
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified global variable's name. If the global variable doesn't
/// have a name, this fills in a unique name for the global.
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
bool isImplicitlyPrivate);
-
+
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified name as the global variable name. GVName must not be
/// empty.
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 87bd84e..1781e47 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
// Include all information about LLVM intrinsics.
-include "llvm/Intrinsics.td"
+include "llvm/IR/Intrinsics.td"
//===----------------------------------------------------------------------===//
// Register file description - These classes are used to fill in the target
@@ -495,7 +495,8 @@ def ptr_rc : PointerLikeRegClass<0>;
/// unknown definition - Mark this operand as being of unknown type, causing
/// it to be resolved by inference in the context it is used.
-def unknown;
+class unknown_class;
+def unknown : unknown_class;
/// AsmOperandClass - Representation for the kinds of operands which the target
/// specific parser can create and the assembly matcher may need to distinguish.
@@ -988,12 +989,64 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> {
// ProcessorModel allows subtargets to specify the more general
// SchedMachineModel instead if a ProcessorItinerary. Subtargets will
// gradually move to this newer form.
+//
+// Although this class always passes NoItineraries to the Processor
+// class, the SchedMachineModel may still define valid Itineraries.
class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f>
: Processor<n, NoItineraries, f> {
let SchedModel = m;
}
//===----------------------------------------------------------------------===//
+// InstrMapping - This class is used to create mapping tables to relate
+// instructions with each other based on the values specified in RowFields,
+// ColFields, KeyCol and ValueCols.
+//
+class InstrMapping {
+ // FilterClass - Used to limit search space only to the instructions that
+ // define the relationship modeled by this InstrMapping record.
+ string FilterClass;
+
+ // RowFields - List of fields/attributes that should be same for all the
+ // instructions in a row of the relation table. Think of this as a set of
+ // properties shared by all the instructions related by this relationship
+ // model and is used to categorize instructions into subgroups. For instance,
+ // if we want to define a relation that maps 'Add' instruction to its
+ // predicated forms, we can define RowFields like this:
+ //
+ // let RowFields = BaseOp
+ // All add instruction predicated/non-predicated will have to set their BaseOp
+ // to the same value.
+ //
+ // def Add: { let BaseOp = 'ADD'; let predSense = 'nopred' }
+ // def Add_predtrue: { let BaseOp = 'ADD'; let predSense = 'true' }
+ // def Add_predfalse: { let BaseOp = 'ADD'; let predSense = 'false' }
+ list<string> RowFields = [];
+
+ // List of fields/attributes that are same for all the instructions
+ // in a column of the relation table.
+ // Ex: let ColFields = 'predSense' -- It means that the columns are arranged
+ // based on the 'predSense' values. All the instruction in a specific
+ // column have the same value and it is fixed for the column according
+ // to the values set in 'ValueCols'.
+ list<string> ColFields = [];
+
+ // Values for the fields/attributes listed in 'ColFields'.
+ // Ex: let KeyCol = 'nopred' -- It means that the key instruction (instruction
+ // that models this relation) should be non-predicated.
+ // In the example above, 'Add' is the key instruction.
+ list<string> KeyCol = [];
+
+ // List of values for the fields/attributes listed in 'ColFields', one for
+ // each column in the relation table.
+ //
+ // Ex: let ValueCols = [['true'],['false']] -- It adds two columns in the
+ // table. First column requires all the instructions to have predSense
+ // set to 'true' and second column requires it to be 'false'.
+ list<list<string> > ValueCols = [];
+}
+
+//===----------------------------------------------------------------------===//
// Pull in the common support for calling conventions.
//
include "llvm/Target/TargetCallingConv.td"
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index f8cebef..2160e37 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -113,9 +113,18 @@ namespace ISD {
MVT VT;
bool Used;
+ /// Index original Function's argument.
+ unsigned OrigArgIndex;
+
+ /// Offset in bytes of current input value relative to the beginning of
+ /// original argument. E.g. if argument was splitted into four 32 bit
+ /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
+ unsigned PartOffset;
+
InputArg() : VT(MVT::Other), Used(false) {}
- InputArg(ArgFlagsTy flags, EVT vt, bool used)
- : Flags(flags), Used(used) {
+ InputArg(ArgFlagsTy flags, EVT vt, bool used,
+ unsigned origIdx, unsigned partOffs)
+ : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
VT = vt.getSimpleVT();
}
};
@@ -131,9 +140,19 @@ namespace ISD {
/// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
bool IsFixed;
+ /// Index original Function's argument.
+ unsigned OrigArgIndex;
+
+ /// Offset in bytes of current output value relative to the beginning of
+ /// original argument. E.g. if argument was splitted into four 32 bit
+ /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
+ unsigned PartOffset;
+
OutputArg() : IsFixed(false) {}
- OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed)
- : Flags(flags), IsFixed(isfixed) {
+ OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed,
+ unsigned origIdx, unsigned partOffs)
+ : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
+ PartOffset(partOffs) {
VT = vt.getSimpleVT();
}
};
diff --git a/include/llvm/Target/TargetELFWriterInfo.h b/include/llvm/Target/TargetELFWriterInfo.h
deleted file mode 100644
index 5e48629..0000000
--- a/include/llvm/Target/TargetELFWriterInfo.h
+++ /dev/null
@@ -1,121 +0,0 @@
-//===-- llvm/Target/TargetELFWriterInfo.h - ELF Writer Info -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TargetELFWriterInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETELFWRITERINFO_H
-#define LLVM_TARGET_TARGETELFWRITERINFO_H
-
-namespace llvm {
-
- //===--------------------------------------------------------------------===//
- // TargetELFWriterInfo
- //===--------------------------------------------------------------------===//
-
- class TargetELFWriterInfo {
- protected:
- // EMachine - This field is the target specific value to emit as the
- // e_machine member of the ELF header.
- unsigned short EMachine;
- bool is64Bit, isLittleEndian;
- public:
-
- // Machine architectures
- enum MachineType {
- EM_NONE = 0, // No machine
- EM_M32 = 1, // AT&T WE 32100
- EM_SPARC = 2, // SPARC
- EM_386 = 3, // Intel 386
- EM_68K = 4, // Motorola 68000
- EM_88K = 5, // Motorola 88000
- EM_486 = 6, // Intel 486 (deprecated)
- EM_860 = 7, // Intel 80860
- EM_MIPS = 8, // MIPS R3000
- EM_PPC = 20, // PowerPC
- EM_ARM = 40, // ARM
- EM_ALPHA = 41, // DEC Alpha
- EM_SPARCV9 = 43, // SPARC V9
- EM_X86_64 = 62, // AMD64
- EM_HEXAGON = 164 // Qualcomm Hexagon
- };
-
- // ELF File classes
- enum {
- ELFCLASS32 = 1, // 32-bit object file
- ELFCLASS64 = 2 // 64-bit object file
- };
-
- // ELF Endianess
- enum {
- ELFDATA2LSB = 1, // Little-endian object file
- ELFDATA2MSB = 2 // Big-endian object file
- };
-
- explicit TargetELFWriterInfo(bool is64Bit_, bool isLittleEndian_);
- virtual ~TargetELFWriterInfo();
-
- unsigned short getEMachine() const { return EMachine; }
- unsigned getEFlags() const { return 0; }
- unsigned getEIClass() const { return is64Bit ? ELFCLASS64 : ELFCLASS32; }
- unsigned getEIData() const {
- return isLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
- }
-
- /// ELF Header and ELF Section Header Info
- unsigned getHdrSize() const { return is64Bit ? 64 : 52; }
- unsigned getSHdrSize() const { return is64Bit ? 64 : 40; }
-
- /// Symbol Table Info
- unsigned getSymTabEntrySize() const { return is64Bit ? 24 : 16; }
-
- /// getPrefELFAlignment - Returns the preferred alignment for ELF. This
- /// is used to align some sections.
- unsigned getPrefELFAlignment() const { return is64Bit ? 8 : 4; }
-
- /// getRelocationEntrySize - Entry size used in the relocation section
- unsigned getRelocationEntrySize() const {
- return is64Bit ? (hasRelocationAddend() ? 24 : 16)
- : (hasRelocationAddend() ? 12 : 8);
- }
-
- /// getRelocationType - Returns the target specific ELF Relocation type.
- /// 'MachineRelTy' contains the object code independent relocation type
- virtual unsigned getRelocationType(unsigned MachineRelTy) const = 0;
-
- /// hasRelocationAddend - True if the target uses an addend in the
- /// ELF relocation entry.
- virtual bool hasRelocationAddend() const = 0;
-
- /// getDefaultAddendForRelTy - Gets the default addend value for a
- /// relocation entry based on the target ELF relocation type.
- virtual long int getDefaultAddendForRelTy(unsigned RelTy,
- long int Modifier = 0) const = 0;
-
- /// getRelTySize - Returns the size of relocatable field in bits
- virtual unsigned getRelocationTySize(unsigned RelTy) const = 0;
-
- /// isPCRelativeRel - True if the relocation type is pc relative
- virtual bool isPCRelativeRel(unsigned RelTy) const = 0;
-
- /// getJumpTableRelocationTy - Returns the machine relocation type used
- /// to reference a jumptable.
- virtual unsigned getAbsoluteLabelMachineRelTy() const = 0;
-
- /// computeRelocation - Some relocatable fields could be relocated
- /// directly, avoiding the relocation symbol emission, compute the
- /// final relocation value for this symbol.
- virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset,
- unsigned RelTy) const = 0;
- };
-
-} // end llvm namespace
-
-#endif // LLVM_TARGET_TARGETELFWRITERINFO_H
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index d56db7b..1958f90 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -15,7 +15,6 @@
#define LLVM_TARGET_TARGETFRAMELOWERING_H
#include "llvm/CodeGen/MachineBasicBlock.h"
-
#include <utility>
#include <vector>
@@ -48,11 +47,12 @@ private:
unsigned StackAlignment;
unsigned TransientStackAlignment;
int LocalAreaOffset;
+ bool StackRealignable;
public:
TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
- unsigned TransAl = 1)
+ unsigned TransAl = 1, bool StackReal = true)
: StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
- LocalAreaOffset(LAO) {}
+ LocalAreaOffset(LAO), StackRealignable(StackReal) {}
virtual ~TargetFrameLowering();
@@ -77,6 +77,12 @@ public:
return TransientStackAlignment;
}
+ /// isStackRealignable - This method returns whether the stack can be
+ /// realigned.
+ bool isStackRealignable() const {
+ return StackRealignable;
+ }
+
/// getOffsetOfLocalArea - This method returns the offset of the local area
/// from the stack pointer on entrance to a function.
///
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index d7cc1cf..fb311d8 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -15,9 +15,9 @@
#define LLVM_TARGET_TARGETINSTRINFO_H
#include "llvm/ADT/SmallSet.h"
-#include "llvm/MC/MCInstrInfo.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/MC/MCInstrInfo.h"
namespace llvm {
@@ -45,8 +45,8 @@ template<class T> class SmallVectorImpl;
/// TargetInstrInfo - Interface to description of machine instruction set
///
class TargetInstrInfo : public MCInstrInfo {
- TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT
- void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT
+ TargetInstrInfo(const TargetInstrInfo &) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetInstrInfo &) LLVM_DELETED_FUNCTION;
public:
TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1)
: CallFrameSetupOpcode(CFSetupOpcode),
@@ -143,9 +143,7 @@ public:
/// missed.
virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
const MachineMemOperand *&MMO,
- int &FrameIndex) const {
- return 0;
- }
+ int &FrameIndex) const;
/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
@@ -173,9 +171,7 @@ public:
/// stack. This is just a hint, as some cases may be missed.
virtual bool hasStoreToStackSlot(const MachineInstr *MI,
const MachineMemOperand *&MMO,
- int &FrameIndex) const {
- return 0;
- }
+ int &FrameIndex) const;
/// reMaterialize - Re-issue the specified 'original' instruction at the
/// specific location targeting a new destination register.
@@ -186,7 +182,7 @@ public:
MachineBasicBlock::iterator MI,
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig,
- const TargetRegisterInfo &TRI) const = 0;
+ const TargetRegisterInfo &TRI) const;
/// duplicate - Create a duplicate of the Orig instruction in MF. This is like
/// MachineFunction::CloneMachineInstr(), but the target may update operands
@@ -194,7 +190,7 @@ public:
///
/// The instruction must be duplicable as indicated by isNotDuplicable().
virtual MachineInstr *duplicate(MachineInstr *Orig,
- MachineFunction &MF) const = 0;
+ MachineFunction &MF) const;
/// convertToThreeAddress - This method must be implemented by targets that
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
@@ -221,13 +217,13 @@ public:
/// method for a non-commutable instruction, but there may be some cases
/// where this method fails and returns null.
virtual MachineInstr *commuteInstruction(MachineInstr *MI,
- bool NewMI = false) const = 0;
+ bool NewMI = false) const;
/// findCommutedOpIndices - If specified MI is commutable, return the two
/// operand indices that would swap value. Return false if the instruction
/// is not in a form which this routine understands.
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
- unsigned &SrcOpIdx2) const = 0;
+ unsigned &SrcOpIdx2) const;
/// produceSameValue - Return true if two machine instructions would produce
/// identical values. By default, this is only true when the two instructions
@@ -236,7 +232,7 @@ public:
/// aggressive checks.
virtual bool produceSameValue(const MachineInstr *MI0,
const MachineInstr *MI1,
- const MachineRegisterInfo *MRI = 0) const = 0;
+ const MachineRegisterInfo *MRI = 0) const;
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
@@ -298,7 +294,7 @@ public:
/// after it, replacing it with an unconditional branch to NewDest. This is
/// used by the tail merging pass.
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
- MachineBasicBlock *NewDest) const = 0;
+ MachineBasicBlock *NewDest) const;
/// isLegalToSplitMBBAt - Return true if it's legal to split the given basic
/// block at the specified instruction (i.e. instruction would be the start
@@ -435,7 +431,7 @@ public:
SmallVectorImpl<MachineOperand> &Cond,
unsigned &TrueOp, unsigned &FalseOp,
bool &Optimizable) const {
- assert(MI && MI->isSelect() && "MI must be a select instruction");
+ assert(MI && MI->getDesc().isSelect() && "MI must be a select instruction");
return true;
}
@@ -569,7 +565,7 @@ public:
/// folding is possible.
virtual
bool canFoldMemoryOperand(const MachineInstr *MI,
- const SmallVectorImpl<unsigned> &Ops) const =0;
+ const SmallVectorImpl<unsigned> &Ops) const;
/// unfoldMemoryOperand - Separate a single instruction which folded a load or
/// a store or a load and a store into two or more instruction. If this is
@@ -621,6 +617,26 @@ public:
return false;
}
+ /// \brief Get the base register and byte offset of a load/store instr.
+ virtual bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
+ unsigned &BaseReg, unsigned &Offset,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ virtual bool shouldClusterLoads(MachineInstr *FirstLdSt,
+ MachineInstr *SecondLdSt,
+ unsigned NumLoads) const {
+ return false;
+ }
+
+ /// \brief Can this target fuse the given instructions if they are scheduled
+ /// adjacent.
+ virtual bool shouldScheduleAdjacent(MachineInstr* First,
+ MachineInstr *Second) const {
+ return false;
+ }
+
/// ReverseBranchCondition - Reverses the branch condition of the specified
/// condition list, returning false on success and true if it cannot be
/// reversed.
@@ -649,13 +665,13 @@ public:
/// isUnpredicatedTerminator - Returns true if the instruction is a
/// terminator instruction that has not been predicated.
- virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const = 0;
+ virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
/// PredicateInstruction - Convert the instruction into a predicated
/// instruction. It returns true if the operation was successful.
virtual
bool PredicateInstruction(MachineInstr *MI,
- const SmallVectorImpl<MachineOperand> &Pred) const = 0;
+ const SmallVectorImpl<MachineOperand> &Pred) const;
/// SubsumesPredicate - Returns true if the first specified predicate
/// subsumes the second, e.g. GE subsumes GT.
@@ -691,7 +707,7 @@ public:
/// terminators.
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
- const MachineFunction &MF) const = 0;
+ const MachineFunction &MF) const;
/// Measure the specified inline asm to determine an approximation of its
/// length.
@@ -703,21 +719,25 @@ public:
/// register allocation.
virtual ScheduleHazardRecognizer*
CreateTargetHazardRecognizer(const TargetMachine *TM,
- const ScheduleDAG *DAG) const = 0;
+ const ScheduleDAG *DAG) const;
/// CreateTargetMIHazardRecognizer - Allocate and return a hazard recognizer
/// to use for this target when scheduling the machine instructions before
/// register allocation.
virtual ScheduleHazardRecognizer*
CreateTargetMIHazardRecognizer(const InstrItineraryData*,
- const ScheduleDAG *DAG) const = 0;
+ const ScheduleDAG *DAG) const;
/// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard
/// recognizer to use for this target when scheduling the machine instructions
/// after register allocation.
virtual ScheduleHazardRecognizer*
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
- const ScheduleDAG *DAG) const = 0;
+ const ScheduleDAG *DAG) const;
+
+ /// Provide a global flag for disabling the PreRA hazard recognizer that
+ /// targets may choose to honor.
+ bool usePreRAHazardRecognizer() const;
/// analyzeCompare - For a comparison instruction, return the source registers
/// in SrcReg and SrcReg2 if having two register operands, and the value it
@@ -765,7 +785,7 @@ public:
/// IssueWidth is the number of microops that can be dispatched each
/// cycle. An instruction with zero microops takes no dispatch resources.
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
- const MachineInstr *MI) const = 0;
+ const MachineInstr *MI) const;
/// isZeroCost - Return true for pseudo instructions that don't consume any
/// machine resources in their current form. These are common cases that the
@@ -777,7 +797,7 @@ public:
virtual int getOperandLatency(const InstrItineraryData *ItinData,
SDNode *DefNode, unsigned DefIdx,
- SDNode *UseNode, unsigned UseIdx) const = 0;
+ SDNode *UseNode, unsigned UseIdx) const;
/// getOperandLatency - Compute and return the use operand latency of a given
/// pair of def and use.
@@ -790,7 +810,7 @@ public:
virtual int getOperandLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx,
const MachineInstr *UseMI,
- unsigned UseIdx) const = 0;
+ unsigned UseIdx) const;
/// computeOperandLatency - Compute and return the latency of the given data
/// dependent def and use when the operand indices are already known.
@@ -801,29 +821,23 @@ public:
const MachineInstr *UseMI, unsigned UseIdx,
bool FindMin = false) const;
- /// getOutputLatency - Compute and return the output dependency latency of a
- /// a given pair of defs which both target the same register. This is usually
- /// one.
- virtual unsigned getOutputLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx,
- const MachineInstr *DepMI) const {
- return 1;
- }
-
/// getInstrLatency - Compute the instruction latency of a given instruction.
/// If the instruction has higher cost when predicated, it's returned via
/// PredCost.
virtual unsigned getInstrLatency(const InstrItineraryData *ItinData,
const MachineInstr *MI,
- unsigned *PredCost = 0) const = 0;
+ unsigned *PredCost = 0) const;
virtual int getInstrLatency(const InstrItineraryData *ItinData,
- SDNode *Node) const = 0;
+ SDNode *Node) const;
/// Return the default expected latency for a def based on it's opcode.
unsigned defaultDefLatency(const MCSchedModel *SchedModel,
const MachineInstr *DefMI) const;
+ int computeDefOperandLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *DefMI, bool FindMin) const;
+
/// isHighLatencyDef - Return true if this opcode has high latency to its
/// result.
virtual bool isHighLatencyDef(int opc) const { return false; }
@@ -845,7 +859,7 @@ public:
/// if the target considered it 'low'.
virtual
bool hasLowDefLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx) const = 0;
+ const MachineInstr *DefMI, unsigned DefIdx) const;
/// verifyInstruction - Perform target specific instruction verification.
virtual
@@ -962,84 +976,6 @@ private:
int CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
-/// TargetInstrInfoImpl - This is the default implementation of
-/// TargetInstrInfo, which just provides a couple of default implementations
-/// for various methods. This separated out because it is implemented in
-/// libcodegen, not in libtarget.
-class TargetInstrInfoImpl : public TargetInstrInfo {
-protected:
- TargetInstrInfoImpl(int CallFrameSetupOpcode = -1,
- int CallFrameDestroyOpcode = -1)
- : TargetInstrInfo(CallFrameSetupOpcode, CallFrameDestroyOpcode) {}
-public:
- virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
- MachineBasicBlock *NewDest) const;
- virtual MachineInstr *commuteInstruction(MachineInstr *MI,
- bool NewMI = false) const;
- virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
- unsigned &SrcOpIdx2) const;
- virtual bool canFoldMemoryOperand(const MachineInstr *MI,
- const SmallVectorImpl<unsigned> &Ops) const;
- virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
- const MachineMemOperand *&MMO,
- int &FrameIndex) const;
- virtual bool hasStoreToStackSlot(const MachineInstr *MI,
- const MachineMemOperand *&MMO,
- int &FrameIndex) const;
- virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
- virtual bool PredicateInstruction(MachineInstr *MI,
- const SmallVectorImpl<MachineOperand> &Pred) const;
- virtual void reMaterialize(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- unsigned DestReg, unsigned SubReg,
- const MachineInstr *Orig,
- const TargetRegisterInfo &TRI) const;
- virtual MachineInstr *duplicate(MachineInstr *Orig,
- MachineFunction &MF) const;
- virtual bool produceSameValue(const MachineInstr *MI0,
- const MachineInstr *MI1,
- const MachineRegisterInfo *MRI) const;
- virtual bool isSchedulingBoundary(const MachineInstr *MI,
- const MachineBasicBlock *MBB,
- const MachineFunction &MF) const;
-
- virtual int getOperandLatency(const InstrItineraryData *ItinData,
- SDNode *DefNode, unsigned DefIdx,
- SDNode *UseNode, unsigned UseIdx) const;
-
- virtual int getInstrLatency(const InstrItineraryData *ItinData,
- SDNode *Node) const;
-
- virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
- const MachineInstr *MI) const;
-
- virtual unsigned getInstrLatency(const InstrItineraryData *ItinData,
- const MachineInstr *MI,
- unsigned *PredCost = 0) const;
-
- virtual
- bool hasLowDefLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx) const;
-
- virtual int getOperandLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx,
- const MachineInstr *UseMI,
- unsigned UseIdx) const;
-
- bool usePreRAHazardRecognizer() const;
-
- virtual ScheduleHazardRecognizer *
- CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const;
-
- virtual ScheduleHazardRecognizer *
- CreateTargetMIHazardRecognizer(const InstrItineraryData*,
- const ScheduleDAG*) const;
-
- virtual ScheduleHazardRecognizer *
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
- const ScheduleDAG*) const;
-};
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h
index c44b923..ce21349 100644
--- a/include/llvm/Target/TargetIntrinsicInfo.h
+++ b/include/llvm/Target/TargetIntrinsicInfo.h
@@ -14,6 +14,7 @@
#ifndef LLVM_TARGET_TARGETINTRINSICINFO_H
#define LLVM_TARGET_TARGETINTRINSICINFO_H
+#include "llvm/Support/Compiler.h"
#include <string>
namespace llvm {
@@ -27,8 +28,8 @@ class Type;
/// TargetIntrinsicInfo - Interface to description of machine instruction set
///
class TargetIntrinsicInfo {
- TargetIntrinsicInfo(const TargetIntrinsicInfo &); // DO NOT IMPLEMENT
- void operator=(const TargetIntrinsicInfo &); // DO NOT IMPLEMENT
+ TargetIntrinsicInfo(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION;
public:
TargetIntrinsicInfo();
virtual ~TargetIntrinsicInfo();
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
index 044afd9..f9bd0fb 100644
--- a/include/llvm/Target/TargetJITInfo.h
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -17,8 +17,8 @@
#ifndef LLVM_TARGET_TARGETJITINFO_H
#define LLVM_TARGET_TARGETJITINFO_H
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
namespace llvm {
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index 2a0a432..ceeba4f 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -10,8 +10,8 @@
#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H
#define LLVM_TARGET_TARGETLIBRARYINFO_H
-#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Pass.h"
namespace llvm {
class Triple;
@@ -49,6 +49,8 @@ namespace llvm {
cxa_guard_release,
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
memcpy_chk,
+ /// int abs(int j);
+ abs,
/// double acos(double x);
acos,
/// float acosf(float x);
@@ -153,6 +155,12 @@ namespace llvm {
fabsf,
/// long double fabsl(long double x);
fabsl,
+ /// int ffs(int i);
+ ffs,
+ /// int ffsl(long int i);
+ ffsl,
+ /// int ffsll(long long int i);
+ ffsll,
/// int fiprintf(FILE *stream, const char *format, ...);
fiprintf,
/// double floor(double x);
@@ -167,6 +175,8 @@ namespace llvm {
fmodf,
/// long double fmodl(long double x, long double y);
fmodl,
+ /// int fprintf(FILE *stream, const char *format, ...);
+ fprintf,
/// int fputc(int c, FILE *stream);
fputc,
/// int fputs(const char *s, FILE *stream);
@@ -178,6 +188,14 @@ namespace llvm {
fwrite,
/// int iprintf(const char *format, ...);
iprintf,
+ /// int isascii(int c);
+ isascii,
+ /// int isdigit(int c);
+ isdigit,
+ /// long int labs(long int j);
+ labs,
+ /// long long int llabs(long long int j);
+ llabs,
/// double log(double x);
log,
/// double log10(double x);
@@ -236,6 +254,8 @@ namespace llvm {
powf,
/// long double powl(long double x, long double y);
powl,
+ /// int printf(const char *format, ...);
+ printf,
/// int putchar(int c);
putchar,
/// int puts(const char *s);
@@ -270,18 +290,26 @@ namespace llvm {
sinl,
/// int siprintf(char *str, const char *format, ...);
siprintf,
+ /// int sprintf(char *str, const char *format, ...);
+ sprintf,
/// double sqrt(double x);
sqrt,
/// float sqrtf(float x);
sqrtf,
/// long double sqrtl(long double x);
sqrtl,
+ /// char *stpcpy(char *s1, const char *s2);
+ stpcpy,
/// char *strcat(char *s1, const char *s2);
strcat,
/// char *strchr(const char *s, int c);
strchr,
+ /// int strcmp(const char *s1, const char *s2);
+ strcmp,
/// char *strcpy(char *s1, const char *s2);
strcpy,
+ /// size_t strcspn(const char *s1, const char *s2);
+ strcspn,
/// char *strdup(const char *s1);
strdup,
/// size_t strlen(const char *s);
@@ -296,6 +324,29 @@ namespace llvm {
strndup,
/// size_t strnlen(const char *s, size_t maxlen);
strnlen,
+ /// char *strpbrk(const char *s1, const char *s2);
+ strpbrk,
+ /// char *strrchr(const char *s, int c);
+ strrchr,
+ /// size_t strspn(const char *s1, const char *s2);
+ strspn,
+ /// char *strstr(const char *s1, const char *s2);
+ strstr,
+ /// double strtod(const char *nptr, char **endptr);
+ strtod,
+ /// float strtof(const char *nptr, char **endptr);
+ strtof,
+ /// long int strtol(const char *nptr, char **endptr, int base);
+ strtol,
+ /// long double strtold(const char *nptr, char **endptr);
+ strtold,
+ /// long long int strtoll(const char *nptr, char **endptr, int base);
+ strtoll,
+ /// unsigned long int strtoul(const char *nptr, char **endptr, int base);
+ strtoul,
+ /// unsigned long long int strtoull(const char *nptr, char **endptr,
+ /// int base);
+ strtoull,
/// double tan(double x);
tan,
/// float tanf(float x);
@@ -308,6 +359,8 @@ namespace llvm {
tanhl,
/// long double tanl(long double x);
tanl,
+ /// int toascii(int c);
+ toascii,
/// double trunc(double x);
trunc,
/// float truncf(float x);
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index ef63422..eee25c9 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -22,13 +22,14 @@
#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
-#include "llvm/CallingConv.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/Attributes.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetMachine.h"
@@ -50,7 +51,7 @@ namespace llvm {
class MCContext;
class MCExpr;
template<typename T> class SmallVectorImpl;
- class TargetData;
+ class DataLayout;
class TargetRegisterClass;
class TargetLibraryInfo;
class TargetLoweringObjectFile;
@@ -67,7 +68,6 @@ namespace llvm {
};
}
-
//===----------------------------------------------------------------------===//
/// TargetLowering - This class defines information used to lower LLVM code to
/// legal SelectionDAG operators that the target instruction selector can accept
@@ -77,8 +77,8 @@ namespace llvm {
/// target-specific constructs to SelectionDAG operators.
///
class TargetLowering {
- TargetLowering(const TargetLowering&); // DO NOT IMPLEMENT
- void operator=(const TargetLowering&); // DO NOT IMPLEMENT
+ TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
public:
/// LegalizeAction - This enum indicates whether operations are valid for a
/// target, and if not, what action should be used to make them valid.
@@ -102,6 +102,10 @@ public:
TypeWidenVector // This vector should be widened into a larger vector.
};
+ /// LegalizeKind holds the legalization kind that needs to happen to EVT
+ /// in order to type-legalize it.
+ typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
+
enum BooleanContent { // How the target represents true/false values.
UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage.
ZeroOrOneBooleanContent, // All bits zero except for bit 0.
@@ -137,12 +141,15 @@ public:
virtual ~TargetLowering();
const TargetMachine &getTargetMachine() const { return TM; }
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
- MVT getPointerTy() const { return PointerTy; }
+ // Return the pointer type for the given address space, defaults to
+ // the pointer type from the data layout.
+ // FIXME: The default needs to be removed once all the code is updated.
+ virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; }
virtual MVT getShiftAmountTy(EVT LHSTy) const;
/// isSelectExpensive - Return true if the select operation is expensive for
@@ -151,18 +158,23 @@ public:
virtual bool isSelectSupported(SelectSupportKind kind) const { return true; }
+ /// shouldSplitVectorElementType - Return true if a vector of the given type
+ /// should be split (TypeSplitVector) instead of promoted
+ /// (TypePromoteInteger) during type legalization.
+ virtual bool shouldSplitVectorElementType(EVT VT) const { return false; }
+
/// isIntDivCheap() - Return true if integer divide is usually cheaper than
/// a sequence of several shifts, adds, and multiplies for this target.
bool isIntDivCheap() const { return IntDivIsCheap; }
/// isSlowDivBypassed - Returns true if target has indicated at least one
/// type should be bypassed.
- bool isSlowDivBypassed() const { return !BypassSlowDivTypes.empty(); }
+ bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); }
/// getBypassSlowDivTypes - Returns map of slow types for division or
/// remainder with corresponding fast types
- const DenseMap<Type *, Type *> &getBypassSlowDivTypes() const {
- return BypassSlowDivTypes;
+ const DenseMap<unsigned int, unsigned int> &getBypassSlowDivWidths() const {
+ return BypassSlowDivWidths;
}
/// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of
@@ -219,9 +231,8 @@ public:
/// getRegClassFor - Return the register class that should be used for the
/// specified value type.
- virtual const TargetRegisterClass *getRegClassFor(EVT VT) const {
- assert(VT.isSimple() && "getRegClassFor called on illegal type!");
- const TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy];
+ virtual const TargetRegisterClass *getRegClassFor(MVT VT) const {
+ const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy];
assert(RC && "This value type is not natively supported!");
return RC;
}
@@ -231,17 +242,15 @@ public:
/// legal super-reg register class for the register class of the value type.
/// For example, on i386 the rep register class for i8, i16, and i32 are GR32;
/// while the rep register class is GR64 on x86_64.
- virtual const TargetRegisterClass *getRepRegClassFor(EVT VT) const {
- assert(VT.isSimple() && "getRepRegClassFor called on illegal type!");
- const TargetRegisterClass *RC = RepRegClassForVT[VT.getSimpleVT().SimpleTy];
+ virtual const TargetRegisterClass *getRepRegClassFor(MVT VT) const {
+ const TargetRegisterClass *RC = RepRegClassForVT[VT.SimpleTy];
return RC;
}
/// getRepRegClassCostFor - Return the cost of the 'representative' register
/// class for the specified value type.
- virtual uint8_t getRepRegClassCostFor(EVT VT) const {
- assert(VT.isSimple() && "getRepRegClassCostFor called on illegal type!");
- return RepRegClassCostForVT[VT.getSimpleVT().SimpleTy];
+ virtual uint8_t getRepRegClassCostFor(MVT VT) const {
+ return RepRegClassCostForVT[VT.SimpleTy];
}
/// isTypeLegal - Return true if the target has native support for the
@@ -267,8 +276,8 @@ public:
return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy];
}
- void setTypeAction(EVT VT, LegalizeTypeAction Action) {
- unsigned I = VT.getSimpleVT().SimpleTy;
+ void setTypeAction(MVT VT, LegalizeTypeAction Action) {
+ unsigned I = VT.SimpleTy;
ValueTypeActions[I] = Action;
}
};
@@ -329,7 +338,7 @@ public:
unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT,
EVT &IntermediateVT,
unsigned &NumIntermediates,
- EVT &RegisterVT) const;
+ MVT &RegisterVT) const;
/// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the
/// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
@@ -403,6 +412,22 @@ public:
getOperationAction(Op, VT) == Custom);
}
+ /// isOperationLegalOrPromote - Return true if the specified operation is
+ /// legal on this target or can be made legal using promotion. This
+ /// is used to help guide high-level lowering decisions.
+ bool isOperationLegalOrPromote(unsigned Op, EVT VT) const {
+ return (VT == MVT::Other || isTypeLegal(VT)) &&
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Promote);
+ }
+
+ /// isOperationExpand - Return true if the specified operation is illegal on
+ /// this target or unlikely to be made legal with custom lowering. This is
+ /// used to help guide high-level lowering decisions.
+ bool isOperationExpand(unsigned Op, EVT VT) const {
+ return (!isTypeLegal(VT) || getOperationAction(Op, VT) == Expand);
+ }
+
/// isOperationLegal - Return true if the specified operation is legal on this
/// target.
bool isOperationLegal(unsigned Op, EVT VT) const {
@@ -414,36 +439,35 @@ public:
/// either it is legal, needs to be promoted to a larger size, needs to be
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
- LegalizeAction getLoadExtAction(unsigned ExtType, EVT VT) const {
- assert(ExtType < ISD::LAST_LOADEXT_TYPE &&
- VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)LoadExtActions[VT.getSimpleVT().SimpleTy][ExtType];
+ return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType];
}
/// isLoadExtLegal - Return true if the specified load with extension is legal
/// on this target.
bool isLoadExtLegal(unsigned ExtType, EVT VT) const {
- return VT.isSimple() && getLoadExtAction(ExtType, VT) == Legal;
+ return VT.isSimple() &&
+ getLoadExtAction(ExtType, VT.getSimpleVT()) == Legal;
}
/// getTruncStoreAction - Return how this store with truncation should be
/// treated: either it is legal, needs to be promoted to a larger size, needs
/// to be expanded to some other code sequence, or the target has a custom
/// expander for it.
- LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
- assert(ValVT.getSimpleVT() < MVT::LAST_VALUETYPE &&
- MemVT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const {
+ assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)TruncStoreActions[ValVT.getSimpleVT().SimpleTy]
- [MemVT.getSimpleVT().SimpleTy];
+ return (LegalizeAction)TruncStoreActions[ValVT.SimpleTy]
+ [MemVT.SimpleTy];
}
/// isTruncStoreLegal - Return true if the specified store with truncation is
/// legal on this target.
bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const {
return isTypeLegal(ValVT) && MemVT.isSimple() &&
- getTruncStoreAction(ValVT, MemVT) == Legal;
+ getTruncStoreAction(ValVT.getSimpleVT(), MemVT.getSimpleVT()) == Legal;
}
/// getIndexedLoadAction - Return how the indexed load should be treated:
@@ -451,11 +475,10 @@ public:
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
LegalizeAction
- getIndexedLoadAction(unsigned IdxMode, EVT VT) const {
- assert(IdxMode < ISD::LAST_INDEXED_MODE &&
- VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ getIndexedLoadAction(unsigned IdxMode, MVT VT) const {
+ assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ unsigned Ty = (unsigned)VT.SimpleTy;
return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
}
@@ -463,8 +486,8 @@ public:
/// on this target.
bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
- (getIndexedLoadAction(IdxMode, VT) == Legal ||
- getIndexedLoadAction(IdxMode, VT) == Custom);
+ (getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal ||
+ getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom);
}
/// getIndexedStoreAction - Return how the indexed store should be treated:
@@ -472,11 +495,10 @@ public:
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
LegalizeAction
- getIndexedStoreAction(unsigned IdxMode, EVT VT) const {
- assert(IdxMode < ISD::LAST_INDEXED_MODE &&
- VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ getIndexedStoreAction(unsigned IdxMode, MVT VT) const {
+ assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ unsigned Ty = (unsigned)VT.SimpleTy;
return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
}
@@ -484,50 +506,54 @@ public:
/// on this target.
bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
- (getIndexedStoreAction(IdxMode, VT) == Legal ||
- getIndexedStoreAction(IdxMode, VT) == Custom);
+ (getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal ||
+ getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom);
}
/// getCondCodeAction - Return how the condition code should be treated:
/// either it is legal, needs to be expanded to some other code sequence,
/// or the target has a custom expander for it.
LegalizeAction
- getCondCodeAction(ISD::CondCode CC, EVT VT) const {
+ getCondCodeAction(ISD::CondCode CC, MVT VT) const {
assert((unsigned)CC < array_lengthof(CondCodeActions) &&
- (unsigned)VT.getSimpleVT().SimpleTy < sizeof(CondCodeActions[0])*4 &&
+ (unsigned)VT.SimpleTy < sizeof(CondCodeActions[0])*4 &&
"Table isn't big enough!");
+ /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit
+ /// value and the upper 27 bits index into the second dimension of the
+ /// array to select what 64bit value to use.
LegalizeAction Action = (LegalizeAction)
- ((CondCodeActions[CC] >> (2*VT.getSimpleVT().SimpleTy)) & 3);
+ ((CondCodeActions[CC][VT.SimpleTy >> 5] >> (2*(VT.SimpleTy & 0x1F))) & 3);
assert(Action != Promote && "Can't promote condition code!");
return Action;
}
/// isCondCodeLegal - Return true if the specified condition code is legal
/// on this target.
- bool isCondCodeLegal(ISD::CondCode CC, EVT VT) const {
- return getCondCodeAction(CC, VT) == Legal ||
- getCondCodeAction(CC, VT) == Custom;
+ bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const {
+ return
+ getCondCodeAction(CC, VT) == Legal ||
+ getCondCodeAction(CC, VT) == Custom;
}
/// getTypeToPromoteTo - If the action for this operation is to promote, this
/// method returns the ValueType to promote to.
- EVT getTypeToPromoteTo(unsigned Op, EVT VT) const {
+ MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
assert(getOperationAction(Op, VT) == Promote &&
"This operation isn't promoted!");
// See if this has an explicit type specified.
std::map<std::pair<unsigned, MVT::SimpleValueType>,
MVT::SimpleValueType>::const_iterator PTTI =
- PromoteToType.find(std::make_pair(Op, VT.getSimpleVT().SimpleTy));
+ PromoteToType.find(std::make_pair(Op, VT.SimpleTy));
if (PTTI != PromoteToType.end()) return PTTI->second;
assert((VT.isInteger() || VT.isFloatingPoint()) &&
"Cannot autopromote this type, add it with AddPromotedToType.");
- EVT NVT = VT;
+ MVT NVT = VT;
do {
- NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1);
+ NVT = (MVT::SimpleValueType)(NVT.SimpleTy+1);
assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid &&
"Didn't find type to promote to!");
} while (!isTypeLegal(NVT) ||
@@ -555,6 +581,11 @@ public:
return EVT::getEVT(Ty, AllowUnknown);
}
+ /// Return the MVT corresponding to this LLVM type. See getValueType.
+ MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const {
+ return getValueType(Ty, AllowUnknown).getSimpleVT();
+ }
+
/// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
/// function arguments in the caller parameter area. This is the actual
/// alignment, not its logarithm.
@@ -562,21 +593,22 @@ public:
/// getRegisterType - Return the type of registers that this ValueType will
/// eventually require.
- EVT getRegisterType(MVT VT) const {
+ MVT getRegisterType(MVT VT) const {
assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT));
return RegisterTypeForVT[VT.SimpleTy];
}
/// getRegisterType - Return the type of registers that this ValueType will
/// eventually require.
- EVT getRegisterType(LLVMContext &Context, EVT VT) const {
+ MVT getRegisterType(LLVMContext &Context, EVT VT) const {
if (VT.isSimple()) {
assert((unsigned)VT.getSimpleVT().SimpleTy <
array_lengthof(RegisterTypeForVT));
return RegisterTypeForVT[VT.getSimpleVT().SimpleTy];
}
if (VT.isVector()) {
- EVT VT1, RegisterVT;
+ EVT VT1;
+ MVT RegisterVT;
unsigned NumIntermediates;
(void)getVectorTypeBreakdown(Context, VT, VT1,
NumIntermediates, RegisterVT);
@@ -601,7 +633,8 @@ public:
return NumRegistersForVT[VT.getSimpleVT().SimpleTy];
}
if (VT.isVector()) {
- EVT VT1, VT2;
+ EVT VT1;
+ MVT VT2;
unsigned NumIntermediates;
return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2);
}
@@ -653,12 +686,14 @@ public:
}
/// This function returns true if the target allows unaligned memory accesses.
- /// of the specified type. This is used, for example, in situations where an
- /// array copy/move/set is converted to a sequence of store operations. It's
- /// use helps to ensure that such replacements don't generate code that causes
- /// an alignment error (trap) on the target machine.
+ /// of the specified type. If true, it also returns whether the unaligned
+ /// memory access is "fast" in the second argument by reference. This is used,
+ /// for example, in situations where an array copy/move/set is converted to a
+ /// sequence of store operations. It's use helps to ensure that such
+ /// replacements don't generate code that causes an alignment error (trap) on
+ /// the target machine.
/// @brief Determine if the target supports unaligned memory accesses.
- virtual bool allowsUnalignedMemoryAccesses(EVT) const {
+ virtual bool allowsUnalignedMemoryAccesses(EVT, bool *Fast = 0) const {
return false;
}
@@ -674,21 +709,31 @@ public:
/// lowering. If DstAlign is zero that means it's safe to destination
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
- /// probably because the source does not need to be loaded. If
- /// 'IsZeroVal' is true, that means it's safe to return a
- /// non-scalar-integer type, e.g. empty string source, constant, or loaded
- /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
- /// constant so it does not need to be loaded.
+ /// probably because the source does not need to be loaded. If 'IsMemset' is
+ /// true, that means it's expanding a memset. If 'ZeroMemset' is true, that
+ /// means it's a memset of zero. 'MemcpyStrSrc' indicates whether the memcpy
+ /// source is constant so it does not need to be loaded.
/// It returns EVT::Other if the type should be determined using generic
/// target-independent logic.
virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
- bool /*IsZeroVal*/,
+ bool /*IsMemset*/,
+ bool /*ZeroMemset*/,
bool /*MemcpyStrSrc*/,
MachineFunction &/*MF*/) const {
return MVT::Other;
}
+ /// isSafeMemOpType - Returns true if it's safe to use load / store of the
+ /// specified type to expand memcpy / memset inline. This is mostly true
+ /// for all types except for some special cases. For example, on X86
+ /// targets without SSE2 f64 load / store are done with fldl / fstpl which
+ /// also does type conversion. Note the specified type doesn't have to be
+ /// legal as the hook is used before type legalization.
+ virtual bool isSafeMemOpType(MVT VT) const {
+ return true;
+ }
+
/// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
/// to implement llvm.setjmp.
bool usesUnderscoreSetJmp() const {
@@ -707,6 +752,12 @@ public:
return SupportJumpTables;
}
+ /// getMinimumJumpTableEntries - return integer threshold on number of
+ /// blocks to use jump tables rather than if sequence.
+ int getMinimumJumpTableEntries() const {
+ return MinimumJumpTableEntries;
+ }
+
/// getStackPointerRegisterToSaveRestore - If a physical register, this
/// specifies the register that llvm.savestack/llvm.restorestack should save
/// and restore.
@@ -843,6 +894,18 @@ public:
}
//===--------------------------------------------------------------------===//
+ /// \name Helpers for TargetTransformInfo implementations
+ /// @{
+
+ /// Get the ISD node that corresponds to the Instruction class opcode.
+ int InstructionOpcodeToISD(unsigned Opcode) const;
+
+ /// Estimate the cost of type-legalization and the legalized type.
+ std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const;
+
+ /// @}
+
+ //===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
//
@@ -912,18 +975,20 @@ public:
struct DAGCombinerInfo {
void *DC; // The DAG Combiner object.
- bool BeforeLegalize;
- bool BeforeLegalizeOps;
+ CombineLevel Level;
bool CalledByLegalizer;
public:
SelectionDAG &DAG;
- DAGCombinerInfo(SelectionDAG &dag, bool bl, bool blo, bool cl, void *dc)
- : DC(dc), BeforeLegalize(bl), BeforeLegalizeOps(blo),
- CalledByLegalizer(cl), DAG(dag) {}
+ DAGCombinerInfo(SelectionDAG &dag, CombineLevel level, bool cl, void *dc)
+ : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {}
- bool isBeforeLegalize() const { return BeforeLegalize; }
- bool isBeforeLegalizeOps() const { return BeforeLegalizeOps; }
+ bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; }
+ bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOps; }
+ bool isAfterLegalizeVectorOps() const {
+ return Level == AfterLegalizeDAG;
+ }
+ CombineLevel getDAGCombineLevel() { return Level; }
bool isCalledByLegalizer() const { return CalledByLegalizer; }
void AddToWorklist(SDNode *N);
@@ -1027,6 +1092,12 @@ protected:
SupportJumpTables = Val;
}
+ /// setMinimumJumpTableEntries - Indicate the number of blocks to generate
+ /// jump tables rather than if sequence.
+ void setMinimumJumpTableEntries(int Val) {
+ MinimumJumpTableEntries = Val;
+ }
+
/// setStackPointerRegisterToSaveRestore - If set to a physical register, this
/// specifies the register that llvm.savestack/llvm.restorestack should save
/// and restore.
@@ -1066,9 +1137,9 @@ protected:
/// of instructions not containing an integer divide.
void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
- /// addBypassSlowDivType - Tells the code generator which types to bypass.
- void addBypassSlowDivType(Type *slow_type, Type *fast_type) {
- BypassSlowDivTypes[slow_type] = fast_type;
+ /// addBypassSlowDiv - Tells the code generator which bitwidths to bypass.
+ void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth) {
+ BypassSlowDivWidths[SlowBitWidth] = FastBitWidth;
}
/// setPow2DivIsCheap - Tells the code generator that it shouldn't generate
@@ -1079,16 +1150,16 @@ protected:
/// addRegisterClass - Add the specified register class as an available
/// regclass for the specified value type. This indicates the selector can
/// handle values of that class natively.
- void addRegisterClass(EVT VT, const TargetRegisterClass *RC) {
- assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
+ void addRegisterClass(MVT VT, const TargetRegisterClass *RC) {
+ assert((unsigned)VT.SimpleTy < array_lengthof(RegClassForVT));
AvailableRegClasses.push_back(std::make_pair(VT, RC));
- RegClassForVT[VT.getSimpleVT().SimpleTy] = RC;
+ RegClassForVT[VT.SimpleTy] = RC;
}
/// findRepresentativeClass - Return the largest legal super-reg register class
/// of the register class for the specified type and its associated "cost".
virtual std::pair<const TargetRegisterClass*, uint8_t>
- findRepresentativeClass(EVT VT) const;
+ findRepresentativeClass(MVT VT) const;
/// computeRegisterProperties - Once all of the register classes are added,
/// this allows us to compute derived properties we expose.
@@ -1153,8 +1224,13 @@ protected:
assert(VT < MVT::LAST_VALUETYPE &&
(unsigned)CC < array_lengthof(CondCodeActions) &&
"Table isn't big enough!");
- CondCodeActions[(unsigned)CC] &= ~(uint64_t(3UL) << VT.SimpleTy*2);
- CondCodeActions[(unsigned)CC] |= (uint64_t)Action << VT.SimpleTy*2;
+ /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit
+ /// value and the upper 27 bits index into the second dimension of the
+ /// array to select what 64bit value to use.
+ CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5]
+ &= ~(uint64_t(3UL) << (VT.SimpleTy & 0x1F)*2);
+ CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5]
+ |= (uint64_t)Action << (VT.SimpleTy & 0x1F)*2;
}
/// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
@@ -1227,7 +1303,7 @@ protected:
public:
//===--------------------------------------------------------------------===//
// Lowering methods - These methods must be implemented by targets so that
- // the SelectionDAGLowering code knows how to lower these.
+ // the SelectionDAGBuilder code knows how to lower these.
//
/// LowerFormalArguments - This hook must be implemented to lower the
@@ -1340,7 +1416,7 @@ public:
}
/// HandleByVal - Target-specific cleanup for formal ByVal parameters.
- virtual void HandleByVal(CCState *, unsigned &) const {}
+ virtual void HandleByVal(CCState *, unsigned &, unsigned) const {}
/// CanLowerReturn - This hook should be implemented to check whether the
/// return values described by the Outs array can fit into the return
@@ -1392,9 +1468,9 @@ public:
/// but this is not true all the time, e.g. i1 on x86-64. It is also not
/// necessary for non-C calling conventions. The frontend should handle this
/// and include all of the necessary information.
- virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT,
+ virtual MVT getTypeForExtArgOrReturn(MVT VT,
ISD::NodeType /*ExtendKind*/) const {
- EVT MinVT = getRegisterType(Context, MVT::i32);
+ MVT MinVT = getRegisterType(MVT::i32);
return VT.bitsLT(MinVT) ? MinVT : VT;
}
@@ -1501,7 +1577,7 @@ public:
Value *CallOperandVal;
/// ConstraintVT - The ValueType for the operand value.
- EVT ConstraintVT;
+ MVT ConstraintVT;
/// isMatchingInputConstraint - Return true of this is an input operand that
/// is a matching constraint like "4".
@@ -1610,6 +1686,17 @@ public:
// Addressing mode description hooks (used by LSR etc).
//
+ /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the
+ /// same BB as Load/Store instructions reading the address. This allows as
+ /// much computation as possible to be done in the address mode for that
+ /// operand. This hook lets targets also pass back when this should be done
+ /// on intrinsics which load/store.
+ virtual bool GetAddrModeArguments(IntrinsicInst *I,
+ SmallVectorImpl<Value*> &Ops,
+ Type *&AccessTy) const {
+ return false;
+ }
+
/// AddrMode - This represents an addressing mode of:
/// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
/// If BaseGV is null, there is no BaseGV.
@@ -1626,17 +1713,6 @@ public:
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
};
- /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the
- /// same BB as Load/Store instructions reading the address. This allows as
- /// much computation as possible to be done in the address mode for that
- /// operand. This hook lets targets also pass back when this should be done
- /// on intrinsics which load/store.
- virtual bool GetAddrModeArguments(IntrinsicInst *I,
- SmallVectorImpl<Value*> &Ops,
- Type *&AccessTy) const {
- return false;
- }
-
/// isLegalAddressingMode - Return true if the addressing mode represented by
/// AM is legal for this target, for a load/store of the specified type.
/// The type may be VoidTy, in which case only return true if the addressing
@@ -1687,6 +1763,13 @@ public:
return false;
}
+ /// isZExtFree - Return true if zero-extending the specific node Val to type
+ /// VT2 is free (either because it's implicitly zero-extended such as ARM
+ /// ldrb / ldrh or because it's folded such as X86 zero-extending loads).
+ virtual bool isZExtFree(SDValue Val, EVT VT2) const {
+ return isZExtFree(Val.getValueType(), VT2);
+ }
+
/// isFNegFree - Return true if an fneg operation is free to the point where
/// it is never worthwhile to replace it with a bitwise operation.
virtual bool isFNegFree(EVT) const {
@@ -1720,9 +1803,9 @@ public:
SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl,
SelectionDAG &DAG) const;
SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
- std::vector<SDNode*>* Created) const;
+ std::vector<SDNode*> *Created) const;
SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
- std::vector<SDNode*>* Created) const;
+ std::vector<SDNode*> *Created) const;
//===--------------------------------------------------------------------===//
@@ -1767,10 +1850,11 @@ public:
private:
const TargetMachine &TM;
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLoweringObjectFile &TLOF;
- /// PointerTy - The type to use for pointers, usually i32 or i64.
+ /// PointerTy - The type to use for pointers for the default address space,
+ /// usually i32 or i64.
///
MVT PointerTy;
@@ -1788,11 +1872,11 @@ private:
/// set to true unconditionally.
bool IntDivIsCheap;
- /// BypassSlowDivTypes - Tells the code generator to bypass slow divide or
- /// remainder instructions. For example, SlowDivBypass[i32,u8] tells the code
- /// generator to bypass 32-bit signed integer div/rem with an 8-bit unsigned
+ /// BypassSlowDivMap - Tells the code generator to bypass slow divide or
+ /// remainder instructions. For example, BypassSlowDivWidths[32,8] tells the
+ /// code generator to bypass 32-bit integer div/rem with an 8-bit unsigned
/// integer div/rem when the operands are positive and less than 256.
- DenseMap <Type *, Type *> BypassSlowDivTypes;
+ DenseMap <unsigned int, unsigned int> BypassSlowDivWidths;
/// Pow2DivIsCheap - Tells the code generator that it shouldn't generate
/// srl/add/sra for a signed divide by power of two, and let the target handle
@@ -1816,6 +1900,9 @@ private:
/// If it's not true, then each jumptable must be lowered into if-then-else's.
bool SupportJumpTables;
+ /// MinimumJumpTableEntries - Number of blocks threshold to use jump tables.
+ int MinimumJumpTableEntries;
+
/// BooleanContents - Information about the contents of the high-bits in
/// boolean values held in a type wider than i1. See getBooleanContents.
BooleanContent BooleanContents;
@@ -1884,7 +1971,7 @@ private:
/// each ValueType the target supports natively.
const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
- EVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
+ MVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
/// RepRegClassForVT - This indicates the "representative" register class to
/// use for each ValueType the target supports natively. This information is
@@ -1904,7 +1991,7 @@ private:
/// contains one step of the expand (e.g. i64 -> i32), even if there are
/// multiple steps required (e.g. i64 -> i16). For types natively supported
/// by the system, this holds the same type (e.g. i32 -> i32).
- EVT TransformToType[MVT::LAST_VALUETYPE];
+ MVT TransformToType[MVT::LAST_VALUETYPE];
/// OpActions - For each operation and each value type, keep a LegalizeAction
/// that indicates how instruction selection should deal with the operation.
@@ -1933,26 +2020,34 @@ private:
/// CondCodeActions - For each condition code (ISD::CondCode) keep a
/// LegalizeAction that indicates how instruction selection should
/// deal with the condition code.
- uint64_t CondCodeActions[ISD::SETCC_INVALID];
+ /// Because each CC action takes up 2 bits, we need to have the array size
+ /// be large enough to fit all of the value types. This can be done by
+ /// dividing the MVT::LAST_VALUETYPE by 32 and adding one.
+ uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1];
ValueTypeActionImpl ValueTypeActions;
- typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
-
+public:
LegalizeKind
getTypeConversion(LLVMContext &Context, EVT VT) const {
// If this is a simple type, use the ComputeRegisterProp mechanism.
if (VT.isSimple()) {
- assert((unsigned)VT.getSimpleVT().SimpleTy <
- array_lengthof(TransformToType));
- EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy];
- LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT());
+ MVT SVT = VT.getSimpleVT();
+ assert((unsigned)SVT.SimpleTy < array_lengthof(TransformToType));
+ MVT NVT = TransformToType[SVT.SimpleTy];
+ LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT);
assert(
- (!(NVT.isSimple() && LA != TypeLegal) ||
- ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteInteger)
+ (LA == TypeLegal ||
+ ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger)
&& "Promote may not follow Expand or Promote");
+ if (LA == TypeSplitVector)
+ return LegalizeKind(LA, EVT::getVectorVT(Context,
+ SVT.getVectorElementType(),
+ SVT.getVectorNumElements()/2));
+ if (LA == TypeScalarizeVector)
+ return LegalizeKind(LA, SVT.getVectorElementType());
return LegalizeKind(LA, NVT);
}
@@ -2055,7 +2150,8 @@ private:
return LegalizeKind(TypeSplitVector, NVT);
}
- std::vector<std::pair<EVT, const TargetRegisterClass*> > AvailableRegClasses;
+private:
+ std::vector<std::pair<MVT, const TargetRegisterClass*> > AvailableRegClasses;
/// TargetDAGCombineArray - Targets can specify ISD nodes that they would
/// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(),
@@ -2148,7 +2244,7 @@ private:
/// GetReturnInfo - Given an LLVM IR type and return type attributes,
/// compute the return value EVTs and flags, and optionally also
/// the offsets, if the return value is being lowered to memory.
-void GetReturnInfo(Type* ReturnType, Attributes attr,
+void GetReturnInfo(Type* ReturnType, AttributeSet attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
const TargetLowering &TLI);
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index d631f58..9958755 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -15,10 +15,10 @@
#ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
-#include "llvm/Module.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/Module.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/SectionKind.h"
-#include "llvm/ADT/ArrayRef.h"
namespace llvm {
class MachineModuleInfo;
@@ -27,16 +27,18 @@ namespace llvm {
class MCExpr;
class MCSection;
class MCSymbol;
+ class MCSymbolRefExpr;
class MCStreamer;
class GlobalValue;
class TargetMachine;
class TargetLoweringObjectFile : public MCObjectFileInfo {
MCContext *Ctx;
-
- TargetLoweringObjectFile(const TargetLoweringObjectFile&); // DO NOT IMPLEMENT
- void operator=(const TargetLoweringObjectFile&); // DO NOT IMPLEMENT
-
+
+ TargetLoweringObjectFile(
+ const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION;
+
public:
MCContext &getContext() const { return *Ctx; }
@@ -107,13 +109,13 @@ public:
return 0;
}
- /// getExprForDwarfGlobalReference - Return an MCExpr to use for a reference
+ /// getTTypeGlobalReference - Return an MCExpr to use for a reference
/// to the specified global variable from exception handling information.
///
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
@@ -122,8 +124,8 @@ public:
///
const MCExpr *
- getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
+ MCStreamer &Streamer) const;
virtual const MCSection *
getStaticCtorSection(unsigned Priority = 65535) const {
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index e4bf32b..aa049f0 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,10 +14,10 @@
#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <string>
@@ -31,8 +31,7 @@ class MCCodeGenInfo;
class MCContext;
class PassManagerBase;
class Target;
-class TargetData;
-class TargetELFWriterInfo;
+class DataLayout;
class TargetFrameLowering;
class TargetInstrInfo;
class TargetIntrinsicInfo;
@@ -42,6 +41,8 @@ class TargetPassConfig;
class TargetRegisterInfo;
class TargetSelectionDAGInfo;
class TargetSubtargetInfo;
+class ScalarTargetTransformInfo;
+class VectorTargetTransformInfo;
class formatted_raw_ostream;
class raw_ostream;
@@ -52,8 +53,8 @@ class raw_ostream;
/// through this interface.
///
class TargetMachine {
- TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT
- void operator=(const TargetMachine &); // DO NOT IMPLEMENT
+ TargetMachine(const TargetMachine &) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetMachine &) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses.
TargetMachine(const Target &T, StringRef TargetTriple,
StringRef CPU, StringRef FS, const TargetOptions &Options);
@@ -106,7 +107,7 @@ public:
virtual const TargetFrameLowering *getFrameLowering() const { return 0; }
virtual const TargetLowering *getTargetLowering() const { return 0; }
virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; }
- virtual const TargetData *getTargetData() const { return 0; }
+ virtual const DataLayout *getDataLayout() const { return 0; }
/// getMCAsmInfo - Return target specific asm information.
///
@@ -142,11 +143,6 @@ public:
return 0;
}
- /// getELFWriterInfo - If this target supports an ELF writer, return
- /// information for it, otherwise return null.
- ///
- virtual const TargetELFWriterInfo *getELFWriterInfo() const { return 0; }
-
/// hasMCRelaxAll - Check whether all machine code instructions should be
/// relaxed.
bool hasMCRelaxAll() const { return MCRelaxAll; }
@@ -232,6 +228,9 @@ public:
/// sections.
static void setFunctionSections(bool);
+ /// \brief Register analysis passes for this target with a pass manager.
+ virtual void addAnalysisPasses(PassManagerBase &) {}
+
/// CodeGenFileType - These enums are meant to be passed into
/// addPassesToEmitFile to indicate what type of file to emit, and returned by
/// it to indicate what type of file could actually be made.
@@ -290,6 +289,11 @@ protected: // Can only create subclasses.
CodeGenOpt::Level OL);
public:
+ /// \brief Register analysis passes for this target with a pass manager.
+ ///
+ /// This registers target independent analysis passes.
+ virtual void addAnalysisPasses(PassManagerBase &PM);
+
/// createPassConfig - Create a pass configuration object to be used by
/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 68ca567..8fc566e 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -24,7 +24,7 @@ namespace llvm {
// Possible float ABI settings. Used with FloatABIType in TargetOptions.h.
namespace FloatABI {
enum ABIType {
- Default, // Target-specific (either soft or hard depending on triple, etc).
+ Default, // Target-specific (either soft or hard depending on triple,etc).
Soft, // Soft float.
Hard // Hard float.
};
@@ -50,7 +50,7 @@ namespace llvm {
GuaranteedTailCallOpt(false), DisableTailCalls(false),
StackAlignmentOverride(0), RealignStack(true), EnableFastISel(false),
PositionIndependentExecutable(false), EnableSegmentedStacks(false),
- UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default),
+ UseInitArray(false), TrapFuncName(""),FloatABIType(FloatABI::Default),
AllowFPOpFusion(FPOpFusion::Standard)
{}
@@ -202,10 +202,10 @@ namespace llvm {
/// Strict mode - allow fusion only if/when it can be proven that the excess
/// precision won't effect the result.
///
- /// Note: This option only controls formation of fused ops by the optimizers.
- /// Fused operations that are explicitly specified (e.g. FMA via the
- /// llvm.fma.* intrinsic) will always be honored, regardless of the value of
- /// this option.
+ /// Note: This option only controls formation of fused ops by the
+ /// optimizers. Fused operations that are explicitly specified (e.g. FMA
+ /// via the llvm.fma.* intrinsic) will always be honored, regardless of
+ /// the value of this option.
FPOpFusion::FPOpFusionMode AllowFPOpFusion;
};
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index df4d900..2a8ef98 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -16,11 +16,11 @@
#ifndef LLVM_TARGET_TARGETREGISTERINFO_H
#define LLVM_TARGET_TARGETREGISTERINFO_H
-#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/CallingConv.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include <cassert>
#include <functional>
@@ -30,12 +30,13 @@ class BitVector;
class MachineFunction;
class RegScavenger;
template<class T> class SmallVectorImpl;
+class VirtRegMap;
class raw_ostream;
class TargetRegisterClass {
public:
- typedef const uint16_t* iterator;
- typedef const uint16_t* const_iterator;
+ typedef const MCPhysReg* iterator;
+ typedef const MCPhysReg* const_iterator;
typedef const MVT::SimpleValueType* vt_iterator;
typedef const TargetRegisterClass* const * sc_iterator;
@@ -45,7 +46,7 @@ public:
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
const sc_iterator SuperClasses;
- ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&);
+ ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
/// getID() - Return the register class ID number.
///
@@ -190,7 +191,7 @@ public:
///
/// By default, this method returns all registers in the class.
///
- ArrayRef<uint16_t> getRawAllocationOrder(const MachineFunction &MF) const {
+ ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const {
return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs());
}
};
@@ -221,13 +222,17 @@ public:
private:
const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
const char *const *SubRegIndexNames; // Names of subreg indexes.
+ // Pointer to array of lane masks, one per sub-reg index.
+ const unsigned *SubRegIndexLaneMasks;
+
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
protected:
TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
regclass_iterator RegClassBegin,
regclass_iterator RegClassEnd,
- const char *const *subregindexnames);
+ const char *const *SRINames,
+ const unsigned *SRILaneMasks);
virtual ~TargetRegisterInfo();
public:
@@ -327,10 +332,36 @@ public:
/// getSubRegIndexName - Return the human-readable symbolic target-specific
/// name for the specified SubRegIndex.
const char *getSubRegIndexName(unsigned SubIdx) const {
- assert(SubIdx && "This is not a subregister index");
+ assert(SubIdx && SubIdx < getNumSubRegIndices() &&
+ "This is not a subregister index");
return SubRegIndexNames[SubIdx-1];
}
+ /// getSubRegIndexLaneMask - Return a bitmask representing the parts of a
+ /// register that are covered by SubIdx.
+ ///
+ /// Lane masks for sub-register indices are similar to register units for
+ /// physical registers. The individual bits in a lane mask can't be assigned
+ /// any specific meaning. They can be used to check if two sub-register
+ /// indices overlap.
+ ///
+ /// If the target has a register such that:
+ ///
+ /// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
+ ///
+ /// then:
+ ///
+ /// getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0
+ ///
+ /// The converse is not necessarily true. If two lane masks have a common
+ /// bit, the corresponding sub-registers may not overlap, but it can be
+ /// assumed that they usually will.
+ unsigned getSubRegIndexLaneMask(unsigned SubIdx) const {
+ // SubIdx == 0 is allowed, it has the lane mask ~0u.
+ assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index");
+ return SubRegIndexLaneMasks[SubIdx];
+ }
+
/// regsOverlap - Returns true if the two registers are equal or alias each
/// other. The registers may be virtual register.
bool regsOverlap(unsigned regA, unsigned regB) const {
@@ -357,27 +388,12 @@ public:
return false;
}
- /// isSubRegister - Returns true if regB is a sub-register of regA.
- ///
- bool isSubRegister(unsigned regA, unsigned regB) const {
- return isSuperRegister(regB, regA);
- }
-
- /// isSuperRegister - Returns true if regB is a super-register of regA.
- ///
- bool isSuperRegister(unsigned RegA, unsigned RegB) const {
- for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
- if (*I == RegB)
- return true;
- return false;
- }
-
/// getCalleeSavedRegs - Return a null-terminated list of all of the
/// callee saved registers on this target. The register should be in the
/// order of desired callee-save stack frame offset. The first register is
/// closest to the incoming stack pointer if stack grows down, and vice versa.
///
- virtual const uint16_t* getCalleeSavedRegs(const MachineFunction *MF = 0)
+ virtual const MCPhysReg* getCalleeSavedRegs(const MachineFunction *MF = 0)
const = 0;
/// getCallPreservedMask - Return a mask of call-preserved registers for the
@@ -416,18 +432,6 @@ public:
return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC->MC);
}
- /// canCombineSubRegIndices - Given a register class and a list of
- /// subregister indices, return true if it's possible to combine the
- /// subregister indices into one that corresponds to a larger
- /// subregister. Return the new subregister index by reference. Note the
- /// new index may be zero if the given subregisters can be combined to
- /// form the whole register.
- virtual bool canCombineSubRegIndices(const TargetRegisterClass *RC,
- SmallVectorImpl<unsigned> &SubIndices,
- unsigned &NewSubIdx) const {
- return 0;
- }
-
/// getMatchingSuperRegClass - Return a subclass of the specified register
/// class A so that each register in it has a sub-register of the
/// specified sub-register index which is in the specified register class B.
@@ -458,6 +462,8 @@ public:
/// composeSubRegIndices - Return the subregister index you get from composing
/// two subregister indices.
///
+ /// The special null sub-register index composes as the identity.
+ ///
/// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b)
/// returns c. Note that composeSubRegIndices does not tell you about illegal
/// compositions. If R does not have a subreg a, or R:a does not have a subreg
@@ -467,11 +473,19 @@ public:
/// ssub_0:S0 - ssub_3:S3 subregs.
/// If you compose subreg indices dsub_1, ssub_0 you get ssub_2.
///
- virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const {
- // This default implementation is correct for most targets.
- return b;
+ unsigned composeSubRegIndices(unsigned a, unsigned b) const {
+ if (!a) return b;
+ if (!b) return a;
+ return composeSubRegIndicesImpl(a, b);
}
+protected:
+ /// Overridden by TableGen in targets that have sub-registers.
+ virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const {
+ llvm_unreachable("Target has no sub-registers");
+ }
+
+public:
/// getCommonSuperRegClass - Find a common super-register class if it exists.
///
/// Find a register class, SuperRC and two sub-register indices, PreA and
@@ -566,10 +580,13 @@ public:
return 0;
}
-// Get the weight in units of pressure for this register class.
+ /// Get the weight in units of pressure for this register class.
virtual const RegClassWeight &getRegClassWeight(
const TargetRegisterClass *RC) const = 0;
+ /// Get the weight in units of pressure for this register unit.
+ virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0;
+
/// Get the number of dimensions of register pressure.
virtual unsigned getNumRegPressureSets() const = 0;
@@ -585,27 +602,29 @@ public:
virtual const int *getRegClassPressureSets(
const TargetRegisterClass *RC) const = 0;
- /// getRawAllocationOrder - Returns the register allocation order for a
- /// specified register class with a target-dependent hint. The returned list
- /// may contain reserved registers that cannot be allocated.
- ///
- /// Register allocators need only call this function to resolve
- /// target-dependent hints, but it should work without hinting as well.
- virtual ArrayRef<uint16_t>
- getRawAllocationOrder(const TargetRegisterClass *RC,
- unsigned HintType, unsigned HintReg,
- const MachineFunction &MF) const {
- return RC->getRawAllocationOrder(MF);
- }
-
- /// ResolveRegAllocHint - Resolves the specified register allocation hint
- /// to a physical register. Returns the physical register if it is successful.
- virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
- const MachineFunction &MF) const {
- if (Type == 0 && Reg && isPhysicalRegister(Reg))
- return Reg;
- return 0;
- }
+ /// Get the dimensions of register pressure impacted by this register unit.
+ /// Returns a -1 terminated array of pressure set IDs.
+ virtual const int *getRegUnitPressureSets(unsigned RegUnit) const = 0;
+
+ /// Get a list of 'hint' registers that the register allocator should try
+ /// first when allocating a physical register for the virtual register
+ /// VirtReg. These registers are effectively moved to the front of the
+ /// allocation order.
+ ///
+ /// The Order argument is the allocation order for VirtReg's register class
+ /// as returned from RegisterClassInfo::getOrder(). The hint registers must
+ /// come from Order, and they must not be reserved.
+ ///
+ /// The default implementation of this function can resolve
+ /// target-independent hints provided to MRI::setRegAllocationHint with
+ /// HintType == 0. Targets that override this function should defer to the
+ /// default implementation if they have no reason to change the allocation
+ /// order for VirtReg. There may be target-independent hints.
+ virtual void getRegAllocationHints(unsigned VirtReg,
+ ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints,
+ const MachineFunction &MF,
+ const VirtRegMap *VRM = 0) const;
/// avoidWriteAfterWrite - Return true if the register allocator should avoid
/// writing a register from RC in two consecutive instructions.
@@ -848,7 +867,8 @@ class PrintReg {
unsigned Reg;
unsigned SubIdx;
public:
- PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx = 0)
+ explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0,
+ unsigned subidx = 0)
: TRI(tri), Reg(reg), SubIdx(subidx) {}
void print(raw_ostream&) const;
};
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 4dc488d..0da82fd 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -10,25 +10,77 @@
// This file defines the target-independent scheduling interfaces which should
// be implemented by each target which is using TableGen based scheduling.
//
+// The SchedMachineModel is defined by subtargets for three categories of data:
+// 1. Basic properties for coarse grained instruction cost model.
+// 2. Scheduler Read/Write resources for simple per-opcode cost model.
+// 3. Instruction itineraties for detailed reservation tables.
+//
+// (1) Basic properties are defined by the SchedMachineModel
+// class. Target hooks allow subtargets to associate opcodes with
+// those properties.
+//
+// (2) A per-operand machine model can be implemented in any
+// combination of the following ways:
+//
+// A. Associate per-operand SchedReadWrite types with Instructions by
+// modifying the Instruction definition to inherit from Sched. For
+// each subtarget, define WriteRes and ReadAdvance to associate
+// processor resources and latency with each SchedReadWrite type.
+//
+// B. In each instruction definition, name an ItineraryClass. For each
+// subtarget, define ItinRW entries to map ItineraryClass to
+// per-operand SchedReadWrite types. Unlike method A, these types may
+// be subtarget specific and can be directly associated with resources
+// by defining SchedWriteRes and SchedReadAdvance.
+//
+// C. In the subtarget, map SchedReadWrite types to specific
+// opcodes. This overrides any SchedReadWrite types or
+// ItineraryClasses defined by the Instruction. As in method B, the
+// subtarget can directly associate resources with SchedReadWrite
+// types by defining SchedWriteRes and SchedReadAdvance.
+//
+// D. In either the target or subtarget, define SchedWriteVariant or
+// SchedReadVariant to map one SchedReadWrite type onto another
+// sequence of SchedReadWrite types. This allows dynamic selection of
+// an instruction's machine model via custom C++ code. It also allows
+// a machine-independent SchedReadWrite type to map to a sequence of
+// machine-dependent types.
+//
+// (3) A per-pipeline-stage machine model can be implemented by providing
+// Itineraries in addition to mapping instructions to ItineraryClasses.
//===----------------------------------------------------------------------===//
+// Include legacy support for instruction itineraries.
include "llvm/Target/TargetItinerary.td"
-// The SchedMachineModel is defined by subtargets for three categories of data:
-// 1) Basic properties for coarse grained instruction cost model.
-// 2) Scheduler Read/Write resources for simple per-opcode cost model.
-// 3) Instruction itineraties for detailed reservation tables.
+class Instruction; // Forward def
+
+// DAG operator that interprets the DAG args as Instruction defs.
+def instrs;
+
+// DAG operator that interprets each DAG arg as a regex pattern for
+// matching Instruction opcode names.
+// The regex must match the beginning of the opcode (as in Python re.match).
+// To avoid matching prefixes, append '$' to the pattern.
+def instregex;
+
+// Define the SchedMachineModel and provide basic properties for
+// coarse grained instruction cost model. Default values for the
+// properties are defined in MCSchedModel. A value of "-1" in the
+// target description's SchedMachineModel indicates that the property
+// is not overriden by the target.
//
-// Default values for basic properties are defined in MCSchedModel. "-1"
-// indicates that the property is not overriden by the target description.
+// Target hooks allow subtargets to associate LoadLatency and
+// HighLatency with groups of opcodes.
class SchedMachineModel {
- int IssueWidth = -1; // Max instructions that may be scheduled per cycle.
+ int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle.
int MinLatency = -1; // Determines which instrucions are allowed in a group.
// (-1) inorder (0) ooo, (1): inorder +var latencies.
int LoadLatency = -1; // Cycles for loads to access the cache.
int HighLatency = -1; // Approximation of cycles for "high latency" ops.
int MispredictPenalty = -1; // Extra cycles for a mispredicted branch.
+ // Per-cycle resources tables.
ProcessorItineraries Itineraries = NoItineraries;
bit NoModel = 0; // Special tag to indicate missing machine model.
@@ -38,4 +90,276 @@ def NoSchedModel : SchedMachineModel {
let NoModel = 1;
}
-// TODO: Define classes for processor and scheduler resources.
+// Define a kind of processor resource that may be common across
+// similar subtargets.
+class ProcResourceKind;
+
+// Define a number of interchangeable processor resources. NumUnits
+// determines the throughput of instructions that require the resource.
+//
+// An optional Super resource may be given to model these resources as
+// a subset of the more general super resources. Using one of these
+// resources implies using one of the super resoruces.
+//
+// ProcResourceUnits normally model a few buffered resources within an
+// out-of-order engine that the compiler attempts to conserve.
+// Buffered resources may be held for multiple clock cycles, but the
+// scheduler does not pin them to a particular clock cycle relative to
+// instruction dispatch. Setting Buffered=0 changes this to an
+// in-order resource. In this case, the scheduler counts down from the
+// cycle that the instruction issues in-order, forcing an interlock
+// with subsequent instructions that require the same resource until
+// the number of ResourceCyles specified in WriteRes expire.
+//
+// SchedModel ties these units to a processor for any stand-alone defs
+// of this class. Instances of subclass ProcResource will be automatically
+// attached to a processor, so SchedModel is not needed.
+class ProcResourceUnits<ProcResourceKind kind, int num> {
+ ProcResourceKind Kind = kind;
+ int NumUnits = num;
+ ProcResourceKind Super = ?;
+ bit Buffered = 1;
+ SchedMachineModel SchedModel = ?;
+}
+
+// EponymousProcResourceKind helps implement ProcResourceUnits by
+// allowing a ProcResourceUnits definition to reference itself. It
+// should not be referenced anywhere else.
+def EponymousProcResourceKind : ProcResourceKind;
+
+// Subtargets typically define processor resource kind and number of
+// units in one place.
+class ProcResource<int num> : ProcResourceKind,
+ ProcResourceUnits<EponymousProcResourceKind, num>;
+
+// A target architecture may define SchedReadWrite types and associate
+// them with instruction operands.
+class SchedReadWrite;
+
+// List the per-operand types that map to the machine model of an
+// instruction. One SchedWrite type must be listed for each explicit
+// def operand in order. Additional SchedWrite types may optionally be
+// listed for implicit def operands. SchedRead types may optionally
+// be listed for use operands in order. The order of defs relative to
+// uses is insignificant. This way, the same SchedReadWrite list may
+// be used for multiple forms of an operation. For example, a
+// two-address instruction could have two tied operands or single
+// operand that both reads and writes a reg. In both cases we have a
+// single SchedWrite and single SchedRead in any order.
+class Sched<list<SchedReadWrite> schedrw> {
+ list<SchedReadWrite> SchedRW = schedrw;
+}
+
+// Define a scheduler resource associated with a def operand.
+class SchedWrite : SchedReadWrite;
+def NoWrite : SchedWrite;
+
+// Define a scheduler resource associated with a use operand.
+class SchedRead : SchedReadWrite;
+
+// Define a SchedWrite that is modeled as a sequence of other
+// SchedWrites with additive latency. This allows a single operand to
+// be mapped the resources composed from a set of previously defined
+// SchedWrites.
+//
+// If the final write in this sequence is a SchedWriteVariant marked
+// Variadic, then the list of prior writes are distributed across all
+// operands after resolving the predicate for the final write.
+//
+// SchedModel silences warnings but is ignored.
+class WriteSequence<list<SchedWrite> writes, int rep = 1> : SchedWrite {
+ list<SchedWrite> Writes = writes;
+ int Repeat = rep;
+ SchedMachineModel SchedModel = ?;
+}
+
+// Define values common to WriteRes and SchedWriteRes.
+//
+// SchedModel ties these resources to a processor.
+class ProcWriteResources<list<ProcResourceKind> resources> {
+ list<ProcResourceKind> ProcResources = resources;
+ list<int> ResourceCycles = [];
+ int Latency = 1;
+ int NumMicroOps = 1;
+ bit BeginGroup = 0;
+ bit EndGroup = 0;
+ // Allow a processor to mark some scheduling classes as unsupported
+ // for stronger verification.
+ bit Unsupported = 0;
+ SchedMachineModel SchedModel = ?;
+}
+
+// Define the resources and latency of a SchedWrite. This will be used
+// directly by targets that have no itinerary classes. In this case,
+// SchedWrite is defined by the target, while WriteResources is
+// defined by the subtarget, and maps the SchedWrite to processor
+// resources.
+//
+// If a target already has itinerary classes, SchedWriteResources can
+// be used instead to define subtarget specific SchedWrites and map
+// them to processor resources in one place. Then ItinRW can map
+// itinerary classes to the subtarget's SchedWrites.
+//
+// ProcResources indicates the set of resources consumed by the write.
+// Optionally, ResourceCycles indicates the number of cycles the
+// resource is consumed. Each ResourceCycles item is paired with the
+// ProcResource item at the same position in its list. Since
+// ResourceCycles are rarely specialized, the list may be
+// incomplete. By default, resources are consumed for a single cycle,
+// regardless of latency, which models a fully pipelined processing
+// unit. A value of 0 for ResourceCycles means that the resource must
+// be available but is not consumed, which is only relevant for
+// unbuffered resources.
+//
+// By default, each SchedWrite takes one micro-op, which is counted
+// against the processor's IssueWidth limit. If an instruction can
+// write multiple registers with a single micro-op, the subtarget
+// should define one of the writes to be zero micro-ops. If a
+// subtarget requires multiple micro-ops to write a single result, it
+// should either override the write's NumMicroOps to be greater than 1
+// or require additional writes. Extra writes can be required either
+// by defining a WriteSequence, or simply listing extra writes in the
+// instruction's list of writers beyond the number of "def"
+// operands. The scheduler assumes that all micro-ops must be
+// dispatched in the same cycle. These micro-ops may be required to
+// begin or end the current dispatch group.
+class WriteRes<SchedWrite write, list<ProcResourceKind> resources>
+ : ProcWriteResources<resources> {
+ SchedWrite WriteType = write;
+}
+
+// Directly name a set of WriteResources defining a new SchedWrite
+// type at the same time. This class is unaware of its SchedModel so
+// must be referenced by InstRW or ItinRW.
+class SchedWriteRes<list<ProcResourceKind> resources> : SchedWrite,
+ ProcWriteResources<resources>;
+
+// Define values common to ReadAdvance and SchedReadAdvance.
+//
+// SchedModel ties these resources to a processor.
+class ProcReadAdvance<int cycles, list<SchedWrite> writes = []> {
+ int Cycles = cycles;
+ list<SchedWrite> ValidWrites = writes;
+ // Allow a processor to mark some scheduling classes as unsupported
+ // for stronger verification.
+ bit Unsupported = 0;
+ SchedMachineModel SchedModel = ?;
+}
+
+// A processor may define a ReadAdvance associated with a SchedRead
+// to reduce latency of a prior write by N cycles. A negative advance
+// effectively increases latency, which may be used for cross-domain
+// stalls.
+//
+// A ReadAdvance may be associated with a list of SchedWrites
+// to implement pipeline bypass. The Writes list may be empty to
+// indicate operands that are always read this number of Cycles later
+// than a normal register read, allowing the read's parent instruction
+// to issue earlier relative to the writer.
+class ReadAdvance<SchedRead read, int cycles, list<SchedWrite> writes = []>
+ : ProcReadAdvance<cycles, writes> {
+ SchedRead ReadType = read;
+}
+
+// Directly associate a new SchedRead type with a delay and optional
+// pipeline bypess. For use with InstRW or ItinRW.
+class SchedReadAdvance<int cycles, list<SchedWrite> writes = []> : SchedRead,
+ ProcReadAdvance<cycles, writes>;
+
+// Define SchedRead defaults. Reads seldom need special treatment.
+def ReadDefault : SchedRead;
+def NoReadAdvance : SchedReadAdvance<0>;
+
+// Define shared code that will be in the same scope as all
+// SchedPredicates. Available variables are:
+// (const MachineInstr *MI, const TargetSchedModel *SchedModel)
+class PredicateProlog<code c> {
+ code Code = c;
+}
+
+// Define a predicate to determine which SchedVariant applies to a
+// particular MachineInstr. The code snippet is used as an
+// if-statement's expression. Available variables are MI, SchedModel,
+// and anything defined in a PredicateProlog.
+//
+// SchedModel silences warnings but is ignored.
+class SchedPredicate<code pred> {
+ SchedMachineModel SchedModel = ?;
+ code Predicate = pred;
+}
+def NoSchedPred : SchedPredicate<[{true}]>;
+
+// Associate a predicate with a list of SchedReadWrites. By default,
+// the selected SchedReadWrites are still associated with a single
+// operand and assumed to execute sequentially with additive
+// latency. However, if the parent SchedWriteVariant or
+// SchedReadVariant is marked "Variadic", then each Selected
+// SchedReadWrite is mapped in place to the instruction's variadic
+// operands. In this case, latency is not additive. If the current Variant
+// is already part of a Sequence, then that entire chain leading up to
+// the Variant is distributed over the variadic operands.
+class SchedVar<SchedPredicate pred, list<SchedReadWrite> selected> {
+ SchedPredicate Predicate = pred;
+ list<SchedReadWrite> Selected = selected;
+}
+
+// SchedModel silences warnings but is ignored.
+class SchedVariant<list<SchedVar> variants> {
+ list<SchedVar> Variants = variants;
+ bit Variadic = 0;
+ SchedMachineModel SchedModel = ?;
+}
+
+// A SchedWriteVariant is a single SchedWrite type that maps to a list
+// of SchedWrite types under the conditions defined by its predicates.
+//
+// A Variadic write is expanded to cover multiple "def" operands. The
+// SchedVariant's Expansion list is then interpreted as one write
+// per-operand instead of the usual sequential writes feeding a single
+// operand.
+class SchedWriteVariant<list<SchedVar> variants> : SchedWrite,
+ SchedVariant<variants> {
+}
+
+// A SchedReadVariant is a single SchedRead type that maps to a list
+// of SchedRead types under the conditions defined by its predicates.
+//
+// A Variadic write is expanded to cover multiple "readsReg" operands as
+// explained above.
+class SchedReadVariant<list<SchedVar> variants> : SchedRead,
+ SchedVariant<variants> {
+}
+
+// Map a set of opcodes to a list of SchedReadWrite types. This allows
+// the subtarget to easily override specific operations.
+//
+// SchedModel ties this opcode mapping to a processor.
+class InstRW<list<SchedReadWrite> rw, dag instrlist> {
+ list<SchedReadWrite> OperandReadWrites = rw;
+ dag Instrs = instrlist;
+ SchedMachineModel SchedModel = ?;
+}
+
+// Map a set of itinerary classes to SchedReadWrite resources. This is
+// used to bootstrap a target (e.g. ARM) when itineraries already
+// exist and changing InstrInfo is undesirable.
+//
+// SchedModel ties this ItineraryClass mapping to a processor.
+class ItinRW<list<SchedReadWrite> rw, list<InstrItinClass> iic> {
+ list<InstrItinClass> MatchedItinClasses = iic;
+ list<SchedReadWrite> OperandReadWrites = rw;
+ SchedMachineModel SchedModel = ?;
+}
+
+// Alias a target-defined SchedReadWrite to a processor specific
+// SchedReadWrite. This allows a subtarget to easily map a
+// SchedReadWrite type onto a WriteSequence, SchedWriteVariant, or
+// SchedReadVariant.
+//
+// SchedModel will usually be provided by surrounding let statement
+// and ties this SchedAlias mapping to a processor.
+class SchedAlias<SchedReadWrite match, SchedReadWrite alias> {
+ SchedReadWrite MatchRW = match;
+ SchedReadWrite AliasRW = alias;
+ SchedMachineModel SchedModel = ?;
+}
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index c9ca722..96793bc 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -20,7 +20,7 @@
namespace llvm {
-class TargetData;
+class DataLayout;
class TargetMachine;
//===----------------------------------------------------------------------===//
@@ -28,13 +28,13 @@ class TargetMachine;
/// SelectionDAG lowering and instruction selection process.
///
class TargetSelectionDAGInfo {
- TargetSelectionDAGInfo(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
- void operator=(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
+ TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
- const TargetData *TD;
+ const DataLayout *TD;
protected:
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
public:
explicit TargetSelectionDAGInfo(const TargetMachine &TM);
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index fc23b2c..3f22f47 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -19,9 +19,11 @@
namespace llvm {
+class MachineInstr;
class SDep;
class SUnit;
class TargetRegisterClass;
+class TargetSchedModel;
template <typename T> class SmallVectorImpl;
//===----------------------------------------------------------------------===//
@@ -31,8 +33,8 @@ template <typename T> class SmallVectorImpl;
/// be exposed through a TargetSubtargetInfo-derived class.
///
class TargetSubtargetInfo : public MCSubtargetInfo {
- TargetSubtargetInfo(const TargetSubtargetInfo&); // DO NOT IMPLEMENT
- void operator=(const TargetSubtargetInfo&); // DO NOT IMPLEMENT
+ TargetSubtargetInfo(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses...
TargetSubtargetInfo();
public:
@@ -43,23 +45,33 @@ public:
virtual ~TargetSubtargetInfo();
- /// getSpecialAddressLatency - For targets where it is beneficial to
- /// backschedule instructions that compute addresses, return a value
- /// indicating the number of scheduling cycles of backscheduling that
- /// should be attempted.
- virtual unsigned getSpecialAddressLatency() const { return 0; }
+ /// Resolve a SchedClass at runtime, where SchedClass identifies an
+ /// MCSchedClassDesc with the isVariant property. This may return the ID of
+ /// another variant SchedClass, but repeated invocation must quickly terminate
+ /// in a nonvariant SchedClass.
+ virtual unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *MI,
+ const TargetSchedModel* SchedModel) const {
+ return 0;
+ }
+
+ /// \brief True if the subtarget should run MachineScheduler after aggressive
+ /// coalescing.
+ ///
+ /// This currently replaces the SelectionDAG scheduler with the "source" order
+ /// scheduler. It does not yet disable the postRA scheduler.
+ virtual bool enableMachineScheduler() const;
// enablePostRAScheduler - If the target can benefit from post-regalloc
// scheduling and the specified optimization level meets the requirement
// return true to enable post-register-allocation scheduling. In
// CriticalPathRCs return any register classes that should only be broken
- // if on the critical path.
+ // if on the critical path.
virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const;
// adjustSchedDependency - Perform target specific adjustments to
// the latency of a schedule dependency.
- virtual void adjustSchedDependency(SUnit *def, SUnit *use,
+ virtual void adjustSchedDependency(SUnit *def, SUnit *use,
SDep& dep) const { }
};
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index 18176e8..e6eb8d3 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -15,7 +15,7 @@
#ifndef LLVM_TRANSFORMS_IPO_H
#define LLVM_TRANSFORMS_IPO_H
-#include <vector>
+#include "llvm/ADT/ArrayRef.h"
namespace llvm {
@@ -104,23 +104,14 @@ Pass *createPruneEHPass();
//===----------------------------------------------------------------------===//
/// createInternalizePass - This pass loops over all of the functions in the
-/// input module, internalizing all globals (functions and variables) not part
-/// of the api. If a list of symbols is specified with the
-/// -internalize-public-api-* command line options, those symbols are not
-/// internalized and all others are. Otherwise if AllButMain is set and the
-/// main function is found, all other globals are marked as internal. If no api
-/// is supplied and AllButMain is not set, or no main function is found, nothing
-/// is internalized.
-///
-ModulePass *createInternalizePass(bool AllButMain);
-
-/// createInternalizePass - This pass loops over all of the functions in the
/// input module, internalizing all globals (functions and variables) not in the
/// given exportList.
///
/// Note that commandline options that are used with the above function are not
-/// used now! Also, when exportList is empty, nothing is internalized.
-ModulePass *createInternalizePass(const std::vector<const char *> &exportList);
+/// used now!
+ModulePass *createInternalizePass(ArrayRef<const char *> exportList);
+/// createInternalizePass - Same as above, but with an empty exportList.
+ModulePass *createInternalizePass();
//===----------------------------------------------------------------------===//
/// createDeadArgEliminationPass - This pass removes arguments from functions
@@ -192,6 +183,16 @@ ModulePass *createMergeFunctionsPass();
/// createPartialInliningPass - This pass inlines parts of functions.
///
ModulePass *createPartialInliningPass();
+
+//===----------------------------------------------------------------------===//
+// createMetaRenamerPass - Rename everything with metasyntatic names.
+//
+ModulePass *createMetaRenamerPass();
+
+//===----------------------------------------------------------------------===//
+/// createBarrierNoopPass - This pass is purely a module pass barrier in a pass
+/// manager.
+ModulePass *createBarrierNoopPass();
} // End llvm namespace
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
index 7c3cfc8..43a0ac8 100644
--- a/include/llvm/Transforms/IPO/InlinerPass.h
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -17,11 +17,11 @@
#ifndef LLVM_TRANSFORMS_IPO_INLINERPASS_H
#define LLVM_TRANSFORMS_IPO_INLINERPASS_H
-#include "llvm/CallGraphSCCPass.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
namespace llvm {
class CallSite;
- class TargetData;
+ class DataLayout;
class InlineCost;
template<class PtrType, unsigned SmallSize>
class SmallPtrSet;
@@ -42,6 +42,7 @@ struct Inliner : public CallGraphSCCPass {
// Pass class.
virtual bool runOnSCC(CallGraphSCC &SCC);
+ using llvm::Pass::doFinalization;
// doFinalization - Remove now-dead linkonce functions at the end of
// processing to avoid breaking the SCC traversal.
virtual bool doFinalization(CallGraph &CG);
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 47ce902..3ea0a42 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -104,6 +104,7 @@ public:
bool DisableUnitAtATime;
bool DisableUnrollLoops;
bool Vectorize;
+ bool LoopVectorize;
private:
/// ExtensionList - This is list of all of the extensions that are registered.
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 4b0c448..5504dc9 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -14,6 +14,8 @@
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H
#define LLVM_TRANSFORMS_INSTRUMENTATION_H
+#include "llvm/ADT/StringRef.h"
+
namespace llvm {
class ModulePass;
@@ -31,19 +33,27 @@ ModulePass *createPathProfilerPass();
// Insert GCOV profiling instrumentation
ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true,
bool Use402Format = false,
- bool UseExtraChecksum = false);
+ bool UseExtraChecksum = false,
+ bool NoRedZone = false);
// Insert AddressSanitizer (address sanity checking) instrumentation
-ModulePass *createAddressSanitizerPass();
+FunctionPass *createAddressSanitizerFunctionPass(
+ bool CheckInitOrder = false, bool CheckUseAfterReturn = false,
+ bool CheckLifetime = false, StringRef BlacklistFile = StringRef());
+ModulePass *createAddressSanitizerModulePass(
+ bool CheckInitOrder = false, StringRef BlacklistFile = StringRef());
+
+// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
+FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false,
+ StringRef BlacklistFile = StringRef());
+
// Insert ThreadSanitizer (race detection) instrumentation
-FunctionPass *createThreadSanitizerPass();
+FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef());
// BoundsChecking - This pass instruments the code to perform run-time bounds
// checking on loads, stores, and other memory intrinsics.
-// Penalty is the maximum run-time that is acceptable for the user.
-//
-FunctionPass *createBoundsCheckingPass(unsigned Penalty = 5);
+FunctionPass *createBoundsCheckingPass();
} // End llvm namespace
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 3dce6fe..d465127 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -70,6 +70,12 @@ FunctionPass *createAggressiveDCEPass();
//===----------------------------------------------------------------------===//
//
+// SROA - Replace aggregates or pieces of aggregates with scalar SSA values.
+//
+FunctionPass *createSROAPass(bool RequiresDomTree = true);
+
+//===----------------------------------------------------------------------===//
+//
// ScalarReplAggregates - Break up alloca's of aggregates into multiple allocas
// if possible.
//
@@ -109,11 +115,9 @@ Pass *createLICMPass();
//===----------------------------------------------------------------------===//
//
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
-// a loop's canonical induction variable as one of their indices. It takes an
-// optional parameter used to consult the target machine whether certain
-// transformations are profitable.
+// a loop's canonical induction variable as one of their indices.
//
-Pass *createLoopStrengthReducePass(const TargetLowering *TLI = 0);
+Pass *createLoopStrengthReducePass();
Pass *createGlobalMergePass(const TargetLowering *TLI = 0);
diff --git a/include/llvm/Transforms/Utils/AddrModeMatcher.h b/include/llvm/Transforms/Utils/AddrModeMatcher.h
deleted file mode 100644
index 90485eb..0000000
--- a/include/llvm/Transforms/Utils/AddrModeMatcher.h
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- AddrModeMatcher.h - Addressing mode matching facility ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// AddressingModeMatcher - This class exposes a single public method, which is
-// used to construct a "maximal munch" of the addressing mode for the target
-// specified by TLI for an access to "V" with an access type of AccessTy. This
-// returns the addressing mode that is actually matched by value, but also
-// returns the list of instructions involved in that addressing computation in
-// AddrModeInsts.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H
-#define LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Target/TargetLowering.h"
-
-namespace llvm {
-
-class GlobalValue;
-class Instruction;
-class Value;
-class Type;
-class User;
-class raw_ostream;
-
-/// ExtAddrMode - This is an extended version of TargetLowering::AddrMode
-/// which holds actual Value*'s for register values.
-struct ExtAddrMode : public TargetLowering::AddrMode {
- Value *BaseReg;
- Value *ScaledReg;
- ExtAddrMode() : BaseReg(0), ScaledReg(0) {}
- void print(raw_ostream &OS) const;
- void dump() const;
-
- bool operator==(const ExtAddrMode& O) const {
- return (BaseReg == O.BaseReg) && (ScaledReg == O.ScaledReg) &&
- (BaseGV == O.BaseGV) && (BaseOffs == O.BaseOffs) &&
- (HasBaseReg == O.HasBaseReg) && (Scale == O.Scale);
- }
-};
-
-static inline raw_ostream &operator<<(raw_ostream &OS, const ExtAddrMode &AM) {
- AM.print(OS);
- return OS;
-}
-
-class AddressingModeMatcher {
- SmallVectorImpl<Instruction*> &AddrModeInsts;
- const TargetLowering &TLI;
-
- /// AccessTy/MemoryInst - This is the type for the access (e.g. double) and
- /// the memory instruction that we're computing this address for.
- Type *AccessTy;
- Instruction *MemoryInst;
-
- /// AddrMode - This is the addressing mode that we're building up. This is
- /// part of the return value of this addressing mode matching stuff.
- ExtAddrMode &AddrMode;
-
- /// IgnoreProfitability - This is set to true when we should not do
- /// profitability checks. When true, IsProfitableToFoldIntoAddressingMode
- /// always returns true.
- bool IgnoreProfitability;
-
- AddressingModeMatcher(SmallVectorImpl<Instruction*> &AMI,
- const TargetLowering &T, Type *AT,
- Instruction *MI, ExtAddrMode &AM)
- : AddrModeInsts(AMI), TLI(T), AccessTy(AT), MemoryInst(MI), AddrMode(AM) {
- IgnoreProfitability = false;
- }
-public:
-
- /// Match - Find the maximal addressing mode that a load/store of V can fold,
- /// give an access type of AccessTy. This returns a list of involved
- /// instructions in AddrModeInsts.
- static ExtAddrMode Match(Value *V, Type *AccessTy,
- Instruction *MemoryInst,
- SmallVectorImpl<Instruction*> &AddrModeInsts,
- const TargetLowering &TLI) {
- ExtAddrMode Result;
-
- bool Success =
- AddressingModeMatcher(AddrModeInsts, TLI, AccessTy,
- MemoryInst, Result).MatchAddr(V, 0);
- (void)Success; assert(Success && "Couldn't select *anything*?");
- return Result;
- }
-private:
- bool MatchScaledValue(Value *ScaleReg, int64_t Scale, unsigned Depth);
- bool MatchAddr(Value *V, unsigned Depth);
- bool MatchOperationAddr(User *Operation, unsigned Opcode, unsigned Depth);
- bool IsProfitableToFoldIntoAddressingMode(Instruction *I,
- ExtAddrMode &AMBefore,
- ExtAddrMode &AMAfter);
- bool ValueAlreadyLiveAtInst(Value *Val, Value *KnownLive1, Value *KnownLive2);
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 2510aec..d08f75e 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -17,7 +17,7 @@
// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
-#include "llvm/BasicBlock.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/DebugLoc.h"
@@ -25,9 +25,11 @@ namespace llvm {
class AliasAnalysis;
class Instruction;
+class MDNode;
class Pass;
class ReturnInst;
class TargetLibraryInfo;
+class TerminatorInst;
/// DeleteDeadBlock - Delete the specified block, which must have no
/// predecessors.
@@ -203,6 +205,29 @@ void SplitLandingPadPredecessors(BasicBlock *OrigBB,ArrayRef<BasicBlock*> Preds,
ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
BasicBlock *Pred);
+/// SplitBlockAndInsertIfThen - Split the containing block at the
+/// specified instruction - everything before and including Cmp stays
+/// in the old basic block, and everything after Cmp is moved to a
+/// new block. The two blocks are connected by a conditional branch
+/// (with value of Cmp being the condition).
+/// Before:
+/// Head
+/// Cmp
+/// Tail
+/// After:
+/// Head
+/// Cmp
+/// if (Cmp)
+/// ThenBlock
+/// Tail
+///
+/// If Unreachable is true, then ThenBlock ends with
+/// UnreachableInst, otherwise it branches to Tail.
+/// Returns the NewBasicBlock's terminator.
+
+TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
+ bool Unreachable, MDNode *BranchWeights = 0);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index a6e41f0..ca2d8f6 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -15,11 +15,11 @@
#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H
#define TRANSFORMS_UTILS_BUILDLIBCALLS_H
-#include "llvm/IRBuilder.h"
+#include "llvm/IR/IRBuilder.h"
namespace llvm {
class Value;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
@@ -28,52 +28,52 @@ namespace llvm {
/// EmitStrLen - Emit a call to the strlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, and the
/// return value has 'intptr_t' type.
- Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, MaxLen must
/// be of size_t type, and the return value has 'intptr_t' type.
Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitStrChr - Emit a call to the strchr function to the builder, for the
/// specified pointer and character. Ptr is required to be some pointer type,
/// and the return value has 'i8*' type.
- Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
/// specified pointer arguments.
Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
StringRef Name = "strcpy");
/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
/// specified pointer arguments and length.
Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
StringRef Name = "strncpy");
/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
/// are pointers.
Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
- IRBuilder<> &B, const TargetData *TD,
+ IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitMemCmp - Emit a call to the memcmp function.
Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
/// (e.g. 'floor'). This function is known to take a single of type matching
@@ -81,32 +81,32 @@ namespace llvm {
/// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f'
/// suffix.
Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
- const AttrListPtr &Attrs);
+ const AttributeSet &Attrs);
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
- Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
/// some pointer.
- Value *EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
/// an i32, and File is a pointer to FILE.
Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitFPutS - Emit a call to the puts function. Str is required to be a
/// pointer and File is a pointer to FILE.
- Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// SimplifyFortifiedLibCalls - Helper class for folding checked library
/// calls (e.g. __strcpy_chk) into their unchecked counterparts.
@@ -118,7 +118,7 @@ namespace llvm {
bool isString) const = 0;
public:
virtual ~SimplifyFortifiedLibCalls();
- bool fold(CallInst *CI, const TargetData *TD, const TargetLibraryInfo *TLI);
+ bool fold(CallInst *CI, const DataLayout *TD, const TargetLibraryInfo *TLI);
};
}
diff --git a/include/llvm/Transforms/Utils/BypassSlowDivision.h b/include/llvm/Transforms/Utils/BypassSlowDivision.h
index c262434..b11be05 100644
--- a/include/llvm/Transforms/Utils/BypassSlowDivision.h
+++ b/include/llvm/Transforms/Utils/BypassSlowDivision.h
@@ -18,7 +18,8 @@
#ifndef TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
#define TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
-#include "llvm/Function.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/Function.h"
namespace llvm {
@@ -26,7 +27,7 @@ namespace llvm {
/// profitably bypassed and carried out with a shorter, faster divide.
bool bypassSlowDivision(Function &F,
Function::iterator &I,
- const DenseMap<Type *, Type *> &BypassTypeMap);
+ const DenseMap<unsigned int, unsigned int> &BypassWidth);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index b7b5d29..14212f6 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -18,9 +18,9 @@
#ifndef LLVM_TRANSFORMS_UTILS_CLONING_H
#define LLVM_TRANSFORMS_UTILS_CLONING_H
-#include "llvm/ADT/ValueMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ValueMap.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
@@ -39,7 +39,7 @@ class ReturnInst;
class CallSite;
class Trace;
class CallGraph;
-class TargetData;
+class DataLayout;
class Loop;
class LoopInfo;
class AllocaInst;
@@ -116,13 +116,6 @@ Function *CloneFunction(const Function *F,
bool ModuleLevelChanges,
ClonedCodeInfo *CodeInfo = 0);
-/// CloneFunction - Version of the function that doesn't need the VMap.
-///
-inline Function *CloneFunction(const Function *F, ClonedCodeInfo *CodeInfo = 0){
- ValueToValueMapTy VMap;
- return CloneFunction(F, VMap, CodeInfo);
-}
-
/// Clone OldFunc into NewFunc, transforming the old arguments into references
/// to VMap values. Note that if NewFunc already has basic blocks, the ones
/// cloned into it will be added to the end of the function. This function
@@ -157,7 +150,7 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = 0,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
Instruction *TheCall = 0);
@@ -165,13 +158,13 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
/// InlineFunction call, and records the auxiliary results produced by it.
class InlineFunctionInfo {
public:
- explicit InlineFunctionInfo(CallGraph *cg = 0, const TargetData *td = 0)
+ explicit InlineFunctionInfo(CallGraph *cg = 0, const DataLayout *td = 0)
: CG(cg), TD(td) {}
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
- const TargetData *TD;
+ const DataLayout *TD;
/// StaticAllocas - InlineFunction fills this in with all static allocas that
/// get copied into the caller.
diff --git a/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
index 7ad7bdd..488d7a5 100644
--- a/include/llvm/Transforms/Utils/CmpInstAnalysis.h
+++ b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
@@ -15,7 +15,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
#define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
-#include "llvm/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
class ICmpInst;
diff --git a/include/llvm/Transforms/Utils/IntegerDivision.h b/include/llvm/Transforms/Utils/IntegerDivision.h
new file mode 100644
index 0000000..cecc807
--- /dev/null
+++ b/include/llvm/Transforms/Utils/IntegerDivision.h
@@ -0,0 +1,48 @@
+//===- llvm/Transforms/Utils/IntegerDivision.h ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains an implementation of 32bit integer division for targets
+// that don't have native support. It's largely derived from compiler-rt's
+// implementation of __udivsi3, but hand-tuned for targets that prefer less
+// control flow.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TRANSFORMS_UTILS_INTEGERDIVISION_H
+#define TRANSFORMS_UTILS_INTEGERDIVISION_H
+
+namespace llvm {
+ class BinaryOperator;
+}
+
+namespace llvm {
+
+ /// Generate code to calculate the remainder of two integers, replacing Rem
+ /// with the generated code. This currently generates code using the udiv
+ /// expansion, but future work includes generating more specialized code,
+ /// e.g. when more information about the operands are known. Currently only
+ /// implements 32bit scalar division (due to udiv's limitation), but future
+ /// work is removing this limitation.
+ ///
+ /// @brief Replace Rem with generated code.
+ bool expandRemainder(BinaryOperator *Rem);
+
+ /// Generate code to divide two integers, replacing Div with the generated
+ /// code. This currently generates code similarly to compiler-rt's
+ /// implementations, but future work includes generating more specialized code
+ /// when more information about the operands are known. Currently only
+ /// implements 32bit scalar division, but future work is removing this
+ /// limitation.
+ ///
+ /// @brief Replace Div with generated code.
+ bool expandDivision(BinaryOperator* Div);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 83f0e7a..687c9d5 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -15,10 +15,10 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H
#define LLVM_TRANSFORMS_UTILS_LOCAL_H
-#include "llvm/IRBuilder.h"
-#include "llvm/Operator.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Operator.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Target/TargetData.h"
namespace llvm {
@@ -35,8 +35,9 @@ class Pass;
class PHINode;
class AllocaInst;
class ConstantExpr;
-class TargetData;
+class DataLayout;
class TargetLibraryInfo;
+class TargetTransformInfo;
class DIBuilder;
template<typename T> class SmallVectorImpl;
@@ -84,7 +85,7 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0);
///
/// This returns true if it changed the code, note that it can delete
/// instructions in other blocks as well in this block.
-bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0,
+bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
//===----------------------------------------------------------------------===//
@@ -103,7 +104,7 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0,
/// .. and delete the predecessor corresponding to the '1', this will attempt to
/// recursively fold the 'and' to 0.
void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
- TargetData *TD = 0);
+ DataLayout *TD = 0);
/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
@@ -134,7 +135,8 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// of the CFG. It returns true if a modification was made, possibly deleting
/// the basic block that was pointed to.
///
-bool SimplifyCFG(BasicBlock *BB, const TargetData *TD = 0);
+bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
+ const DataLayout *TD = 0);
/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch,
/// and if a predecessor branches to us and one of our successors, fold the
@@ -162,10 +164,10 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
/// and it is more than the alignment of the ultimate object, see if we can
/// increase the alignment of the ultimate object, making this check succeed.
unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
- const TargetData *TD = 0);
+ const DataLayout *TD = 0);
/// getKnownAlignment - Try to infer an alignment for the specified pointer.
-static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) {
+static inline unsigned getKnownAlignment(Value *V, const DataLayout *TD = 0) {
return getOrEnforceKnownAlignment(V, 0, TD);
}
@@ -175,7 +177,7 @@ static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) {
/// When NoAssumptions is true, no assumptions about index computation not
/// overflowing is made.
template<typename IRBuilderTy>
-Value *EmitGEPOffset(IRBuilderTy *Builder, const TargetData &TD, User *GEP,
+Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
bool NoAssumptions = false) {
gep_type_iterator GTI = gep_type_begin(GEP);
Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
@@ -250,6 +252,16 @@ bool LowerDbgDeclare(Function &F);
/// an alloca, if any.
DbgDeclareInst *FindAllocaDbgDeclare(Value *V);
+/// replaceDbgDeclareForAlloca - Replaces llvm.dbg.declare instruction when
+/// alloca is replaced with a new value.
+bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
+ DIBuilder &Builder);
+
+/// \brief Remove all blocks that can not be reached from the function's entry.
+///
+/// Returns true if any basic block was removed.
+bool removeUnreachableBlocks(Function &F);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
index 4c82149..cd04893 100644
--- a/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -15,6 +15,7 @@
#define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
class BasicBlock;
@@ -109,8 +110,8 @@ public:
private:
Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
- void operator=(const SSAUpdater&); // DO NOT IMPLEMENT
- SSAUpdater(const SSAUpdater&); // DO NOT IMPLEMENT
+ void operator=(const SSAUpdater&) LLVM_DELETED_FUNCTION;
+ SSAUpdater(const SSAUpdater&) LLVM_DELETED_FUNCTION;
};
/// LoadAndStorePromoter - This little helper class provides a convenient way to
diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h
index 2632d18..7e97e21 100644
--- a/include/llvm/Transforms/Utils/SimplifyIndVar.h
+++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -21,8 +21,6 @@
namespace llvm {
-extern cl::opt<bool> DisableIVRewrite;
-
class CastInst;
class IVUsers;
class Loop;
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
new file mode 100644
index 0000000..6bb81be
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -0,0 +1,53 @@
+//===- SimplifyLibCalls.h - Library call simplifier -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an interface to build some C language libcalls for
+// optimization passes that need to call the various functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
+#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
+
+namespace llvm {
+ class Value;
+ class CallInst;
+ class DataLayout;
+ class Instruction;
+ class TargetLibraryInfo;
+ class LibCallSimplifierImpl;
+
+ /// LibCallSimplifier - This class implements a collection of optimizations
+ /// that replace well formed calls to library functions with a more optimal
+ /// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!")'.
+ class LibCallSimplifier {
+ /// Impl - A pointer to the actual implementation of the library call
+ /// simplifier.
+ LibCallSimplifierImpl *Impl;
+ public:
+ LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI,
+ bool UnsafeFPShrink);
+ virtual ~LibCallSimplifier();
+
+ /// optimizeCall - Take the given call instruction and return a more
+ /// optimal value to replace the instruction with or 0 if a more
+ /// optimal form can't be found. Note that the returned value may
+ /// be equal to the instruction being optimized. In this case all
+ /// other instructions that use the given instruction were modified
+ /// and the given instruction is dead.
+ Value *optimizeCall(CallInst *CI);
+
+ /// replaceAllUsesWith - This method is used when the library call
+ /// simplifier needs to replace instructions other than the library
+ /// call being modified.
+ virtual void replaceAllUsesWith(Instruction *I, Value *With) const;
+ };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index 8594707..5390c5e 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -25,7 +25,7 @@ namespace llvm {
/// ValueMapTypeRemapper - This is a class that can be implemented by clients
/// to remap types when cloning constants and instructions.
class ValueMapTypeRemapper {
- virtual void Anchor(); // Out of line method.
+ virtual void anchor(); // Out of line method.
public:
virtual ~ValueMapTypeRemapper() {}
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
index 1e49a9c..1ba4d22 100644
--- a/include/llvm/Transforms/Vectorize.h
+++ b/include/llvm/Transforms/Vectorize.h
@@ -18,6 +18,7 @@
namespace llvm {
class BasicBlock;
class BasicBlockPass;
+class Pass;
//===----------------------------------------------------------------------===//
/// @brief Vectorize configuration.
@@ -107,6 +108,12 @@ BasicBlockPass *
createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
//===----------------------------------------------------------------------===//
+//
+// LoopVectorize - Create a loop vectorization pass.
+//
+Pass *createLoopVectorizePass();
+
+//===----------------------------------------------------------------------===//
/// @brief Vectorize the BasicBlock.
///
/// @param BB The BasicBlock to be vectorized